diff options
Diffstat (limited to 'indra/newview')
1985 files changed, 104150 insertions, 62007 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 84ac293c63..bd0169fb2f 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -13,16 +13,18 @@ include(EXPAT) include(FMOD) include(OPENAL) include(FindOpenGL) +include(Hunspell) include(JsonCpp) include(LLAudio) include(LLCharacter) include(LLCommon) -include(LLConvexDecomposition) +include(LLCoreHttp) include(LLImage) include(LLImageJ2COJ) include(LLInventory) include(LLMath) include(LLMessage) +include(LLPhysicsExtensions) include(LLPlugin) include(LLPrimitive) include(LLRender) @@ -30,10 +32,10 @@ include(LLUI) include(LLVFS) include(LLWindow) include(LLXML) -include(LLXUIXML) include(LScript) include(Linking) include(NDOF) +include(NVAPI) include(GooglePerfTools) include(TemplateCheck) include(UI) @@ -41,23 +43,31 @@ include(UnixInstall) include(LLKDU) include(ViewerMiscLibs) include(LLLogin) +include(VisualLeakDetector) include(GLOD) include(CMakeCopyIfDifferent) +if (NOT HAVOK_TPV) + # When using HAVOK_TPV, the library is precompiled, so no need for this + add_subdirectory(${LLPHYSICSEXTENSIONS_SRC_DIR} llphysicsextensions) +endif (NOT HAVOK_TPV) + include_directories( ${DBUSGLIB_INCLUDE_DIRS} - ${JSONCPP_INCLUDE_DIRS} + ${JSONCPP_INCLUDE_DIR} ${GLOD_INCLUDE_DIR} ${LLAUDIO_INCLUDE_DIRS} ${LLCHARACTER_INCLUDE_DIRS} ${LLCOMMON_INCLUDE_DIRS} - ${LLCONVEXDECOMP_INCLUDE_DIRS} + ${LLCOREHTTP_INCLUDE_DIRS} + ${LLPHYSICS_INCLUDE_DIRS} ${FMOD_INCLUDE_DIR} ${LLIMAGE_INCLUDE_DIRS} ${LLKDU_INCLUDE_DIRS} ${LLINVENTORY_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} ${LLMESSAGE_INCLUDE_DIRS} + ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS} ${LLPLUGIN_INCLUDE_DIRS} ${LLPRIMITIVE_INCLUDE_DIRS} ${LLRENDER_INCLUDE_DIRS} @@ -65,12 +75,12 @@ 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} ${UPDATER_INCLUDE_DIRS} ${LIBS_PREBUILT_DIR}/include/collada + ${LIBS_PREBUILD_DIR}/include/hunspell ${OPENAL_LIB_INCLUDE_DIRS} ${LIBS_PREBUILT_DIR}/include/collada/1.4 ) @@ -90,6 +100,7 @@ set(viewer_SOURCE_FILES llagentwearables.cpp llagentwearablesfetch.cpp llanimstatelabels.cpp + llappcorehttp.cpp llappearancemgr.cpp llappviewer.cpp llappviewerlistener.cpp @@ -97,17 +108,19 @@ set(viewer_SOURCE_FILES llassetuploadresponders.cpp llattachmentsmgr.cpp llaudiosourcevo.cpp + llautoreplace.cpp llavataractions.cpp llavatariconctrl.cpp llavatarlist.cpp llavatarlistitem.cpp llavatarpropertiesprocessor.cpp + llblockedlistitem.cpp + llblocklist.cpp llbox.cpp llbreadcrumbview.cpp llbrowsernotification.cpp llbuycurrencyhtml.cpp llcallbacklist.cpp - llcallfloater.cpp llcallingcard.cpp llcapabilitylistener.cpp llcaphttpsender.cpp @@ -125,16 +138,24 @@ set(viewer_SOURCE_FILES llcommanddispatcherlistener.cpp llcommandhandler.cpp llcommandlineparser.cpp + llcommunicationchannel.cpp llcompilequeue.cpp llconfirmationmanager.cpp + llconversationlog.cpp + llconversationloglist.cpp + llconversationloglistitem.cpp + llconversationmodel.cpp + llconversationview.cpp llcurrencyuimanager.cpp llcylinder.cpp lldateutil.cpp lldaycyclemanager.cpp lldebugmessagebox.cpp lldebugview.cpp + lldeferredsounds.cpp lldelayedgestureerror.cpp lldirpicker.cpp + lldonotdisturbnotificationstorage.cpp lldndbutton.cpp lldrawable.cpp lldrawpool.cpp @@ -166,8 +187,9 @@ set(viewer_SOURCE_FILES llfirstuse.cpp llflexibleobject.cpp llfloaterabout.cpp - llfloateranimpreview.cpp + llfloaterbvhpreview.cpp llfloaterauction.cpp + llfloaterautoreplacesettings.cpp llfloateravatar.cpp llfloateravatarpicker.cpp llfloateravatartextures.cpp @@ -181,7 +203,10 @@ set(viewer_SOURCE_FILES llfloaterbuycurrencyhtml.cpp llfloaterbuyland.cpp llfloatercamera.cpp + llfloaterchatvoicevolume.cpp llfloatercolorpicker.cpp + llfloaterconversationlog.cpp + llfloaterconversationpreview.cpp llfloaterdeleteenvpreset.cpp llfloaterdestinations.cpp llfloaterdisplayname.cpp @@ -211,11 +236,15 @@ set(viewer_SOURCE_FILES llfloatermemleak.cpp llfloatermodelpreview.cpp llfloatermodeluploadbase.cpp - llfloatermodelwizard.cpp llfloaternamedesc.cpp llfloaternotificationsconsole.cpp llfloaterobjectweights.cpp llfloateropenobject.cpp + llfloateroutbox.cpp + llfloaterpathfindingcharacters.cpp + llfloaterpathfindingconsole.cpp + llfloaterpathfindinglinksets.cpp + llfloaterpathfindingobjects.cpp llfloaterpay.cpp llfloaterperms.cpp llfloaterpostprocess.cpp @@ -232,9 +261,11 @@ set(viewer_SOURCE_FILES llfloatersidepanelcontainer.cpp llfloatersnapshot.cpp llfloatersounddevices.cpp + llfloaterspellchecksettings.cpp llfloatertelehub.cpp llfloatertestinspectors.cpp llfloatertestlistview.cpp + llfloatertexturefetchdebugger.cpp llfloatertools.cpp llfloatertopobjects.cpp llfloatertos.cpp @@ -243,12 +274,13 @@ set(viewer_SOURCE_FILES llfloateruipreview.cpp llfloaterurlentry.cpp llfloatervoiceeffect.cpp + llfloatervoicevolume.cpp llfloaterwebcontent.cpp + llfloaterwebprofile.cpp llfloaterwhitelistentry.cpp llfloaterwindowsize.cpp llfloaterworldmap.cpp - llfolderview.cpp - llfolderviewitem.cpp + llfolderviewmodelinventory.cpp llfollowcam.cpp llfriendcard.cpp llgesturelistener.cpp @@ -274,8 +306,9 @@ set(viewer_SOURCE_FILES llhudrender.cpp llhudtext.cpp llhudview.cpp - llimfloater.cpp - llimfloatercontainer.cpp + llfloaterimsessiontab.cpp + llfloaterimsession.cpp + llfloaterimcontainer.cpp llimhandler.cpp llimview.cpp llinspect.cpp @@ -285,7 +318,6 @@ set(viewer_SOURCE_FILES llinspectremoteobject.cpp llinspecttoast.cpp llinventorybridge.cpp - llinventoryclipboard.cpp llinventoryfilter.cpp llinventoryfunctions.cpp llinventoryicon.cpp @@ -301,6 +333,7 @@ set(viewer_SOURCE_FILES lllistbrowser.cpp lllistcontextmenu.cpp lllistview.cpp + lllocalbitmaps.cpp lllocaltextureobject.cpp lllocationhistory.cpp lllocationinputctrl.cpp @@ -313,10 +346,11 @@ set(viewer_SOURCE_FILES llmaniprotate.cpp llmanipscale.cpp llmaniptranslate.cpp + llmarketplacefunctions.cpp + llmarketplacenotifications.cpp llmediactrl.cpp llmediadataclient.cpp - llmemoryview.cpp - llmenucommands.cpp + llmenuoptionpathfindingrebakenavmesh.cpp llmeshrepository.cpp llmimetypes.cpp llmorphview.cpp @@ -326,10 +360,9 @@ set(viewer_SOURCE_FILES llnameeditor.cpp llnamelistctrl.cpp llnavigationbar.cpp - llnearbychat.cpp - llnearbychatbar.cpp - llnearbychathandler.cpp - llnearbychatbarlistener.cpp + llfloaterimnearbychat.cpp + llfloaterimnearbychathandler.cpp + llfloaterimnearbychatlistener.cpp llnetmap.cpp llnotificationalerthandler.cpp llnotificationgrouphandler.cpp @@ -359,7 +392,6 @@ set(viewer_SOURCE_FILES llpanelgroupnotices.cpp llpanelgrouproles.cpp llpanelhome.cpp - llpanelimcontrolpanel.cpp llpanelland.cpp llpanellandaudio.cpp llpanellandmarkinfo.cpp @@ -370,8 +402,6 @@ set(viewer_SOURCE_FILES llpanelmaininventory.cpp llpanelmarketplaceinbox.cpp llpanelmarketplaceinboxinventory.cpp - llpanelmarketplaceoutbox.cpp - llpanelmarketplaceoutboxinventory.cpp llpanelmediasettingsgeneral.cpp llpanelmediasettingspermissions.cpp llpanelmediasettingssecurity.cpp @@ -393,7 +423,6 @@ set(viewer_SOURCE_FILES llpanelplacestab.cpp llpanelprimmediacontrols.cpp llpanelprofile.cpp - llpanelprofileview.cpp llpanelsnapshot.cpp llpanelsnapshotinventory.cpp llpanelsnapshotlocal.cpp @@ -411,10 +440,23 @@ set(viewer_SOURCE_FILES llparcelselection.cpp llparticipantlist.cpp llpatchvertexarray.cpp + llpathfindingcharacter.cpp + llpathfindingcharacterlist.cpp + llpathfindinglinkset.cpp + llpathfindinglinksetlist.cpp + llpathfindingmanager.cpp + llpathfindingnavmesh.cpp + llpathfindingnavmeshstatus.cpp + llpathfindingnavmeshzone.cpp + llpathfindingobject.cpp + llpathfindingobjectlist.cpp + llpathfindingpathtool.cpp + llpersistentnotificationstorage.cpp llphysicsmotion.cpp llphysicsshapebuilderutil.cpp llplacesinventorybridge.cpp llplacesinventorypanel.cpp + llplacesfolderview.cpp llpopupview.cpp llpolymesh.cpp llpolymorph.cpp @@ -488,6 +530,7 @@ set(viewer_SOURCE_FILES lltoastnotifypanel.cpp lltoastpanel.cpp lltoastscripttextbox.cpp + lltoastscriptquestion.cpp lltool.cpp lltoolbarview.cpp lltoolbrush.cpp @@ -644,6 +687,7 @@ set(viewer_HEADER_FILES llagentwearables.h llagentwearablesfetch.h llanimstatelabels.h + llappcorehttp.h llappearance.h llappearancemgr.h llappviewer.h @@ -652,16 +696,18 @@ set(viewer_HEADER_FILES llassetuploadresponders.h llattachmentsmgr.h llaudiosourcevo.h + llautoreplace.h llavataractions.h llavatariconctrl.h llavatarlist.h llavatarlistitem.h llavatarpropertiesprocessor.h + llblockedlistitem.h + llblocklist.h llbox.h llbreadcrumbview.h llbuycurrencyhtml.h llcallbacklist.h - llcallfloater.h llcallingcard.h llcapabilitylistener.h llcapabilityprovider.h @@ -680,16 +726,24 @@ set(viewer_HEADER_FILES llcommanddispatcherlistener.h llcommandhandler.h llcommandlineparser.h + llcommunicationchannel.h llcompilequeue.h llconfirmationmanager.h + llconversationlog.h + llconversationloglist.h + llconversationloglistitem.h + llconversationmodel.h + llconversationview.h llcurrencyuimanager.h llcylinder.h lldateutil.h lldaycyclemanager.h lldebugmessagebox.h lldebugview.h + lldeferredsounds.h lldelayedgestureerror.h lldirpicker.h + lldonotdisturbnotificationstorage.h lldndbutton.h lldrawable.h lldrawpool.h @@ -721,8 +775,9 @@ set(viewer_HEADER_FILES llfirstuse.h llflexibleobject.h llfloaterabout.h - llfloateranimpreview.h + llfloaterbvhpreview.h llfloaterauction.h + llfloaterautoreplacesettings.h llfloateravatar.h llfloateravatarpicker.h llfloateravatartextures.h @@ -736,7 +791,10 @@ set(viewer_HEADER_FILES llfloaterbuycurrencyhtml.h llfloaterbuyland.h llfloatercamera.h + llfloaterchatvoicevolume.h llfloatercolorpicker.h + llfloaterconversationlog.h + llfloaterconversationpreview.h llfloaterdeleteenvpreset.h llfloaterdestinations.h llfloaterdisplayname.h @@ -766,11 +824,15 @@ set(viewer_HEADER_FILES llfloatermemleak.h llfloatermodelpreview.h llfloatermodeluploadbase.h - llfloatermodelwizard.h llfloaternamedesc.h llfloaternotificationsconsole.h llfloaterobjectweights.h llfloateropenobject.h + llfloateroutbox.h + llfloaterpathfindingcharacters.h + llfloaterpathfindingconsole.h + llfloaterpathfindinglinksets.h + llfloaterpathfindingobjects.h llfloaterpay.h llfloaterperms.h llfloaterpostprocess.h @@ -787,9 +849,11 @@ set(viewer_HEADER_FILES llfloatersidepanelcontainer.h llfloatersnapshot.h llfloatersounddevices.h + llfloaterspellchecksettings.h llfloatertelehub.h llfloatertestinspectors.h llfloatertestlistview.h + llfloatertexturefetchdebugger.h llfloatertools.h llfloatertopobjects.h llfloatertos.h @@ -798,13 +862,13 @@ set(viewer_HEADER_FILES llfloateruipreview.h llfloaterurlentry.h llfloatervoiceeffect.h + llfloatervoicevolume.h llfloaterwebcontent.h + llfloaterwebprofile.h llfloaterwhitelistentry.h llfloaterwindowsize.h llfloaterworldmap.h - llfolderview.h - llfoldervieweventlistener.h - llfolderviewitem.h + llfolderviewmodelinventory.h llfollowcam.h llfriendcard.h llgesturelistener.h @@ -829,8 +893,9 @@ set(viewer_HEADER_FILES llhudrender.h llhudtext.h llhudview.h - llimfloater.h - llimfloatercontainer.h + llfloaterimsessiontab.h + llfloaterimsession.h + llfloaterimcontainer.h llimview.h llinspect.h llinspectavatar.h @@ -839,7 +904,6 @@ set(viewer_HEADER_FILES llinspectremoteobject.h llinspecttoast.h llinventorybridge.h - llinventoryclipboard.h llinventoryfilter.h llinventoryfunctions.h llinventoryicon.h @@ -856,6 +920,7 @@ set(viewer_HEADER_FILES lllistbrowser.h lllistcontextmenu.h lllistview.h + lllocalbitmaps.h lllocaltextureobject.h lllocationhistory.h lllocationinputctrl.h @@ -868,10 +933,11 @@ set(viewer_HEADER_FILES llmaniprotate.h llmanipscale.h llmaniptranslate.h + llmarketplacefunctions.h + llmarketplacenotifications.h llmediactrl.h llmediadataclient.h - llmemoryview.h - llmenucommands.h + llmenuoptionpathfindingrebakenavmesh.h llmeshrepository.h llmimetypes.h llmorphview.h @@ -881,10 +947,9 @@ set(viewer_HEADER_FILES llnameeditor.h llnamelistctrl.h llnavigationbar.h - llnearbychat.h - llnearbychatbar.h - llnearbychathandler.h - llnearbychatbarlistener.h + llfloaterimnearbychat.h + llfloaterimnearbychathandler.h + llfloaterimnearbychatlistener.h llnetmap.h llnotificationhandler.h llnotificationmanager.h @@ -908,7 +973,6 @@ set(viewer_HEADER_FILES llpanelgroupnotices.h llpanelgrouproles.h llpanelhome.h - llpanelimcontrolpanel.h llpanelland.h llpanellandaudio.h llpanellandmarkinfo.h @@ -919,8 +983,6 @@ set(viewer_HEADER_FILES llpanelmaininventory.h llpanelmarketplaceinbox.h llpanelmarketplaceinboxinventory.h - llpanelmarketplaceoutbox.h - llpanelmarketplaceoutboxinventory.h llpanelmediasettingsgeneral.h llpanelmediasettingspermissions.h llpanelmediasettingssecurity.h @@ -942,7 +1004,6 @@ set(viewer_HEADER_FILES llpanelplacestab.h llpanelprimmediacontrols.h llpanelprofile.h - llpanelprofileview.h llpanelsnapshot.h llpanelteleporthistory.h llpaneltiptoast.h @@ -955,10 +1016,23 @@ set(viewer_HEADER_FILES llparcelselection.h llparticipantlist.h llpatchvertexarray.h + llpathfindingcharacter.h + llpathfindingcharacterlist.h + llpathfindinglinkset.h + llpathfindinglinksetlist.h + llpathfindingmanager.h + llpathfindingnavmesh.h + llpathfindingnavmeshstatus.h + llpathfindingnavmeshzone.h + llpathfindingobject.h + llpathfindingobjectlist.h + llpathfindingpathtool.h + llpersistentnotificationstorage.h llphysicsmotion.h llphysicsshapebuilderutil.h llplacesinventorybridge.h llplacesinventorypanel.h + llplacesfolderview.h llpolymesh.h llpolymorph.h llpopupview.h @@ -1034,6 +1108,7 @@ set(viewer_HEADER_FILES lltoastnotifypanel.h lltoastpanel.h lltoastscripttextbox.h + lltoastscriptquestion.h lltool.h lltoolbarview.h lltoolbrush.h @@ -1303,6 +1378,11 @@ if (WINDOWS) res/lltoolgrab.cur res/lltoolland.cur res/lltoolpan.cur + res/lltoolpathfinding.cur + res/lltoolpathfindingpathend.cur + res/lltoolpathfindingpathendadd.cur + res/lltoolpathfindingpathstart.cur + res/lltoolpathfindingpathstartadd.cur res/lltoolpipette.cur res/lltoolrotate.cur res/lltoolscale.cur @@ -1343,7 +1423,9 @@ if (WINDOWS) DXGUID_LIBRARY ) +# see EXP-1765 - theory is opengl32.lib needs to be included before gdi32.lib (windows libs) set(viewer_LIBRARIES + opengl32 ${WINDOWS_LIBRARIES} comdlg32 ${DINPUT_LIBRARY} @@ -1353,7 +1435,6 @@ if (WINDOWS) odbccp32 ole32 oleaut32 - opengl32 shell32 Vfw32 winspool @@ -1510,10 +1591,9 @@ if (WINDOWS) set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES # *TODO -reenable this once we get server usage sorted out - #LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:\"__tcmalloc\"" - LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:__tcmalloc" - LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO" - LINK_FLAGS_RELEASE "" + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS ${TCMALLOC_LINK_FLAGS} /LARGEADDRESSAWARE" + LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO /LARGEADDRESSAWARE" + LINK_FLAGS_RELEASE "/FORCE:MULTIPLE /MAP\"secondlife-bin.MAP\" /OPT:REF /LARGEADDRESSAWARE" ) if(USE_PRECOMPILED_HEADERS) set_target_properties( @@ -1530,7 +1610,7 @@ if (WINDOWS) # In the meantime, if you have any ideas on how to easily maintain one list, either here or in viewer_manifest.py # and have the build deps get tracked *please* tell me about it. - if(USE_GOOGLE_PERFTOOLS) + if(USE_TCMALLOC) # Configure a var for tcmalloc location, if used. # Note the need to specify multiple names explicitly. set(GOOGLE_PERF_TOOLS_SOURCE @@ -1538,7 +1618,7 @@ if (WINDOWS) ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libtcmalloc_minimal.dll ${SHARED_LIB_STAGING_DIR}/Debug/libtcmalloc_minimal-debug.dll ) - endif(USE_GOOGLE_PERFTOOLS) + endif(USE_TCMALLOC) set(COPY_INPUT_DEPENDENCIES @@ -1568,6 +1648,9 @@ if (WINDOWS) ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/msvcp100.dll ${SHARED_LIB_STAGING_DIR}/Debug/msvcr100d.dll ${SHARED_LIB_STAGING_DIR}/Debug/msvcp100d.dll + ${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll + ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll + ${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/SLVoice.exe ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk.dll ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ortp.dll @@ -1718,6 +1801,17 @@ if (WINDOWS) #${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2) endif (PACKAGE) +elseif (DARWIN) + set_target_properties(${VIEWER_BINARY_NAME} + PROPERTIES + LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Xlinker -dead_strip -Xlinker -map -Xlinker ${CMAKE_CURRENT_BINARY_DIR}/${VIEWER_BINARY_NAME}.MAP" + ) +else (WINDOWS) + # Linux + set_target_properties(${VIEWER_BINARY_NAME} + PROPERTIES + LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Wl,--Map=${VIEWER_BINARY_NAME}.MAP" + ) endif (WINDOWS) # *NOTE - this list is very sensitive to ordering, test carefully on all @@ -1742,11 +1836,13 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLVFS_LIBRARIES} ${LLWINDOW_LIBRARIES} ${LLXML_LIBRARIES} - ${LLXUIXML_LIBRARIES} ${LSCRIPT_LIBRARIES} ${LLMATH_LIBRARIES} + ${LLCOREHTTP_LIBRARIES} ${LLCOMMON_LIBRARIES} ${NDOF_LIBRARY} + ${NVAPI_LIBRARY} + ${HUNSPELL_LIBRARY} ${viewer_LIBRARIES} ${BOOST_PROGRAM_OPTIONS_LIBRARY} ${BOOST_REGEX_LIBRARY} @@ -1765,7 +1861,8 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} ${LLLOGIN_LIBRARIES} - ${LLCONVEXDECOMP_LIBRARY} + ${LLPHYSICS_LIBRARIES} + ${LLPHYSICSEXTENSIONS_LIBRARIES} ${TCMALLOC_LIBRARIES} ) @@ -1793,7 +1890,6 @@ if (LINUX) set(COPY_INPUT_DEPENDENCIES ${VIEWER_BINARY_NAME} linux-crash-logger - linux-updater SLPlugin media_plugin_webkit media_plugin_gstreamer010 @@ -1887,6 +1983,12 @@ if (DARWIN) ) add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit mac-updater mac-crash-logger) + + if (ENABLE_SIGNING) + set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}") + else (ENABLE_SIGNING) + set(SIGNING_SETTING "") + endif (ENABLE_SIGNING) if (PACKAGE) add_custom_target(package ALL DEPENDS ${VIEWER_BINARY_NAME}) @@ -1906,6 +2008,7 @@ if (DARWIN) --login_channel=${VIEWER_LOGIN_CHANNEL} --source=${CMAKE_CURRENT_SOURCE_DIR} --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched + ${SIGNING_SETTING} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) @@ -1917,8 +2020,9 @@ if (INSTALL) endif (INSTALL) if (PACKAGE) + set(SYMBOL_SEARCH_DIRS "") if (WINDOWS) - set(VIEWER_DIST_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}") + list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}") set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-windows.tar.bz2") # slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad # set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe") @@ -1927,13 +2031,20 @@ if (PACKAGE) set(VIEWER_COPY_MANIFEST copy_w_viewer_manifest) endif (WINDOWS) if (DARWIN) - set(VIEWER_DIST_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app") + list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}") + # *TODO: Generate these search dirs in the cmake files related to each binary. + list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}") + list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}") + list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_updater/${CMAKE_CFG_INTDIR}") + list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}") + list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}") + list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/webkit/${CMAKE_CFG_INTDIR}") set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin.tar.bz2") - set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin") + set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-updater mac-crash-logger") set(VIEWER_LIB_GLOB "*.dylib") endif (DARWIN) if (LINUX) - set(VIEWER_DIST_DIR "${CMAKE_CURRENT_BINARY_DIR}/packaged") + list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged") set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-linux.tar.bz2") set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin") set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*") @@ -1953,7 +2064,7 @@ if (PACKAGE) ARGS "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py" "${LLBUILD_CONFIG}" - "${VIEWER_DIST_DIR}" + "${SYMBOL_SEARCH_DIRS}" "${VIEWER_EXE_GLOBS}" "${VIEWER_LIB_GLOB}" "${AUTOBUILD_INSTALL_DIR}/bin/dump_syms" @@ -1990,6 +2101,12 @@ if (LL_TESTS) LL_TEST_ADDITIONAL_LIBRARIES "${JSONCPP_LIBRARIES}" ) + set_source_files_properties( + lllogininstance.cpp + PROPERTIES + LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" + ) + ################################################## # DISABLING PRECOMPILED HEADERS USAGE FOR TESTS ################################################## diff --git a/indra/newview/app_settings/autoreplace.xml b/indra/newview/app_settings/autoreplace.xml new file mode 100644 index 0000000000..09d19f7b04 --- /dev/null +++ b/indra/newview/app_settings/autoreplace.xml @@ -0,0 +1,8330 @@ +<llsd> + <array> + <map> + <key>name</key> + <string>Abbreviations</string> + <key>replacements</key> + <map> + <key>afaic</key> + <string>As far as I am concerned</string> + <key>afaik</key> + <string>As far as I know</string> + <key>afk</key> + <string>away from keyboard</string> + <key>atm</key> + <string>at the moment</string> + <key>bbiab</key> + <string>be back in a bit</string> + <key>bbl</key> + <string>be back later</string> + <key>brb</key> + <string>be right back</string> + <key>btw</key> + <string>by the way</string> + <key>fyi</key> + <string>For your information</string> + <key>fwiw</key> + <string>For what its worth</string> + <key>gtg</key> + <string>got to go</string> + <key>idk</key> + <string>I don't know</string> + <key>iirc</key> + <string>if I recall correctly</string> + <key>imho</key> + <string>in my humble opinion</string> + <key>imo</key> + <string>in my opinion</string> + <key>irl</key> + <string>in real life</string> + <key>np</key> + <string>no problem</string> + <key>nsfw</key> + <string>not safe for work</string> + <key>nvm</key> + <string>nevermind</string> + <key>tc</key> + <string>take care</string> + <key>thx</key> + <string>thanks</string> + <key>ttfn</key> + <string>ta-ta for now</string> + <key>ttyl</key> + <string>talk to you later</string> + <key>ty</key> + <string>thank you</string> + <key>tyvm</key> + <string>thank you very much</string> + <key>wb</key> + <string>welcome back</string> + <key>yw</key> + <string>you're welcome</string> + <key>yvw</key> + <string>you're very welcome</string> + </map> + </map> + <map> + <key>name</key> + <string>Spelling Corrections</string> + <key>replacements</key> + <map> + <key>Amercia</key> + <string>America</string> + <key>Bernouilli</key> + <string>Bernoulli</string> + <key>Blitzkreig</key> + <string>Blitzkrieg</string> + <key>Bonnano</key> + <string>Bonanno</string> + <key>Brasillian</key> + <string>Brazilian</string> + <key>Britian</key> + <string>Britain</string> + <key>Brittish</key> + <string>British</string> + <key>Buddah</key> + <string>Buddha</string> + <key>Buddist</key> + <string>Buddhist</string> + <key>Cambrige</key> + <string>Cambridge</string> + <key>Capetown</key> + <string>Cape Town</string> + <key>Carmalite</key> + <string>Carmelite</string> + <key>Carnagie</key> + <string>Carnegie</string> + <key>Carnagie-Mellon</key> + <string>Carnegie-Mellon</string> + <key>Carnigie</key> + <string>Carnegie</string> + <key>Carnigie-Mellon</key> + <string>Carnegie-Mellon</string> + <key>Carribbean</key> + <string>Caribbean</string> + <key>Carribean</key> + <string>Caribbean</string> + <key>Carthagian</key> + <string>Carthaginian</string> + <key>Cataline</key> + <string>Catiline</string> + <key>Ceasar</key> + <string>Caesar</string> + <key>Celcius</key> + <string>Celsius</string> + <key>Champange</key> + <string>Champagne</string> + <key>Cincinatti</key> + <string>Cincinnati</string> + <key>Cincinnatti</key> + <string>Cincinnati</string> + <key>Conneticut</key> + <string>Connecticut</string> + <key>Dardenelles</key> + <string>Dardanelles</string> + <key>Dravadian</key> + <string>Dravidian</string> + <key>Enlish</key> + <string>English</string> + <key>Europian</key> + <string>European</string> + <key>Europians</key> + <string>Europeans</string> + <key>Eurpean</key> + <string>European</string> + <key>Eurpoean</key> + <string>European</string> + <key>Farenheit</key> + <string>Fahrenheit</string> + <key>Febuary</key> + <string>February</string> + <key>Feburary</key> + <string>February</string> + <key>Flemmish</key> + <string>Flemish</string> + <key>Formalhaut</key> + <string>Fomalhaut</string> + <key>Foundland</key> + <string>Newfoundland</string> + <key>Fransiscan</key> + <string>Franciscan</string> + <key>Fransiscans</key> + <string>Franciscans</string> + <key>Galations</key> + <string>Galatians</string> + <key>Gameboy</key> + <string>Game Boy</string> + <key>Ghandi</key> + <string>Gandhi</string> + <key>Godounov</key> + <string>Godunov</string> + <key>Gothenberg</key> + <string>Gothenburg</string> + <key>Gottleib</key> + <string>Gottlieb</string> + <key>Guaduloupe</key> + <string>Guadalupe</string> + <key>Guadulupe</key> + <string>Guadalupe</string> + <key>Guatamala</key> + <string>Guatemala</string> + <key>Guatamalan</key> + <string>Guatemalan</string> + <key>Guilia</key> + <string>Giulia</string> + <key>Guilio</key> + <string>Giulio</string> + <key>Guiness</key> + <string>Guinness</string> + <key>Guiseppe</key> + <string>Giuseppe</string> + <key>Habsbourg</key> + <string>Habsburg</string> + <key>Hallowean</key> + <string>Halloween</string> + <key>Heidelburg</key> + <string>Heidelberg</string> + <key>Ihaca</key> + <string>Ithaca</string> + <key>Israelies</key> + <string>Israelis</string> + <key>Janurary</key> + <string>January</string> + <key>Januray</key> + <string>January</string> + <key>Japanes</key> + <string>Japanese</string> + <key>Johanine</key> + <string>Johannine</string> + <key>Jospeh</key> + <string>Joseph</string> + <key>Juadaism</key> + <string>Judaism</string> + <key>Juadism</key> + <string>Judaism</string> + <key>Lybia</key> + <string>Libya</string> + <key>Malcom</key> + <string>Malcolm</string> + <key>Massachussets</key> + <string>Massachusetts</string> + <key>Massachussetts</key> + <string>Massachusetts</string> + <key>Mediteranean</key> + <string>Mediterranean</string> + <key>Michagan</key> + <string>Michigan</string> + <key>Misouri</key> + <string>Missouri</string> + <key>Missisipi</key> + <string>Mississippi</string> + <key>Missisippi</key> + <string>Mississippi</string> + <key>Monserrat</key> + <string>Montserrat</string> + <key>Montnana</key> + <string>Montana</string> + <key>Morisette</key> + <string>Morissette</string> + <key>Morrisette</key> + <string>Morissette</string> + <key>Mythraic</key> + <string>Mithraic</string> + <key>Naploeon</key> + <string>Napoleon</string> + <key>Napolean</key> + <string>Napoleon</string> + <key>Napoleonian</key> + <string>Napoleonic</string> + <key>Nazereth</key> + <string>Nazareth</string> + <key>Newyorker</key> + <string>New Yorker</string> + <key>Novermber</key> + <string>November</string> + <key>Nullabour</key> + <string>Nullarbor</string> + <key>Nuremburg</key> + <string>Nuremberg</string> + <key>Palistian</key> + <string>Palestinian</string> + <key>Palistinian</key> + <string>Palestinian</string> + <key>Palistinians</key> + <string>Palestinians</string> + <key>Papanicalou</key> + <string>Papanicolaou</string> + <key>Peloponnes</key> + <string>Peloponnesus</string> + <key>Pennyslvania</key> + <string>Pennsylvania</string> + <key>Pharoah</key> + <string>Pharaoh</string> + <key>Philipines</key> + <string>Philippines</string> + <key>Phillipine</key> + <string>Philippine</string> + <key>Phillipines</key> + <string>Philippines</string> + <key>Phillippines</key> + <string>Philippines</string> + <key>Phonecian</key> + <string>Phoenecian</string> + <key>Portugese</key> + <string>Portuguese</string> + <key>Postdam</key> + <string>Potsdam</string> + <key>Premonasterians</key> + <string>Premonstratensians</string> + <key>Pucini</key> + <string>Puccini</string> + <key>Puertorrican</key> + <string>Puerto Rican</string> + <key>Puertorricans</key> + <string>Puerto Ricans</string> + <key>Queenland</key> + <string>Queensland</string> + <key>Rockerfeller</key> + <string>Rockefeller</string> + <key>Russion</key> + <string>Russian</string> + <key>Sanhedrim</key> + <string>Sanhedrin</string> + <key>Saterday</key> + <string>Saturday</string> + <key>Saterdays</key> + <string>Saturdays</string> + <key>Sionist</key> + <string>Zionist</string> + <key>Sionists</key> + <string>Zionists</string> + <key>Sixtin</key> + <string>Sistine</string> + <key>Skagerak</key> + <string>Skagerrak</string> + <key>Tolkein</key> + <string>Tolkien</string> + <key>Tuscon</key> + <string>Tucson</string> + <key>Ukranian</key> + <string>Ukrainian</string> + <key>UnitesStates</key> + <string>UnitedStates</string> + <key>Yementite</key> + <string>Yemenite</string> + <key>abandonned</key> + <string>abandoned</string> + <key>aberation</key> + <string>aberration</string> + <key>abilties</key> + <string>abilities</string> + <key>abilty</key> + <string>ability</string> + <key>abondon</key> + <string>abandon</string> + <key>abondoned</key> + <string>abandoned</string> + <key>abondoning</key> + <string>abandoning</string> + <key>abondons</key> + <string>abandons</string> + <key>aborigene</key> + <string>aborigine</string> + <key>abortificant</key> + <string>abortifacient</string> + <key>abreviate</key> + <string>abbreviate</string> + <key>abreviated</key> + <string>abbreviated</string> + <key>abreviation</key> + <string>abbreviation</string> + <key>abritrary</key> + <string>arbitrary</string> + <key>absail</key> + <string>abseil</string> + <key>absailing</key> + <string>abseiling</string> + <key>absense</key> + <string>absence</string> + <key>absolutly</key> + <string>absolutely</string> + <key>absorbsion</key> + <string>absorption</string> + <key>absorbtion</key> + <string>absorption</string> + <key>abundacies</key> + <string>abundances</string> + <key>abundancies</key> + <string>abundances</string> + <key>abundunt</key> + <string>abundant</string> + <key>abutts</key> + <string>abuts</string> + <key>acadamy</key> + <string>academy</string> + <key>acadmic</key> + <string>academic</string> + <key>accademic</key> + <string>academic</string> + <key>accademy</key> + <string>academy</string> + <key>acccused</key> + <string>accused</string> + <key>accelleration</key> + <string>acceleration</string> + <key>accension</key> + <string>ascension</string> + <key>acceptence</key> + <string>acceptance</string> + <key>acceptible</key> + <string>acceptable</string> + <key>accessable</key> + <string>accessible</string> + <key>accidentaly</key> + <string>accidentally</string> + <key>accidently</key> + <string>accidentally</string> + <key>acclimitization</key> + <string>acclimatization</string> + <key>accomadate</key> + <string>accommodate</string> + <key>accomadated</key> + <string>accommodated</string> + <key>accomadates</key> + <string>accommodates</string> + <key>accomadating</key> + <string>accommodating</string> + <key>accomadation</key> + <string>accommodation</string> + <key>accomadations</key> + <string>accommodations</string> + <key>accomdate</key> + <string>accommodate</string> + <key>accomodate</key> + <string>accommodate</string> + <key>accomodated</key> + <string>accommodated</string> + <key>accomodates</key> + <string>accommodates</string> + <key>accomodating</key> + <string>accommodating</string> + <key>accomodation</key> + <string>accommodation</string> + <key>accomodations</key> + <string>accommodations</string> + <key>accompanyed</key> + <string>accompanied</string> + <key>accordeon</key> + <string>accordion</string> + <key>accordian</key> + <string>accordion</string> + <key>accoring</key> + <string>according</string> + <key>accoustic</key> + <string>acoustic</string> + <key>accquainted</key> + <string>acquainted </string> + <key>accrediation</key> + <string>accreditation</string> + <key>accredidation</key> + <string>accreditation</string> + <key>accross</key> + <string>across</string> + <key>accussed</key> + <string>accused</string> + <key>acedemic</key> + <string>academic</string> + <key>acheive</key> + <string>achieve</string> + <key>acheived</key> + <string>achieved</string> + <key>acheivement</key> + <string>achievement</string> + <key>acheivements</key> + <string>achievements</string> + <key>acheives</key> + <string>achieves</string> + <key>acheiving</key> + <string>achieving</string> + <key>acheivment</key> + <string>achievement</string> + <key>acheivments</key> + <string>achievements</string> + <key>achievment</key> + <string>achievement</string> + <key>achievments</key> + <string>achievements</string> + <key>achivement</key> + <string>achievement</string> + <key>achivements</key> + <string>achievements</string> + <key>acknowldeged</key> + <string>acknowledged</string> + <key>acknowledgeing</key> + <string>acknowledging</string> + <key>ackward</key> + <string>awkward</string> + <key>acommodate</key> + <string>accommodate</string> + <key>acomplish</key> + <string>accomplish</string> + <key>acomplished</key> + <string>accomplished</string> + <key>acomplishment</key> + <string>accomplishment</string> + <key>acomplishments</key> + <string>accomplishments</string> + <key>acording</key> + <string>according</string> + <key>acordingly</key> + <string>accordingly</string> + <key>acquaintence</key> + <string>acquaintance</string> + <key>acquaintences</key> + <string>acquaintances</string> + <key>acquiantence</key> + <string>acquaintance</string> + <key>acquiantences</key> + <string>acquaintances</string> + <key>acquited</key> + <string>acquitted</string> + <key>activites</key> + <string>activities</string> + <key>activly</key> + <string>actively</string> + <key>actualy</key> + <string>actually</string> + <key>acuracy</key> + <string>accuracy</string> + <key>acused</key> + <string>accused</string> + <key>acustom</key> + <string>accustom</string> + <key>acustommed</key> + <string>accustomed</string> + <key>adavanced</key> + <string>advanced</string> + <key>adbandon</key> + <string>abandon</string> + <key>additinally</key> + <string>additionally</string> + <key>additionaly</key> + <string>additionally</string> + <key>additonal</key> + <string>additional</string> + <key>additonally</key> + <string>additionally</string> + <key>addmission</key> + <string>admission</string> + <key>addopt</key> + <string>adopt</string> + <key>addopted</key> + <string>adopted</string> + <key>addoptive</key> + <string>adoptive</string> + <key>addres</key> + <string>address</string> + <key>addresable</key> + <string>addressable</string> + <key>addresed</key> + <string>addressed</string> + <key>addresing</key> + <string>addressing</string> + <key>addressess</key> + <string>addresses</string> + <key>addtion</key> + <string>addition</string> + <key>addtional</key> + <string>additional</string> + <key>adecuate</key> + <string>adequate</string> + <key>adequit</key> + <string>adequate</string> + <key>adhearing</key> + <string>adhering</string> + <key>adherance</key> + <string>adherence</string> + <key>admendment</key> + <string>amendment</string> + <key>admininistrative</key> + <string>administrative</string> + <key>adminstered</key> + <string>administered</string> + <key>adminstrate</key> + <string>administrate</string> + <key>adminstration</key> + <string>administration</string> + <key>adminstrative</key> + <string>administrative</string> + <key>adminstrator</key> + <string>administrator</string> + <key>admissability</key> + <string>admissibility</string> + <key>admissable</key> + <string>admissible</string> + <key>admited</key> + <string>admitted</string> + <key>admitedly</key> + <string>admittedly</string> + <key>adn</key> + <string>and</string> + <key>adolecent</key> + <string>adolescent</string> + <key>adquire</key> + <string>acquire</string> + <key>adquired</key> + <string>acquired</string> + <key>adquires</key> + <string>acquires</string> + <key>adquiring</key> + <string>acquiring</string> + <key>adres</key> + <string>address</string> + <key>adresable</key> + <string>addressable</string> + <key>adresing</key> + <string>addressing</string> + <key>adress</key> + <string>address</string> + <key>adressable</key> + <string>addressable</string> + <key>adressed</key> + <string>addressed</string> + <key>adressing</key> + <string>addressing</string> + <key>adventrous</key> + <string>adventurous</string> + <key>advertisment</key> + <string>advertisement</string> + <key>advertisments</key> + <string>advertisements</string> + <key>advesary</key> + <string>adversary</string> + <key>adviced</key> + <string>advised</string> + <key>aeriel</key> + <string>aerial</string> + <key>aeriels</key> + <string>aerials</string> + <key>afair</key> + <string>affair</string> + <key>afficianados</key> + <string>aficionados</string> + <key>afficionado</key> + <string>aficionado</string> + <key>afficionados</key> + <string>aficionados</string> + <key>affilate</key> + <string>affiliate</string> + <key>affilliate</key> + <string>affiliate</string> + <key>affort</key> + <string>afford</string> + <key>aforememtioned</key> + <string>aforementioned</string> + <key>againnst</key> + <string>against</string> + <key>agains</key> + <string>against</string> + <key>agaisnt</key> + <string>against</string> + <key>aganist</key> + <string>against</string> + <key>aggaravates</key> + <string>aggravates</string> + <key>aggreed</key> + <string>agreed</string> + <key>aggreement</key> + <string>agreement</string> + <key>aggregious</key> + <string>egregious</string> + <key>aggresive</key> + <string>aggressive</string> + <key>agian</key> + <string>again</string> + <key>agianst</key> + <string>against</string> + <key>agin</key> + <string>again</string> + <key>agina</key> + <string>again</string> + <key>aginst</key> + <string>against</string> + <key>agravate</key> + <string>aggravate</string> + <key>agre</key> + <string>agree</string> + <key>agred</key> + <string>agreed</string> + <key>agreeement</key> + <string>agreement</string> + <key>agreemnt</key> + <string>agreement</string> + <key>agregate</key> + <string>aggregate</string> + <key>agregates</key> + <string>aggregates</string> + <key>agreing</key> + <string>agreeing</string> + <key>agression</key> + <string>aggression</string> + <key>agressive</key> + <string>aggressive</string> + <key>agressively</key> + <string>aggressively</string> + <key>agressor</key> + <string>aggressor</string> + <key>agricuture</key> + <string>agriculture</string> + <key>agrieved</key> + <string>aggrieved</string> + <key>ahev</key> + <string>have</string> + <key>ahppen</key> + <string>happen</string> + <key>ahve</key> + <string>have</string> + <key>aicraft</key> + <string>aircraft</string> + <key>aiport</key> + <string>airport</string> + <key>airbourne</key> + <string>airborne</string> + <key>aircaft</key> + <string>aircraft</string> + <key>aircrafts</key> + <string>aircraft</string> + <key>airporta</key> + <string>airports</string> + <key>airrcraft</key> + <string>aircraft</string> + <key>aisian</key> + <string>asian</string> + <key>albiet</key> + <string>albeit</string> + <key>alchohol</key> + <string>alcohol</string> + <key>alchoholic</key> + <string>alcoholic</string> + <key>alchol</key> + <string>alcohol</string> + <key>alcholic</key> + <string>alcoholic</string> + <key>alcohal</key> + <string>alcohol</string> + <key>alcoholical</key> + <string>alcoholic</string> + <key>aledge</key> + <string>allege</string> + <key>aledged</key> + <string>alleged</string> + <key>aledges</key> + <string>alleges</string> + <key>alege</key> + <string>allege</string> + <key>aleged</key> + <string>alleged</string> + <key>alegience</key> + <string>allegiance</string> + <key>algebraical</key> + <string>algebraic</string> + <key>algorhitms</key> + <string>algorithms</string> + <key>algoritm</key> + <string>algorithm</string> + <key>algoritms</key> + <string>algorithms</string> + <key>alientating</key> + <string>alienating</string> + <key>alledge</key> + <string>allege</string> + <key>alledged</key> + <string>alleged</string> + <key>alledgedly</key> + <string>allegedly</string> + <key>alledges</key> + <string>alleges</string> + <key>allegedely</key> + <string>allegedly</string> + <key>allegedy</key> + <string>allegedly</string> + <key>allegely</key> + <string>allegedly</string> + <key>allegence</key> + <string>allegiance</string> + <key>allegience</key> + <string>allegiance</string> + <key>allign</key> + <string>align</string> + <key>alligned</key> + <string>aligned</string> + <key>alliviate</key> + <string>alleviate</string> + <key>allopone</key> + <string>allophone</string> + <key>allopones</key> + <string>allophones</string> + <key>allready</key> + <string>already</string> + <key>allthough</key> + <string>although</string> + <key>alltime</key> + <string>all-time</string> + <key>alltogether</key> + <string>altogether</string> + <key>almsot</key> + <string>almost</string> + <key>alochol</key> + <string>alcohol</string> + <key>alomst</key> + <string>almost</string> + <key>alot</key> + <string>a lot</string> + <key>alotted</key> + <string>allotted</string> + <key>alowed</key> + <string>allowed</string> + <key>alowing</key> + <string>allowing</string> + <key>alreayd</key> + <string>already</string> + <key>alse</key> + <string>else</string> + <key>alsot</key> + <string>also</string> + <key>alternitives</key> + <string>alternatives</string> + <key>altho</key> + <string>although</string> + <key>althought</key> + <string>although</string> + <key>altough</key> + <string>although</string> + <key>alusion</key> + <string>allusion</string> + <key>alwasy</key> + <string>always</string> + <key>alwyas</key> + <string>always</string> + <key>amalgomated</key> + <string>amalgamated</string> + <key>amatuer</key> + <string>amateur</string> + <key>amature</key> + <string>armature</string> + <key>amendmant</key> + <string>amendment</string> + <key>amerliorate</key> + <string>ameliorate</string> + <key>amke</key> + <string>make</string> + <key>amking</key> + <string>making</string> + <key>ammend</key> + <string>amend</string> + <key>ammended</key> + <string>amended</string> + <key>ammendment</key> + <string>amendment</string> + <key>ammendments</key> + <string>amendments</string> + <key>ammount</key> + <string>amount</string> + <key>ammused</key> + <string>amused</string> + <key>amoung</key> + <string>among</string> + <key>amoungst</key> + <string>amongst</string> + <key>amung</key> + <string>among</string> + <key>amunition</key> + <string>ammunition</string> + <key>analagous</key> + <string>analogous</string> + <key>analitic</key> + <string>analytic</string> + <key>analogeous</key> + <string>analogous</string> + <key>anarchim</key> + <string>anarchism</string> + <key>anarchistm</key> + <string>anarchism</string> + <key>anbd</key> + <string>and</string> + <key>ancestory</key> + <string>ancestry</string> + <key>ancilliary</key> + <string>ancillary</string> + <key>androgenous</key> + <string>androgynous</string> + <key>androgeny</key> + <string>androgyny</string> + <key>anihilation</key> + <string>annihilation</string> + <key>aniversary</key> + <string>anniversary</string> + <key>annoint</key> + <string>anoint</string> + <key>annointed</key> + <string>anointed</string> + <key>annointing</key> + <string>anointing</string> + <key>annoints</key> + <string>anoints</string> + <key>annouced</key> + <string>announced</string> + <key>annualy</key> + <string>annually</string> + <key>annuled</key> + <string>annulled</string> + <key>anohter</key> + <string>another</string> + <key>anomolies</key> + <string>anomalies</string> + <key>anomolous</key> + <string>anomalous</string> + <key>anomoly</key> + <string>anomaly</string> + <key>anonimity</key> + <string>anonymity</string> + <key>anounced</key> + <string>announced</string> + <key>anouncement</key> + <string>announcement</string> + <key>ansalisation</key> + <string>nasalisation</string> + <key>ansalization</key> + <string>nasalization</string> + <key>ansestors</key> + <string>ancestors</string> + <key>antartic</key> + <string>antarctic</string> + <key>anthromorphization</key> + <string>anthropomorphization</string> + <key>anthropolgist</key> + <string>anthropologist</string> + <key>anthropolgy</key> + <string>anthropology</string> + <key>anual</key> + <string>annual</string> + <key>anulled</key> + <string>annulled</string> + <key>anwsered</key> + <string>answered</string> + <key>anyhwere</key> + <string>anywhere</string> + <key>anyother</key> + <string>any other</string> + <key>anytying</key> + <string>anything</string> + <key>aparent</key> + <string>apparent</string> + <key>aparment</key> + <string>apartment</string> + <key>apenines</key> + <string>apennines</string> + <key>aplication</key> + <string>application</string> + <key>aplied</key> + <string>applied</string> + <key>apolegetics</key> + <string>apologetics</string> + <key>apon</key> + <string>apron</string> + <key>apparant</key> + <string>apparent</string> + <key>apparantly</key> + <string>apparently</string> + <key>appart</key> + <string>apart</string> + <key>appartment</key> + <string>apartment</string> + <key>appartments</key> + <string>apartments</string> + <key>appealling</key> + <string>appealing</string> + <key>appeareance</key> + <string>appearance</string> + <key>appearence</key> + <string>appearance</string> + <key>appearences</key> + <string>appearances</string> + <key>apperance</key> + <string>appearance</string> + <key>apperances</key> + <string>appearances</string> + <key>appereance</key> + <string>appearance</string> + <key>appereances</key> + <string>appearances</string> + <key>applicaiton</key> + <string>application</string> + <key>applicaitons</key> + <string>applications</string> + <key>appologies</key> + <string>apologies</string> + <key>appology</key> + <string>apology</string> + <key>apprearance</key> + <string>appearance</string> + <key>apprieciate</key> + <string>appreciate</string> + <key>approachs</key> + <string>approaches</string> + <key>appropiate</key> + <string>appropriate</string> + <key>appropraite</key> + <string>appropriate</string> + <key>appropropiate</key> + <string>appropriate</string> + <key>approproximate</key> + <string>approximate</string> + <key>approxamately</key> + <string>approximately</string> + <key>approxiately</key> + <string>approximately</string> + <key>approximitely</key> + <string>approximately</string> + <key>aprehensive</key> + <string>apprehensive</string> + <key>apropriate</key> + <string>appropriate</string> + <key>aproximate</key> + <string>approximate</string> + <key>aproximately</key> + <string>approximately</string> + <key>aquaduct</key> + <string>aqueduct</string> + <key>aquaintance</key> + <string>acquaintance</string> + <key>aquainted</key> + <string>acquainted</string> + <key>aquiantance</key> + <string>acquaintance</string> + <key>aquire</key> + <string>acquire</string> + <key>aquired</key> + <string>acquired</string> + <key>aquiring</key> + <string>acquiring</string> + <key>aquisition</key> + <string>acquisition</string> + <key>aquitted</key> + <string>acquitted</string> + <key>aranged</key> + <string>arranged</string> + <key>arangement</key> + <string>arrangement</string> + <key>arbitarily</key> + <string>arbitrarily</string> + <key>arbitary</key> + <string>arbitrary</string> + <key>archaelogists</key> + <string>archaeologists</string> + <key>archaelogy</key> + <string>archaeology</string> + <key>archaoelogy</key> + <string>archaeology</string> + <key>archaology</key> + <string>archaeology</string> + <key>archeaologist</key> + <string>archaeologist</string> + <key>archeaologists</key> + <string>archaeologists</string> + <key>archetect</key> + <string>architect</string> + <key>archetects</key> + <string>architects</string> + <key>archetectural</key> + <string>architectural</string> + <key>archetecturally</key> + <string>architecturally</string> + <key>archetecture</key> + <string>architecture</string> + <key>archiac</key> + <string>archaic</string> + <key>archictect</key> + <string>architect</string> + <key>archimedian</key> + <string>archimedean</string> + <key>architecht</key> + <string>architect</string> + <key>architechturally</key> + <string>architecturally</string> + <key>architechture</key> + <string>architecture</string> + <key>architechtures</key> + <string>architectures</string> + <key>architectual</key> + <string>architectural</string> + <key>archtype</key> + <string>archetype</string> + <key>archtypes</key> + <string>archetypes</string> + <key>aready</key> + <string>already</string> + <key>areodynamics</key> + <string>aerodynamics</string> + <key>argubly</key> + <string>arguably</string> + <key>arguement</key> + <string>argument</string> + <key>arguements</key> + <string>arguments</string> + <key>arised</key> + <string>arose</string> + <key>arival</key> + <string>arrival</string> + <key>armamant</key> + <string>armament</string> + <key>armistace</key> + <string>armistice</string> + <key>arogant</key> + <string>arrogant</string> + <key>arogent</key> + <string>arrogant</string> + <key>aroud</key> + <string>around</string> + <key>arrangment</key> + <string>arrangement</string> + <key>arrangments</key> + <string>arrangements</string> + <key>arround</key> + <string>around</string> + <key>artical</key> + <string>article</string> + <key>artice</key> + <string>article</string> + <key>articel</key> + <string>article</string> + <key>artifical</key> + <string>artificial</string> + <key>artifically</key> + <string>artificially</string> + <key>artillary</key> + <string>artillery</string> + <key>arund</key> + <string>around</string> + <key>asetic</key> + <string>ascetic</string> + <key>asfar</key> + <string>as far</string> + <key>asign</key> + <string>assign</string> + <key>aslo</key> + <string>also</string> + <key>asociated</key> + <string>associated</string> + <key>asorbed</key> + <string>absorbed</string> + <key>asphyxation</key> + <string>asphyxiation</string> + <key>assasin</key> + <string>assassin</string> + <key>assasinate</key> + <string>assassinate</string> + <key>assasinated</key> + <string>assassinated</string> + <key>assasinates</key> + <string>assassinates</string> + <key>assasination</key> + <string>assassination</string> + <key>assasinations</key> + <string>assassinations</string> + <key>assasined</key> + <string>assassinated</string> + <key>assasins</key> + <string>assassins</string> + <key>assassintation</key> + <string>assassination</string> + <key>assemple</key> + <string>assemble</string> + <key>assertation</key> + <string>assertion</string> + <key>asside</key> + <string>aside</string> + <key>assisnate</key> + <string>assassinate</string> + <key>assit</key> + <string>assist</string> + <key>assitant</key> + <string>assistant</string> + <key>assocation</key> + <string>association</string> + <key>assoicate</key> + <string>associate</string> + <key>assoicated</key> + <string>associated</string> + <key>assoicates</key> + <string>associates</string> + <key>assosication</key> + <string>assassination</string> + <key>asssassans</key> + <string>assassins</string> + <key>assualt</key> + <string>assault</string> + <key>assualted</key> + <string>assaulted</string> + <key>assymetric</key> + <string>asymmetric</string> + <key>assymetrical</key> + <string>asymmetrical</string> + <key>asteriod</key> + <string>asteroid</string> + <key>asthetic</key> + <string>aesthetic</string> + <key>asthetical</key> + <string>aesthetical</string> + <key>asthetically</key> + <string>aesthetically</string> + <key>asume</key> + <string>assume</string> + <key>aswell</key> + <string>as well</string> + <key>atain</key> + <string>attain</string> + <key>atempting</key> + <string>attempting</string> + <key>atheistical</key> + <string>atheistic</string> + <key>athenean</key> + <string>athenian</string> + <key>atheneans</key> + <string>athenians</string> + <key>athiesm</key> + <string>atheism</string> + <key>athiest</key> + <string>atheist</string> + <key>atorney</key> + <string>attorney</string> + <key>atribute</key> + <string>attribute</string> + <key>atributed</key> + <string>attributed</string> + <key>atributes</key> + <string>attributes</string> + <key>attaindre</key> + <string>attainder</string> + <key>attemp</key> + <string>attempt</string> + <key>attemped</key> + <string>attempted</string> + <key>attemt</key> + <string>attempt</string> + <key>attemted</key> + <string>attempted</string> + <key>attemting</key> + <string>attempting</string> + <key>attemts</key> + <string>attempts</string> + <key>attendence</key> + <string>attendance</string> + <key>attendent</key> + <string>attendant</string> + <key>attendents</key> + <string>attendants</string> + <key>attened</key> + <string>attended</string> + <key>attension</key> + <string>attention</string> + <key>attitide</key> + <string>attitude</string> + <key>attributred</key> + <string>attributed</string> + <key>attrocities</key> + <string>atrocities</string> + <key>audeince</key> + <string>audience</string> + <key>auromated</key> + <string>automated</string> + <key>austrailia</key> + <string>Australia</string> + <key>austrailian</key> + <string>Australian</string> + <key>auther</key> + <string>author</string> + <key>authobiographic</key> + <string>autobiographic</string> + <key>authobiography</key> + <string>autobiography</string> + <key>authorative</key> + <string>authoritative</string> + <key>authorites</key> + <string>authorities</string> + <key>authorithy</key> + <string>authority</string> + <key>authoritiers</key> + <string>authorities</string> + <key>authoritive</key> + <string>authoritative</string> + <key>authrorities</key> + <string>authorities</string> + <key>autochtonous</key> + <string>autochthonous</string> + <key>autoctonous</key> + <string>autochthonous</string> + <key>automaticly</key> + <string>automatically</string> + <key>automibile</key> + <string>automobile</string> + <key>automonomous</key> + <string>autonomous</string> + <key>autor</key> + <string>author</string> + <key>autority</key> + <string>authority</string> + <key>auxilary</key> + <string>auxiliary</string> + <key>auxillaries</key> + <string>auxiliaries</string> + <key>auxillary</key> + <string>auxiliary</string> + <key>auxilliaries</key> + <string>auxiliaries</string> + <key>auxilliary</key> + <string>auxiliary</string> + <key>availabe</key> + <string> available</string> + <key>availablity</key> + <string>availability</string> + <key>availaible</key> + <string>available</string> + <key>availble</key> + <string>available</string> + <key>availiable</key> + <string>available</string> + <key>availible</key> + <string>available</string> + <key>avalable</key> + <string>available</string> + <key>avalance</key> + <string>avalanche</string> + <key>avaliable</key> + <string>available</string> + <key>avation</key> + <string>aviation</string> + <key>avengence</key> + <string>a vengeance</string> + <key>averageed</key> + <string>averaged</string> + <key>avilable</key> + <string>available</string> + <key>awared</key> + <string>awarded</string> + <key>awya</key> + <string>away</string> + <key>baceause</key> + <string>because</string> + <key>backgorund</key> + <string>background</string> + <key>backrounds</key> + <string>backgrounds</string> + <key>bakc</key> + <string>back</string> + <key>banannas</key> + <string>bananas</string> + <key>bandwith</key> + <string>bandwidth</string> + <key>bankrupcy</key> + <string>bankruptcy</string> + <key>banruptcy</key> + <string>bankruptcy</string> + <key>baout</key> + <string>about</string> + <key>basicaly</key> + <string>basically</string> + <key>basicly</key> + <string>basically</string> + <key>bcak</key> + <string>back</string> + <key>beachead</key> + <string>beachhead</string> + <key>beacuse</key> + <string>because</string> + <key>beastiality</key> + <string>bestiality</string> + <key>beatiful</key> + <string>beautiful</string> + <key>beaurocracy</key> + <string>bureaucracy</string> + <key>beaurocratic</key> + <string>bureaucratic</string> + <key>beautyfull</key> + <string>beautiful</string> + <key>becamae</key> + <string>became</string> + <key>becames</key> + <string>becomes</string> + <key>becasue</key> + <string>because</string> + <key>beccause</key> + <string>because</string> + <key>becomeing</key> + <string>becoming</string> + <key>becomming</key> + <string>becoming</string> + <key>becouse</key> + <string>because</string> + <key>becuase</key> + <string>because</string> + <key>bedore</key> + <string>before</string> + <key>befoer</key> + <string>before</string> + <key>beggin</key> + <string>begin</string> + <key>begginer</key> + <string>beginner</string> + <key>begginers</key> + <string>beginners</string> + <key>beggining</key> + <string>beginning</string> + <key>begginings</key> + <string>beginnings</string> + <key>beggins</key> + <string>begins</string> + <key>begining</key> + <string>beginning</string> + <key>beginnig</key> + <string>beginning</string> + <key>behavour</key> + <string>behavior</string> + <key>beleagured</key> + <string>beleaguered</string> + <key>beleif</key> + <string>belief</string> + <key>beleive</key> + <string>believe</string> + <key>beleived</key> + <string>believed</string> + <key>beleives</key> + <string>believes</string> + <key>beleiving</key> + <string>believing</string> + <key>beligum</key> + <string>belgium</string> + <key>belive</key> + <string>believe</string> + <key>belived</key> + <string>believed</string> + <key>belives</key> + <string>believes</string> + <key>belligerant</key> + <string>belligerent</string> + <key>bellweather</key> + <string>bellwether</string> + <key>bemusemnt</key> + <string>bemusement</string> + <key>beneficary</key> + <string>beneficiary</string> + <key>beng</key> + <string>being</string> + <key>benificial</key> + <string>beneficial</string> + <key>benifit</key> + <string>benefit</string> + <key>benifits</key> + <string>benefits</string> + <key>bergamont</key> + <string>bergamot</string> + <key>beseige</key> + <string>besiege</string> + <key>beseiged</key> + <string>besieged</string> + <key>beseiging</key> + <string>besieging</string> + <key>betwen</key> + <string>between</string> + <key>beween</key> + <string>between</string> + <key>bewteen</key> + <string>between</string> + <key>bilateraly</key> + <string>bilaterally</string> + <key>billingualism</key> + <string>bilingualism</string> + <key>binominal</key> + <string>binomial</string> + <key>bizzare</key> + <string>bizarre</string> + <key>blaim</key> + <string>blame</string> + <key>blaimed</key> + <string>blamed</string> + <key>blessure</key> + <string>blessing</string> + <key>bodydbuilder</key> + <string>bodybuilder</string> + <key>bombardement</key> + <string>bombardment</string> + <key>bombarment</key> + <string>bombardment</string> + <key>bondary</key> + <string>boundary</string> + <key>borke</key> + <string>broke</string> + <key>boundry</key> + <string>boundary</string> + <key>bouyancy</key> + <string>buoyancy</string> + <key>bouyant</key> + <string>buoyant</string> + <key>boyant</key> + <string>buoyant</string> + <key>breakthough</key> + <string>breakthrough</string> + <key>breakthroughts</key> + <string>breakthroughs</string> + <key>breif</key> + <string>brief</string> + <key>breifly</key> + <string>briefly</string> + <key>brethen</key> + <string>brethren</string> + <key>bretheren</key> + <string>brethren</string> + <key>briliant</key> + <string>brilliant</string> + <key>brillant</key> + <string>brilliant</string> + <key>brimestone</key> + <string>brimstone</string> + <key>broacasted</key> + <string>broadcast</string> + <key>broadacasting</key> + <string>broadcasting</string> + <key>broady</key> + <string>broadly</string> + <key>buisness</key> + <string>business</string> + <key>buisnessman</key> + <string>businessman</string> + <key>buoancy</key> + <string>buoyancy</string> + <key>burried</key> + <string>buried</string> + <key>busineses</key> + <string>businesses</string> + <key>busness</key> + <string>business</string> + <key>bussiness</key> + <string>business</string> + <key>caculater</key> + <string>calculator</string> + <key>cacuses</key> + <string>caucuses</string> + <key>cahracters</key> + <string>characters</string> + <key>calaber</key> + <string>caliber</string> + <key>calculater</key> + <string>calculator</string> + <key>calculs</key> + <string>calculus</string> + <key>calenders</key> + <string>calendars</string> + <key>caligraphy</key> + <string>calligraphy</string> + <key>caluclate</key> + <string>calculate</string> + <key>caluclated</key> + <string>calculated</string> + <key>caluculate</key> + <string>calculate</string> + <key>caluculated</key> + <string>calculated</string> + <key>calulate</key> + <string>calculate</string> + <key>calulated</key> + <string>calculated</string> + <key>calulater</key> + <string>calculator</string> + <key>camoflage</key> + <string>camouflage</string> + <key>campain</key> + <string>campaign</string> + <key>campains</key> + <string>campaigns</string> + <key>candadate</key> + <string>candidate</string> + <key>candiate</key> + <string>candidate</string> + <key>candidiate</key> + <string>candidate</string> + <key>cannister</key> + <string>canister</string> + <key>cannisters</key> + <string>canisters</string> + <key>cannnot</key> + <string>cannot</string> + <key>cannonical</key> + <string>canonical</string> + <key>cannotation</key> + <string>connotation</string> + <key>cannotations</key> + <string>connotations</string> + <key>cant</key> + <string>can't</string> + <key>caost</key> + <string>coast</string> + <key>caperbility</key> + <string>capability</string> + <key>capible</key> + <string>capable</string> + <key>captial</key> + <string>capital</string> + <key>captued</key> + <string>captured</string> + <key>capturd</key> + <string>captured</string> + <key>carachter</key> + <string>character</string> + <key>caracterized</key> + <string>characterized</string> + <key>carcas</key> + <string>carcass</string> + <key>carefull</key> + <string>careful</string> + <key>careing</key> + <string>caring</string> + <key>carismatic</key> + <string>charismatic</string> + <key>carnege</key> + <string>carnage</string> + <key>carnige</key> + <string>carnage</string> + <key>carniverous</key> + <string>carnivorous</string> + <key>carreer</key> + <string>career</string> + <key>carrers</key> + <string>careers</string> + <key>cartdridge</key> + <string>cartridge</string> + <key>carthographer</key> + <string>cartographer</string> + <key>cartilege</key> + <string>cartilage</string> + <key>cartilidge</key> + <string>cartilage</string> + <key>cartrige</key> + <string>cartridge</string> + <key>casette</key> + <string>cassette</string> + <key>casion</key> + <string>caisson</string> + <key>cassawory</key> + <string>cassowary</string> + <key>cassowarry</key> + <string>cassowary</string> + <key>casulaties</key> + <string>casualties</string> + <key>casulaty</key> + <string>casualty</string> + <key>catagories</key> + <string>categories</string> + <key>catagorized</key> + <string>categorized</string> + <key>catagory</key> + <string>category</string> + <key>catapillar</key> + <string>caterpillar</string> + <key>catapillars</key> + <string>caterpillars</string> + <key>catapiller</key> + <string>caterpillar</string> + <key>catapillers</key> + <string>caterpillars</string> + <key>catepillar</key> + <string>caterpillar</string> + <key>catepillars</key> + <string>caterpillars</string> + <key>catergorize</key> + <string>categorize</string> + <key>catergorized</key> + <string>categorized</string> + <key>caterpilar</key> + <string>caterpillar</string> + <key>caterpilars</key> + <string>caterpillars</string> + <key>caterpiller</key> + <string>caterpillar</string> + <key>caterpillers</key> + <string>caterpillars</string> + <key>cathlic</key> + <string>catholic</string> + <key>catholocism</key> + <string>catholicism</string> + <key>catterpilar</key> + <string>caterpillar</string> + <key>catterpilars</key> + <string>caterpillars</string> + <key>catterpillar</key> + <string>caterpillar</string> + <key>catterpillars</key> + <string>caterpillars</string> + <key>cattleship</key> + <string>battleship</string> + <key>causalities</key> + <string>casualties</string> + <key>cellpading</key> + <string>cellpadding</string> + <key>cementary</key> + <string>cemetery</string> + <key>cemetarey</key> + <string>cemetery</string> + <key>cemetaries</key> + <string>cemeteries</string> + <key>cemetary</key> + <string>cemetery</string> + <key>cencus</key> + <string>census</string> + <key>censur</key> + <string>censor</string> + <key>cententenial</key> + <string>centennial</string> + <key>centruies</key> + <string>centuries</string> + <key>centruy</key> + <string>century</string> + <key>ceratin</key> + <string>certain</string> + <key>cerimonial</key> + <string>ceremonial</string> + <key>cerimonies</key> + <string>ceremonies</string> + <key>cerimonious</key> + <string>ceremonious</string> + <key>cerimony</key> + <string>ceremony</string> + <key>ceromony</key> + <string>ceremony</string> + <key>certainity</key> + <string>certainty</string> + <key>certian</key> + <string>certain</string> + <key>chalenging</key> + <string>challenging</string> + <key>challange</key> + <string>challenge</string> + <key>challanged</key> + <string>challenged</string> + <key>challege</key> + <string>challenge</string> + <key>changable</key> + <string>changeable</string> + <key>charachter</key> + <string>character</string> + <key>charachters</key> + <string>characters</string> + <key>charactersistic</key> + <string>characteristic</string> + <key>charactor</key> + <string>character </string> + <key>charactors</key> + <string>characters</string> + <key>charasmatic</key> + <string>charismatic</string> + <key>charaterized</key> + <string>characterized</string> + <key>chariman</key> + <string>chairman</string> + <key>charistics</key> + <string>characteristics</string> + <key>cheif</key> + <string>chief</string> + <key>cheifs</key> + <string>chiefs</string> + <key>chemcial</key> + <string>chemical</string> + <key>chemcially</key> + <string>chemically</string> + <key>chemestry</key> + <string>chemistry</string> + <key>chemicaly</key> + <string>chemically</string> + <key>childbird</key> + <string>childbirth</string> + <key>childen</key> + <string>children</string> + <key>choosen</key> + <string>chosen</string> + <key>chracter</key> + <string>character</string> + <key>chuch</key> + <string>church</string> + <key>churchs</key> + <string>churches</string> + <key>circulaton</key> + <string>circulation</string> + <key>circumsicion</key> + <string>circumcision</string> + <key>circut</key> + <string>circuit</string> + <key>ciricuit</key> + <string>circuit</string> + <key>ciriculum</key> + <string>curriculum</string> + <key>civillian</key> + <string>civilian</string> + <key>claer</key> + <string>clear</string> + <key>claerer</key> + <string>clearer</string> + <key>claerly</key> + <string>clearly</string> + <key>claimes</key> + <string>claims</string> + <key>clas</key> + <string>class</string> + <key>clasic</key> + <string>classic</string> + <key>clasical</key> + <string>classical</string> + <key>clasically</key> + <string>classically</string> + <key>cleareance</key> + <string>clearance</string> + <key>clera</key> + <string>clear</string> + <key>clincial</key> + <string>clinical</string> + <key>clinicaly</key> + <string>clinically</string> + <key>cmo</key> + <string>com</string> + <key>cmoputer</key> + <string>computer</string> + <key>co-incided</key> + <string>coincided</string> + <key>coctail</key> + <string>cocktail</string> + <key>coform</key> + <string>conform</string> + <key>cognizent</key> + <string>cognizant</string> + <key>coincedentally</key> + <string>coincidentally</string> + <key>colaborations</key> + <string>collaborations</string> + <key>colateral</key> + <string>collateral</string> + <key>colelctive</key> + <string>collective</string> + <key>collaberative</key> + <string>collaborative</string> + <key>collecton</key> + <string>collection</string> + <key>collegue</key> + <string>colleague</string> + <key>collegues</key> + <string>colleagues</string> + <key>collonade</key> + <string>colonnade</string> + <key>collonies</key> + <string>colonies</string> + <key>collony</key> + <string>colony </string> + <key>collosal</key> + <string>colossal</string> + <key>colonizators</key> + <string>colonizers</string> + <key>comander</key> + <string>commander</string> + <key>comando</key> + <string>commando</string> + <key>comandos</key> + <string>commandos</string> + <key>comany</key> + <string>company</string> + <key>comapany</key> + <string>company</string> + <key>comback</key> + <string>comeback</string> + <key>combanations</key> + <string>combinations</string> + <key>combinatins</key> + <string>combinations</string> + <key>combusion</key> + <string>combustion</string> + <key>comdemnation</key> + <string>condemnation</string> + <key>comemmorates</key> + <string>commemorates</string> + <key>comemoretion</key> + <string>commemoration</string> + <key>comision</key> + <string>commission</string> + <key>comisioned</key> + <string>commissioned</string> + <key>comisioner</key> + <string>commissioner</string> + <key>comisioning</key> + <string>commissioning</string> + <key>comisions</key> + <string>commissions</string> + <key>comission</key> + <string>commission</string> + <key>comissioned</key> + <string>commissioned</string> + <key>comissioner</key> + <string>commissioner</string> + <key>comissioning</key> + <string>commissioning</string> + <key>comissions</key> + <string>commissions</string> + <key>comited</key> + <string>committed</string> + <key>comiting</key> + <string>committing</string> + <key>comitted</key> + <string>committed</string> + <key>comittee</key> + <string>committee</string> + <key>comitting</key> + <string>committing</string> + <key>commandoes</key> + <string>commandos</string> + <key>commedic</key> + <string>comedic</string> + <key>commemerative</key> + <string>commemorative</string> + <key>commemmorate</key> + <string>commemorate</string> + <key>commemmorating</key> + <string>commemorating</string> + <key>commerical</key> + <string>commercial</string> + <key>commerically</key> + <string>commercially</string> + <key>commericial</key> + <string>commercial</string> + <key>commericially</key> + <string>commercially</string> + <key>commerorative</key> + <string>commemorative</string> + <key>comming</key> + <string>coming</string> + <key>comminication</key> + <string>communication</string> + <key>commision</key> + <string>commission</string> + <key>commisioned</key> + <string>commissioned</string> + <key>commisioner</key> + <string>commissioner</string> + <key>commisioning</key> + <string>commissioning</string> + <key>commisions</key> + <string>commissions</string> + <key>commited</key> + <string>committed</string> + <key>commitee</key> + <string>committee</string> + <key>commiting</key> + <string>committing</string> + <key>committe</key> + <string>committee</string> + <key>committment</key> + <string>commitment</string> + <key>committments</key> + <string>commitments</string> + <key>commmemorated</key> + <string>commemorated</string> + <key>commongly</key> + <string>commonly</string> + <key>commonweath</key> + <string>commonwealth</string> + <key>commuications</key> + <string>communications</string> + <key>commuinications</key> + <string>communications</string> + <key>communciation</key> + <string>communication</string> + <key>communiation</key> + <string>communication</string> + <key>communites</key> + <string>communities</string> + <key>compability</key> + <string>compatibility</string> + <key>comparision</key> + <string>comparison</string> + <key>comparisions</key> + <string>comparisons</string> + <key>comparitive</key> + <string>comparative</string> + <key>comparitively</key> + <string>comparatively</string> + <key>compatabilities</key> + <string>compatibilities</string> + <key>compatability</key> + <string>compatibility</string> + <key>compatable</key> + <string>compatible</string> + <key>compatablities</key> + <string>compatibilities</string> + <key>compatablity</key> + <string>compatibility</string> + <key>compatiable</key> + <string>compatible</string> + <key>compatiblities</key> + <string>compatibilities</string> + <key>compatiblity</key> + <string>compatibility</string> + <key>compeitions</key> + <string>competitions</string> + <key>compensantion</key> + <string>compensation</string> + <key>competance</key> + <string>competence</string> + <key>competant</key> + <string>competent</string> + <key>competative</key> + <string>competitive</string> + <key>competion</key> + <string>competition</string> + <key>competitiion</key> + <string>competition</string> + <key>competive</key> + <string>competitive</string> + <key>competiveness</key> + <string>competitiveness</string> + <key>comphrehensive</key> + <string>comprehensive</string> + <key>compitent</key> + <string>competent</string> + <key>completedthe</key> + <string>completed the</string> + <key>completelyl</key> + <string>completely</string> + <key>completetion</key> + <string>completion</string> + <key>complier</key> + <string>compiler</string> + <key>componant</key> + <string>component</string> + <key>comprable</key> + <string>comparable</string> + <key>comprimise</key> + <string>compromise</string> + <key>compulsary</key> + <string>compulsory</string> + <key>compulsery</key> + <string>compulsory</string> + <key>computarized</key> + <string>computerized</string> + <key>concensus</key> + <string>consensus</string> + <key>concider</key> + <string>consider</string> + <key>concidered</key> + <string>considered</string> + <key>concidering</key> + <string>considering</string> + <key>conciders</key> + <string>considers</string> + <key>concieted</key> + <string>conceited</string> + <key>concieved</key> + <string>conceived</string> + <key>concious</key> + <string>conscious</string> + <key>conciously</key> + <string>consciously</string> + <key>conciousness</key> + <string>consciousness</string> + <key>condamned</key> + <string>condemned</string> + <key>condemmed</key> + <string>condemned</string> + <key>condidtion</key> + <string>condition</string> + <key>condidtions</key> + <string>conditions</string> + <key>conditionsof</key> + <string>conditions of</string> + <key>conected</key> + <string>connected</string> + <key>conection</key> + <string>connection</string> + <key>conesencus</key> + <string>consensus</string> + <key>confidental</key> + <string>confidential</string> + <key>confidentally</key> + <string>confidentially</string> + <key>confids</key> + <string>confides</string> + <key>configureable</key> + <string>configurable</string> + <key>confortable</key> + <string>comfortable</string> + <key>congradulations</key> + <string>congratulations</string> + <key>congresional</key> + <string>congressional</string> + <key>conived</key> + <string>connived</string> + <key>conjecutre</key> + <string>conjecture</string> + <key>conjuction</key> + <string>conjunction</string> + <key>conotations</key> + <string>connotations</string> + <key>conquerd</key> + <string>conquered</string> + <key>conquerer</key> + <string>conqueror</string> + <key>conquerers</key> + <string>conquerors</string> + <key>conqured</key> + <string>conquered</string> + <key>conscent</key> + <string>consent</string> + <key>consciouness</key> + <string>consciousness</string> + <key>consdider</key> + <string>consider</string> + <key>consdidered</key> + <string>considered</string> + <key>consdiered</key> + <string>considered</string> + <key>consectutive</key> + <string>consecutive</string> + <key>consenquently</key> + <string>consequently</string> + <key>consentrate</key> + <string>concentrate</string> + <key>consentrated</key> + <string>concentrated</string> + <key>consentrates</key> + <string>concentrates</string> + <key>consept</key> + <string>concept</string> + <key>consequentually</key> + <string>consequently</string> + <key>consequeseces</key> + <string>consequences</string> + <key>consern</key> + <string>concern</string> + <key>conserned</key> + <string>concerned</string> + <key>conserning</key> + <string>concerning</string> + <key>conservitive</key> + <string>conservative</string> + <key>consiciousness</key> + <string>consciousness</string> + <key>consicousness</key> + <string>consciousness</string> + <key>considerd</key> + <string>considered</string> + <key>consideres</key> + <string>considered</string> + <key>consious</key> + <string>conscious</string> + <key>consistant</key> + <string>consistent</string> + <key>consistantly</key> + <string>consistently</string> + <key>consituencies</key> + <string>constituencies</string> + <key>consituency</key> + <string>constituency</string> + <key>consituted</key> + <string>constituted</string> + <key>consitution</key> + <string>constitution</string> + <key>consitutional</key> + <string>constitutional</string> + <key>consolodate</key> + <string>consolidate</string> + <key>consolodated</key> + <string>consolidated</string> + <key>consonent</key> + <string>consonant</string> + <key>consonents</key> + <string>consonants</string> + <key>consorcium</key> + <string>consortium</string> + <key>conspiracys</key> + <string>conspiracies</string> + <key>conspiriator</key> + <string>conspirator</string> + <key>constaints</key> + <string>constraints</string> + <key>constanly</key> + <string>constantly</string> + <key>constarnation</key> + <string>consternation</string> + <key>constatn</key> + <string>constant</string> + <key>constinually</key> + <string>continually</string> + <key>constituant</key> + <string>constituent</string> + <key>constituants</key> + <string>constituents</string> + <key>constituion</key> + <string>constitution</string> + <key>constituional</key> + <string>constitutional</string> + <key>consttruction</key> + <string>construction</string> + <key>constuction</key> + <string>construction</string> + <key>consulant</key> + <string>consultant</string> + <key>consumate</key> + <string>consummate</string> + <key>consumated</key> + <string>consummated</string> + <key>contaiminate</key> + <string>contaminate</string> + <key>containes</key> + <string>contains</string> + <key>contamporaries</key> + <string>contemporaries</string> + <key>contamporary</key> + <string>contemporary</string> + <key>contempoary</key> + <string>contemporary</string> + <key>contemporaneus</key> + <string>contemporaneous</string> + <key>contempory</key> + <string>contemporary</string> + <key>contendor</key> + <string>contender</string> + <key>contibute</key> + <string>contribute </string> + <key>contibuted</key> + <string>contributed </string> + <key>contibutes</key> + <string>contributes </string> + <key>contigent</key> + <string>contingent</string> + <key>contined</key> + <string>continued</string> + <key>continous</key> + <string>continuous</string> + <key>continously</key> + <string>continuously</string> + <key>continueing</key> + <string>continuing</string> + <key>contravercial</key> + <string>controversial</string> + <key>contraversy</key> + <string>controversy</string> + <key>contributer</key> + <string>contributor</string> + <key>contributers</key> + <string>contributors</string> + <key>contritutions</key> + <string>contributions</string> + <key>controled</key> + <string>controlled</string> + <key>controling</key> + <string>controlling</string> + <key>controll</key> + <string>control</string> + <key>controlls</key> + <string>controls</string> + <key>controvercial</key> + <string>controversial</string> + <key>controvercy</key> + <string>controversy</string> + <key>controveries</key> + <string>controversies</string> + <key>controversal</key> + <string>controversial</string> + <key>controversey</key> + <string>controversy</string> + <key>controvertial</key> + <string>controversial</string> + <key>controvery</key> + <string>controversy</string> + <key>contruction</key> + <string>construction</string> + <key>conveinent</key> + <string>convenient</string> + <key>convenant</key> + <string>covenant</string> + <key>convential</key> + <string>conventional</string> + <key>convertables</key> + <string>convertibles</string> + <key>convertion</key> + <string>conversion</string> + <key>conveyer</key> + <string>conveyor</string> + <key>conviced</key> + <string>convinced</string> + <key>convienient</key> + <string>convenient</string> + <key>coordiantion</key> + <string>coordination</string> + <key>coorperations</key> + <string>corporations</string> + <key>copmetitors</key> + <string>competitors</string> + <key>coputer</key> + <string>computer</string> + <key>copywrite</key> + <string>copyright</string> + <key>coridal</key> + <string>cordial</string> + <key>cornmitted</key> + <string>committed</string> + <key>corosion</key> + <string>corrosion</string> + <key>corparate</key> + <string>corporate</string> + <key>corperations</key> + <string>corporations</string> + <key>correcters</key> + <string>correctors</string> + <key>correponding</key> + <string>corresponding</string> + <key>correposding</key> + <string>corresponding</string> + <key>correspondant</key> + <string>correspondent</string> + <key>correspondants</key> + <string>correspondents</string> + <key>corridoors</key> + <string>corridors</string> + <key>corrispond</key> + <string>correspond</string> + <key>corrispondant</key> + <string>correspondent</string> + <key>corrispondants</key> + <string>correspondents</string> + <key>corrisponded</key> + <string>corresponded</string> + <key>corrisponding</key> + <string>corresponding</string> + <key>corrisponds</key> + <string>corresponds</string> + <key>costitution</key> + <string>constitution</string> + <key>coucil</key> + <string>council</string> + <key>counries</key> + <string>countries</string> + <key>countains</key> + <string>contains</string> + <key>countires</key> + <string>countries</string> + <key>coururier</key> + <string>courier</string> + <key>coverted</key> + <string>converted</string> + <key>cpoy</key> + <string>copy</string> + <key>creaeted</key> + <string>created</string> + <key>creedence</key> + <string>credence</string> + <key>critereon</key> + <string>criterion</string> + <key>criterias</key> + <string>criteria</string> + <key>criticists</key> + <string>critics</string> + <key>critising</key> + <string>criticising</string> + <key>critisising</key> + <string>criticising</string> + <key>critisism</key> + <string>criticism</string> + <key>critisisms</key> + <string>criticisms</string> + <key>critisize</key> + <string>criticise</string> + <key>critisized</key> + <string>criticised</string> + <key>critisizes</key> + <string>criticises</string> + <key>critisizing</key> + <string>criticising</string> + <key>critized</key> + <string>criticized</string> + <key>critizing</key> + <string>criticizing</string> + <key>crockodiles</key> + <string>crocodiles</string> + <key>crowm</key> + <string>crown</string> + <key>crtical</key> + <string>critical</string> + <key>crticised</key> + <string>criticised</string> + <key>crucifiction</key> + <string>crucifixion</string> + <key>crusies</key> + <string>cruises</string> + <key>crystalisation</key> + <string>crystallisation</string> + <key>culiminating</key> + <string>culminating</string> + <key>cumulatative</key> + <string>cumulative</string> + <key>curch</key> + <string>church</string> + <key>curcuit</key> + <string>circuit</string> + <key>currenly</key> + <string>currently</string> + <key>curriculem</key> + <string>curriculum</string> + <key>cxan</key> + <string>cyan</string> + <key>cyclinder</key> + <string>cylinder</string> + <key>dacquiri</key> + <string>daiquiri</string> + <key>dael</key> + <string>deal</string> + <key>dalmation</key> + <string>dalmatian</string> + <key>damenor</key> + <string>demeanor</string> + <key>dammage</key> + <string>damage</string> + <key>daugher</key> + <string>daughter</string> + <key>debateable</key> + <string>debatable</string> + <key>decendant</key> + <string>descendant</string> + <key>decendants</key> + <string>descendants</string> + <key>decendent</key> + <string>descendant</string> + <key>decendents</key> + <string>descendants</string> + <key>decideable</key> + <string>decidable</string> + <key>decidely</key> + <string>decidedly</string> + <key>decieved</key> + <string>deceived</string> + <key>decison</key> + <string>decision</string> + <key>decomissioned</key> + <string>decommissioned</string> + <key>decomposit</key> + <string>decompose</string> + <key>decomposited</key> + <string>decomposed</string> + <key>decompositing</key> + <string>decomposing</string> + <key>decomposits</key> + <string>decomposes</string> + <key>decress</key> + <string>decrees</string> + <key>decribe</key> + <string>describe</string> + <key>decribed</key> + <string>described</string> + <key>decribes</key> + <string>describes</string> + <key>decribing</key> + <string>describing</string> + <key>dectect</key> + <string>detect</string> + <key>defendent</key> + <string>defendant</string> + <key>defendents</key> + <string>defendants</string> + <key>deffensively</key> + <string>defensively</string> + <key>deffine</key> + <string>define</string> + <key>deffined</key> + <string>defined</string> + <key>definance</key> + <string>defiance</string> + <key>definate</key> + <string>definite</string> + <key>definately</key> + <string>definitely</string> + <key>definatly</key> + <string>definitely</string> + <key>definetly</key> + <string>definitely</string> + <key>definining</key> + <string>defining</string> + <key>definit</key> + <string>definite</string> + <key>definitly</key> + <string>definitely</string> + <key>definiton</key> + <string>definition</string> + <key>defintion</key> + <string>definition</string> + <key>degrate</key> + <string>degrade</string> + <key>delagates</key> + <string>delegates</string> + <key>delapidated</key> + <string>dilapidated</string> + <key>delerious</key> + <string>delirious</string> + <key>delevopment</key> + <string>development</string> + <key>deliberatly</key> + <string>deliberately</string> + <key>delusionally</key> + <string>delusively</string> + <key>demenor</key> + <string>demeanor</string> + <key>demographical</key> + <string>demographic</string> + <key>demolision</key> + <string>demolition</string> + <key>demorcracy</key> + <string>democracy</string> + <key>demostration</key> + <string>demonstration</string> + <key>denegrating</key> + <string>denigrating</string> + <key>densly</key> + <string>densely</string> + <key>deparment</key> + <string>department</string> + <key>deparmental</key> + <string>departmental</string> + <key>deparments</key> + <string>departments</string> + <key>dependance</key> + <string>dependence</string> + <key>dependancy</key> + <string>dependency</string> + <key>dependant</key> + <string>dependent</string> + <key>deram</key> + <string>dream</string> + <key>deriviated</key> + <string>derived</string> + <key>derivitive</key> + <string>derivative</string> + <key>derogitory</key> + <string>derogatory</string> + <key>descendands</key> + <string>descendants</string> + <key>descibed</key> + <string>described</string> + <key>descision</key> + <string>decision</string> + <key>descisions</key> + <string>decisions</string> + <key>descriibes</key> + <string>describes</string> + <key>descripters</key> + <string>descriptors</string> + <key>descripton</key> + <string>description</string> + <key>desctruction</key> + <string>destruction</string> + <key>descuss</key> + <string>discuss</string> + <key>desgined</key> + <string>designed</string> + <key>deside</key> + <string>decide</string> + <key>desigining</key> + <string>designing</string> + <key>desinations</key> + <string>destinations</string> + <key>desintegrated</key> + <string>disintegrated</string> + <key>desintegration</key> + <string>disintegration</string> + <key>desireable</key> + <string>desirable</string> + <key>desitned</key> + <string>destined</string> + <key>desktiop</key> + <string>desktop</string> + <key>desorder</key> + <string>disorder</string> + <key>desoriented</key> + <string>disoriented</string> + <key>desparate</key> + <string>desperate</string> + <key>despict</key> + <string>depict</string> + <key>despiration</key> + <string>desperation</string> + <key>dessicated</key> + <string>desiccated</string> + <key>dessigned</key> + <string>designed</string> + <key>destablized</key> + <string>destabilized</string> + <key>destory</key> + <string>destroy</string> + <key>detailled</key> + <string>detailed</string> + <key>detatched</key> + <string>detached</string> + <key>deteoriated</key> + <string>deteriorated</string> + <key>deteriate</key> + <string>deteriorate</string> + <key>deterioriating</key> + <string>deteriorating</string> + <key>determinining</key> + <string>determining</string> + <key>detremental</key> + <string>detrimental</string> + <key>devasted</key> + <string>devastated</string> + <key>develope</key> + <string>develop</string> + <key>developement</key> + <string>development</string> + <key>developped</key> + <string>developed</string> + <key>develpment</key> + <string>development</string> + <key>devels</key> + <string>delves</string> + <key>devestated</key> + <string>devastated</string> + <key>devestating</key> + <string>devastating</string> + <key>devide</key> + <string>divide</string> + <key>devided</key> + <string>divided</string> + <key>devistating</key> + <string>devastating</string> + <key>devolopement</key> + <string>development</string> + <key>diablical</key> + <string>diabolical</string> + <key>diamons</key> + <string>diamonds</string> + <key>diaster</key> + <string>disaster</string> + <key>dichtomy</key> + <string>dichotomy</string> + <key>diconnects</key> + <string>disconnects</string> + <key>dicover</key> + <string>discover</string> + <key>dicovered</key> + <string>discovered</string> + <key>dicovering</key> + <string>discovering</string> + <key>dicovers</key> + <string>discovers</string> + <key>dicovery</key> + <string>discovery</string> + <key>dicussed</key> + <string>discussed</string> + <key>didnt</key> + <string>didn't</string> + <key>diea</key> + <string>idea</string> + <key>dieing</key> + <string>dying</string> + <key>dieties</key> + <string>deities</string> + <key>diety</key> + <string>deity</string> + <key>diferent</key> + <string>different</string> + <key>diferrent</key> + <string>different</string> + <key>differentiatiations</key> + <string>differentiations</string> + <key>differnt</key> + <string>different</string> + <key>difficulity</key> + <string>difficulty</string> + <key>diffrent</key> + <string>different</string> + <key>dificulties</key> + <string>difficulties</string> + <key>dificulty</key> + <string>difficulty</string> + <key>dimenions</key> + <string>dimensions</string> + <key>dimention</key> + <string>dimension</string> + <key>dimentional</key> + <string>dimensional</string> + <key>dimentions</key> + <string>dimensions</string> + <key>dimesnional</key> + <string>dimensional</string> + <key>diminuitive</key> + <string>diminutive</string> + <key>dimunitive</key> + <string>diminutive</string> + <key>diosese</key> + <string>diocese</string> + <key>diphtong</key> + <string>diphthong</string> + <key>diphtongs</key> + <string>diphthongs</string> + <key>diplomancy</key> + <string>diplomacy</string> + <key>dipthong</key> + <string>diphthong</string> + <key>dipthongs</key> + <string>diphthongs</string> + <key>dirived</key> + <string>derived</string> + <key>disagreeed</key> + <string>disagreed</string> + <key>disapeared</key> + <string>disappeared</string> + <key>disapointing</key> + <string>disappointing</string> + <key>disappearred</key> + <string>disappeared</string> + <key>disaproval</key> + <string>disapproval</string> + <key>disasterous</key> + <string>disastrous</string> + <key>disatisfaction</key> + <string>dissatisfaction</string> + <key>disatisfied</key> + <string>dissatisfied</string> + <key>disatrous</key> + <string>disastrous</string> + <key>discontentment</key> + <string>discontent</string> + <key>discribe</key> + <string>describe</string> + <key>discribed</key> + <string>described</string> + <key>discribes</key> + <string>describes</string> + <key>discribing</key> + <string>describing</string> + <key>disctinction</key> + <string>distinction</string> + <key>disctinctive</key> + <string>distinctive</string> + <key>disemination</key> + <string>dissemination</string> + <key>disenchanged</key> + <string>disenchanted</string> + <key>disiplined</key> + <string>disciplined</string> + <key>disobediance</key> + <string>disobedience</string> + <key>disobediant</key> + <string>disobedient</string> + <key>disolved</key> + <string>dissolved</string> + <key>disover</key> + <string>discover</string> + <key>dispair</key> + <string>despair</string> + <key>disparingly</key> + <string>disparagingly</string> + <key>dispence</key> + <string>dispense</string> + <key>dispenced</key> + <string>dispensed</string> + <key>dispencing</key> + <string>dispensing</string> + <key>dispicable</key> + <string>despicable</string> + <key>dispite</key> + <string>despite</string> + <key>dispostion</key> + <string>disposition</string> + <key>disproportiate</key> + <string>disproportionate</string> + <key>disputandem</key> + <string>disputandum</string> + <key>disricts</key> + <string>districts</string> + <key>dissagreement</key> + <string>disagreement</string> + <key>dissapear</key> + <string>disappear</string> + <key>dissapearance</key> + <string>disappearance</string> + <key>dissapeared</key> + <string>disappeared</string> + <key>dissapearing</key> + <string>disappearing</string> + <key>dissapears</key> + <string>disappears</string> + <key>dissappear</key> + <string>disappear</string> + <key>dissappears</key> + <string>disappears</string> + <key>dissappointed</key> + <string>disappointed</string> + <key>dissarray</key> + <string>disarray</string> + <key>dissobediance</key> + <string>disobedience</string> + <key>dissobediant</key> + <string>disobedient</string> + <key>dissobedience</key> + <string>disobedience</string> + <key>dissobedient</key> + <string>disobedient</string> + <key>distiction</key> + <string>distinction</string> + <key>distingish</key> + <string>distinguish</string> + <key>distingished</key> + <string>distinguished</string> + <key>distingishes</key> + <string>distinguishes</string> + <key>distingishing</key> + <string>distinguishing</string> + <key>distingquished</key> + <string>distinguished</string> + <key>distrubution</key> + <string>distribution</string> + <key>distruction</key> + <string>destruction</string> + <key>distructive</key> + <string>destructive</string> + <key>ditributed</key> + <string>distributed</string> + <key>diversed</key> + <string>diverged</string> + <key>divice</key> + <string>device</string> + <key>divison</key> + <string>division</string> + <key>divisons</key> + <string>divisions</string> + <key>doccument</key> + <string>document</string> + <key>doccumented</key> + <string>documented</string> + <key>doccuments</key> + <string>documents</string> + <key>docrines</key> + <string>doctrines</string> + <key>doctines</key> + <string>doctrines</string> + <key>documenatry</key> + <string>documentary</string> + <key>doens</key> + <string>does</string> + <key>doesnt</key> + <string>doesn't</string> + <key>doign</key> + <string>doing</string> + <key>dominaton</key> + <string>domination</string> + <key>dominent</key> + <string>dominant</string> + <key>dominiant</key> + <string>dominant</string> + <key>donig</key> + <string>doing</string> + <key>dont</key> + <string>don't</string> + <key>dosen't</key> + <string>doesn't</string> + <key>doub</key> + <string>doubt</string> + <key>doulbe</key> + <string>double</string> + <key>dowloads</key> + <string>downloads</string> + <key>dramtic</key> + <string>dramatic</string> + <key>draughtman</key> + <string>draughtsman</string> + <key>dreasm</key> + <string>dreams</string> + <key>driectly</key> + <string>directly</string> + <key>drnik</key> + <string>drink</string> + <key>druming</key> + <string>drumming</string> + <key>drummless</key> + <string>drumless</string> + <key>dupicate</key> + <string>duplicate</string> + <key>durig</key> + <string>during</string> + <key>durring</key> + <string>during</string> + <key>duting</key> + <string>during</string> + <key>dyas</key> + <string>dryas</string> + <key>eahc</key> + <string>each</string> + <key>ealier</key> + <string>earlier</string> + <key>earlies</key> + <string>earliest</string> + <key>earnt</key> + <string>earned</string> + <key>ecclectic</key> + <string>eclectic</string> + <key>eceonomy</key> + <string>economy</string> + <key>ecidious</key> + <string>deciduous</string> + <key>eclispe</key> + <string>eclipse</string> + <key>ecomonic</key> + <string>economic</string> + <key>ect</key> + <string>etc</string> + <key>eearly</key> + <string>early</string> + <key>efel</key> + <string>evil</string> + <key>effeciency</key> + <string>efficiency</string> + <key>effecient</key> + <string>efficient</string> + <key>effeciently</key> + <string>efficiently</string> + <key>efficency</key> + <string>efficiency</string> + <key>efficent</key> + <string>efficient</string> + <key>efficently</key> + <string>efficiently</string> + <key>efford</key> + <string>effort</string> + <key>effords</key> + <string>efforts</string> + <key>effulence</key> + <string>effluence</string> + <key>eigth</key> + <string>eight</string> + <key>eiter</key> + <string>either</string> + <key>elction</key> + <string>election</string> + <key>electic</key> + <string>electric</string> + <key>electon</key> + <string>electron</string> + <key>electrial</key> + <string>electrical</string> + <key>electricly</key> + <string>electrically</string> + <key>electricty</key> + <string>electricity</string> + <key>elementay</key> + <string>elementary</string> + <key>eleminated</key> + <string>eliminated</string> + <key>eleminating</key> + <string>eliminating</string> + <key>eles</key> + <string>eels</string> + <key>eletricity</key> + <string>electricity</string> + <key>elicided</key> + <string>elicited</string> + <key>eligable</key> + <string>eligible</string> + <key>elimentary</key> + <string>elementary</string> + <key>ellected</key> + <string>elected</string> + <key>elphant</key> + <string>elephant</string> + <key>embarass</key> + <string>embarrass</string> + <key>embarassed</key> + <string>embarrassed</string> + <key>embarassing</key> + <string>embarrassing</string> + <key>embarassment</key> + <string>embarrassment</string> + <key>embargos</key> + <string>embargoes</string> + <key>embarras</key> + <string>embarrass</string> + <key>embarrased</key> + <string>embarrassed</string> + <key>embarrasing</key> + <string>embarrassing</string> + <key>embarrasment</key> + <string>embarrassment</string> + <key>embezelled</key> + <string>embezzled</string> + <key>emblamatic</key> + <string>emblematic</string> + <key>eminate</key> + <string>emanate</string> + <key>eminated</key> + <string>emanated</string> + <key>emision</key> + <string>emission</string> + <key>emited</key> + <string>emitted</string> + <key>emiting</key> + <string>emitting</string> + <key>emition</key> + <string>emission</string> + <key>emmediately</key> + <string>immediately</string> + <key>emmigrated</key> + <string>immigrated</string> + <key>emminently</key> + <string>eminently</string> + <key>emmisaries</key> + <string>emissaries</string> + <key>emmisarries</key> + <string>emissaries</string> + <key>emmisarry</key> + <string>emissary</string> + <key>emmisary</key> + <string>emissary</string> + <key>emmision</key> + <string>emission</string> + <key>emmisions</key> + <string>emissions</string> + <key>emmited</key> + <string>emitted</string> + <key>emmiting</key> + <string>emitting</string> + <key>emmitted</key> + <string>emitted</string> + <key>emmitting</key> + <string>emitting</string> + <key>emnity</key> + <string>enmity</string> + <key>emperical</key> + <string>empirical</string> + <key>emphaised</key> + <string>emphasised</string> + <key>emphsis</key> + <string>emphasis</string> + <key>emphysyma</key> + <string>emphysema</string> + <key>emprisoned</key> + <string>imprisoned</string> + <key>enameld</key> + <string>enameled</string> + <key>enchancement</key> + <string>enhancement</string> + <key>encouraing</key> + <string>encouraging</string> + <key>encryptiion</key> + <string>encryption</string> + <key>encylopedia</key> + <string>encyclopedia</string> + <key>endevors</key> + <string>endeavors</string> + <key>endevour</key> + <string>endeavour</string> + <key>endig</key> + <string>ending</string> + <key>endolithes</key> + <string>endoliths</string> + <key>enduce</key> + <string>induce</string> + <key>ened</key> + <string>need</string> + <key>enflamed</key> + <string>inflamed</string> + <key>enforceing</key> + <string>enforcing</string> + <key>engagment</key> + <string>engagement</string> + <key>engeneer</key> + <string>engineer</string> + <key>engeneering</key> + <string>engineering</string> + <key>engieneer</key> + <string>engineer</string> + <key>engieneers</key> + <string>engineers</string> + <key>enlargment</key> + <string>enlargement</string> + <key>enlargments</key> + <string>enlargements</string> + <key>enourmous</key> + <string>enormous</string> + <key>enourmously</key> + <string>enormously</string> + <key>ensconsed</key> + <string>ensconced</string> + <key>entaglements</key> + <string>entanglements</string> + <key>enteratinment</key> + <string>entertainment</string> + <key>enthusiatic</key> + <string>enthusiastic</string> + <key>entitity</key> + <string>entity</string> + <key>entitlied</key> + <string>entitled</string> + <key>entrepeneur</key> + <string>entrepreneur</string> + <key>entrepeneurs</key> + <string>entrepreneurs</string> + <key>enviorment</key> + <string>environment</string> + <key>enviormental</key> + <string>environmental</string> + <key>enviormentally</key> + <string>environmentally</string> + <key>enviorments</key> + <string>environments</string> + <key>enviornment</key> + <string>environment</string> + <key>enviornmental</key> + <string>environmental</string> + <key>enviornmentalist</key> + <string>environmentalist</string> + <key>enviornmentally</key> + <string>environmentally</string> + <key>enviornments</key> + <string>environments</string> + <key>enviroment</key> + <string>environment</string> + <key>enviromental</key> + <string>environmental</string> + <key>enviromentalist</key> + <string>environmentalist</string> + <key>enviromentally</key> + <string>environmentally</string> + <key>enviroments</key> + <string>environments</string> + <key>envolutionary</key> + <string>evolutionary</string> + <key>envrionments</key> + <string>environments</string> + <key>enxt</key> + <string>next</string> + <key>epidsodes</key> + <string>episodes</string> + <key>epsiode</key> + <string>episode</string> + <key>equialent</key> + <string>equivalent</string> + <key>equilibium</key> + <string>equilibrium</string> + <key>equilibrum</key> + <string>equilibrium</string> + <key>equiped</key> + <string>equipped</string> + <key>equippment</key> + <string>equipment</string> + <key>equitorial</key> + <string>equatorial</string> + <key>equivelant</key> + <string>equivalent</string> + <key>equivelent</key> + <string>equivalent</string> + <key>equivilant</key> + <string>equivalent</string> + <key>equivilent</key> + <string>equivalent</string> + <key>equivlalent</key> + <string>equivalent</string> + <key>erally</key> + <string>really</string> + <key>eratic</key> + <string>erratic</string> + <key>eratically</key> + <string>erratically</string> + <key>eraticly</key> + <string>erratically</string> + <key>errupted</key> + <string>erupted</string> + <key>esential</key> + <string>essential</string> + <key>esitmated</key> + <string>estimated</string> + <key>esle</key> + <string>else</string> + <key>especialy</key> + <string>especially</string> + <key>essencial</key> + <string>essential</string> + <key>essense</key> + <string>essence</string> + <key>essentail</key> + <string>essential</string> + <key>essentialy</key> + <string>essentially</string> + <key>essentual</key> + <string>essential</string> + <key>essesital</key> + <string>essential</string> + <key>estabishes</key> + <string>establishes</string> + <key>establising</key> + <string>establishing</string> + <key>ethnocentricm</key> + <string>ethnocentrism</string> + <key>ethose</key> + <string>those</string> + <key>evenhtually</key> + <string>eventually</string> + <key>eventally</key> + <string>eventually</string> + <key>eventhough</key> + <string>even though</string> + <key>eventially</key> + <string>eventually</string> + <key>eventualy</key> + <string>eventually</string> + <key>everthing</key> + <string>everything</string> + <key>everytime</key> + <string>every time</string> + <key>everyting</key> + <string>everything</string> + <key>eveyr</key> + <string>every</string> + <key>evidentally</key> + <string>evidently</string> + <key>exagerate</key> + <string>exaggerate</string> + <key>exagerated</key> + <string>exaggerated</string> + <key>exagerates</key> + <string>exaggerates</string> + <key>exagerating</key> + <string>exaggerating</string> + <key>exagerrate</key> + <string>exaggerate</string> + <key>exagerrated</key> + <string>exaggerated</string> + <key>exagerrates</key> + <string>exaggerates</string> + <key>exagerrating</key> + <string>exaggerating</string> + <key>examinated</key> + <string>examined</string> + <key>exampt</key> + <string>exempt</string> + <key>exapansion</key> + <string>expansion</string> + <key>excact</key> + <string>exact</string> + <key>excange</key> + <string>exchange</string> + <key>excecute</key> + <string>execute</string> + <key>excecuted</key> + <string>executed</string> + <key>excecutes</key> + <string>executes</string> + <key>excecuting</key> + <string>executing</string> + <key>excecution</key> + <string>execution</string> + <key>excedded</key> + <string>exceeded</string> + <key>excelent</key> + <string>excellent</string> + <key>excell</key> + <string>excel</string> + <key>excellance</key> + <string>excellence</string> + <key>excellant</key> + <string>excellent</string> + <key>excells</key> + <string>excels</string> + <key>excercise</key> + <string>exercise</string> + <key>exchanching</key> + <string>exchanging</string> + <key>excisted</key> + <string>existed</string> + <key>exculsivly</key> + <string>exclusively</string> + <key>execising</key> + <string>exercising</string> + <key>exection</key> + <string>execution</string> + <key>exectued</key> + <string>executed</string> + <key>exeedingly</key> + <string>exceedingly</string> + <key>exelent</key> + <string>excellent</string> + <key>exellent</key> + <string>excellent</string> + <key>exemple</key> + <string>example</string> + <key>exept</key> + <string>except</string> + <key>exeptional</key> + <string>exceptional</string> + <key>exerbate</key> + <string>exacerbate</string> + <key>exerbated</key> + <string>exacerbated</string> + <key>exerciese</key> + <string>exercises</string> + <key>exerpt</key> + <string>excerpt</string> + <key>exerpts</key> + <string>excerpts</string> + <key>exersize</key> + <string>exercise</string> + <key>exerternal</key> + <string>external</string> + <key>exhalted</key> + <string>exalted</string> + <key>exhibtion</key> + <string>exhibition</string> + <key>exibition</key> + <string>exhibition</string> + <key>exibitions</key> + <string>exhibitions</string> + <key>exicting</key> + <string>exciting</string> + <key>exinct</key> + <string>extinct</string> + <key>existance</key> + <string>existence</string> + <key>existant</key> + <string>existent</string> + <key>existince</key> + <string>existence</string> + <key>exliled</key> + <string>exiled</string> + <key>exludes</key> + <string>excludes</string> + <key>exmaple</key> + <string>example</string> + <key>exonorate</key> + <string>exonerate</string> + <key>exoskelaton</key> + <string>exoskeleton</string> + <key>expalin</key> + <string>explain</string> + <key>expatriot</key> + <string>expatriate</string> + <key>expeced</key> + <string>expected</string> + <key>expecially</key> + <string>especially</string> + <key>expeditonary</key> + <string>expeditionary</string> + <key>expeiments</key> + <string>experiments</string> + <key>expell</key> + <string>expel</string> + <key>expells</key> + <string>expels</string> + <key>experiance</key> + <string>experience</string> + <key>experianced</key> + <string>experienced</string> + <key>expiditions</key> + <string>expeditions</string> + <key>expierence</key> + <string>experience</string> + <key>explaination</key> + <string>explanation</string> + <key>explaning</key> + <string>explaining</string> + <key>explictly</key> + <string>explicitly</string> + <key>exploititive</key> + <string>exploitative</string> + <key>explotation</key> + <string>exploitation</string> + <key>expropiated</key> + <string>expropriated</string> + <key>expropiation</key> + <string>expropriation</string> + <key>exressed</key> + <string>expressed</string> + <key>extemely</key> + <string>extremely</string> + <key>extention</key> + <string>extension</string> + <key>extentions</key> + <string>extensions</string> + <key>extered</key> + <string>exerted</string> + <key>extermist</key> + <string>extremist</string> + <key>extint</key> + <string>extinct</string> + <key>extradiction</key> + <string>extradition</string> + <key>extraterrestial</key> + <string>extraterrestrial</string> + <key>extraterrestials</key> + <string>extraterrestrials</string> + <key>extravagent</key> + <string>extravagant</string> + <key>extrememly</key> + <string>extremely</string> + <key>extremeophile</key> + <string>extremophile</string> + <key>extremly</key> + <string>extremely</string> + <key>extrordinarily</key> + <string>extraordinarily</string> + <key>extrordinary</key> + <string>extraordinary</string> + <key>eyar</key> + <string>year</string> + <key>eyars</key> + <string>years</string> + <key>eyasr</key> + <string>years</string> + <key>faciliate</key> + <string>facilitate</string> + <key>faciliated</key> + <string>facilitated</string> + <key>faciliates</key> + <string>facilitates</string> + <key>facilites</key> + <string>facilities</string> + <key>facillitate</key> + <string>facilitate</string> + <key>facinated</key> + <string>fascinated</string> + <key>facist</key> + <string>fascist</string> + <key>familes</key> + <string>families</string> + <key>familliar</key> + <string>familiar</string> + <key>famoust</key> + <string>famous</string> + <key>fanatism</key> + <string>fanaticism</string> + <key>fatc</key> + <string>fact</string> + <key>faught</key> + <string>fought</string> + <key>favoutrable</key> + <string>favourable</string> + <key>feasable</key> + <string>feasible</string> + <key>fedreally</key> + <string>federally</string> + <key>feromone</key> + <string>pheromone</string> + <key>fertily</key> + <string>fertility</string> + <key>fianite</key> + <string>finite</string> + <key>fianlly</key> + <string>finally</string> + <key>ficticious</key> + <string>fictitious</string> + <key>fictious</key> + <string>fictitious</string> + <key>fidn</key> + <string>find</string> + <key>fiercly</key> + <string>fiercely</string> + <key>fightings</key> + <string>fighting</string> + <key>filiament</key> + <string>filament</string> + <key>fimilies</key> + <string>families</string> + <key>finacial</key> + <string>financial</string> + <key>finaly</key> + <string>finally</string> + <key>financialy</key> + <string>financially</string> + <key>firends</key> + <string>friends</string> + <key>firts</key> + <string>first</string> + <key>fisionable</key> + <string>fissionable</string> + <key>flamable</key> + <string>flammable</string> + <key>flawess</key> + <string>flawless</string> + <key>fleed</key> + <string>fled</string> + <key>florescent</key> + <string>fluorescent</string> + <key>flourescent</key> + <string>fluorescent</string> + <key>flourine</key> + <string>fluorine</string> + <key>fluorish</key> + <string>flourish</string> + <key>follwoing</key> + <string>following</string> + <key>folowing</key> + <string>following</string> + <key>fomed</key> + <string>formed</string> + <key>fomr</key> + <string>from</string> + <key>fonetic</key> + <string>phonetic</string> + <key>fontrier</key> + <string>fontier</string> + <key>foootball</key> + <string>football</string> + <key>forbad</key> + <string>forbade</string> + <key>forbiden</key> + <string>forbidden</string> + <key>foreward</key> + <string>foreword</string> + <key>forfiet</key> + <string>forfeit</string> + <key>forhead</key> + <string>forehead</string> + <key>foriegn</key> + <string>foreign</string> + <key>formallize</key> + <string>formalize</string> + <key>formallized</key> + <string>formalized</string> + <key>formaly</key> + <string>formally</string> + <key>formelly</key> + <string>formerly</string> + <key>formidible</key> + <string>formidable</string> + <key>formost</key> + <string>foremost</string> + <key>forsaw</key> + <string>foresaw</string> + <key>forseeable</key> + <string>foreseeable</string> + <key>fortelling</key> + <string>foretelling</string> + <key>forunner</key> + <string>forerunner</string> + <key>foucs</key> + <string>focus</string> + <key>foudn</key> + <string>found</string> + <key>fougth</key> + <string>fought</string> + <key>foundaries</key> + <string>foundries</string> + <key>foundary</key> + <string>foundry</string> + <key>fourties</key> + <string>forties</string> + <key>fourty</key> + <string>forty</string> + <key>fouth</key> + <string>fourth</string> + <key>foward</key> + <string>forward</string> + <key>freind</key> + <string>friend</string> + <key>freindly</key> + <string>friendly</string> + <key>frequentily</key> + <string>frequently</string> + <key>frome</key> + <string>from</string> + <key>fromed</key> + <string>formed</string> + <key>froniter</key> + <string>frontier</string> + <key>fucntion</key> + <string>function</string> + <key>fucntioning</key> + <string>functioning</string> + <key>fufill</key> + <string>fulfill</string> + <key>fufilled</key> + <string>fulfilled</string> + <key>fulfiled</key> + <string>fulfilled</string> + <key>fullfill</key> + <string>fulfill</string> + <key>fullfilled</key> + <string>fulfilled</string> + <key>fundametal</key> + <string>fundamental</string> + <key>fundametals</key> + <string>fundamentals</string> + <key>funguses</key> + <string>fungi</string> + <key>funtion</key> + <string>function</string> + <key>furuther</key> + <string>further</string> + <key>futher</key> + <string>further</string> + <key>futhermore</key> + <string>furthermore</string> + <key>galatic</key> + <string>galactic</string> + <key>gallaxies</key> + <string>galaxies</string> + <key>galvinized</key> + <string>galvanized</string> + <key>ganerate</key> + <string>generate</string> + <key>ganes</key> + <string>games</string> + <key>ganster</key> + <string>gangster</string> + <key>garantee</key> + <string>guarantee</string> + <key>garanteed</key> + <string>guaranteed</string> + <key>garantees</key> + <string>guarantees</string> + <key>garnison</key> + <string>garrison</string> + <key>gaurantee</key> + <string>guarantee</string> + <key>gauranteed</key> + <string>guaranteed</string> + <key>gaurantees</key> + <string>guarantees</string> + <key>gaurd</key> + <string>guard</string> + <key>gaurentee</key> + <string>guarantee</string> + <key>gaurenteed</key> + <string>guaranteed</string> + <key>gaurentees</key> + <string>guarantees</string> + <key>geneological</key> + <string>genealogical</string> + <key>geneologies</key> + <string>genealogies</string> + <key>geneology</key> + <string>genealogy</string> + <key>generaly</key> + <string>generally</string> + <key>generatting</key> + <string>generating</string> + <key>genialia</key> + <string>genitalia</string> + <key>geographicial</key> + <string>geographical</string> + <key>geometrician</key> + <string>geometer</string> + <key>geometricians</key> + <string>geometers</string> + <key>gerat</key> + <string>great</string> + <key>glight</key> + <string>flight</string> + <key>gnawwed</key> + <string>gnawed</string> + <key>godess</key> + <string>goddess</string> + <key>godesses</key> + <string>goddesses</string> + <key>gogin</key> + <string>going</string> + <key>goign</key> + <string>going</string> + <key>gonig</key> + <string>going</string> + <key>gouvener</key> + <string>governor</string> + <key>govement</key> + <string>government</string> + <key>govenment</key> + <string>government</string> + <key>govenrment</key> + <string>government</string> + <key>goverance</key> + <string>governance</string> + <key>goverment</key> + <string>government</string> + <key>govermental</key> + <string>governmental</string> + <key>governer</key> + <string>governor</string> + <key>governmnet</key> + <string>government</string> + <key>govorment</key> + <string>government</string> + <key>govormental</key> + <string>governmental</string> + <key>govornment</key> + <string>government</string> + <key>gracefull</key> + <string>graceful</string> + <key>graet</key> + <string>great</string> + <key>grafitti</key> + <string>graffiti</string> + <key>gramatically</key> + <string>grammatically</string> + <key>grammaticaly</key> + <string>grammatically</string> + <key>grammer</key> + <string>grammar</string> + <key>grat</key> + <string>great</string> + <key>gratuitious</key> + <string>gratuitous</string> + <key>greatful</key> + <string>grateful</string> + <key>greatfully</key> + <string>gratefully</string> + <key>greif</key> + <string>grief</string> + <key>gridles</key> + <string>griddles</string> + <key>gropu</key> + <string>group</string> + <key>grwo</key> + <string>grow</string> + <key>guage</key> + <string>gauge</string> + <key>guarentee</key> + <string>guarantee</string> + <key>guarenteed</key> + <string>guaranteed</string> + <key>guarentees</key> + <string>guarantees</string> + <key>guerilla</key> + <string>guerrilla</string> + <key>guerillas</key> + <string>guerrillas</string> + <key>guerrila</key> + <string>guerrilla</string> + <key>guerrilas</key> + <string>guerrillas</string> + <key>guidence</key> + <string>guidance</string> + <key>gunanine</key> + <string>guanine</string> + <key>gurantee</key> + <string>guarantee</string> + <key>guranteed</key> + <string>guaranteed</string> + <key>gurantees</key> + <string>guarantees</string> + <key>guttaral</key> + <string>guttural</string> + <key>gutteral</key> + <string>guttural</string> + <key>habaeus</key> + <string>habeas</string> + <key>habeus</key> + <string>habeas</string> + <key>haemorrage</key> + <string>haemorrhage</string> + <key>haev</key> + <string>have</string> + <key>halp</key> + <string>help</string> + <key>hapen</key> + <string>happen</string> + <key>hapened</key> + <string>happened</string> + <key>hapening</key> + <string>happening</string> + <key>happend</key> + <string>happened</string> + <key>happended</key> + <string>happened</string> + <key>happenned</key> + <string>happened</string> + <key>harased</key> + <string>harassed</string> + <key>harases</key> + <string>harasses</string> + <key>harasment</key> + <string>harassment</string> + <key>harasments</key> + <string>harassments</string> + <key>harassement</key> + <string>harassment</string> + <key>harras</key> + <string>harass</string> + <key>harrased</key> + <string>harassed</string> + <key>harrases</key> + <string>harasses</string> + <key>harrasing</key> + <string>harassing</string> + <key>harrasment</key> + <string>harassment</string> + <key>harrasments</key> + <string>harassments</string> + <key>harrassed</key> + <string>harassed</string> + <key>harrasses</key> + <string>harassed</string> + <key>harrassing</key> + <string>harassing</string> + <key>harrassment</key> + <string>harassment</string> + <key>harrassments</key> + <string>harassments</string> + <key>hasnt</key> + <string>hasn't</string> + <key>haviest</key> + <string>heaviest</string> + <key>headquarer</key> + <string>headquarter</string> + <key>headquater</key> + <string>headquarter</string> + <key>headquatered</key> + <string>headquartered</string> + <key>headquaters</key> + <string>headquarters</string> + <key>healthercare</key> + <string>healthcare</string> + <key>heared</key> + <string>heard</string> + <key>heathy</key> + <string>healthy</string> + <key>heigher</key> + <string>higher</string> + <key>heirarchy</key> + <string>hierarchy</string> + <key>heiroglyphics</key> + <string>hieroglyphics</string> + <key>helment</key> + <string>helmet</string> + <key>helpfull</key> + <string>helpful</string> + <key>helpped</key> + <string>helped</string> + <key>hemmorhage</key> + <string>hemorrhage</string> + <key>herad</key> + <string>heard</string> + <key>heridity</key> + <string>heredity</string> + <key>heroe</key> + <string>hero</string> + <key>heros</key> + <string>heroes</string> + <key>hertiage</key> + <string>heritage</string> + <key>hertzs</key> + <string>hertz</string> + <key>hesistant</key> + <string>hesitant</string> + <key>heterogenous</key> + <string>heterogeneous</string> + <key>hieght</key> + <string>height</string> + <key>hierachical</key> + <string>hierarchical</string> + <key>hierachies</key> + <string>hierarchies</string> + <key>hierachy</key> + <string>hierarchy</string> + <key>hierarcical</key> + <string>hierarchical</string> + <key>hierarcy</key> + <string>hierarchy</string> + <key>hieroglph</key> + <string>hieroglyph</string> + <key>hieroglphs</key> + <string>hieroglyphs</string> + <key>higer</key> + <string>higher</string> + <key>higest</key> + <string>highest</string> + <key>higway</key> + <string>highway</string> + <key>hillarious</key> + <string>hilarious</string> + <key>himselv</key> + <string>himself</string> + <key>hinderance</key> + <string>hindrance</string> + <key>hinderence</key> + <string>hindrance</string> + <key>hindrence</key> + <string>hindrance</string> + <key>hipopotamus</key> + <string>hippopotamus</string> + <key>hismelf</key> + <string>himself</string> + <key>histocompatability</key> + <string>histocompatibility</string> + <key>historicians</key> + <string>historians</string> + <key>hitsingles</key> + <string>hit singles</string> + <key>holliday</key> + <string>holiday</string> + <key>homestate</key> + <string>home state</string> + <key>homogeneize</key> + <string>homogenize</string> + <key>homogeneized</key> + <string>homogenized</string> + <key>honory</key> + <string>honorary</string> + <key>horrifing</key> + <string>horrifying</string> + <key>hosited</key> + <string>hoisted</string> + <key>hospitible</key> + <string>hospitable</string> + <key>hounour</key> + <string>honour</string> + <key>housr</key> + <string>hours</string> + <key>howver</key> + <string>however</string> + <key>hsitorians</key> + <string>historians</string> + <key>hstory</key> + <string>history</string> + <key>hten</key> + <string>then</string> + <key>htere</key> + <string>there</string> + <key>htey</key> + <string>they</string> + <key>htikn</key> + <string>think</string> + <key>hting</key> + <string>thing</string> + <key>htink</key> + <string>think</string> + <key>htis</key> + <string>this</string> + <key>humer</key> + <string>humor</string> + <key>humerous</key> + <string>humorous</string> + <key>huminoid</key> + <string>humanoid</string> + <key>humoural</key> + <string>humoral</string> + <key>humurous</key> + <string>humorous</string> + <key>husban</key> + <string>husband</string> + <key>hvae</key> + <string>have</string> + <key>hvaing</key> + <string>having</string> + <key>hvea</key> + <string>have</string> + <key>hwihc</key> + <string>which</string> + <key>hwile</key> + <string>while</string> + <key>hwole</key> + <string>whole</string> + <key>hydogen</key> + <string>hydrogen</string> + <key>hydropile</key> + <string>hydrophile</string> + <key>hydropilic</key> + <string>hydrophilic</string> + <key>hydropobe</key> + <string>hydrophobe</string> + <key>hydropobic</key> + <string>hydrophobic</string> + <key>hygeine</key> + <string>hygiene</string> + <key>hypocracy</key> + <string>hypocrisy</string> + <key>hypocrasy</key> + <string>hypocrisy</string> + <key>hypocricy</key> + <string>hypocrisy</string> + <key>hypocrit</key> + <string>hypocrite</string> + <key>hypocrits</key> + <string>hypocrites</string> + <key>i</key> + <string>I</string> + <key>iconclastic</key> + <string>iconoclastic</string> + <key>idaeidae</key> + <string>idea</string> + <key>idaes</key> + <string>ideas</string> + <key>idealogies</key> + <string>ideologies</string> + <key>idealogy</key> + <string>ideology</string> + <key>identicial</key> + <string>identical</string> + <key>identifers</key> + <string>identifiers</string> + <key>ideosyncratic</key> + <string>idiosyncratic</string> + <key>idesa</key> + <string>ideas</string> + <key>idiosyncracy</key> + <string>idiosyncrasy</string> + <key>illegimacy</key> + <string>illegitimacy</string> + <key>illegitmate</key> + <string>illegitimate</string> + <key>illess</key> + <string>illness</string> + <key>illiegal</key> + <string>illegal</string> + <key>illution</key> + <string>illusion</string> + <key>ilness</key> + <string>illness</string> + <key>ilogical</key> + <string>illogical</string> + <key>imagenary</key> + <string>imaginary</string> + <key>imagin</key> + <string>imagine</string> + <key>imaginery</key> + <string>imaginary</string> + <key>imcomplete</key> + <string>incomplete</string> + <key>imediately</key> + <string>immediately</string> + <key>imense</key> + <string>immense</string> + <key>immediatley</key> + <string>immediately</string> + <key>immediatly</key> + <string>immediately</string> + <key>immidately</key> + <string>immediately</string> + <key>immidiately</key> + <string>immediately</string> + <key>immitate</key> + <string>imitate</string> + <key>immitated</key> + <string>imitated</string> + <key>immitating</key> + <string>imitating</string> + <key>immitator</key> + <string>imitator</string> + <key>immunosupressant</key> + <string>immunosuppressant</string> + <key>impecabbly</key> + <string>impeccably</string> + <key>impedence</key> + <string>impedance</string> + <key>implamenting</key> + <string>implementing</string> + <key>impliment</key> + <string>implement</string> + <key>implimented</key> + <string>implemented</string> + <key>imploys</key> + <string>employs</string> + <key>importamt</key> + <string>important</string> + <key>imprioned</key> + <string>imprisoned</string> + <key>imprisonned</key> + <string>imprisoned</string> + <key>improvision</key> + <string>improvisation</string> + <key>improvments</key> + <string>improvements</string> + <key>inablility</key> + <string>inability</string> + <key>inaccessable</key> + <string>inaccessible</string> + <key>inadiquate</key> + <string>inadequate</string> + <key>inadquate</key> + <string>inadequate</string> + <key>inadvertant</key> + <string>inadvertent</string> + <key>inadvertantly</key> + <string>inadvertently</string> + <key>inagurated</key> + <string>inaugurated</string> + <key>inaguration</key> + <string>inauguration</string> + <key>inappropiate</key> + <string>inappropriate</string> + <key>inaugures</key> + <string>inaugurates</string> + <key>inbalance</key> + <string>imbalance</string> + <key>inbalanced</key> + <string>imbalanced</string> + <key>inbetween</key> + <string>between</string> + <key>incarcirated</key> + <string>incarcerated</string> + <key>incidentially</key> + <string>incidentally</string> + <key>incidently</key> + <string>incidentally</string> + <key>inclreased</key> + <string>increased</string> + <key>includ</key> + <string>include</string> + <key>includng</key> + <string>including</string> + <key>incompatabilities</key> + <string>incompatibilities</string> + <key>incompatability</key> + <string>incompatibility</string> + <key>incompatable</key> + <string>incompatible</string> + <key>incompatablities</key> + <string>incompatibilities</string> + <key>incompatablity</key> + <string>incompatibility</string> + <key>incompatiblities</key> + <string>incompatibilities</string> + <key>incompatiblity</key> + <string>incompatibility</string> + <key>incompetance</key> + <string>incompetence</string> + <key>incompetant</key> + <string>incompetent</string> + <key>incomptable</key> + <string>incompatible</string> + <key>incomptetent</key> + <string>incompetent</string> + <key>inconsistant</key> + <string>inconsistent</string> + <key>incoroporated</key> + <string>incorporated</string> + <key>incorperation</key> + <string>incorporation</string> + <key>incorportaed</key> + <string>incorporated</string> + <key>incorprates</key> + <string>incorporates</string> + <key>incorruptable</key> + <string>incorruptible</string> + <key>incramentally</key> + <string>incrementally</string> + <key>increadible</key> + <string>incredible</string> + <key>incredable</key> + <string>incredible</string> + <key>inctroduce</key> + <string>introduce</string> + <key>inctroduced</key> + <string>introduced</string> + <key>incuding</key> + <string>including</string> + <key>incunabla</key> + <string>incunabula</string> + <key>indefinately</key> + <string>indefinitely</string> + <key>indefineable</key> + <string>undefinable</string> + <key>indefinitly</key> + <string>indefinitely</string> + <key>indentical</key> + <string>identical</string> + <key>indepedantly</key> + <string>independently</string> + <key>indepedence</key> + <string>independence</string> + <key>independance</key> + <string>independence</string> + <key>independant</key> + <string>independent</string> + <key>independantly</key> + <string>independently</string> + <key>independece</key> + <string>independence</string> + <key>independendet</key> + <string>independent</string> + <key>indespensable</key> + <string>indispensable</string> + <key>indespensible</key> + <string>indispensable</string> + <key>indictement</key> + <string>indictment</string> + <key>indigineous</key> + <string>indigenous</string> + <key>indipendence</key> + <string>independence</string> + <key>indipendent</key> + <string>independent</string> + <key>indipendently</key> + <string>independently</string> + <key>indispensible</key> + <string>indispensable</string> + <key>indisputible</key> + <string>indisputable</string> + <key>indisputibly</key> + <string>indisputably</string> + <key>indite</key> + <string>indict</string> + <key>individualy</key> + <string>individually</string> + <key>indpendent</key> + <string>independent</string> + <key>indpendently</key> + <string>independently</string> + <key>indulgue</key> + <string>indulge</string> + <key>indutrial</key> + <string>industrial</string> + <key>indviduals</key> + <string>individuals</string> + <key>inefficienty</key> + <string>inefficiently</string> + <key>inevatible</key> + <string>inevitable</string> + <key>inevitible</key> + <string>inevitable</string> + <key>inevititably</key> + <string>inevitably</string> + <key>infalability</key> + <string>infallibility</string> + <key>infallable</key> + <string>infallible</string> + <key>infectuous</key> + <string>infectious</string> + <key>infered</key> + <string>inferred</string> + <key>infilitrate</key> + <string>infiltrate</string> + <key>infilitrated</key> + <string>infiltrated</string> + <key>infilitration</key> + <string>infiltration</string> + <key>infinit</key> + <string>infinite</string> + <key>inflamation</key> + <string>inflammation</string> + <key>influencial</key> + <string>influential</string> + <key>influented</key> + <string>influenced</string> + <key>infomation</key> + <string>information</string> + <key>informtion</key> + <string>information</string> + <key>infrantryman</key> + <string>infantryman</string> + <key>infrigement</key> + <string>infringement</string> + <key>ingenius</key> + <string>ingenious</string> + <key>ingreediants</key> + <string>ingredients</string> + <key>inhabitans</key> + <string>inhabitants</string> + <key>inherantly</key> + <string>inherently</string> + <key>inheritence</key> + <string>inheritance</string> + <key>inital</key> + <string>initial</string> + <key>initally</key> + <string>initially</string> + <key>initation</key> + <string>initiation</string> + <key>initiaitive</key> + <string>initiative</string> + <key>inlcuding</key> + <string>including</string> + <key>inmigrant</key> + <string>immigrant</string> + <key>inmigrants</key> + <string>immigrants</string> + <key>innoculated</key> + <string>inoculated</string> + <key>inocence</key> + <string>innocence</string> + <key>inofficial</key> + <string>unofficial</string> + <key>inot</key> + <string>into</string> + <key>inpeach</key> + <string>impeach</string> + <key>inpolite</key> + <string>impolite</string> + <key>inprisonment</key> + <string>imprisonment</string> + <key>inproving</key> + <string>improving</string> + <key>insectiverous</key> + <string>insectivorous</string> + <key>insensative</key> + <string>insensitive</string> + <key>inseperable</key> + <string>inseparable</string> + <key>insistance</key> + <string>insistence</string> + <key>insitution</key> + <string>institution</string> + <key>insitutions</key> + <string>institutions</string> + <key>inspite</key> + <string>in spite</string> + <key>instade</key> + <string>instead</string> + <key>instatance</key> + <string>instance</string> + <key>institue</key> + <string>institute</string> + <key>instuction</key> + <string>instruction</string> + <key>instuments</key> + <string>instruments</string> + <key>instutionalized</key> + <string>institutionalized</string> + <key>instutions</key> + <string>intuitions</string> + <key>insurence</key> + <string>insurance</string> + <key>intelectual</key> + <string>intellectual</string> + <key>inteligence</key> + <string>intelligence</string> + <key>inteligent</key> + <string>intelligent</string> + <key>intenational</key> + <string>international</string> + <key>intented</key> + <string>intended</string> + <key>intepretation</key> + <string>interpretation</string> + <key>intepretator</key> + <string>interpretor</string> + <key>interational</key> + <string>international</string> + <key>interbread</key> + <string>interbreed</string> + <key>interchangable</key> + <string>interchangeable</string> + <key>interchangably</key> + <string>interchangeably</string> + <key>intercontinetal</key> + <string>intercontinental</string> + <key>intered</key> + <string>interred</string> + <key>interelated</key> + <string>interrelated</string> + <key>interferance</key> + <string>interference</string> + <key>interfereing</key> + <string>interfering</string> + <key>intergrated</key> + <string>integrated</string> + <key>intergration</key> + <string>integration</string> + <key>interm</key> + <string>interim</string> + <key>internation</key> + <string>international</string> + <key>interpet</key> + <string>interpret</string> + <key>interrim</key> + <string>interim</string> + <key>interrugum</key> + <string>interregnum</string> + <key>intertaining</key> + <string>entertaining</string> + <key>interupt</key> + <string>interrupt</string> + <key>intervines</key> + <string>intervenes</string> + <key>intevene</key> + <string>intervene</string> + <key>intial</key> + <string>initial</string> + <key>intially</key> + <string>initially</string> + <key>intrduced</key> + <string>introduced</string> + <key>intrest</key> + <string>interest</string> + <key>introdued</key> + <string>introduced</string> + <key>intruduced</key> + <string>introduced</string> + <key>intrument</key> + <string>instrument</string> + <key>intrumental</key> + <string>instrumental</string> + <key>intruments</key> + <string>instruments</string> + <key>intrusted</key> + <string>entrusted</string> + <key>intutive</key> + <string>intuitive</string> + <key>intutively</key> + <string>intuitively</string> + <key>inudstry</key> + <string>industry</string> + <key>inventer</key> + <string>inventor</string> + <key>invertibrates</key> + <string>invertebrates</string> + <key>investingate</key> + <string>investigate</string> + <key>involvment</key> + <string>involvement</string> + <key>irelevent</key> + <string>irrelevant</string> + <key>iresistable</key> + <string>irresistible</string> + <key>iresistably</key> + <string>irresistibly</string> + <key>iresistible</key> + <string>irresistible</string> + <key>iresistibly</key> + <string>irresistibly</string> + <key>iritable</key> + <string>irritable</string> + <key>iritated</key> + <string>irritated</string> + <key>ironicly</key> + <string>ironically</string> + <key>irregardless</key> + <string>regardless</string> + <key>irrelevent</key> + <string>irrelevant</string> + <key>irreplacable</key> + <string>irreplaceable</string> + <key>irresistable</key> + <string>irresistible</string> + <key>irresistably</key> + <string>irresistibly</string> + <key>isnt</key> + <string>isn't</string> + <key>issueing</key> + <string>issuing</string> + <key>itnroduced</key> + <string>introduced</string> + <key>iunior</key> + <string>junior</string> + <key>iwll</key> + <string>will</string> + <key>iwth</key> + <string>with</string> + <key>jaques</key> + <string>jacques</string> + <key>jeapardy</key> + <string>jeopardy</string> + <key>jewllery</key> + <string>jewellery</string> + <key>jouney</key> + <string>journey</string> + <key>journied</key> + <string>journeyed</string> + <key>journies</key> + <string>journeys</string> + <key>jstu</key> + <string>just</string> + <key>jsut</key> + <string>just</string> + <key>judical</key> + <string>judicial</string> + <key>judisuary</key> + <string>judiciary</string> + <key>juducial</key> + <string>judicial</string> + <key>juristiction</key> + <string>jurisdiction</string> + <key>juristictions</key> + <string>jurisdictions</string> + <key>kindergarden</key> + <string>kindergarten</string> + <key>klenex</key> + <string>kleenex</string> + <key>knifes</key> + <string>knives</string> + <key>knive</key> + <string>knife</string> + <key>knowlege</key> + <string>knowledge</string> + <key>knowlegeable</key> + <string>knowledgeable</string> + <key>knwo</key> + <string>know</string> + <key>knwos</key> + <string>knows</string> + <key>konw</key> + <string>know</string> + <key>konws</key> + <string>knows</string> + <key>kwno</key> + <string>know</string> + <key>labatory</key> + <string>laboratory</string> + <key>labratory</key> + <string>laboratory</string> + <key>laguage</key> + <string>language</string> + <key>laguages</key> + <string>languages</string> + <key>larg</key> + <string>large</string> + <key>largst</key> + <string>largest</string> + <key>larrry</key> + <string>larry</string> + <key>lastr</key> + <string>last</string> + <key>lattitude</key> + <string>latitude</string> + <key>launhed</key> + <string>launched</string> + <key>lavae</key> + <string>larvae</string> + <key>layed</key> + <string>laid</string> + <key>lazyness</key> + <string>laziness</string> + <key>leage</key> + <string>league</string> + <key>leanr</key> + <string>learn</string> + <key>leathal</key> + <string>lethal</string> + <key>lefted</key> + <string>left</string> + <key>legitamate</key> + <string>legitimate</string> + <key>legitmate</key> + <string>legitimate</string> + <key>leibnitz</key> + <string>leibniz</string> + <key>lenght</key> + <string>length</string> + <key>leran</key> + <string>learn</string> + <key>lerans</key> + <string>learns</string> + <key>leutenant</key> + <string>lieutenant</string> + <key>levetate</key> + <string>levitate</string> + <key>levetated</key> + <string>levitated</string> + <key>levetates</key> + <string>levitates</string> + <key>levetating</key> + <string>levitating</string> + <key>levle</key> + <string>level</string> + <key>liasion</key> + <string>liaison</string> + <key>liason</key> + <string>liaison</string> + <key>liasons</key> + <string>liaisons</string> + <key>libary</key> + <string>library</string> + <key>libell</key> + <string>libel</string> + <key>libguistic</key> + <string>linguistic</string> + <key>libguistics</key> + <string>linguistics</string> + <key>libitarianisn</key> + <string>libertarianism</string> + <key>lieing</key> + <string>lying</string> + <key>liek</key> + <string>like</string> + <key>liekd</key> + <string>liked</string> + <key>liesure</key> + <string>leisure</string> + <key>lieuenant</key> + <string>lieutenant</string> + <key>lieved</key> + <string>lived</string> + <key>liftime</key> + <string>lifetime</string> + <key>lightyear</key> + <string>light year</string> + <key>lightyears</key> + <string>light years</string> + <key>likelyhood</key> + <string>likelihood</string> + <key>linnaena</key> + <string>linnaean</string> + <key>lippizaner</key> + <string>lipizzaner</string> + <key>liquify</key> + <string>liquefy</string> + <key>liscense</key> + <string>license</string> + <key>lisence</key> + <string>license</string> + <key>lisense</key> + <string>license</string> + <key>listners</key> + <string>listeners</string> + <key>litature</key> + <string>literature</string> + <key>literaly</key> + <string>literally</string> + <key>literture</key> + <string>literature</string> + <key>littel</key> + <string>little</string> + <key>litterally</key> + <string>literally</string> + <key>liuke</key> + <string>like</string> + <key>livley</key> + <string>lively</string> + <key>lmits</key> + <string>limits</string> + <key>loev</key> + <string>love</string> + <key>lonelyness</key> + <string>loneliness</string> + <key>longitudonal</key> + <string>longitudinal</string> + <key>lonley</key> + <string>lonely</string> + <key>lonly</key> + <string>lonely</string> + <key>loosing</key> + <string>losing</string> + <key>lotharingen</key> + <string>lothringen</string> + <key>lsat</key> + <string>last</string> + <key>lukid</key> + <string>likud</string> + <key>lveo</key> + <string>love</string> + <key>lvoe</key> + <string>love</string> + <key>maching</key> + <string>machine</string> + <key>mackeral</key> + <string>mackerel</string> + <key>magasine</key> + <string>magazine</string> + <key>magincian</key> + <string>magician</string> + <key>magnificient</key> + <string>magnificent</string> + <key>magolia</key> + <string>magnolia</string> + <key>mailny</key> + <string>mainly</string> + <key>maintainance</key> + <string>maintenance</string> + <key>maintainence</key> + <string>maintenance</string> + <key>maintance</key> + <string>maintenance</string> + <key>maintenence</key> + <string>maintenance</string> + <key>maintinaing</key> + <string>maintaining</string> + <key>maintioned</key> + <string>mentioned</string> + <key>majoroty</key> + <string>majority</string> + <key>maked</key> + <string>marked</string> + <key>makse</key> + <string>makes</string> + <key>maltesian</key> + <string>Maltese</string> + <key>mamal</key> + <string>mammal</string> + <key>mamalian</key> + <string>mammalian</string> + <key>managable</key> + <string>manageable</string> + <key>managment</key> + <string>management</string> + <key>maneouvre</key> + <string>manoeuvre</string> + <key>maneouvred</key> + <string>manoeuvred</string> + <key>maneouvres</key> + <string>manoeuvres</string> + <key>maneouvring</key> + <string>manoeuvring</string> + <key>manisfestations</key> + <string>manifestations</string> + <key>manoeuverability</key> + <string>maneuverability</string> + <key>manouver</key> + <string>maneuver</string> + <key>manouverability</key> + <string>maneuverability</string> + <key>manouverable</key> + <string>maneuverable</string> + <key>manouvers</key> + <string>maneuvers</string> + <key>mantained</key> + <string>maintained</string> + <key>manuever</key> + <string>maneuver</string> + <key>manuevers</key> + <string>maneuvers</string> + <key>manufacturedd</key> + <string>manufactured</string> + <key>manufature</key> + <string>manufacture</string> + <key>manufatured</key> + <string>manufactured</string> + <key>manufaturing</key> + <string>manufacturing</string> + <key>manuver</key> + <string>maneuver</string> + <key>mariage</key> + <string>marriage</string> + <key>marjority</key> + <string>majority</string> + <key>markes</key> + <string>marks</string> + <key>marketting</key> + <string>marketing</string> + <key>marmelade</key> + <string>marmalade</string> + <key>marrage</key> + <string>marriage</string> + <key>marraige</key> + <string>marriage</string> + <key>marrtyred</key> + <string>martyred</string> + <key>marryied</key> + <string>married</string> + <key>massmedia</key> + <string>mass media</string> + <key>masterbation</key> + <string>masturbation</string> + <key>mataphysical</key> + <string>metaphysical</string> + <key>materalists</key> + <string>materialist</string> + <key>mathamatics</key> + <string>mathematics</string> + <key>mathematican</key> + <string>mathematician</string> + <key>mathematicas</key> + <string>mathematics</string> + <key>matheticians</key> + <string>mathematicians</string> + <key>mathmatically</key> + <string>mathematically</string> + <key>mathmatician</key> + <string>mathematician</string> + <key>mathmaticians</key> + <string>mathematicians</string> + <key>mccarthyst</key> + <string>mccarthyist</string> + <key>mchanics</key> + <string>mechanics</string> + <key>meaninng</key> + <string>meaning</string> + <key>mear</key> + <string>wear</string> + <key>mechandise</key> + <string>merchandise</string> + <key>medacine</key> + <string>medicine</string> + <key>medeival</key> + <string>medieval</string> + <key>medevial</key> + <string>medieval</string> + <key>mediciney</key> + <string>mediciny</string> + <key>medievel</key> + <string>medieval</string> + <key>mediterainnean</key> + <string>mediterranean</string> + <key>meerkrat</key> + <string>meerkat</string> + <key>melieux</key> + <string>milieux</string> + <key>membranaphone</key> + <string>membranophone</string> + <key>memeber</key> + <string>member</string> + <key>menally</key> + <string>mentally</string> + <key>meranda</key> + <string>Miranda</string> + <key>mercentile</key> + <string>mercantile</string> + <key>messanger</key> + <string>messenger</string> + <key>messenging</key> + <string>messaging</string> + <key>metalic</key> + <string>metallic</string> + <key>metalurgic</key> + <string>metallurgic</string> + <key>metalurgical</key> + <string>metallurgical</string> + <key>metalurgy</key> + <string>metallurgy</string> + <key>metamorphysis</key> + <string>metamorphosis</string> + <key>metaphoricial</key> + <string>metaphorical</string> + <key>meterologist</key> + <string>meteorologist</string> + <key>meterology</key> + <string>meteorology</string> + <key>methaphor</key> + <string>metaphor</string> + <key>methaphors</key> + <string>metaphors</string> + <key>micoscopy</key> + <string>microscopy</string> + <key>midwifes</key> + <string>midwives</string> + <key>mileau</key> + <string>milieu</string> + <key>milennia</key> + <string>millennia</string> + <key>milennium</key> + <string>millennium</string> + <key>mileu</key> + <string>milieu</string> + <key>miliary</key> + <string>military</string> + <key>milion</key> + <string>million</string> + <key>miliraty</key> + <string>military</string> + <key>millenia</key> + <string>millennia</string> + <key>millenial</key> + <string>millennial</string> + <key>millenialism</key> + <string>millennialism</string> + <key>millenium</key> + <string>millennium</string> + <key>millepede</key> + <string>millipede</string> + <key>millioniare</key> + <string>millionaire</string> + <key>millitary</key> + <string>military</string> + <key>millon</key> + <string>million</string> + <key>miltary</key> + <string>military</string> + <key>minature</key> + <string>miniature</string> + <key>minerial</key> + <string>mineral</string> + <key>miniscule</key> + <string>minuscule</string> + <key>ministery</key> + <string>ministry</string> + <key>minstries</key> + <string>ministries</string> + <key>minstry</key> + <string>ministry</string> + <key>minumum</key> + <string>minimum</string> + <key>mirrorred</key> + <string>mirrored</string> + <key>miscelaneous</key> + <string>miscellaneous</string> + <key>miscellanious</key> + <string>miscellaneous</string> + <key>miscellanous</key> + <string>miscellaneous</string> + <key>mischeivous</key> + <string>mischievous</string> + <key>mischevious</key> + <string>mischievous</string> + <key>mischievious</key> + <string>mischievous</string> + <key>misdameanor</key> + <string>misdemeanor</string> + <key>misdameanors</key> + <string>misdemeanors</string> + <key>misdemenor</key> + <string>misdemeanor</string> + <key>misdemenors</key> + <string>misdemeanors</string> + <key>misfourtunes</key> + <string>misfortunes</string> + <key>misile</key> + <string>missile</string> + <key>mispell</key> + <string>misspell</string> + <key>mispelled</key> + <string>misspelled</string> + <key>mispelling</key> + <string>misspelling</string> + <key>missen</key> + <string>mizzen</string> + <key>missle</key> + <string>missile</string> + <key>missonary</key> + <string>missionary</string> + <key>misterious</key> + <string>mysterious</string> + <key>mistery</key> + <string>mystery</string> + <key>misteryous</key> + <string>mysterious</string> + <key>mkae</key> + <string>make</string> + <key>mkaes</key> + <string>makes</string> + <key>mkaing</key> + <string>making</string> + <key>mkea</key> + <string>make</string> + <key>moderm</key> + <string>modem</string> + <key>modle</key> + <string>model</string> + <key>moent</key> + <string>moment</string> + <key>moeny</key> + <string>money</string> + <key>mohammedans</key> + <string>muslims</string> + <key>moil</key> + <string>soil</string> + <key>moleclues</key> + <string>molecules</string> + <key>momento</key> + <string>memento</string> + <key>monestaries</key> + <string>monasteries</string> + <key>monestary</key> + <string>monastery</string> + <key>monickers</key> + <string>monikers</string> + <key>monolite</key> + <string>monolithic</string> + <key>montains</key> + <string>mountains</string> + <key>montanous</key> + <string>mountainous</string> + <key>monts</key> + <string>months</string> + <key>montypic</key> + <string>monotypic</string> + <key>moreso</key> + <string>more so</string> + <key>morgage</key> + <string>mortgage</string> + <key>morroccan</key> + <string>moroccan</string> + <key>morrocco</key> + <string>morocco</string> + <key>morroco</key> + <string>morocco</string> + <key>mortage</key> + <string>mortgage</string> + <key>mosture</key> + <string>moisture</string> + <key>motiviated</key> + <string>motivated</string> + <key>mounth</key> + <string>month</string> + <key>movei</key> + <string>movie</string> + <key>movment</key> + <string>movement</string> + <key>mroe</key> + <string>more</string> + <key>mucuous</key> + <string>mucous</string> + <key>muder</key> + <string>murder</string> + <key>mudering</key> + <string>murdering</string> + <key>muhammadan</key> + <string>muslim</string> + <key>multicultralism</key> + <string>multiculturalism</string> + <key>multipled</key> + <string>multiplied</string> + <key>multiplers</key> + <string>multipliers</string> + <key>munbers</key> + <string>numbers</string> + <key>muncipalities</key> + <string>municipalities</string> + <key>muncipality</key> + <string>municipality</string> + <key>munnicipality</key> + <string>municipality</string> + <key>muscels</key> + <string>muscles</string> + <key>muscial</key> + <string>musical</string> + <key>muscician</key> + <string>musician</string> + <key>muscicians</key> + <string>musicians</string> + <key>mutiliated</key> + <string>mutilated</string> + <key>myraid</key> + <string>myriad</string> + <key>mysef</key> + <string>myself</string> + <key>mysogynist</key> + <string>misogynist</string> + <key>mysogyny</key> + <string>misogyny</string> + <key>mysterous</key> + <string>mysterious</string> + <key>naieve</key> + <string>naive</string> + <key>naturaly</key> + <string>naturally</string> + <key>naturely</key> + <string>naturally</string> + <key>naturual</key> + <string>natural</string> + <key>naturually</key> + <string>naturally</string> + <key>neccesarily</key> + <string>necessarily</string> + <key>neccesary</key> + <string>necessary</string> + <key>neccessarily</key> + <string>necessarily</string> + <key>neccessary</key> + <string>necessary</string> + <key>neccessities</key> + <string>necessities</string> + <key>necesarily</key> + <string>necessarily</string> + <key>necesary</key> + <string>necessary</string> + <key>necessiate</key> + <string>necessitate</string> + <key>neglible</key> + <string>negligible</string> + <key>negligable</key> + <string>negligible</string> + <key>negociate</key> + <string>negotiate</string> + <key>negociation</key> + <string>negotiation</string> + <key>negociations</key> + <string>negotiations</string> + <key>negotation</key> + <string>negotiation</string> + <key>neice</key> + <string>niece</string> + <key>neigborhood</key> + <string>neighborhood</string> + <key>neigbour</key> + <string>neighbour</string> + <key>neigbourhood</key> + <string>neighbourhood</string> + <key>neolitic</key> + <string>neolithic</string> + <key>nessasarily</key> + <string>necessarily</string> + <key>nessecary</key> + <string>necessary</string> + <key>nestin</key> + <string>nesting</string> + <key>neverthless</key> + <string>nevertheless</string> + <key>newletters</key> + <string>newsletters</string> + <key>nickle</key> + <string>nickel</string> + <key>nightfa;;</key> + <string>nightfall</string> + <key>nightime</key> + <string>nighttime</string> + <key>nineth</key> + <string>ninth</string> + <key>ninteenth</key> + <string>nineteenth</string> + <key>ninties</key> + <string>1990s</string> + <key>ninty</key> + <string>ninety</string> + <key>nkow</key> + <string>know</string> + <key>nkwo</key> + <string>know</string> + <key>nmae</key> + <string>name</string> + <key>noncombatents</key> + <string>noncombatants</string> + <key>nonsence</key> + <string>nonsense</string> + <key>nontheless</key> + <string>nonetheless</string> + <key>noone</key> + <string>no one</string> + <key>norhern</key> + <string>northern</string> + <key>northen</key> + <string>northern</string> + <key>northereastern</key> + <string>northeastern</string> + <key>notabley</key> + <string>notably</string> + <key>noteable</key> + <string>notable</string> + <key>noteably</key> + <string>notably</string> + <key>noteriety</key> + <string>notoriety</string> + <key>noth</key> + <string>north</string> + <key>nothern</key> + <string>northern</string> + <key>noticable</key> + <string>noticeable</string> + <key>noticably</key> + <string>noticeably</string> + <key>noticeing</key> + <string>noticing</string> + <key>noticible</key> + <string>noticeable</string> + <key>notwhithstanding</key> + <string>notwithstanding</string> + <key>noveau</key> + <string>nouveau</string> + <key>nowdays</key> + <string>nowadays</string> + <key>nowe</key> + <string>now</string> + <key>nto</key> + <string>not</string> + <key>nucular</key> + <string>nuclear</string> + <key>nuculear</key> + <string>nuclear</string> + <key>nuisanse</key> + <string>nuisance</string> + <key>numberous</key> + <string>numerous</string> + <key>nusance</key> + <string>nuisance</string> + <key>nutritent</key> + <string>nutrient</string> + <key>nutritents</key> + <string>nutrients</string> + <key>nuturing</key> + <string>nurturing</string> + <key>obediance</key> + <string>obedience</string> + <key>obediant</key> + <string>obedient</string> + <key>obession</key> + <string>obsession</string> + <key>obssessed</key> + <string>obsessed</string> + <key>obstacal</key> + <string>obstacle</string> + <key>obstancles</key> + <string>obstacles</string> + <key>obstruced</key> + <string>obstructed</string> + <key>ocasion</key> + <string>occasion</string> + <key>ocasional</key> + <string>occasional</string> + <key>ocasionally</key> + <string>occasionally</string> + <key>ocasionaly</key> + <string>occasionally</string> + <key>ocasioned</key> + <string>occasioned</string> + <key>ocasions</key> + <string>occasions</string> + <key>ocassion</key> + <string>occasion</string> + <key>ocassional</key> + <string>occasional</string> + <key>ocassionally</key> + <string>occasionally</string> + <key>ocassionaly</key> + <string>occasionally</string> + <key>ocassioned</key> + <string>occasioned</string> + <key>ocassions</key> + <string>occasions</string> + <key>occaison</key> + <string>occasion</string> + <key>occassion</key> + <string>occasion</string> + <key>occassional</key> + <string>occasional</string> + <key>occassionally</key> + <string>occasionally</string> + <key>occassionaly</key> + <string>occasionally</string> + <key>occassioned</key> + <string>occasioned</string> + <key>occassions</key> + <string>occasions</string> + <key>occationally</key> + <string>occasionally</string> + <key>occour</key> + <string>occur</string> + <key>occurance</key> + <string>occurrence</string> + <key>occurances</key> + <string>occurrences</string> + <key>occured</key> + <string>occurred</string> + <key>occurence</key> + <string>occurrence</string> + <key>occurences</key> + <string>occurrences</string> + <key>occuring</key> + <string>occurring</string> + <key>occurr</key> + <string>occur</string> + <key>occurrance</key> + <string>occurrence</string> + <key>occurrances</key> + <string>occurrences</string> + <key>octohedra</key> + <string>octahedra</string> + <key>octohedral</key> + <string>octahedral</string> + <key>octohedron</key> + <string>octahedron</string> + <key>ocuntries</key> + <string>countries</string> + <key>ocuntry</key> + <string>country</string> + <key>ocurr</key> + <string>occur</string> + <key>ocurrance</key> + <string>occurrence</string> + <key>ocurred</key> + <string>occurred</string> + <key>ocurrence</key> + <string>occurrence</string> + <key>offcers</key> + <string>officers</string> + <key>offcially</key> + <string>officially</string> + <key>offereings</key> + <string>offerings</string> + <key>offical</key> + <string>official</string> + <key>offically</key> + <string>officially</string> + <key>officals</key> + <string>officials</string> + <key>officaly</key> + <string>officially</string> + <key>officialy</key> + <string>officially</string> + <key>offred</key> + <string>offered</string> + <key>oftenly</key> + <string>often</string> + <key>oging</key> + <string>going</string> + <key>omision</key> + <string>omission</string> + <key>omited</key> + <string>omitted</string> + <key>omiting</key> + <string>omitting</string> + <key>omlette</key> + <string>omelette</string> + <key>ommision</key> + <string>omission</string> + <key>ommited</key> + <string>omitted</string> + <key>ommiting</key> + <string>omitting</string> + <key>ommitted</key> + <string>omitted</string> + <key>ommitting</key> + <string>omitting</string> + <key>omniverous</key> + <string>omnivorous</string> + <key>omniverously</key> + <string>omnivorously</string> + <key>omre</key> + <string>more</string> + <key>onot</key> + <string>note</string> + <key>onxy</key> + <string>onyx</string> + <key>onyl</key> + <string>only</string> + <key>openess</key> + <string>openness</string> + <key>oponent</key> + <string>opponent</string> + <key>oportunity</key> + <string>opportunity</string> + <key>opose</key> + <string>oppose</string> + <key>oposite</key> + <string>opposite</string> + <key>oposition</key> + <string>opposition</string> + <key>oppenly</key> + <string>openly</string> + <key>oppinion</key> + <string>opinion</string> + <key>opponant</key> + <string>opponent</string> + <key>oppononent</key> + <string>opponent</string> + <key>oppositition</key> + <string>opposition</string> + <key>oppossed</key> + <string>opposed</string> + <key>opprotunity</key> + <string>opportunity</string> + <key>opression</key> + <string>oppression</string> + <key>opressive</key> + <string>oppressive</string> + <key>opthalmic</key> + <string>ophthalmic</string> + <key>opthalmologist</key> + <string>ophthalmologist</string> + <key>opthalmology</key> + <string>ophthalmology</string> + <key>opthamologist</key> + <string>ophthalmologist</string> + <key>optmizations</key> + <string>optimizations</string> + <key>optomism</key> + <string>optimism</string> + <key>orded</key> + <string>ordered</string> + <key>organim</key> + <string>organism</string> + <key>organistion</key> + <string>organisation</string> + <key>organiztion</key> + <string>organization</string> + <key>orgin</key> + <string>origin</string> + <key>orginal</key> + <string>original</string> + <key>orginally</key> + <string>originally</string> + <key>orginize</key> + <string>organise</string> + <key>oridinarily</key> + <string>ordinarily</string> + <key>origanaly</key> + <string>originally</string> + <key>originall</key> + <string>original</string> + <key>originaly</key> + <string>originally</string> + <key>originially</key> + <string>originally</string> + <key>originnally</key> + <string>originally</string> + <key>origional</key> + <string>original</string> + <key>orignally</key> + <string>originally</string> + <key>orignially</key> + <string>originally</string> + <key>otehr</key> + <string>other</string> + <key>oublisher</key> + <string>publisher</string> + <key>ouevre</key> + <string>oeuvre</string> + <key>oustanding</key> + <string>outstanding</string> + <key>overshaddowed</key> + <string>overshadowed</string> + <key>overthere</key> + <string>over there</string> + <key>overwelming</key> + <string>overwhelming</string> + <key>overwheliming</key> + <string>overwhelming</string> + <key>owrk</key> + <string>work</string> + <key>owudl</key> + <string>would</string> + <key>oxigen</key> + <string>oxygen</string> + <key>oximoron</key> + <string>oxymoron</string> + <key>p0enis</key> + <string>penis</string> + <key>paide</key> + <string>paid</string> + <key>paitience</key> + <string>patience</string> + <key>palce</key> + <string>place</string> + <key>paleolitic</key> + <string>paleolithic</string> + <key>paliamentarian</key> + <string>parliamentarian</string> + <key>pallete</key> + <string>palette</string> + <key>pamflet</key> + <string>pamphlet</string> + <key>pamplet</key> + <string>pamphlet</string> + <key>pantomine</key> + <string>pantomime</string> + <key>paralel</key> + <string>parallel</string> + <key>paralell</key> + <string>parallel</string> + <key>paralelly</key> + <string>parallelly</string> + <key>paralely</key> + <string>parallelly</string> + <key>parallely</key> + <string>parallelly</string> + <key>paranthesis</key> + <string>parenthesis</string> + <key>paraphenalia</key> + <string>paraphernalia</string> + <key>parellels</key> + <string>parallels</string> + <key>parituclar</key> + <string>particular</string> + <key>parliment</key> + <string>parliament</string> + <key>parrakeets</key> + <string>parakeets</string> + <key>parralel</key> + <string>parallel</string> + <key>parrallel</key> + <string>parallel</string> + <key>parrallell</key> + <string>parallel</string> + <key>parrallelly</key> + <string>parallelly</string> + <key>parrallely</key> + <string>parallelly</string> + <key>partialy</key> + <string>partially</string> + <key>particually</key> + <string>particularly</string> + <key>particualr</key> + <string>particular</string> + <key>particuarly</key> + <string>particularly</string> + <key>particularily</key> + <string>particularly</string> + <key>particulary</key> + <string>particularly</string> + <key>pary</key> + <string>party</string> + <key>pased</key> + <string>passed</string> + <key>pasengers</key> + <string>passengers</string> + <key>passerbys</key> + <string>passersby</string> + <key>pasttime</key> + <string>pastime</string> + <key>pastural</key> + <string>pastoral</string> + <key>paticular</key> + <string>particular</string> + <key>pattented</key> + <string>patented</string> + <key>pavillion</key> + <string>pavilion</string> + <key>payed</key> + <string>paid</string> + <key>pblisher</key> + <string>publisher</string> + <key>pbulisher</key> + <string>publisher</string> + <key>peacefuland</key> + <string>peaceful and</string> + <key>peageant</key> + <string>pageant</string> + <key>peculure</key> + <string>peculiar</string> + <key>pedestrain</key> + <string>pedestrian</string> + <key>peformed</key> + <string>performed</string> + <key>peice</key> + <string>piece</string> + <key>penatly</key> + <string>penalty</string> + <key>penerator</key> + <string>penetrator</string> + <key>penisula</key> + <string>peninsula</string> + <key>penisular</key> + <string>peninsular</string> + <key>penninsula</key> + <string>peninsula</string> + <key>penninsular</key> + <string>peninsular</string> + <key>pennisula</key> + <string>peninsula</string> + <key>pensinula</key> + <string>peninsula</string> + <key>peom</key> + <string>poem</string> + <key>peoms</key> + <string>poems</string> + <key>peopel</key> + <string>people</string> + <key>peotry</key> + <string>poetry</string> + <key>perade</key> + <string>parade</string> + <key>percepted</key> + <string>perceived</string> + <key>percieve</key> + <string>perceive</string> + <key>percieved</key> + <string>perceived</string> + <key>perenially</key> + <string>perennially</string> + <key>perfomance</key> + <string>performance</string> + <key>perfomers</key> + <string>performers</string> + <key>performence</key> + <string>performance</string> + <key>performes</key> + <string>performed</string> + <key>perhasp</key> + <string>perhaps</string> + <key>perheaps</key> + <string>perhaps</string> + <key>perhpas</key> + <string>perhaps</string> + <key>peripathetic</key> + <string>peripatetic</string> + <key>peristent</key> + <string>persistent</string> + <key>perjery</key> + <string>perjury</string> + <key>perjorative</key> + <string>pejorative</string> + <key>permanant</key> + <string>permanent</string> + <key>permenant</key> + <string>permanent</string> + <key>permenantly</key> + <string>permanently</string> + <key>permissable</key> + <string>permissible</string> + <key>perogative</key> + <string>prerogative</string> + <key>peronal</key> + <string>personal</string> + <key>perosnality</key> + <string>personality</string> + <key>perphas</key> + <string>perhaps</string> + <key>perpindicular</key> + <string>perpendicular</string> + <key>perseverence</key> + <string>perseverance</string> + <key>persistance</key> + <string>persistence</string> + <key>persistant</key> + <string>persistent</string> + <key>personel</key> + <string>personnel</string> + <key>personell</key> + <string>personnel</string> + <key>personnell</key> + <string>personnel</string> + <key>persuded</key> + <string>persuaded</string> + <key>persue</key> + <string>pursue</string> + <key>persued</key> + <string>pursued</string> + <key>persuing</key> + <string>pursuing</string> + <key>persuit</key> + <string>pursuit</string> + <key>persuits</key> + <string>pursuits</string> + <key>pertubation</key> + <string>perturbation</string> + <key>pertubations</key> + <string>perturbations</string> + <key>pessiary</key> + <string>pessary</string> + <key>petetion</key> + <string>petition</string> + <key>phenomenom</key> + <string>phenomenon</string> + <key>phenomenonal</key> + <string>phenomenal</string> + <key>phenomenonly</key> + <string>phenomenally</string> + <key>phenomonenon</key> + <string>phenomenon</string> + <key>phenomonon</key> + <string>phenomenon</string> + <key>phenonmena</key> + <string>phenomena</string> + <key>philisopher</key> + <string>philosopher</string> + <key>philisophical</key> + <string>philosophical</string> + <key>philisophy</key> + <string>philosophy</string> + <key>phillosophically</key> + <string>philosophically</string> + <key>philospher</key> + <string>philosopher</string> + <key>philosphies</key> + <string>philosophies</string> + <key>philosphy</key> + <string>philosophy</string> + <key>phongraph</key> + <string>phonograph</string> + <key>phylosophical</key> + <string>philosophical</string> + <key>physicaly</key> + <string>physically</string> + <key>piblisher</key> + <string>publisher</string> + <key>pich</key> + <string>pitch</string> + <key>pilgrimmage</key> + <string>pilgrimage</string> + <key>pilgrimmages</key> + <string>pilgrimages</string> + <key>pinapple</key> + <string>pineapple</string> + <key>pinnaple</key> + <string>pineapple</string> + <key>pinoneered</key> + <string>pioneered</string> + <key>plagarism</key> + <string>plagiarism</string> + <key>planation</key> + <string>plantation</string> + <key>planed</key> + <string>planned</string> + <key>plantiff</key> + <string>plaintiff</string> + <key>plateu</key> + <string>plateau</string> + <key>plausable</key> + <string>plausible</string> + <key>playright</key> + <string>playwright</string> + <key>playwrite</key> + <string>playwright</string> + <key>playwrites</key> + <string>playwrights</string> + <key>pleasent</key> + <string>pleasant</string> + <key>plebicite</key> + <string>plebiscite</string> + <key>plesant</key> + <string>pleasant</string> + <key>poenis</key> + <string>penis</string> + <key>poeoples</key> + <string>peoples</string> + <key>poety</key> + <string>poetry</string> + <key>poisin</key> + <string>poison</string> + <key>polical</key> + <string>political</string> + <key>polinator</key> + <string>pollinator</string> + <key>polinators</key> + <string>pollinators</string> + <key>politican</key> + <string>politician</string> + <key>politicans</key> + <string>politicians</string> + <key>poltical</key> + <string>political</string> + <key>polute</key> + <string>pollute</string> + <key>poluted</key> + <string>polluted</string> + <key>polutes</key> + <string>pollutes</string> + <key>poluting</key> + <string>polluting</string> + <key>polution</key> + <string>pollution</string> + <key>polyphonyic</key> + <string>polyphonic</string> + <key>polysaccaride</key> + <string>polysaccharide</string> + <key>polysaccharid</key> + <string>polysaccharide</string> + <key>pomegranite</key> + <string>pomegranate</string> + <key>pomotion</key> + <string>promotion</string> + <key>poportional</key> + <string>proportional</string> + <key>popoulation</key> + <string>population</string> + <key>popularaty</key> + <string>popularity</string> + <key>populare</key> + <string>popular</string> + <key>populer</key> + <string>popular</string> + <key>portait</key> + <string>portrait</string> + <key>portayed</key> + <string>portrayed</string> + <key>portraing</key> + <string>portraying</string> + <key>portuguease</key> + <string>portuguese</string> + <key>portugues</key> + <string>Portuguese</string> + <key>posess</key> + <string>possess</string> + <key>posessed</key> + <string>possessed</string> + <key>posesses</key> + <string>possesses</string> + <key>posessing</key> + <string>possessing</string> + <key>posession</key> + <string>possession</string> + <key>posessions</key> + <string>possessions</string> + <key>posion</key> + <string>poison</string> + <key>positon</key> + <string>position</string> + <key>possable</key> + <string>possible</string> + <key>possably</key> + <string>possibly</string> + <key>posseses</key> + <string>possesses</string> + <key>possesing</key> + <string>possessing</string> + <key>possesion</key> + <string>possession</string> + <key>possessess</key> + <string>possesses</string> + <key>possibile</key> + <string>possible</string> + <key>possibilty</key> + <string>possibility</string> + <key>possiblility</key> + <string>possibility</string> + <key>possiblilty</key> + <string>possibility</string> + <key>possiblities</key> + <string>possibilities</string> + <key>possiblity</key> + <string>possibility</string> + <key>possition</key> + <string>position</string> + <key>posthomous</key> + <string>posthumous</string> + <key>postion</key> + <string>position</string> + <key>postive</key> + <string>positive</string> + <key>potatos</key> + <string>potatoes</string> + <key>potrait</key> + <string>portrait</string> + <key>potrayed</key> + <string>portrayed</string> + <key>poulations</key> + <string>populations</string> + <key>poverful</key> + <string>powerful</string> + <key>poweful</key> + <string>powerful</string> + <key>powerfull</key> + <string>powerful</string> + <key>ppublisher</key> + <string>publisher</string> + <key>practial</key> + <string>practical</string> + <key>practially</key> + <string>practically</string> + <key>practicaly</key> + <string>practically</string> + <key>practicioner</key> + <string>practitioner</string> + <key>practicioners</key> + <string>practitioners</string> + <key>practicly</key> + <string>practically</string> + <key>practioner</key> + <string>practitioner</string> + <key>practioners</key> + <string>practitioners</string> + <key>prairy</key> + <string>prairie</string> + <key>prarie</key> + <string>prairie</string> + <key>praries</key> + <string>prairies</string> + <key>pratice</key> + <string>practice</string> + <key>preample</key> + <string>preamble</string> + <key>precedessor</key> + <string>predecessor</string> + <key>preceed</key> + <string>precede</string> + <key>preceeded</key> + <string>preceded</string> + <key>preceeding</key> + <string>preceding</string> + <key>preceeds</key> + <string>precedes</string> + <key>precentage</key> + <string>percentage</string> + <key>precice</key> + <string>precise</string> + <key>precisly</key> + <string>precisely</string> + <key>precurser</key> + <string>precursor</string> + <key>predecesors</key> + <string>predecessors</string> + <key>predicatble</key> + <string>predictable</string> + <key>predicitons</key> + <string>predictions</string> + <key>predomiantly</key> + <string>predominately</string> + <key>prefered</key> + <string>preferred</string> + <key>prefering</key> + <string>preferring</string> + <key>preferrably</key> + <string>preferably</string> + <key>pregancies</key> + <string>pregnancies</string> + <key>preiod</key> + <string>period</string> + <key>preliferation</key> + <string>proliferation</string> + <key>premeire</key> + <string>premiere</string> + <key>premeired</key> + <string>premiered</string> + <key>premillenial</key> + <string>premillennial</string> + <key>preminence</key> + <string>preeminence</string> + <key>premission</key> + <string>permission</string> + <key>preocupation</key> + <string>preoccupation</string> + <key>prepair</key> + <string>prepare</string> + <key>prepartion</key> + <string>preparation</string> + <key>prepatory</key> + <string>preparatory</string> + <key>preperation</key> + <string>preparation</string> + <key>preperations</key> + <string>preparations</string> + <key>preriod</key> + <string>period</string> + <key>presedential</key> + <string>presidential</string> + <key>presense</key> + <string>presence</string> + <key>presidenital</key> + <string>presidential</string> + <key>presidental</key> + <string>presidential</string> + <key>presitgious</key> + <string>prestigious</string> + <key>prespective</key> + <string>perspective</string> + <key>prestigeous</key> + <string>prestigious</string> + <key>prestigous</key> + <string>prestigious</string> + <key>presumabely</key> + <string>presumably</string> + <key>presumibly</key> + <string>presumably</string> + <key>pretection</key> + <string>protection</string> + <key>prevelant</key> + <string>prevalent</string> + <key>preverse</key> + <string>perverse</string> + <key>previvous</key> + <string>previous</string> + <key>pricipal</key> + <string>principal</string> + <key>priciple</key> + <string>principle</string> + <key>priestood</key> + <string>priesthood</string> + <key>primarly</key> + <string>primarily</string> + <key>primative</key> + <string>primitive</string> + <key>primatively</key> + <string>primitively</string> + <key>primatives</key> + <string>primitives</string> + <key>primordal</key> + <string>primordial</string> + <key>priveledges</key> + <string>privileges</string> + <key>privelege</key> + <string>privilege</string> + <key>priveleged</key> + <string>privileged</string> + <key>priveleges</key> + <string>privileges</string> + <key>privelige</key> + <string>privilege</string> + <key>priveliged</key> + <string>privileged</string> + <key>priveliges</key> + <string>privileges</string> + <key>privelleges</key> + <string>privileges</string> + <key>privilage</key> + <string>privilege</string> + <key>priviledge</key> + <string>privilege</string> + <key>priviledges</key> + <string>privileges</string> + <key>privledge</key> + <string>privilege</string> + <key>privte</key> + <string>private</string> + <key>probabilaty</key> + <string>probability</string> + <key>probablistic</key> + <string>probabilistic</string> + <key>probablly</key> + <string>probably</string> + <key>probalibity</key> + <string>probability</string> + <key>probaly</key> + <string>probably</string> + <key>probelm</key> + <string>problem</string> + <key>proccess</key> + <string>process</string> + <key>proccessing</key> + <string>processing</string> + <key>procede</key> + <string>proceed</string> + <key>proceded</key> + <string>proceeded</string> + <key>procedes</key> + <string>proceeds</string> + <key>procedger</key> + <string>procedure</string> + <key>proceding</key> + <string>proceeding</string> + <key>procedings</key> + <string>proceedings</string> + <key>proceedure</key> + <string>procedure</string> + <key>proces</key> + <string>process</string> + <key>processer</key> + <string>processor</string> + <key>proclaimation</key> + <string>proclamation</string> + <key>proclamed</key> + <string>proclaimed</string> + <key>proclaming</key> + <string>proclaiming</string> + <key>proclomation</key> + <string>proclamation</string> + <key>profesion</key> + <string>profession</string> + <key>profesor</key> + <string>professor</string> + <key>professer</key> + <string>professor</string> + <key>proffesed</key> + <string>professed</string> + <key>proffesion</key> + <string>profession</string> + <key>proffesional</key> + <string>professional</string> + <key>proffesor</key> + <string>professor</string> + <key>profilic</key> + <string>prolific</string> + <key>progessed</key> + <string>progressed</string> + <key>programable</key> + <string>programmable</string> + <key>progrom</key> + <string>program</string> + <key>progroms</key> + <string>programs</string> + <key>prohabition</key> + <string>prohibition</string> + <key>prologomena</key> + <string>prolegomena</string> + <key>prominance</key> + <string>prominence</string> + <key>prominant</key> + <string>prominent</string> + <key>prominantly</key> + <string>prominently</string> + <key>prominately</key> + <string>prominently</string> + <key>promiscous</key> + <string>promiscuous</string> + <key>promotted</key> + <string>promoted</string> + <key>pronomial</key> + <string>pronominal</string> + <key>pronouced</key> + <string>pronounced</string> + <key>pronounched</key> + <string>pronounced</string> + <key>pronounciation</key> + <string>pronunciation</string> + <key>proove</key> + <string>prove</string> + <key>prooved</key> + <string>proved</string> + <key>prophacy</key> + <string>prophecy</string> + <key>propietary</key> + <string>proprietary</string> + <key>propmted</key> + <string>prompted</string> + <key>propoganda</key> + <string>propaganda</string> + <key>propogate</key> + <string>propagate</string> + <key>propogates</key> + <string>propagates</string> + <key>propogation</key> + <string>propagation</string> + <key>propostion</key> + <string>proposition</string> + <key>propotions</key> + <string>proportions</string> + <key>propper</key> + <string>proper</string> + <key>propperly</key> + <string>properly</string> + <key>proprietory</key> + <string>proprietary</string> + <key>proseletyzing</key> + <string>proselytizing</string> + <key>protaganist</key> + <string>protagonist</string> + <key>protaganists</key> + <string>protagonists</string> + <key>protocal</key> + <string>protocol</string> + <key>protoganist</key> + <string>protagonist</string> + <key>protrayed</key> + <string>portrayed</string> + <key>protruberance</key> + <string>protuberance</string> + <key>protruberances</key> + <string>protuberances</string> + <key>prouncements</key> + <string>pronouncements</string> + <key>provacative</key> + <string>provocative</string> + <key>provded</key> + <string>provided</string> + <key>provicial</key> + <string>provincial</string> + <key>provinicial</key> + <string>provincial</string> + <key>provisiosn</key> + <string>provision</string> + <key>provisonal</key> + <string>provisional</string> + <key>proximty</key> + <string>proximity</string> + <key>pseudononymous</key> + <string>pseudonymous</string> + <key>pseudonyn</key> + <string>pseudonym</string> + <key>psuedo</key> + <string>pseudo</string> + <key>psycology</key> + <string>psychology</string> + <key>psyhic</key> + <string>psychic</string> + <key>pubilsher</key> + <string>publisher</string> + <key>pubisher</key> + <string>publisher</string> + <key>publiaher</key> + <string>publisher</string> + <key>publically</key> + <string>publicly</string> + <key>publicaly</key> + <string>publicly</string> + <key>publicher</key> + <string>publisher</string> + <key>publihser</key> + <string>publisher</string> + <key>publisehr</key> + <string>publisher</string> + <key>publiser</key> + <string>publisher</string> + <key>publisger</key> + <string>publisher</string> + <key>publisheed</key> + <string>published</string> + <key>publisherr</key> + <string>publisher</string> + <key>publishher</key> + <string>publisher</string> + <key>publishor</key> + <string>publisher</string> + <key>publishre</key> + <string>publisher</string> + <key>publissher</key> + <string>publisher</string> + <key>publlisher</key> + <string>publisher</string> + <key>publsiher</key> + <string>publisher</string> + <key>publusher</key> + <string>publisher</string> + <key>puchasing</key> + <string>purchasing</string> + <key>pulisher</key> + <string>publisher</string> + <key>pumkin</key> + <string>pumpkin</string> + <key>puplisher</key> + <string>publisher</string> + <key>puritannical</key> + <string>puritanical</string> + <key>purposedly</key> + <string>purposely</string> + <key>purpotedly</key> + <string>purportedly</string> + <key>pursuade</key> + <string>persuade</string> + <key>pursuaded</key> + <string>persuaded</string> + <key>pursuades</key> + <string>persuades</string> + <key>pususading</key> + <string>persuading</string> + <key>puting</key> + <string>putting</string> + <key>pwoer</key> + <string>power</string> + <key>pyscic</key> + <string>psychic</string> + <key>qtuie</key> + <string>quiet</string> + <key>quantaty</key> + <string>quantity</string> + <key>quantitiy</key> + <string>quantity</string> + <key>quarantaine</key> + <string>quarantine</string> + <key>questonable</key> + <string>questionable</string> + <key>quicklyu</key> + <string>quickly</string> + <key>quinessential</key> + <string>quintessential</string> + <key>quitted</key> + <string>quit</string> + <key>quizes</key> + <string>quizzes</string> + <key>qutie</key> + <string>quiet</string> + <key>rabinnical</key> + <string>rabbinical</string> + <key>racaus</key> + <string>raucous</string> + <key>radiactive</key> + <string>radioactive</string> + <key>radify</key> + <string>ratify</string> + <key>raelly</key> + <string>really</string> + <key>rarified</key> + <string>rarefied</string> + <key>reaccurring</key> + <string>recurring</string> + <key>reacing</key> + <string>reaching</string> + <key>reacll</key> + <string>recall</string> + <key>readmition</key> + <string>readmission</string> + <key>realitvely</key> + <string>relatively</string> + <key>realsitic</key> + <string>realistic</string> + <key>realtions</key> + <string>relations</string> + <key>realy</key> + <string>really</string> + <key>realyl</key> + <string>really</string> + <key>reasearch</key> + <string>research</string> + <key>rebiulding</key> + <string>rebuilding</string> + <key>rebllions</key> + <string>rebellions</string> + <key>rebounce</key> + <string>rebound</string> + <key>reccomend</key> + <string>recommend</string> + <key>reccomendations</key> + <string>recommendations</string> + <key>reccomended</key> + <string>recommended</string> + <key>reccomending</key> + <string>recommending</string> + <key>reccommend</key> + <string>recommend</string> + <key>reccommended</key> + <string>recommended</string> + <key>reccommending</key> + <string>recommending</string> + <key>reccuring</key> + <string>recurring</string> + <key>receeded</key> + <string>receded</string> + <key>receeding</key> + <string>receding</string> + <key>receivedfrom</key> + <string>received from</string> + <key>recepient</key> + <string>recipient</string> + <key>recepients</key> + <string>recipients</string> + <key>receving</key> + <string>receiving</string> + <key>rechargable</key> + <string>rechargeable</string> + <key>reched</key> + <string>reached</string> + <key>recide</key> + <string>reside</string> + <key>recided</key> + <string>resided</string> + <key>recident</key> + <string>resident</string> + <key>recidents</key> + <string>residents</string> + <key>reciding</key> + <string>residing</string> + <key>reciepents</key> + <string>recipients</string> + <key>reciept</key> + <string>receipt</string> + <key>recieve</key> + <string>receive</string> + <key>recieved</key> + <string>received</string> + <key>reciever</key> + <string>receiver</string> + <key>recievers</key> + <string>receivers</string> + <key>recieves</key> + <string>receives</string> + <key>recieving</key> + <string>receiving</string> + <key>recipiant</key> + <string>recipient</string> + <key>recipiants</key> + <string>recipients</string> + <key>recived</key> + <string>received</string> + <key>recivership</key> + <string>receivership</string> + <key>recogise</key> + <string>recognise</string> + <key>recogize</key> + <string>recognize</string> + <key>recomend</key> + <string>recommend</string> + <key>recomended</key> + <string>recommended</string> + <key>recomending</key> + <string>recommending</string> + <key>recomends</key> + <string>recommends</string> + <key>recommedations</key> + <string>recommendations</string> + <key>reconaissance</key> + <string>reconnaissance</string> + <key>reconcilation</key> + <string>reconciliation</string> + <key>reconized</key> + <string>recognized</string> + <key>reconnaisance</key> + <string>reconnaissance</string> + <key>reconnaissence</key> + <string>reconnaissance</string> + <key>recontructed</key> + <string>reconstructed</string> + <key>recordproducer</key> + <string>record producer</string> + <key>recquired</key> + <string>required</string> + <key>recrational</key> + <string>recreational</string> + <key>recrod</key> + <string>record</string> + <key>recuiting</key> + <string>recruiting</string> + <key>recuring</key> + <string>recurring</string> + <key>recurrance</key> + <string>recurrence</string> + <key>rediculous</key> + <string>ridiculous</string> + <key>reedeming</key> + <string>redeeming</string> + <key>reenforced</key> + <string>reinforced</string> + <key>refect</key> + <string>reflect</string> + <key>refedendum</key> + <string>referendum</string> + <key>referal</key> + <string>referral</string> + <key>referece</key> + <string>reference</string> + <key>refereces</key> + <string>references</string> + <key>refered</key> + <string>referred</string> + <key>referemce</key> + <string>reference</string> + <key>referemces</key> + <string>references</string> + <key>referencs</key> + <string>references</string> + <key>referenece</key> + <string>reference</string> + <key>refereneced</key> + <string>referenced</string> + <key>refereneces</key> + <string>references</string> + <key>referiang</key> + <string>referring</string> + <key>refering</key> + <string>referring</string> + <key>refernce</key> + <string>references</string> + <key>refernces</key> + <string>references</string> + <key>referrence</key> + <string>reference</string> + <key>referrences</key> + <string>references</string> + <key>referrs</key> + <string>refers</string> + <key>reffered</key> + <string>referred</string> + <key>refference</key> + <string>reference</string> + <key>reffering</key> + <string>referring</string> + <key>refrence</key> + <string>reference</string> + <key>refrences</key> + <string>references</string> + <key>refrers</key> + <string>refers</string> + <key>refridgeration</key> + <string>refrigeration</string> + <key>refridgerator</key> + <string>refrigerator</string> + <key>refromist</key> + <string>reformist</string> + <key>refusla</key> + <string>refusal</string> + <key>regardes</key> + <string>regards</string> + <key>regluar</key> + <string>regular</string> + <key>reguarly</key> + <string>regularly</string> + <key>regulaion</key> + <string>regulation</string> + <key>regulaotrs</key> + <string>regulators</string> + <key>regularily</key> + <string>regularly</string> + <key>rehersal</key> + <string>rehearsal</string> + <key>reicarnation</key> + <string>reincarnation</string> + <key>reigining</key> + <string>reigning</string> + <key>reknown</key> + <string>renown</string> + <key>reknowned</key> + <string>renowned</string> + <key>rela</key> + <string>real</string> + <key>relaly</key> + <string>really</string> + <key>relatiopnship</key> + <string>relationship</string> + <key>relativly</key> + <string>relatively</string> + <key>relected</key> + <string>reelected</string> + <key>releive</key> + <string>relieve</string> + <key>releived</key> + <string>relieved</string> + <key>releiver</key> + <string>reliever</string> + <key>releses</key> + <string>releases</string> + <key>relevence</key> + <string>relevance</string> + <key>relevent</key> + <string>relevant</string> + <key>reliablity</key> + <string>reliability</string> + <key>relient</key> + <string>reliant</string> + <key>religeous</key> + <string>religious</string> + <key>religous</key> + <string>religious</string> + <key>religously</key> + <string>religiously</string> + <key>relinqushment</key> + <string>relinquishment</string> + <key>relitavely</key> + <string>relatively</string> + <key>relized</key> + <string>realized</string> + <key>relpacement</key> + <string>replacement</string> + <key>remaing</key> + <string>remaining</string> + <key>remeber</key> + <string>remember</string> + <key>rememberable</key> + <string>memorable</string> + <key>rememberance</key> + <string>remembrance</string> + <key>remembrence</key> + <string>remembrance</string> + <key>remenant</key> + <string>remnant</string> + <key>remenicent</key> + <string>reminiscent</string> + <key>reminent</key> + <string>remnant</string> + <key>reminescent</key> + <string>reminiscent</string> + <key>reminscent</key> + <string>reminiscent</string> + <key>reminsicent</key> + <string>reminiscent</string> + <key>rendevous</key> + <string>rendezvous</string> + <key>rendezous</key> + <string>rendezvous</string> + <key>renedered</key> + <string>rende</string> + <key>renewl</key> + <string>renewal</string> + <key>rennovate</key> + <string>renovate</string> + <key>rennovated</key> + <string>renovated</string> + <key>rennovating</key> + <string>renovating</string> + <key>rennovation</key> + <string>renovation</string> + <key>rentors</key> + <string>renters</string> + <key>reoccurrence</key> + <string>recurrence</string> + <key>reorganision</key> + <string>reorganisation</string> + <key>repatition</key> + <string>repetition</string> + <key>repectively</key> + <string>respectively</string> + <key>repeition</key> + <string>repetition</string> + <key>repentence</key> + <string>repentance</string> + <key>repentent</key> + <string>repentant</string> + <key>repeteadly</key> + <string>repeatedly</string> + <key>repetion</key> + <string>repetition</string> + <key>repid</key> + <string>rapid</string> + <key>reponse</key> + <string>response</string> + <key>reponsible</key> + <string>responsible</string> + <key>reportadly</key> + <string>reportedly</string> + <key>represantative</key> + <string>representative</string> + <key>representive</key> + <string>representative</string> + <key>representives</key> + <string>representatives</string> + <key>reproducable</key> + <string>reproducible</string> + <key>reprtoire</key> + <string>repertoire</string> + <key>repsectively</key> + <string>respectively</string> + <key>reptition</key> + <string>repetition</string> + <key>requirment</key> + <string>requirement</string> + <key>requred</key> + <string>required</string> + <key>resaurant</key> + <string>restaurant</string> + <key>resembelance</key> + <string>resemblance</string> + <key>resembes</key> + <string>resembles</string> + <key>resemblence</key> + <string>resemblance</string> + <key>resevoir</key> + <string>reservoir</string> + <key>residental</key> + <string>residential</string> + <key>resignement</key> + <string>resignment</string> + <key>resistable</key> + <string>resistible</string> + <key>resistence</key> + <string>resistance</string> + <key>resistent</key> + <string>resistant</string> + <key>respectivly</key> + <string>respectively</string> + <key>responce</key> + <string>response</string> + <key>responibilities</key> + <string>responsibilities</string> + <key>responisble</key> + <string>responsible</string> + <key>responnsibilty</key> + <string>responsibility</string> + <key>responsability</key> + <string>responsibility</string> + <key>responsibile</key> + <string>responsible</string> + <key>responsibilites</key> + <string>responsibilities</string> + <key>responsiblities</key> + <string>responsibilities</string> + <key>responsiblity</key> + <string>responsibility</string> + <key>ressemblance</key> + <string>resemblance</string> + <key>ressemble</key> + <string>resemble</string> + <key>ressembled</key> + <string>resembled</string> + <key>ressemblence</key> + <string>resemblance</string> + <key>ressembling</key> + <string>resembling</string> + <key>resssurecting</key> + <string>resurrecting</string> + <key>ressurect</key> + <string>resurrect</string> + <key>ressurected</key> + <string>resurrected</string> + <key>ressurection</key> + <string>resurrection</string> + <key>ressurrection</key> + <string>resurrection</string> + <key>restarant</key> + <string>restaurant</string> + <key>restarants</key> + <string>restaurants</string> + <key>restaraunt</key> + <string>restaurant</string> + <key>restaraunteur</key> + <string>restaurateur</string> + <key>restaraunteurs</key> + <string>restaurateurs</string> + <key>restaraunts</key> + <string>restaurants</string> + <key>restauranteurs</key> + <string>restaurateurs</string> + <key>restauration</key> + <string>restoration</string> + <key>restauraunt</key> + <string>restaurant</string> + <key>resteraunt</key> + <string>restaurant</string> + <key>resteraunts</key> + <string>restaurants</string> + <key>resticted</key> + <string>restricted</string> + <key>restraunt</key> + <string>restraint</string> + <key>resturant</key> + <string>restaurant</string> + <key>resturants</key> + <string>restaurants</string> + <key>resturaunt</key> + <string>restaurant</string> + <key>resturaunts</key> + <string>restaurants</string> + <key>resurecting</key> + <string>resurrecting</string> + <key>retalitated</key> + <string>retaliated</string> + <key>retalitation</key> + <string>retaliation</string> + <key>retreive</key> + <string>retrieve</string> + <key>returnd</key> + <string>returned</string> + <key>revaluated</key> + <string>reevaluated</string> + <key>reveiw</key> + <string>review</string> + <key>reveral</key> + <string>reversal</string> + <key>reversable</key> + <string>reversible</string> + <key>revolutionar</key> + <string>revolutionary</string> + <key>rewitten</key> + <string>rewritten</string> + <key>rewriet</key> + <string>rewrite</string> + <key>rference</key> + <string>reference</string> + <key>rferences</key> + <string>references</string> + <key>rhymme</key> + <string>rhyme</string> + <key>rhythem</key> + <string>rhythm</string> + <key>rhythim</key> + <string>rhythm</string> + <key>rhytmic</key> + <string>rhythmic</string> + <key>rigourous</key> + <string>rigorous</string> + <key>rininging</key> + <string>ringing</string> + <key>rised</key> + <string>rose</string> + <key>rococco</key> + <string>rococo</string> + <key>rocord</key> + <string>record</string> + <key>roomate</key> + <string>roommate</string> + <key>rougly</key> + <string>roughly</string> + <key>rucuperate</key> + <string>recuperate</string> + <key>rudimentatry</key> + <string>rudimentary</string> + <key>rulle</key> + <string>rule</string> + <key>runing</key> + <string>running</string> + <key>runnung</key> + <string>running</string> + <key>russina</key> + <string>Russian</string> + <key>rwite</key> + <string>write</string> + <key>rythem</key> + <string>rhythm</string> + <key>rythim</key> + <string>rhythm</string> + <key>rythm</key> + <string>rhythm</string> + <key>rythmic</key> + <string>rhythmic</string> + <key>rythyms</key> + <string>rhythms</string> + <key>sacrafice</key> + <string>sacrifice</string> + <key>sacreligious</key> + <string>sacrilegious</string> + <key>sacrifical</key> + <string>sacrificial</string> + <key>saftey</key> + <string>safety</string> + <key>safty</key> + <string>safety</string> + <key>salery</key> + <string>salary</string> + <key>sanctionning</key> + <string>sanctioning</string> + <key>sandwhich</key> + <string>sandwich</string> + <key>santioned</key> + <string>sanctioned</string> + <key>sargant</key> + <string>sergeant</string> + <key>sargeant</key> + <string>sergeant</string> + <key>satelite</key> + <string>satellite</string> + <key>satelites</key> + <string>satellites</string> + <key>satisfactority</key> + <string>satisfactorily</string> + <key>satric</key> + <string>satiric</string> + <key>satrical</key> + <string>satirical</string> + <key>satrically</key> + <string>satirically</string> + <key>sattelite</key> + <string>satellite</string> + <key>sattelites</key> + <string>satellites</string> + <key>saught</key> + <string>sought</string> + <key>saveing</key> + <string>saving</string> + <key>saxaphone</key> + <string>saxophone</string> + <key>scaleable</key> + <string>scalable</string> + <key>scandanavia</key> + <string>Scandinavia</string> + <key>scaricity</key> + <string>scarcity</string> + <key>scavanged</key> + <string>scavenged</string> + <key>schedual</key> + <string>schedule</string> + <key>scholarhip</key> + <string>scholarship</string> + <key>scholarstic</key> + <string>scholastic</string> + <key>scientfic</key> + <string>scientific</string> + <key>scientifc</key> + <string>scientific</string> + <key>scientis</key> + <string>scientist</string> + <key>scince</key> + <string>science</string> + <key>scinece</key> + <string>science</string> + <key>scirpt</key> + <string>script</string> + <key>scoll</key> + <string>scroll</string> + <key>screenwrighter</key> + <string>screenwriter</string> + <key>scrutinity</key> + <string>scrutiny</string> + <key>scuptures</key> + <string>sculptures</string> + <key>seach</key> + <string>search</string> + <key>seached</key> + <string>searched</string> + <key>seaches</key> + <string>searches</string> + <key>secratary</key> + <string>secretary</string> + <key>secretery</key> + <string>secretary</string> + <key>sedereal</key> + <string>sidereal</string> + <key>seeked</key> + <string>sought</string> + <key>segementation</key> + <string>segmentation</string> + <key>seguoys</key> + <string>segues</string> + <key>seige</key> + <string>siege</string> + <key>seing</key> + <string>seeing</string> + <key>seinor</key> + <string>senior</string> + <key>seldomly</key> + <string>seldom</string> + <key>senarios</key> + <string>scenarios</string> + <key>senstive</key> + <string>sensitive</string> + <key>sensure</key> + <string>censure</string> + <key>seperate</key> + <string>separate</string> + <key>seperated</key> + <string>separated</string> + <key>seperately</key> + <string>separately</string> + <key>seperates</key> + <string>separates</string> + <key>seperating</key> + <string>separating</string> + <key>seperation</key> + <string>separation</string> + <key>seperatism</key> + <string>separatism</string> + <key>seperatist</key> + <string>separatist</string> + <key>sepina</key> + <string>subpoena</string> + <key>sergent</key> + <string>sergeant</string> + <key>settelement</key> + <string>settlement</string> + <key>settlment</key> + <string>settlement</string> + <key>severeal</key> + <string>several</string> + <key>severley</key> + <string>severely</string> + <key>severly</key> + <string>severely</string> + <key>sevice</key> + <string>service</string> + <key>shadasloo</key> + <string>shadaloo</string> + <key>shaddow</key> + <string>shadow</string> + <key>shadoloo</key> + <string>shadaloo</string> + <key>shamen</key> + <string>shaman</string> + <key>sheat</key> + <string>sheath</string> + <key>sheild</key> + <string>shield</string> + <key>sherif</key> + <string>sheriff</string> + <key>shineing</key> + <string>shining</string> + <key>shiped</key> + <string>shipped</string> + <key>shiping</key> + <string>shipping</string> + <key>shopkeeepers</key> + <string>shopkeepers</string> + <key>shorly</key> + <string>shortly</string> + <key>shortwhile</key> + <string>short while</string> + <key>shoudl</key> + <string>should</string> + <key>shoudln</key> + <string>shouldn't</string> + <key>shouldnt</key> + <string>shouldn't</string> + <key>shreak</key> + <string>shriek</string> + <key>shrinked</key> + <string>shrunk</string> + <key>sicne</key> + <string>since</string> + <key>sideral</key> + <string>sidereal</string> + <key>siezure</key> + <string>seizure</string> + <key>siezures</key> + <string>seizures</string> + <key>siginificant</key> + <string>significant</string> + <key>signficant</key> + <string>significant</string> + <key>signficiant</key> + <string>significant</string> + <key>signfies</key> + <string>signifies</string> + <key>signifantly</key> + <string>significantly</string> + <key>significently</key> + <string>significantly</string> + <key>signifigant</key> + <string>significant</string> + <key>signifigantly</key> + <string>significantly</string> + <key>signitories</key> + <string>signatories</string> + <key>signitory</key> + <string>signatory</string> + <key>similarily</key> + <string>similarly</string> + <key>similiar</key> + <string>similar</string> + <key>similiarity</key> + <string>similarity</string> + <key>similiarly</key> + <string>similarly</string> + <key>simmilar</key> + <string>similar</string> + <key>simpley</key> + <string>simply</string> + <key>simplier</key> + <string>simpler</string> + <key>simultanous</key> + <string>simultaneous</string> + <key>simultanously</key> + <string>simultaneously</string> + <key>sincerley</key> + <string>sincerely</string> + <key>singsog</key> + <string>singsong</string> + <key>sinse</key> + <string>since</string> + <key>skateing</key> + <string>skating</string> + <key>slaugterhouses</key> + <string>slaughterhouses</string> + <key>slighly</key> + <string>slightly</string> + <key>slowy</key> + <string>slowly</string> + <key>smae</key> + <string>same</string> + <key>smealting</key> + <string>smelting</string> + <key>smoe</key> + <string>some</string> + <key>sneeks</key> + <string>sneaks</string> + <key>snese</key> + <string>sneeze</string> + <key>socalism</key> + <string>socialism</string> + <key>socities</key> + <string>societies</string> + <key>soem</key> + <string>some</string> + <key>sofware</key> + <string>software</string> + <key>sohw</key> + <string>show</string> + <key>soilders</key> + <string>soldiers</string> + <key>solatary</key> + <string>solitary</string> + <key>soley</key> + <string>solely</string> + <key>soliders</key> + <string>soldiers</string> + <key>soliliquy</key> + <string>soliloquy</string> + <key>soluable</key> + <string>soluble</string> + <key>somene</key> + <string>someone</string> + <key>somtimes</key> + <string>sometimes</string> + <key>somwhere</key> + <string>somewhere</string> + <key>sophicated</key> + <string>sophisticated</string> + <key>sophmore</key> + <string>sophomore</string> + <key>sorceror</key> + <string>sorcerer</string> + <key>sorrounding</key> + <string>surrounding</string> + <key>sotry</key> + <string>story</string> + <key>sotyr</key> + <string>story</string> + <key>soudn</key> + <string>sound</string> + <key>soudns</key> + <string>sounds</string> + <key>sould</key> + <string>could</string> + <key>sountrack</key> + <string>soundtrack</string> + <key>sourth</key> + <string>south</string> + <key>sourthern</key> + <string>southern</string> + <key>souvenier</key> + <string>souvenir</string> + <key>souveniers</key> + <string>souvenirs</string> + <key>soveits</key> + <string>soviets</string> + <key>sovereignity</key> + <string>sovereignty</string> + <key>soverign</key> + <string>sovereign</string> + <key>soverignity</key> + <string>sovereignty</string> + <key>soverignty</key> + <string>sovereignty</string> + <key>spainish</key> + <string>Spanish</string> + <key>speach</key> + <string>speech</string> + <key>specfic</key> + <string>specific</string> + <key>speciallized</key> + <string>specialized</string> + <key>specifiying</key> + <string>specifying</string> + <key>speciman</key> + <string>specimen</string> + <key>spectauclar</key> + <string>spectacular</string> + <key>spectaulars</key> + <string>spectaculars</string> + <key>spectum</key> + <string>spectrum</string> + <key>speices</key> + <string>species</string> + <key>spendour</key> + <string>splendour</string> + <key>spermatozoan</key> + <string>spermatozoon</string> + <key>spoace</key> + <string>space</string> + <key>sponser</key> + <string>sponsor</string> + <key>sponsered</key> + <string>sponsored</string> + <key>spontanous</key> + <string>spontaneous</string> + <key>sponzored</key> + <string>sponsored</string> + <key>spoonfulls</key> + <string>spoonfuls</string> + <key>sppeches</key> + <string>speeches</string> + <key>spreaded</key> + <string>spread</string> + <key>sprech</key> + <string>speech</string> + <key>spred</key> + <string>spread</string> + <key>spriritual</key> + <string>spiritual</string> + <key>spritual</key> + <string>spiritual</string> + <key>sqaure</key> + <string>square</string> + <key>stablility</key> + <string>stability</string> + <key>stainlees</key> + <string>stainless</string> + <key>staion</key> + <string>station</string> + <key>standars</key> + <string>standards</string> + <key>stange</key> + <string>strange</string> + <key>startegic</key> + <string>strategic</string> + <key>startegies</key> + <string>strategies</string> + <key>startegy</key> + <string>strategy</string> + <key>stateman</key> + <string>statesman</string> + <key>statememts</key> + <string>statements</string> + <key>statment</key> + <string>statement</string> + <key>steriods</key> + <string>steroids</string> + <key>sterotypes</key> + <string>stereotypes</string> + <key>stilus</key> + <string>stylus</string> + <key>stingent</key> + <string>stringent</string> + <key>stiring</key> + <string>stirring</string> + <key>stirrs</key> + <string>stirs</string> + <key>stlye</key> + <string>style</string> + <key>stomache</key> + <string>stomach</string> + <key>stong</key> + <string>strong</string> + <key>stopry</key> + <string>story</string> + <key>storeis</key> + <string>stories</string> + <key>storise</key> + <string>stories</string> + <key>stornegst</key> + <string>strongest</string> + <key>stoyr</key> + <string>story</string> + <key>stpo</key> + <string>stop</string> + <key>stradegies</key> + <string>strategies</string> + <key>stradegy</key> + <string>strategy</string> + <key>strat</key> + <string>start</string> + <key>stratagically</key> + <string>strategically</string> + <key>streemlining</key> + <string>streamlining</string> + <key>stregth</key> + <string>strength</string> + <key>strenghen</key> + <string>strengthen</string> + <key>strenghened</key> + <string>strengthened</string> + <key>strenghening</key> + <string>strengthening</string> + <key>strenght</key> + <string>strength</string> + <key>strenghten</key> + <string>strengthen</string> + <key>strenghtened</key> + <string>strengthened</string> + <key>strenghtening</key> + <string>strengthening</string> + <key>strengtened</key> + <string>strengthened</string> + <key>strenous</key> + <string>strenuous</string> + <key>strictist</key> + <string>strictest</string> + <key>strikely</key> + <string>strikingly</string> + <key>strnad</key> + <string>strand</string> + <key>stroy</key> + <string>story</string> + <key>structual</key> + <string>structural</string> + <key>stubborness</key> + <string>stubbornness</string> + <key>stucture</key> + <string>structure</string> + <key>stuctured</key> + <string>structured</string> + <key>studdy</key> + <string>study</string> + <key>studing</key> + <string>studying</string> + <key>stuggling</key> + <string>struggling</string> + <key>sturcture</key> + <string>structure</string> + <key>subcatagories</key> + <string>subcategories</string> + <key>subcatagory</key> + <string>subcategory</string> + <key>subconsiously</key> + <string>subconsciously</string> + <key>subjudgation</key> + <string>subjugation</string> + <key>submachne</key> + <string>submachine</string> + <key>subpecies</key> + <string>subspecies</string> + <key>subsidary</key> + <string>subsidiary</string> + <key>subsiduary</key> + <string>subsidiary</string> + <key>subsquent</key> + <string>subsequent</string> + <key>subsquently</key> + <string>subsequently</string> + <key>substace</key> + <string>substance</string> + <key>substancial</key> + <string>substantial</string> + <key>substatial</key> + <string>substantial</string> + <key>substituded</key> + <string>substituted</string> + <key>substract</key> + <string>subtract</string> + <key>substracted</key> + <string>subtracted</string> + <key>substracting</key> + <string>subtracting</string> + <key>substraction</key> + <string>subtraction</string> + <key>substracts</key> + <string>subtracts</string> + <key>subtances</key> + <string>substances</string> + <key>subterranian</key> + <string>subterranean</string> + <key>suburburban</key> + <string>suburban</string> + <key>succceeded</key> + <string>succeeded</string> + <key>succcesses</key> + <string>successes</string> + <key>succedded</key> + <string>succeeded</string> + <key>succeded</key> + <string>succeeded</string> + <key>succeds</key> + <string>succeeds</string> + <key>succesful</key> + <string>successful</string> + <key>succesfully</key> + <string>successfully</string> + <key>succesfuly</key> + <string>successfully</string> + <key>succesion</key> + <string>succession</string> + <key>succesive</key> + <string>successive</string> + <key>successfull</key> + <string>successful</string> + <key>successully</key> + <string>successfully</string> + <key>succsess</key> + <string>success</string> + <key>succsessfull</key> + <string>successful</string> + <key>suceed</key> + <string>succeed</string> + <key>suceeded</key> + <string>succeeded</string> + <key>suceeding</key> + <string>succeeding</string> + <key>suceeds</key> + <string>succeeds</string> + <key>sucesful</key> + <string>successful</string> + <key>sucesfully</key> + <string>successfully</string> + <key>sucesfuly</key> + <string>successfully</string> + <key>sucesion</key> + <string>succession</string> + <key>sucess</key> + <string>success</string> + <key>sucesses</key> + <string>successes</string> + <key>sucessful</key> + <string>successful</string> + <key>sucessfull</key> + <string>successful</string> + <key>sucessfully</key> + <string>successfully</string> + <key>sucessfuly</key> + <string>successfully</string> + <key>sucession</key> + <string>succession</string> + <key>sucessive</key> + <string>successive</string> + <key>sucessor</key> + <string>successor</string> + <key>sucessot</key> + <string>successor</string> + <key>sucide</key> + <string>suicide</string> + <key>sucidial</key> + <string>suicidal</string> + <key>sufferage</key> + <string>suffrage</string> + <key>sufferred</key> + <string>suffered</string> + <key>sufferring</key> + <string>suffering</string> + <key>sufficent</key> + <string>sufficient</string> + <key>sufficently</key> + <string>sufficiently</string> + <key>sumary</key> + <string>summary</string> + <key>sunglases</key> + <string>sunglasses</string> + <key>suop</key> + <string>soup</string> + <key>superceeded</key> + <string>superseded</string> + <key>superintendant</key> + <string>superintendent</string> + <key>suphisticated</key> + <string>sophisticated</string> + <key>suplimented</key> + <string>supplemented</string> + <key>supose</key> + <string>suppose</string> + <key>suposed</key> + <string>supposed</string> + <key>suposedly</key> + <string>supposedly</string> + <key>suposes</key> + <string>supposes</string> + <key>suposing</key> + <string>supposing</string> + <key>supplamented</key> + <string>supplemented</string> + <key>suppliementing</key> + <string>supplementing</string> + <key>suppoed</key> + <string>supposed</string> + <key>supposingly</key> + <string>supposedly</string> + <key>suppy</key> + <string>supply</string> + <key>supress</key> + <string>suppress</string> + <key>supressed</key> + <string>suppressed</string> + <key>supresses</key> + <string>suppresses</string> + <key>supressing</key> + <string>suppressing</string> + <key>suprise</key> + <string>surprise</string> + <key>suprised</key> + <string>surprised</string> + <key>suprising</key> + <string>surprising</string> + <key>suprisingly</key> + <string>surprisingly</string> + <key>suprize</key> + <string>surprise</string> + <key>suprized</key> + <string>surprised</string> + <key>suprizing</key> + <string>surprising</string> + <key>suprizingly</key> + <string>surprisingly</string> + <key>surfce</key> + <string>surface</string> + <key>surley</key> + <string>surely</string> + <key>suround</key> + <string>surround</string> + <key>surounded</key> + <string>surrounded</string> + <key>surounding</key> + <string>surrounding</string> + <key>suroundings</key> + <string>surroundings</string> + <key>surounds</key> + <string>surrounds</string> + <key>surplanted</key> + <string>supplanted</string> + <key>surpress</key> + <string>suppress</string> + <key>surpressed</key> + <string>suppressed</string> + <key>surprize</key> + <string>surprise</string> + <key>surprized</key> + <string>surprised</string> + <key>surprizing</key> + <string>surprising</string> + <key>surprizingly</key> + <string>surprisingly</string> + <key>surrended</key> + <string>surrendered</string> + <key>surrepetitious</key> + <string>surreptitious</string> + <key>surrepetitiously</key> + <string>surreptitiously</string> + <key>surreptious</key> + <string>surreptitious</string> + <key>surreptiously</key> + <string>surreptitiously</string> + <key>surronded</key> + <string>surrounded</string> + <key>surrouded</key> + <string>surrounded</string> + <key>surrouding</key> + <string>surrounding</string> + <key>surrundering</key> + <string>surrendering</string> + <key>surveilence</key> + <string>surveillance</string> + <key>surveill</key> + <string>surveil</string> + <key>surveyer</key> + <string>surveyor</string> + <key>surviver</key> + <string>survivor</string> + <key>survivers</key> + <string>survivors</string> + <key>survivied</key> + <string>survived</string> + <key>suseptable</key> + <string>susceptible</string> + <key>suseptible</key> + <string>susceptible</string> + <key>suspention</key> + <string>suspension</string> + <key>swaer</key> + <string>swear</string> + <key>swaers</key> + <string>swears</string> + <key>swepth</key> + <string>swept</string> + <key>swiming</key> + <string>swimming</string> + <key>syas</key> + <string>says</string> + <key>symetrical</key> + <string>symmetrical</string> + <key>symetrically</key> + <string>symmetrically</string> + <key>symetry</key> + <string>symmetry</string> + <key>symettric</key> + <string>symmetric</string> + <key>symmetral</key> + <string>symmetric</string> + <key>symmetricaly</key> + <string>symmetrically</string> + <key>synagouge</key> + <string>synagogue</string> + <key>syncronization</key> + <string>synchronization</string> + <key>synonomous</key> + <string>synonymous</string> + <key>synonymns</key> + <string>synonyms</string> + <key>synphony</key> + <string>symphony</string> + <key>syphyllis</key> + <string>syphilis</string> + <key>sypmtoms</key> + <string>symptoms</string> + <key>syrap</key> + <string>syrup</string> + <key>sysmatically</key> + <string>systematically</string> + <key>sytem</key> + <string>system</string> + <key>sytle</key> + <string>style</string> + <key>tabacco</key> + <string>tobacco</string> + <key>tahn</key> + <string>than</string> + <key>taht</key> + <string>that</string> + <key>talekd</key> + <string>talked</string> + <key>targetted</key> + <string>targeted</string> + <key>targetting</key> + <string>targeting</string> + <key>tast</key> + <string>taste</string> + <key>tath</key> + <string>that</string> + <key>tattooes</key> + <string>tattoos</string> + <key>taxanomic</key> + <string>taxonomic</string> + <key>taxanomy</key> + <string>taxonomy</string> + <key>teached</key> + <string>taught</string> + <key>techician</key> + <string>technician</string> + <key>techicians</key> + <string>technicians</string> + <key>techiniques</key> + <string>techniques</string> + <key>technitian</key> + <string>technician</string> + <key>technnology</key> + <string>technology</string> + <key>technolgy</key> + <string>technology</string> + <key>teh</key> + <string>the</string> + <key>tehy</key> + <string>they</string> + <key>telelevision</key> + <string>television</string> + <key>televsion</key> + <string>television</string> + <key>telphony</key> + <string>telephony</string> + <key>temerature</key> + <string>temperature</string> + <key>tempalte</key> + <string>template</string> + <key>tempaltes</key> + <string>templates</string> + <key>temparate</key> + <string>temperate</string> + <key>temperarily</key> + <string>temporarily</string> + <key>temperment</key> + <string>temperament</string> + <key>tempertaure</key> + <string>temperature</string> + <key>temperture</key> + <string>temperature</string> + <key>temprary</key> + <string>temporary</string> + <key>tenacle</key> + <string>tentacle</string> + <key>tenacles</key> + <string>tentacles</string> + <key>tendacy</key> + <string>tendency</string> + <key>tendancies</key> + <string>tendencies</string> + <key>tendancy</key> + <string>tendency</string> + <key>tennisplayer</key> + <string>tennis player</string> + <key>tepmorarily</key> + <string>temporarily</string> + <key>terrestial</key> + <string>terrestrial</string> + <key>terriories</key> + <string>territories</string> + <key>terriory</key> + <string>territory</string> + <key>territorist</key> + <string>terrorist</string> + <key>territoy</key> + <string>territory</string> + <key>terroist</key> + <string>terrorist</string> + <key>testiclular</key> + <string>testicular</string> + <key>tghe</key> + <string>the</string> + <key>thast</key> + <string>that's</string> + <key>theather</key> + <string>theater</string> + <key>theese</key> + <string>these</string> + <key>theif</key> + <string>thief</string> + <key>theives</key> + <string>thieves</string> + <key>themselfs</key> + <string>themselves</string> + <key>themslves</key> + <string>themselves</string> + <key>ther</key> + <string>there</string> + <key>therafter</key> + <string>thereafter</string> + <key>therby</key> + <string>thereby</string> + <key>theri</key> + <string>their</string> + <key>theyre</key> + <string>they're</string> + <key>thgat</key> + <string>that</string> + <key>thge</key> + <string>the</string> + <key>thier</key> + <string>their</string> + <key>thign</key> + <string>thing</string> + <key>thigns</key> + <string>things</string> + <key>thigsn</key> + <string>things</string> + <key>thikn</key> + <string>think</string> + <key>thikning</key> + <string>thinking</string> + <key>thikns</key> + <string>thinks</string> + <key>thiunk</key> + <string>think</string> + <key>thn</key> + <string>then</string> + <key>thna</key> + <string>than</string> + <key>thne</key> + <string>then</string> + <key>thnig</key> + <string>thing</string> + <key>thnigs</key> + <string>things</string> + <key>thoughout</key> + <string>throughout</string> + <key>threatend</key> + <string>threatened</string> + <key>threatning</key> + <string>threatening</string> + <key>threee</key> + <string>three</string> + <key>threshhold</key> + <string>threshold</string> + <key>thrid</key> + <string>third</string> + <key>throrough</key> + <string>thorough</string> + <key>throughly</key> + <string>thoroughly</string> + <key>throught</key> + <string>throat</string> + <key>througout</key> + <string>throughout</string> + <key>thru</key> + <string>through</string> + <key>thsi</key> + <string>this</string> + <key>thsoe</key> + <string>those</string> + <key>thta</key> + <string>that</string> + <key>thyat</key> + <string>that</string> + <key>tiem</key> + <string>time</string> + <key>tihkn</key> + <string>think</string> + <key>tihs</key> + <string>this</string> + <key>timne</key> + <string>time</string> + <key>tiome</key> + <string>time</string> + <key>tje</key> + <string>the</string> + <key>tjhe</key> + <string>the</string> + <key>tjpanishad</key> + <string>upanishad</string> + <key>tkae</key> + <string>take</string> + <key>tkaes</key> + <string>takes</string> + <key>tkaing</key> + <string>taking</string> + <key>tlaking</key> + <string>talking</string> + <key>tobbaco</key> + <string>tobacco</string> + <key>todays</key> + <string>today's</string> + <key>todya</key> + <string>today</string> + <key>toghether</key> + <string>together</string> + <key>toke</key> + <string>took</string> + <key>tolerence</key> + <string>tolerance</string> + <key>tomatos</key> + <string>tomatoes</string> + <key>tommorow</key> + <string>tomorrow</string> + <key>tommorrow</key> + <string>tomorrow</string> + <key>tongiht</key> + <string>tonight</string> + <key>toriodal</key> + <string>toroidal</string> + <key>tormenters</key> + <string>tormentors</string> + <key>tornadoe</key> + <string>tornado</string> + <key>torpeados</key> + <string>torpedoes</string> + <key>torpedos</key> + <string>torpedoes</string> + <key>tothe</key> + <string>to the</string> + <key>toubles</key> + <string>troubles</string> + <key>tounge</key> + <string>tongue</string> + <key>tourch</key> + <string>torch</string> + <key>towords</key> + <string>towards</string> + <key>towrad</key> + <string>toward</string> + <key>tradionally</key> + <string>traditionally</string> + <key>traditionaly</key> + <string>traditionally</string> + <key>traditionnal</key> + <string>traditional</string> + <key>traditition</key> + <string>tradition</string> + <key>tradtionally</key> + <string>traditionally</string> + <key>trafficed</key> + <string>trafficked</string> + <key>trafficing</key> + <string>trafficking</string> + <key>trafic</key> + <string>traffic</string> + <key>trancendent</key> + <string>transcendent</string> + <key>trancending</key> + <string>transcending</string> + <key>tranform</key> + <string>transform</string> + <key>tranformed</key> + <string>transformed</string> + <key>transcendance</key> + <string>transcendence</string> + <key>transcendant</key> + <string>transcendent</string> + <key>transcendentational</key> + <string>transcendental</string> + <key>transcripting</key> + <string>transcribing</string> + <key>transending</key> + <string>transcending</string> + <key>transesxuals</key> + <string>transsexuals</string> + <key>transfered</key> + <string>transferred</string> + <key>transfering</key> + <string>transferring</string> + <key>transformaton</key> + <string>transformation</string> + <key>transistion</key> + <string>transition</string> + <key>translater</key> + <string>translator</string> + <key>translaters</key> + <string>translators</string> + <key>transmissable</key> + <string>transmissible</string> + <key>transporation</key> + <string>transportation</string> + <key>tremelo</key> + <string>tremolo</string> + <key>tremelos</key> + <string>tremolos</string> + <key>triguered</key> + <string>triggered</string> + <key>triology</key> + <string>trilogy</string> + <key>troling</key> + <string>trolling</string> + <key>troup</key> + <string>troupe</string> + <key>troups</key> + <string>troops</string> + <key>truely</key> + <string>truly</string> + <key>trustworthyness</key> + <string>trustworthiness</string> + <key>turnk</key> + <string>trunk</string> + <key>tust</key> + <string>trust</string> + <key>twelth</key> + <string>twelfth</string> + <key>twon</key> + <string>town</string> + <key>twpo</key> + <string>two</string> + <key>tyhat</key> + <string>that</string> + <key>tyhe</key> + <string>they</string> + <key>typcial</key> + <string>typical</string> + <key>typicaly</key> + <string>typically</string> + <key>tyranies</key> + <string>tyrannies</string> + <key>tyrany</key> + <string>tyranny</string> + <key>tyrranies</key> + <string>tyrannies</string> + <key>tyrrany</key> + <string>tyranny</string> + <key>ubiquitious</key> + <string>ubiquitous</string> + <key>ublisher</key> + <string>publisher</string> + <key>uise</key> + <string>use</string> + <key>ultimely</key> + <string>ultimately</string> + <key>unacompanied</key> + <string>unaccompanied</string> + <key>unahppy</key> + <string>unhappy</string> + <key>unanymous</key> + <string>unanimous</string> + <key>unathorised</key> + <string>unauthorised</string> + <key>unavailible</key> + <string>unavailable</string> + <key>unballance</key> + <string>unbalance</string> + <key>unbeknowst</key> + <string>unbeknownst</string> + <key>unbeleivable</key> + <string>unbelievable</string> + <key>uncertainity</key> + <string>uncertainty</string> + <key>unchallengable</key> + <string>unchallengeable</string> + <key>unchangable</key> + <string>unchangeable</string> + <key>uncompetive</key> + <string>uncompetitive</string> + <key>unconcious</key> + <string>unconscious</string> + <key>unconciousness</key> + <string>unconsciousness</string> + <key>unconfortability</key> + <string>discomfort</string> + <key>uncontitutional</key> + <string>unconstitutional</string> + <key>unconvential</key> + <string>unconventional</string> + <key>undecideable</key> + <string>undecidable</string> + <key>understoon</key> + <string>understood</string> + <key>undesireable</key> + <string>undesirable</string> + <key>undetecable</key> + <string>undetectable</string> + <key>undoubtely</key> + <string>undoubtedly</string> + <key>undreground</key> + <string>underground</string> + <key>uneccesary</key> + <string>unnecessary</string> + <key>unecessary</key> + <string>unnecessary</string> + <key>unequalities</key> + <string>inequalities</string> + <key>unforetunately</key> + <string>unfortunately</string> + <key>unforgetable</key> + <string>unforgettable</string> + <key>unforgiveable</key> + <string>unforgivable</string> + <key>unfortunatley</key> + <string>unfortunately</string> + <key>unfortunatly</key> + <string>unfortunately</string> + <key>unfourtunately</key> + <string>unfortunately</string> + <key>unihabited</key> + <string>uninhabited</string> + <key>unilateraly</key> + <string>unilaterally</string> + <key>unilatreal</key> + <string>unilateral</string> + <key>unilatreally</key> + <string>unilaterally</string> + <key>uninterruped</key> + <string>uninterrupted</string> + <key>uninterupted</key> + <string>uninterrupted</string> + <key>univeral</key> + <string>universal</string> + <key>univeristies</key> + <string>universities</string> + <key>univeristy</key> + <string>university</string> + <key>univerity</key> + <string>university</string> + <key>universtiy</key> + <string>university</string> + <key>univesities</key> + <string>universities</string> + <key>univesity</key> + <string>university</string> + <key>unkown</key> + <string>unknown</string> + <key>unlikey</key> + <string>unlikely</string> + <key>unmanouverable</key> + <string>unmaneuverable</string> + <key>unmistakeably</key> + <string>unmistakably</string> + <key>unneccesarily</key> + <string>unnecessarily</string> + <key>unneccesary</key> + <string>unnecessary</string> + <key>unneccessarily</key> + <string>unnecessarily</string> + <key>unneccessary</key> + <string>unnecessary</string> + <key>unnecesarily</key> + <string>unnecessarily</string> + <key>unnecesary</key> + <string>unnecessary</string> + <key>unoffical</key> + <string>unofficial</string> + <key>unoperational</key> + <string>nonoperational</string> + <key>unoticeable</key> + <string>unnoticeable</string> + <key>unplease</key> + <string>displease</string> + <key>unplesant</key> + <string>unpleasant</string> + <key>unprecendented</key> + <string>unprecedented</string> + <key>unprecidented</key> + <string>unprecedented</string> + <key>unrepentent</key> + <string>unrepentant</string> + <key>unrepetant</key> + <string>unrepentant</string> + <key>unrepetent</key> + <string>unrepentant</string> + <key>unsed</key> + <string>unused</string> + <key>unsubstanciated</key> + <string>unsubstantiated</string> + <key>unsuccesful</key> + <string>unsuccessful</string> + <key>unsuccesfully</key> + <string>unsuccessfully</string> + <key>unsuccessfull</key> + <string>unsuccessful</string> + <key>unsucesful</key> + <string>unsuccessful</string> + <key>unsucesfuly</key> + <string>unsuccessfully</string> + <key>unsucessful</key> + <string>unsuccessful</string> + <key>unsucessfull</key> + <string>unsuccessful</string> + <key>unsucessfully</key> + <string>unsuccessfully</string> + <key>unsuprised</key> + <string>unsurprised</string> + <key>unsuprising</key> + <string>unsurprising</string> + <key>unsuprisingly</key> + <string>unsurprisingly</string> + <key>unsuprized</key> + <string>unsurprised</string> + <key>unsuprizing</key> + <string>unsurprising</string> + <key>unsuprizingly</key> + <string>unsurprisingly</string> + <key>unsurprized</key> + <string>unsurprised</string> + <key>unsurprizing</key> + <string>unsurprising</string> + <key>unsurprizingly</key> + <string>unsurprisingly</string> + <key>untill</key> + <string>until</string> + <key>untranslateable</key> + <string>untranslatable</string> + <key>unuseable</key> + <string>unusable</string> + <key>unusuable</key> + <string>unusable</string> + <key>unviersity</key> + <string>university</string> + <key>unwarrented</key> + <string>unwarranted</string> + <key>unweildly</key> + <string>unwieldy</string> + <key>unwieldly</key> + <string>unwieldy</string> + <key>upcomming</key> + <string>upcoming</string> + <key>upgradded</key> + <string>upgraded</string> + <key>upto</key> + <string>up to</string> + <key>usally</key> + <string>usually</string> + <key>useage</key> + <string>usage</string> + <key>usefull</key> + <string>useful</string> + <key>usefuly</key> + <string>usefully</string> + <key>useing</key> + <string>using</string> + <key>usualy</key> + <string>usually</string> + <key>ususally</key> + <string>usually</string> + <key>vaccum</key> + <string>vacuum</string> + <key>vaccume</key> + <string>vacuum</string> + <key>vacinity</key> + <string>vicinity</string> + <key>vaguaries</key> + <string>vagaries</string> + <key>vaieties</key> + <string>varieties</string> + <key>vailidty</key> + <string>validity</string> + <key>valetta</key> + <string>valletta</string> + <key>valuble</key> + <string>valuable</string> + <key>valueable</key> + <string>valuable</string> + <key>varations</key> + <string>variations</string> + <key>varient</key> + <string>variant</string> + <key>variey</key> + <string>variety</string> + <key>varing</key> + <string>varying</string> + <key>varities</key> + <string>varieties</string> + <key>varity</key> + <string>variety</string> + <key>vasall</key> + <string>vassal</string> + <key>vasalls</key> + <string>vassals</string> + <key>vegatarian</key> + <string>vegetarian</string> + <key>vegitable</key> + <string>vegetable</string> + <key>vegitables</key> + <string>vegetables</string> + <key>vegtable</key> + <string>vegetable</string> + <key>vehicule</key> + <string>vehicle</string> + <key>vell</key> + <string>well</string> + <key>venemous</key> + <string>venomous</string> + <key>vengance</key> + <string>vengeance</string> + <key>vengence</key> + <string>vengeance</string> + <key>verfication</key> + <string>verification</string> + <key>verison</key> + <string>version</string> + <key>verisons</key> + <string>versions</string> + <key>vermillion</key> + <string>vermilion</string> + <key>versitilaty</key> + <string>versatility</string> + <key>versitlity</key> + <string>versatility</string> + <key>vetween</key> + <string>between</string> + <key>veyr</key> + <string>very</string> + <key>vigeur</key> + <string>vigor</string> + <key>vigilence</key> + <string>vigilance</string> + <key>vigourous</key> + <string>vigorous</string> + <key>villian</key> + <string>villain</string> + <key>villification</key> + <string>vilification</string> + <key>villify</key> + <string>vilify</string> + <key>villin</key> + <string>villain</string> + <key>vincinity</key> + <string>vicinity</string> + <key>violentce</key> + <string>violence</string> + <key>virtualy</key> + <string>virtually</string> + <key>virutal</key> + <string>virtual</string> + <key>virutally</key> + <string>virtually</string> + <key>visable</key> + <string>visible</string> + <key>visably</key> + <string>visibly</string> + <key>visting</key> + <string>visiting</string> + <key>vistors</key> + <string>visitors</string> + <key>vitories</key> + <string>victories</string> + <key>volcanoe</key> + <string>volcano</string> + <key>voleyball</key> + <string>volleyball</string> + <key>volontary</key> + <string>voluntary</string> + <key>volonteer</key> + <string>volunteer</string> + <key>volonteered</key> + <string>volunteered</string> + <key>volonteering</key> + <string>volunteering</string> + <key>volonteers</key> + <string>volunteers</string> + <key>volounteer</key> + <string>volunteer</string> + <key>volounteered</key> + <string>volunteered</string> + <key>volounteering</key> + <string>volunteering</string> + <key>volounteers</key> + <string>volunteers</string> + <key>volumne</key> + <string>volume</string> + <key>vreity</key> + <string>variety</string> + <key>vrey</key> + <string>very</string> + <key>vriety</key> + <string>variety</string> + <key>vulnerablility</key> + <string>vulnerability</string> + <key>vyer</key> + <string>very</string> + <key>vyre</key> + <string>very</string> + <key>waht</key> + <string>what</string> + <key>wanna</key> + <string>want to</string> + <key>warantee</key> + <string>warranty</string> + <key>wardobe</key> + <string>wardrobe</string> + <key>warrent</key> + <string>warrant</string> + <key>warrriors</key> + <string>warriors</string> + <key>wasnt</key> + <string>wasn't</string> + <key>wass</key> + <string>was</string> + <key>watn</key> + <string>want</string> + <key>wayword</key> + <string>wayward</string> + <key>weaponary</key> + <string>weaponry</string> + <key>weas</key> + <string>was</string> + <key>wehn</key> + <string>when</string> + <key>weild</key> + <string>wield</string> + <key>weilded</key> + <string>wielded</string> + <key>wendsay</key> + <string>Wednesday</string> + <key>wensday</key> + <string>Wednesday</string> + <key>wereabouts</key> + <string>whereabouts</string> + <key>whant</key> + <string>want</string> + <key>whants</key> + <string>wants</string> + <key>whcih</key> + <string>which</string> + <key>wheras</key> + <string>whereas</string> + <key>wherease</key> + <string>whereas</string> + <key>whereever</key> + <string>wherever</string> + <key>whic</key> + <string>which</string> + <key>whihc</key> + <string>which</string> + <key>whith</key> + <string>with</string> + <key>whlch</key> + <string>which</string> + <key>whn</key> + <string>when</string> + <key>wholey</key> + <string>wholly</string> + <key>wholy</key> + <string>holy</string> + <key>whta</key> + <string>what</string> + <key>whther</key> + <string>whether</string> + <key>wich</key> + <string>which</string> + <key>widesread</key> + <string>widespread</string> + <key>wief</key> + <string>wife</string> + <key>wierd</key> + <string>weird</string> + <key>wiew</key> + <string>view</string> + <key>wih</key> + <string>with</string> + <key>wiht</key> + <string>with</string> + <key>wille</key> + <string>will</string> + <key>willingless</key> + <string>willingness</string> + <key>wirting</key> + <string>writing</string> + <key>withdrawl</key> + <string>withdrawal</string> + <key>witheld</key> + <string>withheld</string> + <key>withh</key> + <string>with</string> + <key>withing</key> + <string>within</string> + <key>withold</key> + <string>withhold</string> + <key>witht</key> + <string>with</string> + <key>witn</key> + <string>with</string> + <key>wiull</key> + <string>will</string> + <key>wnat</key> + <string>want</string> + <key>wnated</key> + <string>wanted</string> + <key>wnats</key> + <string>wants</string> + <key>wohle</key> + <string>whole</string> + <key>wokr</key> + <string>work</string> + <key>wokring</key> + <string>working</string> + <key>wonderfull</key> + <string>wonderful</string> + <key>wont</key> + <string>won't</string> + <key>wordlwide</key> + <string>worldwide</string> + <key>workststion</key> + <string>workstation</string> + <key>worls</key> + <string>world</string> + <key>worstened</key> + <string>worsened</string> + <key>woudl</key> + <string>would</string> + <key>wresters</key> + <string>wrestlers</string> + <key>wriet</key> + <string>write</string> + <key>writen</key> + <string>written</string> + <key>wroet</key> + <string>wrote</string> + <key>wrok</key> + <string>work</string> + <key>wroking</key> + <string>working</string> + <key>wtih</key> + <string>with</string> + <key>wupport</key> + <string>support</string> + <key>xenophoby</key> + <string>xenophobia</string> + <key>yaching</key> + <string>yachting</string> + <key>yaer</key> + <string>year</string> + <key>yaerly</key> + <string>yearly</string> + <key>yaers</key> + <string>years</string> + <key>yatch</key> + <string>yacht</string> + <key>yearm</key> + <string>year</string> + <key>yeasr</key> + <string>years</string> + <key>yeild</key> + <string>yield</string> + <key>yeilding</key> + <string>yielding</string> + <key>yera</key> + <string>year</string> + <key>yeras</key> + <string>years</string> + <key>yersa</key> + <string>years</string> + <key>yotube</key> + <string>YouTube</string> + <key>youre</key> + <string>you're</string> + <key>youseff</key> + <string>yousef</string> + <key>youself</key> + <string>yourself</string> + <key>ytou</key> + <string>you</string> + <key>yuo</key> + <string>you</string> + <key>zeebra</key> + <string>zebra</string> + </map> + </map> + </array> +</llsd> diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 15434f2b8f..7ab7787d77 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -1,117 +1,167 @@ <?xml version="1.0"?> <llsd> <map> - <key>help</key> + <!-- Please insert new keys in alphabetical order. --> + <key>analyzeperformance</key> <map> <key>desc</key> - <string>display this help message</string> + <string>When used in conjunction with logperformance, analyzes result of log against baseline.</string> + <key>map-to</key> + <string>AnalyzePerformance</string> + </map> - <key>short</key> - <string>h</string> + <key>autologin</key> + <map> + <key>desc</key> + <string>log in as last saved user</string> + <key>map-to</key> + <string>AutoLogin</string> </map> - <key>port</key> + <key>channel</key> <map> <key>count</key> <integer>1</integer> - <key>map-to</key> - <string>UserConnectionPort</string> + <!-- Special case. Not mapped to a setting. --> </map> - <key>drop</key> + <key>console</key> <map> <key>count</key> <integer>1</integer> <key>map-to</key> - <string>PacketDropPercentage</string> + <string>ShowConsoleWindow</string> </map> - <key>inbw</key> + <key>cooperative</key> <map> + <key>desc</key> + <string>Yield some idle time to local host.</string> <key>count</key> <integer>1</integer> <key>map-to</key> - <string>InBandwidth</string> + <string>YieldTime</string> </map> - <key>outbw</key> + <key>crashonstartup</key> <map> - <key>count</key> - <integer>1</integer> + <key>desc</key> + <string>Crashes on startup. For QA use.</string> <key>map-to</key> - <string>OutBandwidth</string> + <string>CrashOnStartup</string> </map> - <key>grid</key> + <key>debugsession</key> <map> <key>desc</key> - <string>Specify the name of the grid, local, or an IP address to connect to.</string> + <string>Run as if RenderDebugGL is TRUE, but log errors until end of session.</string> + <key>map-to</key> + <string>DebugSession</string> + </map> + + <key>debugviews</key> + <map> + <key>map-to</key> + <string>DebugViews</string> + </map> + + <key>disablecrashlogger</key> + <map> + <key>desc</key> + <string>Disables the crash logger and lets the OS handle crashes</string> + <key>map-to</key> + <string>DisableCrashLogger</string> + </map> + + <key>drop</key> + <map> <key>count</key> <integer>1</integer> <key>map-to</key> - <string>CmdLineGridChoice</string> + <string>PacketDropPercentage</string> </map> - <key>loginuri</key> + <key>god</key> <map> <key>desc</key> - <string>login server and CGI script to use</string> + <string>Log in a god if you have god access.</string> + <key>map-to</key> + <string>ConnectAsGod</string> + </map> + + <key>graphicslevel</key> + <map> + <key>desc</key> + <string>Set the detail level. +0 - low, 1 - medium, 2 - high, 3 - ultra</string> <key>count</key> <integer>1</integer> - <key>compose</key> - <boolean>true</boolean> - <key>map-to</key> - <string>CmdLineLoginURI</string> </map> - <key>helperuri</key> + <key>grid</key> <map> <key>desc</key> - <string>helper web CGI prefix to use</string> + <string>Specify the name of the grid to connect to.</string> <key>count</key> <integer>1</integer> <key>map-to</key> - <string>CmdLineHelperURI</string> + <string>CmdLineGridChoice</string> </map> - <key>debugviews</key> + <key>help</key> <map> - <key>map-to</key> - <string>DebugViews</string> + <key>desc</key> + <string>display this help message</string> + + <key>short</key> + <string>h</string> </map> - <key>skin</key> + <key>ignorepixeldepth</key> <map> <key>desc</key> - <string>ui/branding skin folder to use</string> + <string>Ignore pixel depth settings.</string> + <key>map-to</key> + <string>IgnorePixelDepth</string> + </map> + + <key>inbw</key> + <map> <key>count</key> <integer>1</integer> <key>map-to</key> - <string>SkinFolder</string> + <string>InBandwidth</string> </map> - <key>autologin</key> + <key>leap</key> <map> <key>desc</key> - <string>log in as last saved user</string> + <string>command line to run an LLSD Event API Plugin</string> + <key>count</key> + <integer>1</integer> + <!-- you can specify multiple such plugins --> + <key>compose</key> + <boolean>true</boolean> <key>map-to</key> - <string>AutoLogin</string> + <string>LeapCommand</string> </map> - <key>quitafter</key> + <key>logfile</key> <map> <key>count</key> <integer>1</integer> <key>map-to</key> - <string>QuitAfterSeconds</string> + <string>UserLogFile</string> </map> - <key>logperformance</key> + <key>login</key> <map> <key>desc</key> - <string>Log performance metrics for benchmarking</string> + <string>3 tokens: first, last and password</string> + <key>count</key> + <integer>3</integer> <key>map-to</key> - <string>LogPerformance</string> + <string>UserLoginInfo</string> </map> <key>logmetrics</key> @@ -123,55 +173,49 @@ <key>map-to</key> <string>LogMetrics</string> </map> - - <key>analyzeperformance</key> - <map> - <key>desc</key> - <string>When used in conjunction with logperformance, analyzes result of log against baseline.</string> - <key>map-to</key> - <string>AnalyzePerformance</string> - </map> - <key>debugsession</key> + <key>logperformance</key> <map> <key>desc</key> - <string>Run as if RenderDebugGL is TRUE, but log errors until end of session.</string> + <string>Log performance metrics for benchmarking</string> <key>map-to</key> - <string>DebugSession</string> + <string>LogPerformance</string> </map> - <key>replaysession</key> + <key>multiple</key> <map> <key>desc</key> - <string>After login, replay last recorded session and quit.</string> + <string>Allow multiple viewers.</string> <key>map-to</key> - <string>ReplaySession</string> + <string>AllowMultipleViewers</string> </map> - <key>nonotifications</key> + <key>noaudio</key> <map> - <key>desc</key> - <string>User will not get any notifications. NOTE: All notifications that occur will get added to ignore file for future runs.</string> <key>map-to</key> - <string>IgnoreAllNotifications</string> + <string>NoAudio</string> </map> - <key>rotate</key> + <key>noinvlib</key> <map> + <key>desc</key> + <string>Do not request the inventory library.</string> <key>map-to</key> - <string>RotateRight</string> + <string>NoInventoryLibrary</string> </map> - <key>noaudio</key> + <key>nonotifications</key> <map> + <key>desc</key> + <string>User will not get any notifications. NOTE: All notifications that occur will get added to ignore file for future runs.</string> <key>map-to</key> - <string>NoAudio</string> + <string>IgnoreAllNotifications</string> </map> - <key>nosound</key> + <key>nopreload</key> <map> <key>map-to</key> - <string>NoAudio</string> + <string>NoPreload</string> </map> <key>noprobe</key> @@ -186,151 +230,134 @@ <string>NoQuickTime</string> </map> - <key>nopreload</key> + <key>nosound</key> <map> <key>map-to</key> - <string>NoPreload</string> + <string>NoAudio</string> </map> - <key>purge</key> + <key>no-verify-ssl-cert</key> <map> - <key>desc</key> - <string>Delete files in the cache.</string> <key>map-to</key> - <string>PurgeCacheOnNextStartup</string> + <string>NoVerifySSLCert</string> </map> - <key>noinvlib</key> + <key>novoice</key> <map> <key>desc</key> - <string>Do not request the inventory library.</string> + <string>Disable voice.</string> <key>map-to</key> - <string>NoInventoryLibrary</string> + <string>CmdLineDisableVoice</string> </map> - <key>logfile</key> + <key>outbw</key> <map> <key>count</key> <integer>1</integer> <key>map-to</key> - <string>UserLogFile</string> + <string>OutBandwidth</string> </map> - <key>graphicslevel</key> + <key>port</key> <map> - <key>desc</key> - <string>Set the detail level. -0 - low, 1 - medium, 2 - high, 3 - ultra</string> <key>count</key> <integer>1</integer> + <key>map-to</key> + <string>UserConnectionPort</string> </map> - <key>setdefault</key> + <key>purge</key> <map> <key>desc</key> - <string>specify the value of a particular configuration variable which can be overridden by settings.xml.</string> - <key>count</key> - <integer>2</integer> - <!-- Special case. Mapped to settings procedurally. --> + <string>Delete files in the cache.</string> + <key>map-to</key> + <string>PurgeCacheOnNextStartup</string> </map> - <key>set</key> + <key>qa</key> <map> <key>desc</key> - <string>specify the value of a particular configuration variable that overrides all other settings.</string> - <key>count</key> - <integer>2</integer> - <key>compose</key> - <boolean>true</boolean> - <!-- Special case. Mapped to settings procedurally. --> + <string>Activated debugging menu in Advanced Settings.</string> + <key>map-to</key> + <string>QAMode</string> </map> - <key>settings</key> + <key>quitafter</key> <map> - <key>desc</key> - <string>Specify the filename of a configuration file.</string> <key>count</key> <integer>1</integer> - <!-- Special case. Mapped to settings procedurally. --> + <key>map-to</key> + <string>QuitAfterSeconds</string> </map> - <key>sessionsettings</key> + <key>replaysession</key> <map> <key>desc</key> - <string>Specify the filename of a configuration file that contains temporary per-session configuration overrides.</string> - <key>count</key> - <integer>1</integer> - <!-- Special case. Mapped to settings procedurally. --> + <string>After login, replay last recorded session and quit.</string> + <key>map-to</key> + <string>ReplaySession</string> </map> - <key>usersessionsettings</key> + <key>rotate</key> <map> - <key>desc</key> - <string>Specify the filename of a configuration file that contains temporary per-session configuration user overrides.</string> - <key>count</key> - <integer>1</integer> - <!-- Special case. Mapped to settings procedurally. --> + <key>map-to</key> + <string>RotateRight</string> </map> - <key>login</key> + <key>safe</key> <map> <key>desc</key> - <string>3 tokens: first, last and password</string> - <key>count</key> - <integer>3</integer> + <string>Reset preferences, run in safe mode.</string> <key>map-to</key> - <string>UserLoginInfo</string> + <string>SafeMode</string> </map> - <key>god</key> + <key>sessionsettings</key> <map> <key>desc</key> - <string>Log in a god if you have god access.</string> - <key>map-to</key> - <string>ConnectAsGod</string> - </map> - - <key>console</key> - <map> + <string>Specify the filename of a configuration file that contains temporary per-session configuration overrides.</string> <key>count</key> <integer>1</integer> - <key>map-to</key> - <string>ShowConsoleWindow</string> + <!-- Special case. Mapped to settings procedurally. --> </map> - <key>safe</key> + <key>set</key> <map> <key>desc</key> - <string>Reset preferences, run in safe mode.</string> - <key>map-to</key> - <string>SafeMode</string> + <string>specify the value of a particular configuration variable that overrides all other settings.</string> + <key>count</key> + <integer>2</integer> + <key>compose</key> + <boolean>true</boolean> + <!-- Special case. Mapped to settings procedurally. --> </map> - <key>multiple</key> + <key>setdefault</key> <map> <key>desc</key> - <string>Allow multiple viewers.</string> - <key>map-to</key> - <string>AllowMultipleViewers</string> + <string>specify the value of a particular configuration variable which can be overridden by settings.xml.</string> + <key>count</key> + <integer>2</integer> + <!-- Special case. Mapped to settings procedurally. --> </map> - <key>novoice</key> + <key>settings</key> <map> <key>desc</key> - <string>Disable voice.</string> - <key>map-to</key> - <string>CmdLineDisableVoice</string> + <string>Specify the filename of a configuration file.</string> + <key>count</key> + <integer>1</integer> + <!-- Special case. Mapped to settings procedurally. --> </map> - <key>url</key> + <key>skin</key> <map> <key>desc</key> - <string>Startup location</string> + <string>ui/branding skin folder to use</string> <key>count</key> <integer>1</integer> - <key>last_option</key> - <boolean>true</boolean> - <!-- Special case. Not mapped to a setting. --> + <key>map-to</key> + <string>SkinCurrent</string> </map> <key>slurl</key> @@ -346,69 +373,24 @@ <!-- Special case. Not mapped to a setting. --> </map> - <key>ignorepixeldepth</key> - <map> - <key>desc</key> - <string>Ignore pixel depth settings.</string> - <key>map-to</key> - <string>IgnorePixelDepth</string> - </map> - - <key>cooperative</key> + <key>url</key> <map> <key>desc</key> - <string>Yield some idle time to local host.</string> - <key>count</key> - <integer>1</integer> - <key>map-to</key> - <string>YieldTime</string> - </map> - - <key>no-verify-ssl-cert</key> - <map> - <key>map-to</key> - <string>NoVerifySSLCert</string> - </map> - - <key>channel</key> - <map> + <string>Startup location</string> <key>count</key> <integer>1</integer> + <key>last_option</key> + <boolean>true</boolean> <!-- Special case. Not mapped to a setting. --> </map> - <key>loginpage</key> + <key>usersessionsettings</key> <map> <key>desc</key> - <string>Login authentication page to use.</string> + <string>Specify the filename of a configuration file that contains temporary per-session configuration user overrides.</string> <key>count</key> <integer>1</integer> - <key>map-to</key> - <string>LoginPage</string> - </map> - - <key>qa</key> - <map> - <key>desc</key> - <string>Activated debugging menu in Advanced Settings.</string> - <key>map-to</key> - <string>QAMode</string> - </map> - - <key>crashonstartup</key> - <map> - <key>desc</key> - <string>Crashes on startup. For QA use.</string> - <key>map-to</key> - <string>CrashOnStartup</string> - </map> - - <key>disablecrashlogger</key> - <map> - <key>desc</key> - <string>Disables the crash logger and lets the OS handle crashes</string> - <key>map-to</key> - <string>DisableCrashLogger</string> + <!-- Special case. Mapped to settings procedurally. --> </map> </map> </llsd> diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index a44b895f7b..4659673333 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -37,18 +37,21 @@ tooltip_ref="Command_Build_Tooltip" execute_function="Build.Toggle" execute_parameters="build" + is_enabled_function="Build.Enabled" + is_enabled_parameters="build" is_running_function="Floater.IsOpen" is_running_parameters="build" /> <command name="chat" available_in_toybox="true" + is_flashing_allowed="true" icon="Command_Chat_Icon" label_ref="Command_Chat_Label" - tooltip_ref="Command_Chat_Tooltip" + tooltip_ref="Command_Conversations_Tooltip" execute_function="Floater.ToggleOrBringToFront" - execute_parameters="chat_bar" + execute_parameters="im_container" is_running_function="Floater.IsOpen" - is_running_parameters="chat_bar" + is_running_parameters="im_container" /> <command name="compass" available_in_toybox="false" @@ -135,6 +138,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" @@ -227,14 +240,4 @@ is_running_function="Floater.IsOpen" is_running_parameters="camera" /> - <command name="voice" - available_in_toybox="true" - icon="Command_Voice_Icon" - label_ref="Command_Voice_Label" - tooltip_ref="Command_Voice_Tooltip" - execute_function="Floater.ToggleOrBringToFront" - execute_parameters="voice_controls" - is_running_function="Floater.IsOpen" - is_running_parameters="voice_controls" - /> </commands> diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index 82b43432eb..6120f22ba4 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -91,6 +91,7 @@ PERMISSION_CHANGE_LINKS Passed to llRequestPermissions library function to req # PERMISSION_CHANGE_PERMISSIONS Passed to llRequestPermissions library function to request permission to change permissions PERMISSION_TRACK_CAMERA Passed to llRequestPermissions library function to request permission to track agent's camera PERMISSION_CONTROL_CAMERA Passed to llRequestPermissions library function to request permission to change agent's camera +PERMISSION_TELEPORT Passed to llRequestPermissions library function to request permission to teleport agent DEBUG_CHANNEL Chat channel reserved for debug and error messages from scripts PUBLIC_CHANNEL Chat channel that broadcasts to all nearby users @@ -558,6 +559,98 @@ STATUS_NOT_SUPPORTED Feature not supported STATUS_INTERNAL_ERROR An internal error occurred STATUS_WHITELIST_FAILED URL failed to pass whitelist +PROFILE_NONE Disables profiling +PROFILE_SCRIPT_MEMORY Enables memory profiling + +RC_DATA_FLAGS TODO: add documentation +RC_DETECT_PHANTOM TODO: add documentation +RC_GET_LINK_NUM TODO: add documentation +RC_GET_NORMAL TODO: add documentation +RC_GET_ROOT_KEY TODO: add documentation +RC_MAX_HITS TODO: add documentation +RC_REJECT_TYPES Optional parameter set in llCastRay() to reject hit against certain object types. +RC_REJECT_AGENTS Bit mask for RC_REJECT_TYPES, rejects hits against avatars. +RC_REJECT_PHYSICAL Bit mask for RC_REJECT_TYPES, rejects hits against moving objects. +RC_REJECT_NONPHYSICAL Bit mask for RC_REJECT_TYPES, rejects hits against non-moving objects. +RC_REJECT_LAND Bit mask for RC_REJECT_TYPES, rejects hits against the terrian. + +RCERR_CAST_TIME_EXCEEDED TODO: add documentation +RCERR_SIM_PERF_LOW TODO: add documentation +RCERR_UNKNOWN TODO: add documentation + +ESTATE_ACCESS_ALLOWED_AGENT_ADD TODO: add documentation +ESTATE_ACCESS_ALLOWED_AGENT_REMOVE TODO: add documentation +ESTATE_ACCESS_ALLOWED_GROUP_ADD TODO: add documentation +ESTATE_ACCESS_ALLOWED_GROUP_REMOVE TODO: add documentation +ESTATE_ACCESS_BANNED_AGENT_ADD TODO: add documentation +ESTATE_ACCESS_BANNED_AGENT_REMOVE TODO: add documentation + +DENSITY TODO: add documentation +FRICTION TODO: add documentation +RESTITUTION TODO: add documentation +GRAVITY_MULTIPLIER TODO: add documentation + +KFM_COMMAND TODO: add documentation +KFM_CMD_PLAY TODO: add documentation +KFM_CMD_STOP TODO: add documentation +KFM_CMD_PAUSE TODO: add documentation +KFM_CMD_SET_MODE TODO: add documentation +KFM_MODE TODO: add documentation +KFM_FORWARD TODO: add documentation +KFM_LOOP TODO: add documentation +KFM_PING_PONG TODO: add documentation +KFM_REVERSE TODO: add documentation +KFM_DATA TODO: add documentation +KFM_ROTATION TODO: add documentation +KFM_TRANSLATION TODO: add documentation + +CHARACTER_CMD_STOP TODO: add documentation +CHARACTER_CMD_JUMP TODO: add documentation + +CHARACTER_DESIRED_SPEED TODO: add documentation +CHARACTER_RADIUS TODO: add documentation +CHARACTER_LENGTH TODO: add documentation +CHARACTER_ORIENTATION TODO: add documentation +CHARACTER_AVOIDANCE_MODE TODO: add documentation +PURSUIT_OFFSET TODO: add documentation +REQUIRE_LINE_OF_SIGHT TODO: add documentation +PURSUIT_FUZZ_FACTOR TODO: add documentation +PURSUIT_INTERCEPT TODO: add documentation +FORCE_DIRECT_PATH TODO: add documentation +VERTICAL TODO: add documentation +HORIZONTAL TODO: add documentation +AVOID_CHARACTERS TODO: add documentation +AVOID_DYNAMIC_OBSTACLES TODO: add documentation + +PU_EVADE_HIDDEN Triggered when an llEvade character thinks it has hidden from its pursuer. +PU_EVADE_SPOTTED Triggered when an llEvade character switches from hiding to running +PU_FAILURE_INVALID_GOAL Goal is not on the navigation-mesh and cannot be reached. +PU_FAILURE_INVALID_START Character cannot navigate from the current location - e.g., the character is off the navmesh or too high above it. +PU_FAILURE_NO_VALID_DESTINATION There's no good place for the character to go - e.g., it is patrolling and all the patrol points are now unreachable. +PU_FAILURE_OTHER Unknown failure +PU_FAILURE_TARGET_GONE Target (for llPursue or llEvade) can no longer be tracked - e.g., it left the region or is an avatar that is now more than about 30m outside the region. +PU_FAILURE_UNREACHABLE Goal is no longer reachable for some reason - e.g., an obstacle blocks the path. +PU_GOAL_REACHED Character has reached the goal and will stop or choose a new goal (if wandering). +PU_SLOWDOWN_DISTANCE_REACHED Character is near current goal. + +CHARACTER_TYPE TODO: add documentation +CHARACTER_TYPE_A TODO: add documentation +CHARACTER_TYPE_B TODO: add documentation +CHARACTER_TYPE_C TODO: add documentation +CHARACTER_TYPE_D TODO: add documentation +CHARACTER_TYPE_NONE TODO: add documentation + +TRAVERSAL_TYPE TODO: add documentation +TRAVERSAL_TYPE_SLOW TODO: add documentation +TRAVERSAL_TYPE_FAST TODO: add documentation +TRAVERSAL_TYPE_NONE TODO: add documentation + +CHARACTER_MAX_ACCEL TODO: add documentation +CHARACTER_MAX_DECEL TODO: add documentation +CHARACTER_MAX_ANGULAR_SPEED TODO: add documentation +CHARACTER_MAX_ANGULAR_ACCEL TODO: add documentation +CHARACTER_TURN_SPEED_MULTIPLIER TODO: add documentation + # string constants [word .1, .3, .5] NULL_KEY Indicates an empty key diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index a76eb3cd37..92a241857e 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -20,7 +20,7 @@ <key>tags</key> <array> <string>AppInit</string> - <string>Capabilities</string> + <string>Capabilities</string> <string>SystemInfo</string> <string>TextureCache</string> <string>AppCache</string> @@ -42,10 +42,12 @@ </array> <key>tags</key> <array> - <!-- sample entry for debugging a specific item --> -<!-- <string>Voice</string> --> + <!-- sample entry for debugging specific items + <string>Avatar</string> + <string>Voice</string> + --> </array> </map> - </array> + </array> </map> </llsd> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6c2ff61274..e216c7865d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2,6 +2,28 @@ <llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="llsd.xsd"> <map> + <key>IMShowTime</key> + <map> + <key>Comment</key> + <string>Enable(disable) timestamp showing in the chat.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>IMShowNamesForP2PConv</key> + <map> + <key>Comment</key> + <string>Enable(disable) showing of a names in the chat.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>CrashHostUrl</key> <map> <key>Comment</key> @@ -47,7 +69,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>0.95</real> + <real>1</real> </map> <key>AdvanceSnapshot</key> <map> @@ -148,7 +170,7 @@ <key>Value</key> <integer>1</integer> </map> - <key>ApplyTextureImmediately</key> + <key>TextureLivePreview</key> <map> <key>Comment</key> <string>Preview selections in texture picker immediately</string> @@ -335,17 +357,17 @@ <key>Value</key> <integer>1</integer> </map> - <key>AuditTexture</key> - <map> - <key>Comment</key> - <string>Enable texture auditting.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> + <key>AutoReplace</key> + <map> + <key>Comment</key> + <string>Replaces keywords with a configured word or phrase</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>AutoAcceptNewInventory</key> <map> <key>Comment</key> @@ -621,6 +643,28 @@ <key>Value</key> <string>http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/[GRID_LOWERCASE]/avatars.html</string> </map> + <key>AvatarRotateThresholdSlow</key> + <map> + <key>Comment</key> + <string>Angle between avatar facing and camera facing at which avatar turns to face same direction as camera, when moving slowly (degrees)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>60</integer> + </map> + <key>AvatarRotateThresholdFast</key> + <map> + <key>Comment</key> + <string>Angle between avatar facing and camera facing at which avatar turns to face same direction as camera, when moving fast (degrees)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>2</integer> + </map> <key>AvatarBakedTextureUploadTimeout</key> <map> <key>Comment</key> @@ -1150,6 +1194,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> @@ -1529,6 +1584,28 @@ <key>Value</key> <integer>0</integer> </map> + <key>ChatLoadGroupMaxMembers</key> + <map> + <key>Comment</key> + <string>Max number of active members we'll show up for an unresponsive group</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <real>100</real> + </map> + <key>ChatLoadGroupTimeout</key> + <map> + <key>Comment</key> + <string>Time we give the server to send group participants before we hit the server for group info (seconds)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>10.0</real> + </map> <key>ChatOnlineNotification</key> <map> <key>Comment</key> @@ -1562,49 +1639,93 @@ <key>Value</key> <integer>1</integer> </map> - <key>ChatVisible</key> + <key>CheesyBeacon</key> <map> <key>Comment</key> - <string>Chat bar is visible</string> + <string>Enable cheesy beacon effects</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <integer>0</integer> </map> - <key>ChatWindow</key> + <key>ClientSettingsFile</key> <map> <key>Comment</key> - <string>Show chat in multiple windows(by default) or in one multi-tabbed window(requires restart)</string> + <string>Client settings file name (per install).</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string /> + </map> + <key>ContextConeInAlpha</key> + <map> + <key>Comment</key> + <string>Cone In Alpha</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.0</real> + </map> + <key>ContextConeOutAlpha</key> + <map> + <key>Comment</key> + <string>Cone Out Alpha</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>1.0</real> + </map> + <key>ContextConeFadeTime</key> + <map> + <key>Comment</key> + <string>Cone Fade Time</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>.08</real> + </map> + <key>ConversationHistoryPageSize</key> + <map> + <key>Comment</key> + <string>Chat history of conversation opened from call log is displayed by pages. So this is number of entries per page.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>S32</string> <key>Value</key> - <integer>0</integer> + <integer>100</integer> </map> - <key>CheesyBeacon</key> + <key>ConversationSortOrder</key> <map> <key>Comment</key> - <string>Enable cheesy beacon effects</string> + <string>Specifies sort key for conversations</string> <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>Boolean</string> + <string>U32</string> <key>Value</key> - <integer>0</integer> + <integer>131073</integer> </map> - <key>ClientSettingsFile</key> + <key>NearbyChatIsNotTornOff</key> <map> <key>Comment</key> - <string>Client settings file name (per install).</string> + <string>saving torn-off state of the nearby chat between sessions</string> <key>Persist</key> - <integer>0</integer> + <integer>1</integer> <key>Type</key> - <string>String</string> + <string>Boolean</string> <key>Value</key> - <string /> + <integer>1</integer> </map> <key>CloseChatOnReturn</key> <map> @@ -1828,6 +1949,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> @@ -1892,7 +2035,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>0</integer> + <integer>1</integer> </map> <key>DebugBeaconLineWidth</key> <map> @@ -1905,6 +2048,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>DebugHideEmptySystemFolders</key> + <map> + <key>Comment</key> + <string>Hide empty system folders when on</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>DebugInventoryFilters</key> <map> <key>Comment</key> @@ -3215,6 +3369,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>FastCacheFetchEnabled</key> + <map> + <key>Comment</key> + <string>Enable texture fast cache fetching if set</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <string>1</string> + </map> <key>FeatureManagerHTTPTable</key> <map> <key>Comment</key> @@ -3985,17 +4150,6 @@ <key>Value</key> <integer>305</integer> </map> - <key>HelpUseLocal</key> - <map> - <key>Comment</key> - <string>If set, always use this for help: skins/default/html/[LANGUAGE]/help-offline/index.html</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>HelpURLFormat</key> <map> <key>Comment</key> @@ -4170,7 +4324,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>0.65</real> + <real>0.95</real> </map> <key>InBandwidth</key> <map> @@ -4249,6 +4403,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>InventoryInboxToggleState</key> + <map> + <key>Comment</key> + <string>Stores the open/closed state of inventory Received items panel</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>InventoryLinking</key> <map> <key>Comment</key> @@ -4260,16 +4425,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> @@ -4513,6 +4711,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>LeapCommand</key> + <map> + <key>Comment</key> + <string>Zero or more command lines to run LLSD Event API Plugin programs.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>LLSD</string> + <key>Value</key> + <array /> + </map> <key>LSLFindCaseInsensitivity</key> <map> <key>Comment</key> @@ -4913,7 +5122,7 @@ <key>LoginLocation</key> <map> <key>Comment</key> - <string>Login location ('last', 'home')</string> + <string>Default Login location ('last', 'home') preference</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -5058,7 +5267,7 @@ <key>Comment</key> <string>Center the focal point of the minimap.</string> <key>Persist</key> - <integer>0</integer> + <integer>1</integer> <key>Type</key> <string>Boolean</string> <key>Value</key> @@ -5645,7 +5854,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <integer>0</integer> </map> <key>MemoryPrivatePoolSize</key> <map> @@ -6013,7 +6222,7 @@ <key>NextLoginLocation</key> <map> <key>Comment</key> - <string>Location to log into by default.</string> + <string>Location to log into for this session - set from command line or the login panel, cleared following a successfull login.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -6098,6 +6307,61 @@ <key>Value</key> <integer>305</integer> </map> + <key>NotificationConferenceIMOptions</key> + <map> + <key>Comment</key> + <string>Specifies how the UI responds to Conference IM Notifications.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>toast</string> + </map> + <key>NotificationFriendIMOptions</key> + <map> + <key>Comment</key> + <string>Specifies how the UI responds to Friend IM Notifications.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>toast</string> + </map> + <key>NotificationGroupChatOptions</key> + <map> + <key>Comment</key> + <string>Specifies how the UI responds to Group Chat Notifications.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>toast</string> + </map> + <key>NotificationNearbyChatOptions</key> + <map> + <key>Comment</key> + <string>Specifies how the UI responds to Nearby Chat Notifications.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>toast</string> + </map> + <key>NotificationNonFriendIMOptions</key> + <map> + <key>Comment</key> + <string>Specifies how the UI responds to Non Friend IM Notifications.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>toast</string> + </map> <key>NotificationToastLifeTime</key> <map> <key>Comment</key> @@ -6268,17 +6532,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>NumpadControl</key> - <map> - <key>Comment</key> - <string>How numpad keys control your avatar. 0 = Like the normal arrow keys, 1 = Numpad moves avatar when numlock is off, 2 = Numpad moves avatar regardless of numlock (use this if you have no numlock)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>0</integer> - </map> <key>ObjectCacheEnabled</key> <map> <key>Comment</key> @@ -6625,6 +6878,50 @@ <key>Value</key> <integer>1</integer> </map> + <key>PlaySoundIncomingVoiceCall</key> + <map> + <key>Comment</key> + <string>Plays a sound when have an incoming voice call.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>PlaySoundInventoryOffer</key> + <map> + <key>Comment</key> + <string>Plays a sound when have an inventory offer.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>PlaySoundNewConversation</key> + <map> + <key>Comment</key> + <string>Plays a sound when have a new conversation.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>PlaySoundTeleportOffer</key> + <map> + <key>Comment</key> + <string>Plays a sound when have a teleport offer.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>PluginAttachDebuggerToPlugins</key> <map> <key>Comment</key> @@ -7076,7 +7373,7 @@ <key>QAModeEventHostPort</key> <map> <key>Comment</key> - <string>Port on which lleventhost should listen</string> + <string>DEPRECATED: Port on which lleventhost should listen</string> <key>Persist</key> <integer>0</integer> <key>Type</key> @@ -7095,6 +7392,17 @@ <key>Value</key> <integer>-1</integer> </map> + <key>QAModeMetrics</key> + <map> + <key>Comment</key> + <string>"Enables QA features (logging, faster cycling) for metrics collector"</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>QuietSnapshotsToDisk</key> <map> <key>Comment</key> @@ -7175,7 +7483,7 @@ <key>WebContentWindowLimit</key> <map> <key>Comment</key> - <string>Maximum number of web brower windows that can be open at once in the Web content floater (0 for no limit)</string> + <string>Maximum number of web browser windows that can be open at once in the Web content floater (0 for no limit)</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -7543,6 +7851,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>RenderCompressTextures</key> + <map> + <key>Comment</key> + <string>Enable texture compression on OpenGL 3.0 and later implementations (EXPERIMENTAL, requires restart)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderPerformanceTest</key> <map> <key>Comment</key> @@ -7858,18 +8177,6 @@ <integer>0</integer> </map> - <key>RenderAnimateTrees</key> - <map> - <key>Comment</key> - <string>Use GL matrix ops to animate tree branches.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>RenderMinimumLODTriangleCount</key> <map> <key>Comment</key> @@ -7981,7 +8288,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>0</real> + <real>-0.007</real> </map> <key>RenderShadowOffsetError</key> <map> @@ -7995,6 +8302,18 @@ <real>0</real> </map> + <key>RenderDepthPrePass</key> + <map> + <key>Comment</key> + <string>EXPERIMENTAL: Prime the depth buffer with simple prim geometry before rendering with textures.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>RenderDepthOfField</key> <map> <key>Comment</key> @@ -8163,7 +8482,7 @@ <key>Type</key> <string>U32</string> <key>Value</key> - <real>128</real> + <real>512</real> </map> <key>RenderSpecularResY</key> @@ -8187,7 +8506,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>8</real> + <real>384</real> </map> <key>RenderDeferred</key> @@ -9025,28 +9344,41 @@ <key>Value</key> <integer>1</integer> </map> - <key>RenderUseShaderLOD</key> - <map> - <key>Comment</key> - <string>Whether we want to have different shaders for LOD</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>RenderUseShaderNearParticles</key> - <map> - <key>Comment</key> - <string>Whether we want to use shaders on near particles</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</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>RenderAutoHideSurfaceAreaLimit</key> + <map> + <key>Comment</key> + <string>Maximum surface area of a set of proximal objects inworld before automatically hiding geometry to prevent system overload.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>RenderVBOEnable</key> <map> <key>Comment</key> @@ -9061,7 +9393,7 @@ <key>RenderUseVAO</key> <map> <key>Comment</key> - <string>Use GL Vertex Array Objects</string> + <string>[EXPERIMENTAL] Use GL Vertex Array Objects</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -9069,7 +9401,19 @@ <key>Value</key> <integer>0</integer> </map> - <key>RenderVBOMappingDisable</key> + <key>RenderUseTransformFeedback</key> + <map> + <key>Comment</key> + <string>[EXPERIMENTAL] Use transform feedback shaders for LoD updates</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + + <key>RenderVBOMappingDisable</key> <map> <key>Comment</key> <string>Disable VBO glMapBufferARB</string> @@ -9532,18 +9876,29 @@ <key>Value</key> <integer>1</integer> </map> - <key>ShowConsoleWindow</key> - <map> - <key>Comment</key> - <string>Show log in separate OS window</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>NavBarShowCoordinates</key> + <key>ShowConsoleWindow</key> + <map> + <key>Comment</key> + <string>Show log in separate OS window</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>EnableVisualLeakDetector</key> + <map> + <key>Comment</key> + <string>EnableVisualLeakDetector</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>NavBarShowCoordinates</key> <map> <key>Comment</key> <string>Show coordinates in navigation bar</string> @@ -9678,7 +10033,7 @@ <key>ShowScriptErrorsLocation</key> <map> <key>Comment</key> - <string>Show script error in chat or window</string> + <string>Show script error in chat (0) or window (1).</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -9862,6 +10217,39 @@ <key>Value</key> <integer>2</integer> </map> + <key>BlockPeopleSortOrder</key> + <map> + <key>Comment</key> + <string>Specifies sort order for recent people (0 = by name, 1 = by type)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>CallLogSortOrder</key> + <map> + <key>Comment</key> + <string>Specifies sort order for Call Log (0 = by name, 1 = by date)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>SortFriendsFirst</key> + <map> + <key>Comment</key> + <string>Specifies whether friends will be sorted first in Call Log</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>ShowPGSearchAll</key> <map> <key>Comment</key> @@ -10379,39 +10767,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>SnapshotLocalLastResolution</key> - <map> - <key>Comment</key> - <string>Take next local snapshot at this resolution</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>SnapshotProfileLastResolution</key> - <map> - <key>Comment</key> - <string>Take next profile snapshot at this resolution</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>SnapshotPostcardLastResolution</key> - <map> - <key>Comment</key> - <string>Take next postcard snapshot at this resolution</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>0</integer> - </map> <key>SnapshotQuality</key> <map> <key>Comment</key> @@ -10445,17 +10800,6 @@ <key>Value</key> <string>http://photos.apps.staging.avatarsunited.com/viewer_config</string> </map> - <key>SnapshotTextureLastResolution</key> - <map> - <key>Comment</key> - <string>Take next texture snapshot at this resolution</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>0</integer> - </map> <key>SpeedTest</key> <map> <key>Comment</key> @@ -10599,6 +10943,39 @@ <key>Value</key> <real>20.0</real> </map> + <key>TexelPixelRatio</key> + <map> + <key>Comment</key> + <string>texel pixel ratio = texel / pixel</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>1.0</real> + </map> + <key>TextureCameraMotionThreshold</key> + <map> + <key>Comment</key> + <string>If the overall motion is lower than this value, textures will be loaded faster</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.2</real> + </map> + <key>TextureCameraMotionBoost</key> + <map> + <key>Comment</key> + <string>Progressive discard level decrement when the camera is still</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>3</integer> + </map> <key>TextureDecodeDisabled</key> <map> <key>Comment</key> @@ -10632,6 +11009,105 @@ <key>Value</key> <integer>0</integer> </map> + <key>TextureFetchConcurrency</key> + <map> + <key>Comment</key> + <string>Maximum number of HTTP connections used for texture fetches</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>TextureFetchDebuggerEnabled</key> + <map> + <key>Comment</key> + <string>Enable the texture fetching debugger if set</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>TextureFetchSource</key> + <map> + <key>Comment</key> + <string>Debug use: Source to fetch textures</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>TextureFetchUpdateHighPriority</key> + <map> + <key>Comment</key> + <string>Number of high priority textures to update per frame</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>32</integer> + </map> + <key>TextureFetchUpdateMaxMediumPriority</key> + <map> + <key>Comment</key> + <string>Maximum number of medium priority textures to update per frame</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>256</integer> + </map> + <key>TextureFetchUpdateMinMediumPriority</key> + <map> + <key>Comment</key> + <string>Minimum number of medium priority textures to update per frame</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>32</integer> + </map> + <key>TextureFetchUpdatePriorityThreshold</key> + <map> + <key>Comment</key> + <string>Threshold under which textures will be considered too low priority and skipped for update</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>0.0</integer> + </map> + <key>TextureFetchUpdateSkipLowPriority</key> + <map> + <key>Comment</key> + <string>Flag indicating if we want to skip textures with too low of a priority</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>TextureFetchUpdatePriorities</key> + <map> + <key>Comment</key> + <string>Number of priority texture to update per frame</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>32</integer> + </map> <key>TextureLoadFullRes</key> <map> <key>Comment</key> @@ -10654,6 +11130,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>TextureNewByteRange</key> + <map> + <key>Comment</key> + <string>Use the new more accurate byte range computation for j2c discard levels</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>TexturePickerShowFolders</key> <map> <key>Comment</key> @@ -10676,6 +11163,17 @@ <key>Value</key> <integer>2</integer> </map> + <key>TextureReverseByteRange</key> + <map> + <key>Comment</key> + <string>Minimal percent of the optimal byte range allowed to render a given discard level</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>50</integer> + </map> <key>ThrottleBandwidthKBPS</key> <map> <key>Comment</key> @@ -10719,7 +11217,8 @@ <string>F32</string> <key>Value</key> <real>0.1</real> - </map> <key>ToolTipFadeTime</key> + </map> + <key>ToolTipFadeTime</key> <map> <key>Comment</key> <string>Seconds over which tooltip fades away</string> @@ -11390,17 +11889,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> @@ -12070,7 +12558,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <boolean>1</boolean> </map> <key>UseFreezeFrame</key> <map> @@ -12094,6 +12582,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>RenderSynchronousOcclusion</key> + <map> + <key>Comment</key> + <string>Don't let occlusion queries get more than one frame behind (block until they complete).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>RenderDelayVBUpdate</key> <map> <key>Comment</key> @@ -12105,16 +12604,16 @@ <key>Value</key> <integer>0</integer> </map> - <key>SpeakerParticipantDefaultOrder</key> + <key>sourceid</key> <map> <key>Comment</key> - <string>Order for displaying speakers in voice controls. 0 = alphabetical. 1 = recent.</string> + <string>Identify referring agency to Linden web servers</string> <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>U32</string> + <string>String</string> <key>Value</key> - <integer>1</integer> + <string /> </map> <key>SpeakerParticipantRemoveDelay</key> <map> @@ -12127,6 +12626,28 @@ <key>Value</key> <real>10.0</real> </map> + <key>SpellCheck</key> + <map> + <key>Comment</key> + <string>Enable spellchecking on line and text editors</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>SpellCheckDictionary</key> + <map> + <key>Comment</key> + <string>Current primary and secondary dictionaries used for spell checking</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>English (United States),Second Life Glossary</string> + </map> <key>UseNewWalkRun</key> <map> <key>Comment</key> @@ -12138,6 +12659,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>UsePeopleAPI</key> + <map> + <key>Comment</key> + <string>Use the people API cap for avatar name fetching, use old legacy protocol if false. Requires restart.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>UseStartScreen</key> <map> <key>Comment</key> @@ -12632,10 +13164,10 @@ <key>Value</key> <real>50.0</real> </map> - <key>WellIconFlashCount</key> + <key>FlashCount</key> <map> <key>Comment</key> - <string>Number of flashes of IM Well and Notification Well icons after which flashing buttons stay lit up. Requires restart.</string> + <string>Number of flashes of item. Requires restart.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -12643,16 +13175,16 @@ <key>Value</key> <integer>3</integer> </map> - <key>WellIconFlashPeriod</key> + <key>FlashPeriod</key> <map> <key>Comment</key> - <string>Period at which IM Well and Notification Well icons flash (seconds). Requires restart.</string> + <string>Period at which item flash (seconds). Requires restart.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>F32</string> <key>Value</key> - <real>0.25</real> + <real>0.5</real> </map> <key>WindLightUseAtmosShaders</key> <map> @@ -12676,6 +13208,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>MinWindowHeight</key> + <map> + <key>Comment</key> + <string>SL viewer minimum window height in pixels</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>WindowHeight</key> <map> <key>Comment</key> @@ -12683,7 +13226,7 @@ <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>S32</string> + <string>U32</string> <key>Value</key> <integer>738</integer> </map> @@ -12698,6 +13241,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>MinWindowWidth</key> + <map> + <key>Comment</key> + <string>SL viewer minimum window width in pixels</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>WindowWidth</key> <map> <key>Comment</key> @@ -12705,14 +13259,14 @@ <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>S32</string> + <string>U32</string> <key>Value</key> <integer>1024</integer> </map> <key>WindowX</key> <map> <key>Comment</key> - <string>X coordinate of lower left corner of SL viewer window, relative to primary display (pixels)</string> + <string>X coordinate of upper left corner of SL viewer window, relative to upper left corner of primary display (pixels)</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -12723,7 +13277,7 @@ <key>WindowY</key> <map> <key>Comment</key> - <string>Y coordinate of lower left corner of SL viewer window, relative to primary display (pixels)</string> + <string>Y coordinate of upper left corner of SL viewer window, relative to upper left corner of primary display (pixels)</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -13402,10 +13956,10 @@ <key>Value</key> <integer>1</integer> </map> - <key>WebProfileRect</key> + <key>WebProfileFloaterRect</key> <map> <key>Comment</key> - <string>Web profile dimensions</string> + <string>Web profile floater dimensions</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -13413,8 +13967,8 @@ <key>Value</key> <array> <integer>0</integer> - <integer>650</integer> - <integer>490</integer> + <integer>680</integer> + <integer>485</integer> <integer>0</integer> </array> </map> @@ -13440,5 +13994,336 @@ <key>Value</key> <integer>0</integer> </map> + <key>PathfindingRetrieveNeighboringRegion</key> + <map> + <key>Comment</key> + <string>Download a neighboring region when visualizing a pathfinding navmesh (default val 99 means do not download neighbors).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>99</integer> + </map> + <key>PathfindingNavMeshClear</key> + <map> + <key>Comment</key> + <string>Background color when displaying pathfinding navmesh.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>0</real> + <real>0</real> + <real>0</real> + <real>1.0</real> + </array> + </map> + <key>PathfindingWalkable</key> + <map> + <key>Comment</key> + <string>Color of walkable objects when displaying pathfinding navmesh object types.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>0.45490196078431372549019607843137</real> + <real>0.93333333333333333333333333333333</real> + <real>0.38823529411764705882352941176471</real> + <real>1.0</real> + </array> + </map> + <key>PathfindingObstacle</key> + <map> + <key>Comment</key> + <string>Color of static obstacle objects when displaying pathfinding navmesh object types.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>0.0</real> + <real>0.0</real> + <real>1.0</real> + </array> + </map> + <key>PathfindingMaterial</key> + <map> + <key>Comment</key> + <string>Color of material volumes when displaying pathfinding navmesh object types.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>0.5</real> + <real>0.0</real> + <real>1.0</real> + <real>0.3</real> + </array> + </map> + <key>PathfindingExclusion</key> + <map> + <key>Comment</key> + <string>Color of exclusion volumes when displaying pathfinding navmesh object types.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>1.0</real> + <real>0.0</real> + <real>0.3</real> + </array> + </map> + <key>PathfindingConnectedEdge</key> + <map> + <key>Comment</key> + <string>Color of a connected (crossable) edge when displaying pathfinding navmesh.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>0.86</real> + <real>0.86</real> + <real>0.86</real> + <real>1.0</real> + </array> + </map> + <key>PathfindingBoundaryEdge</key> + <map> + <key>Comment</key> + <string>Color of a boundary (non-crossable) edge when displaying pathfinding navmesh.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>0.0</real> + <real>0.0</real> + <real>1.0</real> + </array> + </map> + <key>PathfindingHeatColorBase</key> + <map> + <key>Comment</key> + <string>Color of the least walkable value when displaying the pathfinding navmesh as a heatmap.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>0.0</real> + <real>0.0</real> + <real>1.0</real> + </array> + </map> + <key>PathfindingHeatColorMax</key> + <map> + <key>Comment</key> + <string>Color of the most walkable value when displaying the pathfinding navmesh as a heatmap.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + </array> + </map> + <key>PathfindingFaceColor</key> + <map> + <key>Comment</key> + <string>Color of the faces when displaying the default view of the pathfinding navmesh.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + </array> + </map> + <key>PathfindingTestPathValidEndColor</key> + <map> + <key>Comment</key> + <string>Color of the pathfinding test-pathing tool end-point when the path is valid.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>0.78</real> + <real>0.47</real> + <real>0.0</real> + <real>1.0</real> + </array> + </map> + <key>PathfindingTestPathInvalidEndColor</key> + <map> + <key>Comment</key> + <string>Color of the pathfinding test-pathing tool end-point when the path is invalid.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>0.0</real> + <real>1.0</real> + <real>1.0</real> + </array> + </map> + <key>PathfindingTestPathColor</key> + <map> + <key>Comment</key> + <string>Color of the pathfinding test-path when the path is valid.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>0.59</real> + <real>0.0</real> + <real>0.9</real> + </array> + </map> + <key>PathfindingAmbiance</key> + <map> + <key>Comment</key> + <string>Ambiance of lit pathfinding navmesh displays.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.5</real> + </map> + + <key>PathfindingXRayTint</key> + <map> + <key>Comment</key> + <string>Amount to darken/lighten x-ray lines in pathfinding display.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.8</real> + </map> + + <key>PathfindingXRayOpacity</key> + <map> + <key>Comment</key> + <string>Opacity of xray lines in pathfinding display.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.25</real> + </map> + + <key>PathfindingXRayWireframe</key> + <map> + <key>Comment</key> + <string>Render pathfinding navmesh xray as a wireframe.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + + <key>PathfindingLineWidth</key> + <map> + <key>Comment</key> + <string>Width of volume outlines in pathfinding navmesh display.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>2.0</real> + </map> + + <key>PathfindingLineOffset</key> + <map> + <key>Comment</key> + <string>Depth offset of volume outlines in pathfinding display.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>2.3</real> + </map> + + <key>PathfindingWaterColor</key> + <map> + <key>Comment</key> + <string>Color of water plane when displaying pathfinding navmesh.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>0.0</real> + <real>0.0</real> + <real>1.0</real> + <real>1.0</real> + </array> + </map> + + <key>HideUIControls</key> + <map> + <key>Comment</key> + <string>Hide all menu items and buttons</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + + <key>SimulateFBOFailure</key> + <map> + <key>Comment</key> + <string>[DEBUG] Make allocateScreenBuffer return false. Used to test error handling.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> </map> </llsd> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 8cdd8ed838..363713f2f4 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -1,9 +1,9 @@ <llsd> <map> - <key>BusyResponseChanged</key> + <key>DoNotDisturbResponseChanged</key> <map> <key>Comment</key> - <string>Does user's busy mode message differ from default?</string> + <string>Does user's do not disturb mode message differ from default?</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -11,17 +11,72 @@ <key>Value</key> <integer>0</integer> </map> - <key>BusyModeResponse</key> + <key>DoNotDisturbModeResponse</key> <map> <key>Comment</key> - <string>Auto response to instant messages while in busy mode.</string> + <string>Auto response to instant messages while in do not disturb mode.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>String</string> <key>Value</key> - <string>The Resident you messaged is in 'busy mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing.</string> + <string>This resident has turned on 'Do Not Disturb' and will see your message later.</string> </map> + <key>ConversationsExpandMessagePaneFirst</key> + <map> + <key>Comment</key> + <string>Expand either messages or conversations list pane from Conversations compact mode.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ConversationsListPaneCollapsed</key> + <map> + <key>Comment</key> + <string>Stores the expanded/collapsed state of the conversations list pane in Conversations floater.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>ConversationsListPaneWidth</key> + <map> + <key>Comment</key> + <string>Conversations floater list pane width.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>205</integer> + </map> + <key>ConversationsMessagePaneCollapsed</key> + <map> + <key>Comment</key> + <string>Stores the expanded/collapsed state of Conversations floater message pane.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>ConversationsMessagePaneWidth</key> + <map> + <key>Comment</key> + <string>Conversations floater message pane width.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>412</integer> + </map> <key>InstantMessageLogPath</key> <map> <key>Comment</key> @@ -33,6 +88,28 @@ <key>Value</key> <string /> </map> + <key>InventoryInboxHeight</key> + <map> + <key>Comment</key> + <string>Inventory inbox panel height in Inventory floater.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>200</integer> + </map> + <key>InventoryInboxToggleState</key> + <map> + <key>Comment</key> + <string>Stores the open/closed state of inventory Received Items panel.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>DisplayDestinationsOnInitialRun</key> <map> <key>Comment</key> @@ -99,17 +176,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>LogInstantMessages</key> - <map> - <key>Comment</key> - <string>Log Instant Messages</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>LogShowHistory</key> <map> <key>Comment</key> @@ -193,7 +259,29 @@ <key>Value</key> <integer>0</integer> </map> - <key>ShowFavoritesOnLogin</key> + <key>TranslatingEnabled</key> + <map> + <key>Comment</key> + <string>Translation prefs are set</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>KeepConversationLogTranscripts</key> + <map> + <key>Comment</key> + <string>Keep a conversation log and transcripts</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>2</integer> + </map> + <key>ShowFavoritesOnLogin</key> <map> <key>Comment</key> <string>Determines whether favorites of last logged in user will be saved on exit from viewer and shown on login screen</string> diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl index 3e4d438ed3..7a35905280 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -34,5 +36,5 @@ uniform sampler2D diffuseMap; void main() { - gl_FragColor = vec4(vertex_color.rgb, texture2D(diffuseMap, vary_texcoord0.xy).a); + frag_color = vec4(vertex_color.rgb, texture2D(diffuseMap, vary_texcoord0.xy).a); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 4cca287356..dd87ddb330 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -26,15 +26,15 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect depthMap; vec4 diffuseLookup(vec2 texcoord); -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; uniform vec2 screen_res; vec3 atmosLighting(vec3 light); @@ -51,19 +51,6 @@ VARYING vec2 vary_texcoord0; uniform mat4 inv_proj; -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - void main() { vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; @@ -82,6 +69,6 @@ void main() color.rgb += diff.rgb * vary_pointlight_col.rgb; - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl index 8641827777..beb3290187 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl @@ -26,15 +26,15 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect depthMap; uniform sampler2D diffuseMap; -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; uniform vec2 screen_res; vec3 atmosLighting(vec3 light); @@ -81,9 +81,9 @@ void main() color.rgb += diff.rgb * vary_pointlight_col.rgb; - gl_FragColor = color; - //gl_FragColor = vec4(1,0,1,1); - //gl_FragColor = vec4(1,0,1,1)*shadow; + frag_color = color; + //frag_color = vec4(1,0,1,1); + //frag_color = vec4(1,0,1,1)*shadow; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl index c13ea702db..1113a9845b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl @@ -26,14 +26,16 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif +uniform float minimum_alpha; + uniform sampler2DRect depthMap; uniform sampler2D diffuseMap; -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; uniform vec2 screen_res; vec3 atmosLighting(vec3 light); @@ -70,15 +72,21 @@ void main() vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy); + if (diff.a < minimum_alpha) + { + discard; + } + vec4 col = vec4(vary_ambient + vary_directional.rgb, 1.0); vec4 color = diff * col; + color.rgb = atmosLighting(color.rgb); color.rgb = scaleSoftClip(color.rgb); color.rgb += diff.rgb * vary_pointlight_col.rgb; - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl index b09441f7eb..5a0e8ff684 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,13 +37,10 @@ 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; VARYING vec3 vary_directional; -VARYING vec3 vary_normal; VARYING vec3 vary_fragcoord; VARYING vec3 vary_pointlight_col; VARYING vec4 vertex_color; @@ -58,23 +54,29 @@ uniform vec3 light_direction[8]; uniform vec3 light_attenuation[8]; uniform vec3 light_diffuse[8]; +float calcDirectionalLight(vec3 n, vec3 l) +{ + float a = max(dot(n,l),0.0); + return a; +} + float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) { //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. @@ -82,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; @@ -107,8 +109,7 @@ void main() gl_Position = frag_pos; vary_position = pos.xyz; - vary_normal = norm; - + calcAtmospherics(pos.xyz); vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a); diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 93b1a114db..cf38a2f4f7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -48,7 +48,6 @@ VARYING vec3 vary_ambient; VARYING vec3 vary_directional; VARYING vec3 vary_fragcoord; VARYING vec3 vary_position; -VARYING vec3 vary_light; VARYING vec3 vary_pointlight_col; VARYING vec4 vertex_color; @@ -64,23 +63,29 @@ uniform vec3 light_direction[8]; uniform vec3 light_attenuation[8]; uniform vec3 light_diffuse[8]; +float calcDirectionalLight(vec3 n, vec3 l) +{ + float a = max(dot(n,l),0.0); + return a; +} + float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) { //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. @@ -88,7 +93,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,14 +128,11 @@ 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 col.rgb = atmosAmbient(vec3(0.)); - vary_light = light_position[0].xyz; - vary_ambient = col.rgb*diffuse_color.rgb; vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a))); diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl index 402f681631..22c9a4d14e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl @@ -23,17 +23,17 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2D diffuseMap; -VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; void main() { - //gl_FragColor = vec4(1,1,1,vertex_color.a * texture2D(diffuseMap, vary_texcoord0.xy).a); - gl_FragColor = vec4(1,1,1,1); + frag_color = vec4(1,1,1,1); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl index ded6cced27..81961d7746 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl @@ -27,11 +27,8 @@ uniform mat4 modelview_matrix; uniform mat4 texture_matrix0; ATTRIBUTE vec3 position; -ATTRIBUTE vec4 diffuse_color; ATTRIBUTE vec2 texcoord0; -VARYING vec4 vertex_color; - mat4 getObjectSkinnedTransform(); void main() @@ -42,8 +39,6 @@ void main() mat = modelview_matrix * mat; vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; - vertex_color = diffuse_color; - vec4 p = projection_matrix * vec4(pos, 1.0); p.z = max(p.z, -p.w+0.01); gl_Position = p; diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl new file mode 100644 index 0000000000..5f395801e5 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl @@ -0,0 +1,148 @@ +/** + * @file avatarAlphaNoColorV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +uniform mat4 projection_matrix; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec3 normal; +ATTRIBUTE vec2 texcoord0; + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +mat4 getSkinnedTransform(); +void calcAtmospherics(vec3 inPositionEye); + +float calcDirectionalLight(vec3 n, vec3 l); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); +vec3 scaleUpLight(vec3 light); + +VARYING vec3 vary_position; +VARYING vec3 vary_ambient; +VARYING vec3 vary_directional; +VARYING vec3 vary_fragcoord; +VARYING vec3 vary_pointlight_col; +VARYING vec2 vary_texcoord0; + + +uniform float near_clip; + +uniform vec4 color; + +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8]; +uniform vec3 light_diffuse[8]; + +float calcDirectionalLight(vec3 n, vec3 l) +{ + float a = max(dot(n,l),0.0); + return a; +} + +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = dot(lv,lv); + + float da = 0.0; + + if (d > 0.0 && la > 0.0 && fa > 0.0) + { + //normalize light vector + lv = normalize(lv); + + //distance attenuation + float dist2 = d/la; + da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + + //angular attenuation + da *= max(dot(n, lv), 0.0); + } + + return da; +} + +void main() +{ + vary_texcoord0 = texcoord0; + + vec4 pos; + vec3 norm; + + mat4 trans = getSkinnedTransform(); + vec4 pos_in = vec4(position.xyz, 1.0); + pos.x = dot(trans[0], pos_in); + pos.y = dot(trans[1], pos_in); + pos.z = dot(trans[2], pos_in); + pos.w = 1.0; + + norm.x = dot(trans[0].xyz, normal); + norm.y = dot(trans[1].xyz, normal); + norm.z = dot(trans[2].xyz, normal); + norm = normalize(norm); + + vec4 frag_pos = projection_matrix * pos; + gl_Position = frag_pos; + + vary_position = pos.xyz; + + calcAtmospherics(pos.xyz); + + vec4 col = vec4(0.0, 0.0, 0.0, 1.0); + + // Collect normal lights + col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z); + col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z); + col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z); + col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z); + col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z); + 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*color.rgb; + + col.rgb = vec3(0,0,0); + + // Add windlight lights + col.rgb = atmosAmbient(vec3(0.)); + + vary_ambient = col.rgb*color.rgb; + vary_directional = color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), 0.0)); + + col.rgb = col.rgb * color.rgb; + + vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip); +} + + diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl index d7b90978ba..d6149fcc32 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl @@ -59,23 +59,29 @@ uniform vec3 light_direction[8]; uniform vec3 light_attenuation[8]; uniform vec3 light_diffuse[8]; +float calcDirectionalLight(vec3 n, vec3 l) +{ + float a = max(dot(n,l),0.0); + return a; +} + float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) { //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. @@ -83,7 +89,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/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 9a3b2e3e8a..bfd9b9b3eb 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif uniform sampler2D diffuseMap; @@ -41,9 +43,9 @@ void main() discard; } - gl_FragData[0] = vec4(diff.rgb, 0.0); - gl_FragData[1] = vec4(0,0,0,0); + frag_data[0] = vec4(diff.rgb, 0.0); + frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl index 558a88009a..3686f2f647 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2D diffuseMap; @@ -33,7 +35,7 @@ VARYING vec4 post_pos; void main() { - gl_FragColor = vec4(1,1,1,1); + frag_color = vec4(1,1,1,1); gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index 60d4dae99f..f400eb7a5b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect depthMap; @@ -111,6 +113,6 @@ void main() col /= defined_weight.xyxx; col.y *= col.y; - gl_FragColor = col; + frag_color = col; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 6cc5f23aca..23c4ea2fff 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif uniform sampler2D diffuseMap; @@ -46,9 +48,9 @@ void main() dot(norm,vary_mat1), dot(norm,vary_mat2)); - gl_FragData[0] = vec4(col, 0.0); - gl_FragData[1] = vertex_color.aaaa; // spec - //gl_FragData[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested + frag_data[0] = vec4(col, 0.0); + frag_data[1] = vertex_color.aaaa; // spec + //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested vec3 nvn = normalize(tnorm); - gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl index 6c205074b4..8ba75010a2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl @@ -30,7 +30,7 @@ ATTRIBUTE vec3 position; ATTRIBUTE vec4 diffuse_color; ATTRIBUTE vec3 normal; ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec2 texcoord2; +ATTRIBUTE vec3 binormal; VARYING vec3 vary_mat0; VARYING vec3 vary_mat1; @@ -52,7 +52,7 @@ void main() vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz); - vec3 b = normalize((mat * vec4(vec4(texcoord2,0,1).xyz+position.xyz, 1.0)).xyz-pos.xyz); + vec3 b = normalize((mat * vec4(binormal.xyz+position.xyz, 1.0)).xyz-pos.xyz); vec3 t = cross(b, n); vary_mat0 = vec3(t.x, b.x, n.x); diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl index db272cf601..1d8ca04ccd 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl @@ -25,7 +25,9 @@ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif ///////////////////////////////////////////////////////////////////////// @@ -98,8 +100,8 @@ void main() color *= 2.; /// Gamma correct for WL (soft clip effect). - gl_FragData[0] = vec4(scaleSoftClip(color.rgb), alpha1); - gl_FragData[1] = vec4(0.0,0.0,0.0,0.0); - gl_FragData[2] = vec4(0,0,1,0); + frag_data[0] = vec4(scaleSoftClip(color.rgb), alpha1); + frag_data[1] = vec4(0.0,0.0,0.0,0.0); + frag_data[2] = vec4(0,0,1,0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl index 64e094e3c5..17f425475c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl @@ -50,18 +50,18 @@ uniform vec4 sunlight_color; uniform vec4 ambient; uniform vec4 blue_horizon; uniform vec4 blue_density; -uniform vec4 haze_horizon; -uniform vec4 haze_density; +uniform float haze_horizon; +uniform float haze_density; -uniform vec4 cloud_shadow; -uniform vec4 density_multiplier; -uniform vec4 max_y; +uniform float cloud_shadow; +uniform float density_multiplier; +uniform float max_y; uniform vec4 glow; uniform vec4 cloud_color; -uniform vec4 cloud_scale; +uniform float cloud_scale; void main() { @@ -77,7 +77,7 @@ void main() // Set altitude if (P.y > 0.) { - P *= (max_y.x / P.y); + P *= (max_y / P.y); } else { @@ -99,12 +99,12 @@ void main() // Sunlight attenuation effect (hue and brightness) due to atmosphere // this is used later for sunlight modulation at various altitudes - light_atten = (blue_density * 1.0 + haze_density.x * 0.25) * (density_multiplier.x * max_y.x); + light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); // Calculate relative weights - temp1 = blue_density + haze_density.x; + temp1 = blue_density + haze_density; blue_weight = blue_density / temp1; - haze_weight = haze_density.x / temp1; + haze_weight = haze_density / temp1; // Compute sunlight from P & lightnorm (for long rays like sky) temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); @@ -112,7 +112,7 @@ void main() sunlight *= exp( - light_atten * temp2.y); // Distance - temp2.z = Plen * density_multiplier.x; + temp2.z = Plen * density_multiplier; // Transparency (-> temp1) // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati @@ -136,14 +136,14 @@ void main() // Increase ambient when there are more clouds vec4 tmpAmbient = ambient; - tmpAmbient += (1. - tmpAmbient) * cloud_shadow.x * 0.5; + tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; // Dim sunlight by cloud shadow percentage - sunlight *= (1. - cloud_shadow.x); + sunlight *= (1. - cloud_shadow); // Haze color below cloud vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient) - + (haze_horizon.r * haze_weight) * (sunlight * temp2.x + tmpAmbient) + + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient) ); // CLOUDS @@ -164,13 +164,13 @@ void main() vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1); // Make a nice cloud density based on the cloud_shadow value that was passed in. - vary_CloudDensity = 2. * (cloud_shadow.x - 0.25); + vary_CloudDensity = 2. * (cloud_shadow - 0.25); // Texture coords vary_texcoord0 = texcoord0; vary_texcoord0.xy -= 0.5; - vary_texcoord0.xy /= cloud_scale.x; + vary_texcoord0.xy /= cloud_scale; vary_texcoord0.xy += 0.5; vary_texcoord1 = vary_texcoord0; diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl index 88fe3c3dee..ccbc3c557c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect diffuseRect; @@ -57,7 +59,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 +81,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; + frag_color.rgb = diff.rgb + bloom.rgb; + frag_color.a = sc/max_cof*0.5+0.5; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl index e9989a4e48..c1fa9e4aac 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif uniform float minimum_alpha; @@ -44,9 +46,9 @@ void main() discard; } - gl_FragData[0] = vec4(col.rgb, 0.0); - gl_FragData[1] = vec4(0,0,0,0); // spec + frag_data[0] = vec4(col.rgb, 0.0); + frag_data[1] = vec4(0,0,0,0); // spec vec3 nvn = normalize(vary_normal); - gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index fdf8d72b38..4c68123fac 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif VARYING vec3 vary_normal; @@ -43,8 +45,8 @@ void main() discard; } - gl_FragData[0] = vec4(col.rgb, 0.0); - gl_FragData[1] = vec4(0,0,0,0); + frag_data[0] = vec4(col.rgb, 0.0); + frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl index bb20e2ca47..ad65c7d330 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl @@ -25,7 +25,9 @@ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif uniform float minimum_alpha; @@ -44,9 +46,9 @@ void main() discard; } - gl_FragData[0] = vec4(col.rgb, 0.0); - gl_FragData[1] = vec4(0,0,0,0); // spec + frag_data[0] = vec4(col.rgb, 0.0); + frag_data[1] = vec4(0,0,0,0); // spec vec3 nvn = normalize(vary_normal); - gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 7bde49eb86..86390bdd83 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif uniform sampler2D diffuseMap; @@ -36,10 +38,10 @@ VARYING vec2 vary_texcoord0; void main() { vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb; - gl_FragData[0] = vec4(col, 0.0); - gl_FragData[1] = vertex_color.aaaa; // spec - //gl_FragData[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested + frag_data[0] = vec4(col, 0.0); + frag_data[1] = vertex_color.aaaa; // spec + //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested vec3 nvn = normalize(vary_normal); - gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl index 75b45111e0..788b966af8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif VARYING vec3 vary_normal; @@ -35,9 +37,9 @@ void main() { vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb; - gl_FragData[0] = vec4(col, 0.0); - gl_FragData[1] = vertex_color.aaaa; // spec - //gl_FragData[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested + frag_data[0] = vec4(col, 0.0); + frag_data[1] = vertex_color.aaaa; // spec + //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested vec3 nvn = normalize(vary_normal); - gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl index 21453aefaa..a425e5062e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect diffuseRect; @@ -37,18 +39,28 @@ uniform vec2 screen_res; uniform float max_cof; uniform float res_scale; +uniform float dof_width; +uniform float dof_height; VARYING vec2 vary_fragcoord; +vec4 dofSample(sampler2DRect tex, vec2 tc) +{ + tc.x = min(tc.x, dof_width); + tc.y = min(tc.y, dof_height); + + return texture2DRect(tex, tc); +} + void main() { vec2 tc = vary_fragcoord.xy; - vec4 dof = texture2DRect(diffuseRect, vary_fragcoord.xy*res_scale); + vec4 dof = dofSample(diffuseRect, vary_fragcoord.xy*res_scale); 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 @@ -63,5 +75,5 @@ void main() diff = mix(diff, col*0.25, a); } - gl_FragColor = mix(diff, dof, a); + frag_color = mix(diff, dof, a); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl index 92f78125d8..6aa4d7b4ed 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif vec3 fullbrightAtmosTransport(vec3 light); @@ -45,6 +47,6 @@ void main() color.rgb = fullbrightScaleSoftClip(color.rgb); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 84ae2f9f10..36433a5827 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -46,6 +48,6 @@ void main() color.rgb = fullbrightScaleSoftClip(color.rgb); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl index 5af9406452..2cef8f2a5d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif #define FXAA_PC 1 @@ -341,18 +343,23 @@ A. Or use FXAA_GREEN_AS_LUMA. // 1 = API supports gather4 on alpha channel. // 0 = API does not support gather4 on alpha channel. // + #if (FXAA_GLSL_130 == 0) + #define FXAA_GATHER4_ALPHA 0 + #endif #if (FXAA_HLSL_5 == 1) #define FXAA_GATHER4_ALPHA 1 #endif - #ifdef GL_ARB_gpu_shader5 - #define FXAA_GATHER4_ALPHA 1 - #endif - #ifdef GL_NV_gpu_shader5 - #define FXAA_GATHER4_ALPHA 1 - #endif #ifndef FXAA_GATHER4_ALPHA - #define FXAA_GATHER4_ALPHA 0 - #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifndef FXAA_GATHER4_ALPHA + #define FXAA_GATHER4_ALPHA 0 + #endif + #endif #endif /*============================================================================ @@ -2086,7 +2093,6 @@ uniform sampler2D diffuseMap; uniform vec2 rcp_screen_res; uniform vec4 rcp_frame_opt; uniform vec4 rcp_frame_opt2; -uniform vec2 screen_res; VARYING vec2 vary_fragcoord; VARYING vec2 vary_tc; @@ -2113,6 +2119,6 @@ void main() //diff = texture2D(diffuseMap, vary_tc); - gl_FragColor = diff; + frag_color = diff; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl index 29ca80ae92..da1b234240 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect depthMap; @@ -184,5 +186,5 @@ void main() vec3 norm = texture2DRect(normalMap, pos_screen).xyz; norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm - gl_FragColor.xyz = giAmbient(pos, norm); + frag_color.xyz = giAmbient(pos, norm); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index a44173a2a4..bc0719cb82 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif uniform float minimum_alpha; @@ -45,7 +47,7 @@ void main() discard; } - gl_FragData[0] = vec4(col.rgb, col.a * 0.005); - gl_FragData[1] = texture2D(specularMap, vary_texcoord0.xy); - gl_FragData[2] = vec4(texture2D(normalMap, vary_texcoord0.xy).xyz, 0.0); + frag_data[0] = vec4(col.rgb, col.a * 0.005); + frag_data[1] = texture2D(specularMap, vary_texcoord0.xy); + frag_data[2] = vec4(texture2D(normalMap, vary_texcoord0.xy).xyz, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl index e014a14ad8..dcf474824d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl @@ -26,12 +26,14 @@ uniform sampler2DRect diffuseMap; #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec2 vary_fragcoord; void main() { - gl_FragColor = texture2DRect(diffuseMap, vary_fragcoord.xy); + frag_color = texture2DRect(diffuseMap, vary_fragcoord.xy); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 179c721a2f..7e79317543 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect depthMap; @@ -77,7 +79,7 @@ void main() } vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = (norm.xyz-0.5)*2.0; // unpack norm norm = normalize(norm); vec4 spec = texture2DRect(specularRect, frag.xy); vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb; @@ -126,7 +128,7 @@ void main() if (sa > 0.0) { - sa = texture2D(lightFunc,vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); + sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); sa *= noise; col += da*sa*light_col[i].rgb*spec.rgb; } @@ -141,6 +143,6 @@ void main() discard; } - gl_FragColor.rgb = out_col; - gl_FragColor.a = 0.0; + frag_color.rgb = out_col; + frag_color.a = 0.0; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index 2196d14895..bff87cb6aa 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif //class 1 -- no shadows @@ -53,8 +55,6 @@ uniform float far_clip; uniform vec3 proj_origin; //origin of projection to be used for angular attenuation uniform float sun_wash; -uniform int proj_shadow_idx; -uniform float shadow_fade; uniform vec3 center; uniform vec3 color; @@ -141,7 +141,8 @@ void main() discard; } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; + vec3 norm = texture2DRect(normalMap, frag.xy).xyz; + norm = vec3((norm.xy-0.5)*2.0, norm.z); norm = normalize(norm); float l_dist = -dot(lv, proj_n); @@ -242,6 +243,6 @@ void main() } } - gl_FragColor.rgb = col; - gl_FragColor.a = 0.0; + frag_color.rgb = col; + frag_color.a = 0.0; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl index 879942d8fa..62cfa5c316 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2D alphaMap; @@ -52,5 +54,5 @@ void main() norm *= 0.5; norm += 0.5; - gl_FragColor = vec4(norm, alpha); + frag_color = vec4(norm, alpha); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index b673d00d6e..75757b26c8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect diffuseRect; @@ -40,12 +42,13 @@ uniform sampler2DRect depthMap; uniform vec3 env_mat[3]; uniform float sun_wash; -uniform vec3 center; uniform vec3 color; uniform float falloff; uniform float size; VARYING vec4 vary_fragcoord; +VARYING vec3 trans_center; + uniform vec2 screen_res; uniform mat4 inv_proj; @@ -72,7 +75,7 @@ void main() frag.xy *= screen_res; vec3 pos = getPosition(frag.xy).xyz; - vec3 lv = center.xyz-pos; + vec3 lv = trans_center.xyz-pos; float dist2 = dot(lv,lv); dist2 /= size; if (dist2 > 1.0) @@ -81,7 +84,7 @@ void main() } vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = (norm.xyz-0.5)*2.0; // unpack norm float da = dot(norm, lv); if (da < 0.0) { @@ -107,7 +110,7 @@ void main() float sa = dot(normalize(lv-normalize(pos)),norm); if (sa > 0.0) { - sa = texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); + sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); sa *= noise; col += da*sa*color.rgb*spec.rgb; } @@ -118,6 +121,6 @@ void main() discard; } - gl_FragColor.rgb = col; - gl_FragColor.a = 0.0; + frag_color.rgb = col; + frag_color.a = 0.0; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl index cb14e6d4e8..9491421236 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl @@ -24,16 +24,22 @@ */ uniform mat4 modelview_projection_matrix; +uniform mat4 modelview_matrix; ATTRIBUTE vec3 position; +uniform vec3 center; +uniform float size; + VARYING vec4 vary_fragcoord; +VARYING vec3 trans_center; void main() { //transform vertex - vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0); + vec3 p = position*sqrt(size)+center; + vec4 pos = modelview_projection_matrix * vec4(p.xyz, 1.0); vary_fragcoord = pos; - + trans_center = (modelview_matrix*vec4(center.xyz, 1.0)).xyz; gl_Position = pos; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl index 4603d99c5e..bf362e21a4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect diffuseRect; @@ -42,7 +44,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 +59,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 +82,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,9 +120,9 @@ void main() sc -= 1.0; } } - + diff /= w; } - gl_FragColor = diff; + frag_color = diff; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl index c275434777..eb5beeef39 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect diffuseRect; @@ -40,6 +42,6 @@ void main() vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res); - gl_FragColor = diff + bloom; + frag_color = diff + bloom; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl index 0d5c8e7287..bd0cb50464 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl @@ -1,5 +1,5 @@ /** - * @file postgiV.glsl + * @file postDeferredV.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code @@ -24,17 +24,17 @@ */ uniform mat4 modelview_projection_matrix; - -ATTRIBUTE vec3 position; +ATTRIBUTE vec3 position; VARYING vec2 vary_fragcoord; + uniform vec2 screen_res; void main() { //transform vertex vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0); - gl_Position = pos; + gl_Position = pos; vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl index 84d65d5b3b..96f9628424 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl @@ -24,8 +24,10 @@ */ #ifdef DEFINE_GL_FRAGCOLOR - out vec4 gl_FragColor; - #endif +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; @@ -96,5 +98,5 @@ void main() col = col*col*blur_quad.x + col*blur_quad.y + blur_quad.z; - gl_FragColor.rgb = col; + frag_color.rgb = col; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl index 46d42d2a4a..bced4a5577 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl @@ -24,27 +24,37 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif -uniform float minimum_alpha; - uniform sampler2D diffuseMap; -VARYING vec4 post_pos; +VARYING float pos_zd2; +VARYING float pos_w; +VARYING float target_pos_x; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; void main() { - float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a; + float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a; - if (alpha < minimum_alpha) + if (alpha < 0.05) // treat as totally transparent { discard; } - gl_FragColor = vec4(1,1,1,1); + if (alpha < 0.88) // treat as semi-transparent + { + if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25) + { + discard; + } + } + + frag_color = vec4(1,1,1,1); - gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); + gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl index 6a3cba771b..c1f2d90712 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl @@ -25,24 +25,33 @@ uniform mat4 texture_matrix0; uniform mat4 modelview_projection_matrix; +uniform float shadow_target_width; ATTRIBUTE vec3 position; ATTRIBUTE vec4 diffuse_color; ATTRIBUTE vec2 texcoord0; -VARYING vec4 post_pos; +VARYING float pos_zd2; +VARYING float pos_w; +VARYING float target_pos_x; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +void passTextureIndex(); + void main() { //transform vertex - vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0); - - post_pos = pos; + vec4 pre_pos = vec4(position.xyz, 1.0); + vec4 pos = modelview_projection_matrix * pre_pos; + target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; + pos_w = pos.w; + pos_zd2 = pos.z * 0.5; gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); + passTextureIndex(); + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; vertex_color = diffuse_color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl new file mode 100644 index 0000000000..6195e2f1ec --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl @@ -0,0 +1,44 @@ +/** + * @file shadowCubeV.glsl + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; + +VARYING vec4 post_pos; + +uniform vec3 box_center; +uniform vec3 box_size; + +void main() +{ + //transform vertex + vec3 p = position*box_size+box_center; + vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0); + + post_pos = pos; + + gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl index bf75ca262e..7e55fdc12a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl @@ -24,14 +24,16 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 post_pos; void main() { - gl_FragColor = vec4(1,1,1,1); + frag_color = vec4(1,1,1,1); gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl index 96ad0aa93a..faa54a316e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif ///////////////////////////////////////////////////////////////////////// @@ -57,8 +59,8 @@ void main() color *= 2.; /// Gamma correct for WL (soft clip effect). - gl_FragData[0] = vec4(scaleSoftClip(color.rgb), 1.0); - gl_FragData[1] = vec4(0.0,0.0,0.0,0.0); - gl_FragData[2] = vec4(0,0,1,0); + frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0); + frag_data[1] = vec4(0.0,0.0,0.0,0.0); + frag_data[2] = vec4(0,0,1,0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl index 721de18e0b..7c02d31d43 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -26,7 +26,6 @@ uniform mat4 modelview_projection_matrix; ATTRIBUTE vec3 position; -ATTRIBUTE vec2 texcoord0; // SKY //////////////////////////////////////////////////////////////////////// // The vertex shader for creating the atmospheric sky @@ -34,7 +33,6 @@ ATTRIBUTE vec2 texcoord0; // Output parameters VARYING vec4 vary_HazeColor; -VARYING vec2 vary_texcoord0; // Inputs uniform vec3 camPosLocal; @@ -44,26 +42,23 @@ uniform vec4 sunlight_color; uniform vec4 ambient; uniform vec4 blue_horizon; uniform vec4 blue_density; -uniform vec4 haze_horizon; -uniform vec4 haze_density; +uniform float haze_horizon; +uniform float haze_density; -uniform vec4 cloud_shadow; -uniform vec4 density_multiplier; -uniform vec4 max_y; +uniform float cloud_shadow; +uniform float density_multiplier; +uniform float max_y; uniform vec4 glow; uniform vec4 cloud_color; -uniform vec4 cloud_scale; - void main() { // World / view / projection gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - vary_texcoord0 = texcoord0; - + // Get relative position vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0); //vec3 P = position.xyz + vec3(0,50,0); @@ -71,7 +66,7 @@ void main() // Set altitude if (P.y > 0.) { - P *= (max_y.x / P.y); + P *= (max_y / P.y); } else { @@ -93,12 +88,12 @@ void main() // Sunlight attenuation effect (hue and brightness) due to atmosphere // this is used later for sunlight modulation at various altitudes - light_atten = (blue_density * 1.0 + haze_density.x * 0.25) * (density_multiplier.x * max_y.x); + light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); // Calculate relative weights - temp1 = blue_density + haze_density.x; + temp1 = blue_density + haze_density; blue_weight = blue_density / temp1; - haze_weight = haze_density.x / temp1; + haze_weight = haze_density / temp1; // Compute sunlight from P & lightnorm (for long rays like sky) temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); @@ -106,7 +101,7 @@ void main() sunlight *= exp( - light_atten * temp2.y); // Distance - temp2.z = Plen * density_multiplier.x; + temp2.z = Plen * density_multiplier; // Transparency (-> temp1) // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati @@ -131,20 +126,20 @@ void main() // Haze color above cloud vary_HazeColor = ( blue_horizon * blue_weight * (sunlight + ambient) - + (haze_horizon.r * haze_weight) * (sunlight * temp2.x + ambient) + + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient) ); // Increase ambient when there are more clouds vec4 tmpAmbient = ambient; - tmpAmbient += (1. - tmpAmbient) * cloud_shadow.x * 0.5; + tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; // Dim sunlight by cloud shadow percentage - sunlight *= (1. - cloud_shadow.x); + sunlight *= (1. - cloud_shadow); // Haze color below cloud vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient) - + (haze_horizon.r * haze_weight) * (sunlight * temp2.x + tmpAmbient) + + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient) ); // Final atmosphere additive diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 60952ea38e..89448e2167 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect diffuseRect; @@ -35,7 +37,6 @@ uniform sampler2DRect positionMap; uniform sampler2DRect normalMap; uniform sampler2DRect lightMap; uniform sampler2DRect depthMap; -uniform sampler2D noiseMap; uniform samplerCube environmentMap; uniform sampler2D lightFunc; @@ -52,17 +53,15 @@ uniform vec4 sunlight_color; uniform vec4 ambient; uniform vec4 blue_horizon; uniform vec4 blue_density; -uniform vec4 haze_horizon; -uniform vec4 haze_density; -uniform vec4 cloud_shadow; -uniform vec4 density_multiplier; -uniform vec4 distance_multiplier; -uniform vec4 max_y; +uniform float haze_horizon; +uniform float haze_density; +uniform float cloud_shadow; +uniform float density_multiplier; +uniform float distance_multiplier; +uniform float max_y; uniform vec4 glow; uniform float scene_light_strength; -uniform vec3 env_mat[3]; -//uniform mat4 shadow_matrix[3]; -//uniform vec4 shadow_clip; +uniform mat3 env_mat; uniform mat3 ssao_effect_mat; uniform vec3 sun_dir; @@ -162,13 +161,13 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { //sunlight attenuation effect (hue and brightness) due to atmosphere //this is used later for sunlight modulation at various altitudes - light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); + light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); //I had thought blue_density and haze_density should have equal weighting, //but attenuation due to haze_density tends to seem too strong - temp1 = blue_density + vec4(haze_density.r); + temp1 = blue_density + vec4(haze_density); blue_weight = blue_density / temp1; - haze_weight = vec4(haze_density.r) / temp1; + haze_weight = vec4(haze_density) / temp1; //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) temp2.y = max(0.0, tmpLightnorm.y); @@ -176,12 +175,12 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { sunlight *= exp( - light_atten * temp2.y); // main atmospheric scattering line integral - temp2.z = Plen * density_multiplier.x; + temp2.z = Plen * density_multiplier; // Transparency (-> temp1) - // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati // compiler gets confused. - temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); + temp1 = exp(-temp1 * temp2.z * distance_multiplier); //final atmosphere attenuation factor setAtmosAttenuation(temp1.rgb); @@ -202,7 +201,7 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { temp2.x += .25; //increase ambient when there are more clouds - vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; + vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; /* decrease value and saturation (that in HSV, not HSL) for occluded areas * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html @@ -216,8 +215,8 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { //haze color setAdditiveColor( - vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) - + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) + + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x + tmpAmbient))); //brightness of surface both sunlight and ambient @@ -278,9 +277,8 @@ void main() float depth = texture2DRect(depthMap, tc.xy).r; vec3 pos = getPosition_d(tc, depth).xyz; vec3 norm = texture2DRect(normalMap, tc).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm - //vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; - + norm = (norm.xyz-0.5)*2.0; // unpack norm + float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); vec4 diffuse = texture2DRect(diffuseRect, tc); @@ -303,12 +301,17 @@ void main() // vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); float sa = dot(refnormpersp, sun_dir.xyz); - vec3 dumbshiny = vary_SunlitColor*texture2D(lightFunc, vec2(sa, spec.a)).r; + vec3 dumbshiny = vary_SunlitColor*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r); // add the two types of shiny together vec3 spec_contrib = dumbshiny * spec.rgb; - bloom = dot(spec_contrib, spec_contrib); + bloom = dot(spec_contrib, spec_contrib) / 4; col += spec_contrib; + + //add environmentmap + vec3 env_vec = env_mat * refnormpersp; + col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb, + max(spec.a-diffuse.a*2.0, 0.0)); } col = atmosLighting(col); @@ -321,7 +324,7 @@ void main() col = diffuse.rgb; } - gl_FragColor.rgb = col; + frag_color.rgb = col; - gl_FragColor.a = bloom; + frag_color.a = bloom; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index cc0f4e5b6b..cca63872de 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -24,16 +24,21 @@ */ -#extension GL_ARB_texture_rectangle : enable - #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif +//class 1 -- no shadows + +#extension GL_ARB_texture_rectangle : enable + uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; uniform sampler2D noiseMap; uniform sampler2D projectionMap; @@ -44,6 +49,7 @@ uniform vec3 proj_n; uniform float proj_focus; //distance from plane to begin blurring uniform float proj_lod; //(number of mips in proj map) uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; uniform float proj_ambiance; uniform float near_clip; uniform float far_clip; @@ -51,19 +57,66 @@ uniform float far_clip; uniform vec3 proj_origin; //origin of projection to be used for angular attenuation uniform float sun_wash; -uniform vec3 center; uniform vec3 color; uniform float falloff; uniform float size; VARYING vec4 vary_fragcoord; +VARYING vec3 trans_center; + uniform vec2 screen_res; uniform mat4 inv_proj; +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ + vec4 ret = texture2DLod(projectionMap, tc, lod); + + vec2 dist = tc-vec2(0.5); + + float det = max(1.0-lod/(proj_lod*0.5), 0.0); + + float d = dot(dist,dist); + + ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); + + return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ + vec4 ret = texture2DLod(projectionMap, tc, lod); + + vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); + + float det = min(lod/(proj_lod*0.5), 1.0); + + float d = min(dist.x, dist.y); + + float edge = 0.25*det; + + ret *= clamp(d/edge, 0.0, 1.0); + + return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ + vec4 ret = texture2DLod(projectionMap, tc, lod); + + vec2 dist = tc-vec2(0.5); + + float d = dot(dist,dist); + + ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); + + return ret; +} + + vec4 getPosition(vec2 pos_screen) { - float depth = texture2DRect(depthMap, pos_screen.xy).a; + float depth = texture2DRect(depthMap, pos_screen.xy).r; vec2 sc = pos_screen.xy*2.0; sc /= screen_res; sc -= vec2(1.0,1.0); @@ -82,16 +135,16 @@ void main() frag.xy *= screen_res; vec3 pos = getPosition(frag.xy).xyz; - vec3 lv = center.xyz-pos.xyz; + vec3 lv = trans_center.xyz-pos.xyz; float dist2 = dot(lv,lv); dist2 /= size; if (dist2 > 1.0) { discard; } - + vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = vec3((norm.xy-0.5)*2.0, norm.z); norm = normalize(norm); float l_dist = -dot(lv, proj_n); @@ -105,7 +158,11 @@ void main() proj_tc.xyz /= proj_tc.w; float fa = falloff+1.0; - float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); + if (dist_atten <= 0.0) + { + discard; + } lv = proj_origin-pos.xyz; lv = normalize(lv); @@ -123,32 +180,32 @@ void main() proj_tc.y > 0.0) { float lit = 0.0; + float amb_da = proj_ambiance; + if (da > 0.0) { float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); float lod = diff * proj_lod; - vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); vec3 lcol = color.rgb * plcol.rgb * plcol.a; lit = da * dist_atten * noise; col = lcol*lit*diff_tex; + amb_da += (da*0.5)*proj_ambiance; } - float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); - float lod = diff * proj_lod; - vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod); - //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0)); - float amb_da = proj_ambiance; - + //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); + amb_da += (da*da*0.5+0.5)*proj_ambiance; - + amb_da *= dist_atten * noise; - + amb_da = min(amb_da, 1.0-lit); - + col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; } @@ -166,24 +223,28 @@ void main() { vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; - vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; + vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); if (stc.z > 0.0) { - stc.xy /= stc.z+proj_near; - + stc.xy /= stc.w; + + float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); + + stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); + if (stc.x < 1.0 && stc.y < 1.0 && stc.x > 0.0 && stc.y > 0.0) { - vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb; } } } } - gl_FragColor.rgb = col; - gl_FragColor.a = 0.0; + frag_color.rgb = col; + frag_color.a = 0.0; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl index 03fccd2766..821058804c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif VARYING vec4 vertex_color; @@ -36,7 +38,7 @@ void main() { vec4 col = vertex_color * texture2D(diffuseMap, vary_texcoord0.xy); - gl_FragData[0] = col; - gl_FragData[1] = vec4(0,0,0,0); - gl_FragData[2] = vec4(0,0,1,0); + frag_data[0] = col; + frag_data[1] = vec4(0,0,0,0); + frag_data[2] = vec4(0,0,1,0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl index adc7c5d005..5ca817aff6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl @@ -28,10 +28,12 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif void main() { - gl_FragColor = vec4(0,0,0,0); + frag_color = vec4(0,0,0,0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/giV.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightNoFragCoordV.glsl index e5d3bb8ea6..47e9d15fbc 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/giV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightNoFragCoordV.glsl @@ -1,5 +1,5 @@ /** - * @file giV.glsl + * @file sunLightF.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code @@ -24,13 +24,8 @@ */ uniform mat4 modelview_projection_matrix; - + ATTRIBUTE vec3 position; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec2 texcoord0; - -VARYING vec4 vertex_color; -VARYING vec2 vary_fragcoord; uniform vec2 screen_res; @@ -39,10 +34,4 @@ void main() //transform vertex vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0); gl_Position = pos; - - vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; - vec4 tex = vec4(texcoord0,0,1); - tex.w = 1.0; - - vertex_color = diffuse_color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index fc5959a33c..bac74cbbef 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif //class 1 -- no shadow, SSAO only @@ -37,8 +39,6 @@ uniform sampler2D noiseMap; // Inputs -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; uniform float ssao_radius; uniform float ssao_max_radius; uniform float ssao_factor; @@ -49,9 +49,6 @@ VARYING vec2 vary_fragcoord; uniform mat4 inv_proj; uniform vec2 screen_res; -uniform float shadow_bias; -uniform float shadow_offset; - vec4 getPosition(vec2 pos_screen) { float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -126,10 +123,10 @@ void main() vec4 pos = getPosition(pos_screen); vec3 norm = texture2DRect(normalMap, pos_screen).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = (norm.xyz-0.5)*2.0; // unpack norm - gl_FragColor[0] = 1.0; - gl_FragColor[1] = calcAmbientOcclusion(pos, norm); - gl_FragColor[2] = 1.0; - gl_FragColor[3] = 1.0; + frag_color[0] = 1.0; + frag_color[1] = calcAmbientOcclusion(pos, norm); + frag_color[2] = 1.0; + frag_color[3] = 1.0; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index e014e53d25..daf1cc7ea2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif uniform sampler2D detail_0; @@ -51,9 +53,9 @@ void main() float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a; vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal ); - gl_FragData[0] = vec4(outColor.rgb, 0.0); - gl_FragData[1] = vec4(outColor.rgb*0.2, 0.2); + frag_data[0] = vec4(outColor.rgb, 0.0); + frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index ea98d6884c..da253846ef 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif uniform sampler2D diffuseMap; @@ -43,8 +45,8 @@ void main() discard; } - gl_FragData[0] = vec4(vertex_color.rgb*col.rgb, 0.0); - gl_FragData[1] = vec4(0,0,0,0); + frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0); + frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl index 20d0170535..d4d2f5f571 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform float minimum_alpha; @@ -43,7 +45,7 @@ void main() discard; } - gl_FragColor = vec4(1,1,1,1); + frag_color = vec4(1,1,1,1); gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 4c9ea24a24..3427d6db57 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragData[3]; +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData #endif vec3 scaleSoftClip(vec3 inColor); @@ -157,7 +159,7 @@ void main() //wavef = normalize(wavef); vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz; - gl_FragData[0] = vec4(color.rgb, 0.5); // diffuse - gl_FragData[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec - gl_FragData[2] = vec4(screenspacewavef.xy*0.5+0.5, screenspacewavef.z, screenspacewavef.z*0.5); // normalxyz, displace + frag_data[0] = vec4(color.rgb, 0.5); // diffuse + frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec + frag_data[2] = vec4(screenspacewavef.xyz*0.5+0.5, screenspacewavef.z*0.5); // normalxyz, displace } diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl index 9a3d792224..0f5eb288fd 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect diffuseMap; @@ -46,7 +48,7 @@ void main() float lum = smoothstep(minLuminance, minLuminance+1.0, dot(col.rgb, lumWeights ) ); float warmth = smoothstep(minLuminance, minLuminance+1.0, max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)) ); - gl_FragColor.rgb = col.rgb; - gl_FragColor.a = max(col.a, mix(lum, warmth, warmthAmount) * maxExtractAlpha); + frag_color.rgb = col.rgb; + frag_color.a = max(col.a, mix(lum, warmth, warmthAmount) * maxExtractAlpha); } diff --git a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl index 90bb84323c..c1f6af9f57 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2D diffuseMap; @@ -54,5 +56,5 @@ void main() col += kern[6] * texture2D(diffuseMap, vary_texcoord2.zw); col += kern[7] * texture2D(diffuseMap, vary_texcoord3.zw); - gl_FragColor = vec4(col.rgb * glowStrength, col.a); + frag_color = vec4(col.rgb * glowStrength, col.a); } diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl index 18f6d91804..668a710c04 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -59,6 +61,6 @@ void main() /// Add WL Components outColor.rgb = atmosLighting(outColor.rgb * vertex_color.rgb); - gl_FragColor = vec4(scaleSoftClip(outColor.rgb), 1.0); + frag_color = vec4(scaleSoftClip(outColor.rgb), 1.0); } diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl index e5c7ced52c..a956562396 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -60,6 +62,6 @@ void main() outColor.rgb = atmosLighting(outColor.rgb * vertex_color.rgb); outColor = applyWaterFog(outColor); - gl_FragColor = outColor; + frag_color = outColor; } diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl index 1fdb90f792..0d8dab0a41 100644 --- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2D diffuseMap; @@ -106,5 +108,5 @@ void main() vec4 fb = texture2D(screenTex, distort); - gl_FragColor = applyWaterFog(fb,view.xyz); + frag_color = applyWaterFog(fb,view.xyz); } diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl index 444c896d38..79bffab745 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif vec3 scaleSoftClip(vec3 inColor); @@ -135,5 +137,5 @@ void main() color.rgb = scaleSoftClip(color.rgb); color.a = spec * sunAngle2; - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl b/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl index d2f5e1987a..f520f301d9 100644 --- a/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2D diffuseMap; @@ -42,5 +44,5 @@ void main() discard; } - gl_FragColor = col; + frag_color = col; } diff --git a/indra/newview/app_settings/shaders/class1/interface/clipF.glsl b/indra/newview/app_settings/shaders/class1/interface/clipF.glsl new file mode 100644 index 0000000000..ac2bc8703b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/clipF.glsl @@ -0,0 +1,46 @@ +/** + * @file debugF.glsl + * + * $LicenseInfo:firstyear=2007&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$ + */ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform vec4 color; +uniform vec4 clip_plane; + +VARYING vec3 vary_position; + + +void main() +{ + if (dot(vary_position,clip_plane.xyz)+clip_plane.w < 0.0) + { + discard; + } + + frag_color = color; +} diff --git a/indra/newview/app_settings/shaders/class1/interface/clipV.glsl b/indra/newview/app_settings/shaders/class1/interface/clipV.glsl new file mode 100644 index 0000000000..e376b25a71 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/clipV.glsl @@ -0,0 +1,38 @@ +/** + * @file debugV.glsl + * + * $LicenseInfo:firstyear=2007&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$ + */ + +uniform mat4 modelview_projection_matrix; +uniform mat4 modelview_matrix; + +ATTRIBUTE vec3 position; + +VARYING vec3 vary_position; + +void main() +{ + vary_position = (modelview_matrix*vec4(position.xyz,1.0)).xyz; + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl b/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl index 4b481ba834..a96d04cc39 100644 --- a/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2D diffuseMap; @@ -38,5 +40,5 @@ void main() { vec4 color = vertex_color*texture2D(diffuseMap, vary_texcoord0.xy); color.a *= custom_alpha; - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/interface/debugF.glsl b/indra/newview/app_settings/shaders/class1/interface/debugF.glsl index 6bcc97ba18..67c6baddbb 100644 --- a/indra/newview/app_settings/shaders/class1/interface/debugF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/debugF.glsl @@ -24,12 +24,14 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform vec4 color; void main() { - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl index f67703b839..ed803de277 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif #extension GL_ARB_texture_rectangle : enable @@ -37,6 +39,6 @@ VARYING vec2 vary_texcoord1; void main() { - gl_FragColor = texture2D(glowMap, vary_texcoord0.xy) + + frag_color = texture2D(glowMap, vary_texcoord0.xy) + texture2DRect(screenMap, vary_texcoord1.xy); } diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl index c66a6e5b48..59520bb99f 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect diffuseRect; @@ -38,5 +40,5 @@ void main() { vec3 col = texture2DRect(diffuseRect, vary_tc*screen_res).rgb; - gl_FragColor = vec4(col.rgb, dot(col.rgb, vec3(0.299, 0.587, 0.144))); + frag_color = vec4(col.rgb, dot(col.rgb, vec3(0.299, 0.587, 0.144))); } diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl index ecbc30f05f..6cc9bbbea2 100644 --- a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform vec4 color; @@ -34,5 +36,5 @@ VARYING vec2 vary_texcoord0; void main() { - gl_FragColor = color*texture2D(diffuseMap, vary_texcoord0.xy); + frag_color = color*texture2D(diffuseMap, vary_texcoord0.xy); } diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl new file mode 100644 index 0000000000..5c479d27a9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl @@ -0,0 +1,38 @@ +/** + * @file occlusionCubeV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; + +uniform vec3 box_center; +uniform vec3 box_size; + +void main() +{ + vec3 p = position*box_size+box_center; + gl_Position = modelview_projection_matrix * vec4(p.xyz, 1.0); +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl index 85f819f4c2..db130e456c 100644 --- a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl @@ -24,10 +24,12 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif void main() { - gl_FragColor = vec4(1,1,1,1); + frag_color = vec4(1,1,1,1); } diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl index fafeb5a7b4..415181126b 100644 --- a/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2D tex0; @@ -33,5 +35,5 @@ VARYING vec2 vary_texcoord0; void main() { - gl_FragColor = texture2D(tex0, vary_texcoord0.xy); + frag_color = texture2D(tex0, vary_texcoord0.xy); } diff --git a/indra/newview/llmenucommands.h b/indra/newview/app_settings/shaders/class1/interface/pathfindingF.glsl index fa845c6f02..7379360e17 100644 --- a/indra/newview/llmenucommands.h +++ b/indra/newview/app_settings/shaders/class1/interface/pathfindingF.glsl @@ -1,10 +1,9 @@ /** - * @file llmenucommands.h - * @brief Implementations of menu commands. + * @file pathfindingF.glsl * - * $LicenseInfo:firstyear=2003&license=viewerlgpl$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2007, 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 @@ -24,14 +23,15 @@ * $/LicenseInfo$ */ -#ifndef LL_LLMENUCOMMANDS_H -#define LL_LLMENUCOMMANDS_H - -class LLUUID; +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif -void handle_mouselook(void*); -void handle_chat(void*); -void handle_return_key(void*); -void handle_slash_key(void*); +VARYING vec4 vertex_color; -#endif +void main() +{ + frag_color = vertex_color; +} diff --git a/indra/newview/app_settings/shaders/class1/interface/pathfindingNoNormalV.glsl b/indra/newview/app_settings/shaders/class1/interface/pathfindingNoNormalV.glsl new file mode 100644 index 0000000000..19fa607307 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/pathfindingNoNormalV.glsl @@ -0,0 +1,42 @@ +/** + * @file pathfindingV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec4 diffuse_color; + +VARYING vec4 vertex_color; + +uniform float tint; +uniform float alpha_scale; + +void main() +{ + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + + vertex_color = vec4(diffuse_color.rgb * tint, diffuse_color.a*alpha_scale); +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/pathfindingV.glsl b/indra/newview/app_settings/shaders/class1/interface/pathfindingV.glsl new file mode 100644 index 0000000000..91f252cf1e --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/pathfindingV.glsl @@ -0,0 +1,54 @@ +/** + * @file pathfindingV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec4 diffuse_color; +ATTRIBUTE vec3 normal; + +VARYING vec4 vertex_color; + +uniform float tint; +uniform float ambiance; +uniform float alpha_scale; + +void main() +{ + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + + vec3 l1 = vec3(-0.75, 1, 1.0)*0.5; + vec3 l2 = vec3(0.5, -0.6, 0.4)*0.25; + vec3 l3 = vec3(0.5, -0.8, 0.3)*0.5; + + float lit = max(dot(normal, l1), 0.0); + lit += max(dot(normal, l2), 0.0); + lit += max(dot(normal, l3), 0.0); + + lit = clamp(lit, ambiance, 1.0); + + vertex_color = vec4(diffuse_color.rgb * tint * lit, diffuse_color.a*alpha_scale); +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl index f790122749..67dc500493 100644 --- a/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2D tex0; @@ -36,5 +38,5 @@ void main() { float alpha = texture2D(tex0, vary_texcoord0.xy).a * vertex_color.a; - gl_FragColor = vec4(vertex_color.rgb, alpha); + frag_color = vec4(vertex_color.rgb, alpha); } diff --git a/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl b/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl index a0bb255cfa..772bb374e8 100644 --- a/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect screenMap; @@ -36,5 +38,5 @@ VARYING vec2 vary_texcoord0; void main() { - gl_FragColor = texture2DRect(screenMap, vary_texcoord0.xy) * vertex_color; + frag_color = texture2DRect(screenMap, vary_texcoord0.xy) * vertex_color; } diff --git a/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl b/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl index cdb48163dd..95679e93e7 100644 --- a/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2D tex0; @@ -35,5 +37,5 @@ VARYING vec2 vary_texcoord1; void main() { - gl_FragColor = texture2D(tex0, vary_texcoord0.xy)+texture2D(tex1, vary_texcoord1.xy); + frag_color = texture2D(tex0, vary_texcoord0.xy)+texture2D(tex1, vary_texcoord1.xy); } diff --git a/indra/newview/app_settings/shaders/class1/interface/uiF.glsl b/indra/newview/app_settings/shaders/class1/interface/uiF.glsl index 36d6e06fc5..299bfb72aa 100644 --- a/indra/newview/app_settings/shaders/class1/interface/uiF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/uiF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2D diffuseMap; @@ -34,5 +36,5 @@ VARYING vec4 vertex_color; void main() { - gl_FragColor = vertex_color*texture2D(diffuseMap, vary_texcoord0.xy); + frag_color = vertex_color*texture2D(diffuseMap, vary_texcoord0.xy); } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl index 10413bdeb0..cf29939cb2 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform float minimum_alpha; @@ -48,6 +50,6 @@ void default_lighting() color.rgb = scaleSoftClip(color.rgb); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl index 1164e5b0a6..4070d41f47 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform float minimum_alpha; @@ -50,6 +52,6 @@ void default_lighting() color.rgb = scaleSoftClip(color.rgb); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl index 735f5b3813..d6ebfcb825 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -41,6 +43,6 @@ void default_lighting() color.rgb = scaleSoftClip(color.rgb); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl index ba99c0ed71..6c34643aab 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform float minimum_alpha; @@ -48,6 +50,6 @@ void fullbright_lighting() color.rgb = fullbrightScaleSoftClip(color.rgb); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl index c3edc0bd70..2ff7f795b0 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -41,6 +43,6 @@ void fullbright_lighting() color.rgb = fullbrightScaleSoftClip(color.rgb); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl index 276fad4f44..f4477bd29a 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform float minimum_alpha; @@ -50,6 +52,6 @@ void fullbright_lighting() color.rgb = fullbrightScaleSoftClip(color.rgb); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl index 4e1e664e6b..2738ff8947 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -43,6 +45,6 @@ void fullbright_lighting() color.rgb = fullbrightScaleSoftClip(color.rgb); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl index c981e9eba2..777c8b45bb 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -50,6 +52,6 @@ void fullbright_shiny_lighting() color.a = max(color.a, vertex_color.a); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl index a4893f0359..4fa3b1d939 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -51,6 +53,6 @@ void fullbright_shiny_lighting() color.a = max(color.a, vertex_color.a); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl index c10cde98e0..58984a4263 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl @@ -23,7 +23,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -48,6 +50,6 @@ void fullbright_shiny_lighting_water() color.rgb = fullbrightScaleSoftClip(color.rgb); color.a = max(color.a, vertex_color.a); - gl_FragColor = applyWaterFog(color); + frag_color = applyWaterFog(color); } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl index e9b26087f4..a39b7205d7 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl @@ -23,7 +23,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -49,6 +51,6 @@ void fullbright_shiny_lighting_water() color.rgb = fullbrightScaleSoftClip(color.rgb); color.a = max(color.a, vertex_color.a); - gl_FragColor = applyWaterFog(color); + frag_color = applyWaterFog(color); } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl index 754b2922d9..99a6fe85fe 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform float minimum_alpha; @@ -48,6 +50,6 @@ void fullbright_lighting_water() color.rgb = fullbrightAtmosTransport(color.rgb); - gl_FragColor = applyWaterFog(color); + frag_color = applyWaterFog(color); } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl index 2547f9e750..df182168f3 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -41,6 +43,6 @@ void fullbright_lighting_water() color.rgb = fullbrightAtmosTransport(color.rgb); - gl_FragColor = applyWaterFog(color); + frag_color = applyWaterFog(color); } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl index f69b907dc7..63f92a8844 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform float minimum_alpha; @@ -48,6 +50,6 @@ void fullbright_lighting_water() color.rgb = fullbrightAtmosTransport(color.rgb); - gl_FragColor = applyWaterFog(color); + frag_color = applyWaterFog(color); } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl index aa3ef8cdd9..0e68091e7c 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -41,6 +43,6 @@ void fullbright_lighting_water() color.rgb = fullbrightAtmosTransport(color.rgb); - gl_FragColor = applyWaterFog(color); + frag_color = applyWaterFog(color); } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl index 9f1a358b53..0aca768021 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -43,6 +45,6 @@ void default_lighting() color.rgb = scaleSoftClip(color.rgb); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl index e9c27dbefd..52e3b2ad02 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -49,6 +51,6 @@ void shiny_lighting() color.rgb = scaleSoftClip(color.rgb); color.a = max(color.a, vertex_color.a); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl index 595ad74365..474d5ea496 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -50,6 +52,6 @@ void shiny_lighting() color.rgb = scaleSoftClip(color.rgb); color.a = max(color.a, vertex_color.a); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl index 68c727d62c..d2a4c47aac 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -46,6 +48,6 @@ void shiny_lighting_water() color.rgb = atmosLighting(color.rgb); color.a = max(color.a, vertex_color.a); - gl_FragColor = applyWaterFog(color); + frag_color = applyWaterFog(color); } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl index f32b9e1958..f3bd662364 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -47,6 +49,6 @@ void shiny_lighting_water() color.rgb = atmosLighting(color.rgb); color.a = max(color.a, vertex_color.a); - gl_FragColor = applyWaterFog(color); + frag_color = applyWaterFog(color); } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl index 103dd633c9..b68240ba0d 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform float minimum_alpha; @@ -46,6 +48,6 @@ void default_lighting_water() color.rgb = atmosLighting(color.rgb); - gl_FragColor = applyWaterFog(color); + frag_color = applyWaterFog(color); } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl index bef72752da..da3b20012d 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform float minimum_alpha; @@ -50,6 +52,6 @@ void default_lighting_water() color = applyWaterFog(color); - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl index e9537d1e9d..00609e93cd 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl @@ -24,8 +24,10 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; -#endif +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; @@ -39,6 +41,6 @@ void default_lighting_water() color.rgb = atmosLighting(color.rgb); - gl_FragColor = applyWaterFog(color); + frag_color = applyWaterFog(color); } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl index 8b0c25b705..13ecb7a636 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; @@ -41,6 +43,6 @@ void default_lighting_water() color.rgb = atmosLighting(color.rgb); - gl_FragColor = applyWaterFog(color); + frag_color = applyWaterFog(color); } diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl index 4b85d61aca..d55f0db530 100644 --- a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2D texture0; @@ -38,5 +40,5 @@ void main() float tex0 = texture2D(texture0, vary_texcoord0.xy).a; float tex1 = texture2D(texture1, vary_texcoord1.xy).a; - gl_FragColor = vec4(tex0+(1.0-tex1)-0.5); + frag_color = vec4(tex0+(1.0-tex1)-0.5); } diff --git a/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl b/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl index 3c6e22b295..add437d144 100644 --- a/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform float minimum_alpha; @@ -42,5 +44,5 @@ void main() discard; } - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl b/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl index a95c9e0ab9..ca29bf3143 100644 --- a/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl @@ -23,9 +23,9 @@ * $/LicenseInfo$ */ -ATTRIBUTE float texture_index; +ATTRIBUTE int texture_index; -VARYING float vary_texture_index; +VARYING_FLAT int vary_texture_index; void passTextureIndex() { diff --git a/indra/newview/app_settings/shaders/class1/objects/previewF.glsl b/indra/newview/app_settings/shaders/class1/objects/previewF.glsl new file mode 100644 index 0000000000..284da3d0ac --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/previewF.glsl @@ -0,0 +1,41 @@ +/** + * @file previewF.glsl + * + * $LicenseInfo:firstyear=2011&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$ + */ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2D diffuseMap; + +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; + +void main() +{ + vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color; + frag_color = color; +} diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl index 5dcfa87066..7f3f84398b 100644 --- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl @@ -32,12 +32,51 @@ ATTRIBUTE vec3 position; ATTRIBUTE vec3 normal; ATTRIBUTE vec2 texcoord0; +uniform vec4 color; + VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8]; +uniform vec3 light_diffuse[8]; + +//=================================================================================================== +//declare these here explicitly to separate them from atmospheric lighting elsewhere to work around +//drivers that are picky about functions being declared but not defined even if they aren't called +float calcDirectionalLight(vec3 n, vec3 l) +{ + float a = max(dot(n,l),0.0); + return a; +} + + +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float da = clamp(1.0/(la * d), 0.0, 1.0); + + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + + //angular attenuation + da *= calcDirectionalLight(n, lv); + + return da; +} +//==================================================================================================== -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); -void calcAtmospherics(vec3 inPositionEye); void main() { @@ -45,13 +84,15 @@ void main() vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0)); gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - + vec3 norm = normalize(normal_matrix * normal); - calcAtmospherics(pos.xyz); - - vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0.)); - vertex_color = color; + vec4 col = vec4(0,0,0,1); - + // Collect normal lights (need to be divided by two, as we later multiply by 2) + col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz); + col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z); + col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z); + + vertex_color = col*color; } diff --git a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl new file mode 100644 index 0000000000..44f1aa34a0 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl @@ -0,0 +1,36 @@ +/** + * @file binormalV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +uniform mat3 normal_matrix; + +ATTRIBUTE vec3 binormal; + +VARYING vec4 binormal_out; + +void main() +{ + binormal_out = vec4(normal_matrix * binormal, 0.0); +} + diff --git a/indra/newview/app_settings/shaders/class1/transform/colorV.glsl b/indra/newview/app_settings/shaders/class1/transform/colorV.glsl new file mode 100644 index 0000000000..59c4a7d895 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/transform/colorV.glsl @@ -0,0 +1,36 @@ +/** + * @file colorV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +uniform int color_in; + +ATTRIBUTE vec3 position; + +VARYING int color_out; + +void main() +{ + color_out = color_in; +} + diff --git a/indra/newview/app_settings/shaders/class1/transform/normalV.glsl b/indra/newview/app_settings/shaders/class1/transform/normalV.glsl new file mode 100644 index 0000000000..a213aa0ae8 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/transform/normalV.glsl @@ -0,0 +1,36 @@ +/** + * @file normalV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +uniform mat3 normal_matrix; + +ATTRIBUTE vec3 normal; + +VARYING vec4 normal_out; + +void main() +{ + normal_out = vec4(normalize(normal_matrix * normal), 0.0); +} + diff --git a/indra/newview/app_settings/shaders/class1/transform/positionV.glsl b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl new file mode 100644 index 0000000000..01eed18de4 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl @@ -0,0 +1,40 @@ +/** + * @file positionV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +uniform mat4 modelview_matrix; + +uniform int texture_index_in; + +ATTRIBUTE vec3 position; + +VARYING vec3 position_out; +VARYING int texture_index_out; + +void main() +{ + texture_index_out = texture_index_in; + position_out = (modelview_matrix*vec4(position, 1.0)).xyz; +} + diff --git a/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl b/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl new file mode 100644 index 0000000000..0e074f3cec --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl @@ -0,0 +1,35 @@ +/** + * @file texcoordV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + + +ATTRIBUTE vec2 texcoord0; + +VARYING vec2 texcoord_out; + +void main() +{ + texcoord_out = texcoord0; +} + diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index 8d88e93698..12706f130b 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -26,16 +26,18 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; uniform sampler2DRect depthMap; uniform mat4 shadow_matrix[6]; @@ -56,33 +58,22 @@ uniform float shadow_bias; uniform mat4 inv_proj; -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos.xyz /= pos.w; - pos.w = 1.0; - return pos; -} - -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +float pcfShadow(sampler2DShadow shadowMap, vec4 stc) { stc.xyz /= stc.w; stc.z += shadow_bias; + + stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here - float cs = shadow2DRect(shadowMap, stc.xyz).x; + float cs = shadow2D(shadowMap, stc.xyz).x; float shadow = cs; - - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs); - - return shadow/5.0; + + shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + + return shadow*0.2; } @@ -91,7 +82,7 @@ void main() vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; - float shadow = 1.0; + float shadow = 0.0; vec4 pos = vec4(vary_position, 1.0); vec4 spos = pos; @@ -100,31 +91,61 @@ void main() { vec4 lpos; - if (spos.z < -shadow_clip.z) + vec4 near_split = shadow_clip*-0.75; + vec4 far_split = shadow_clip*-1.25; + vec4 transition_domain = near_split-far_split; + float weight = 0.0; + + if (spos.z < near_split.z) { lpos = shadow_matrix[3]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap3, lpos, 1.5); + + float w = 1.0; + w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap3, lpos)*w; + weight += w; shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); } - else if (spos.z < -shadow_clip.y) + + if (spos.z < near_split.y && spos.z > far_split.z) { lpos = shadow_matrix[2]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap2, lpos, 1.5); + + float w = 1.0; + w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; + w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap2, lpos)*w; + weight += w; } - else if (spos.z < -shadow_clip.x) + + if (spos.z < near_split.x && spos.z > far_split.y) { lpos = shadow_matrix[1]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap1, lpos, 1.5); + + float w = 1.0; + w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; + w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; + shadow += pcfShadow(shadowMap1, lpos)*w; + weight += w; } - else + + if (spos.z > far_split.x) { lpos = shadow_matrix[0]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap0, lpos, 1.5); + + float w = 1.0; + w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; + + shadow += pcfShadow(shadowMap0, lpos)*w; + weight += w; } + + + shadow /= weight; + } + else + { + shadow = 1.0; } vec4 diff = diffuseLookup(vary_texcoord0.xy); @@ -138,6 +159,6 @@ void main() color.rgb += diff.rgb * vary_pointlight_col.rgb; - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl index 0df557f2aa..228dc104ac 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl @@ -26,20 +26,21 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; uniform sampler2DRect depthMap; uniform sampler2D diffuseMap; uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; uniform vec2 screen_res; -uniform vec2 shadow_res; vec3 atmosLighting(vec3 light); vec3 scaleSoftClip(vec3 light); @@ -52,6 +53,7 @@ VARYING vec3 vary_pointlight_col; VARYING vec2 vary_texcoord0; VARYING vec4 vertex_color; +uniform vec2 shadow_res; uniform float shadow_bias; uniform mat4 inv_proj; @@ -69,20 +71,22 @@ vec4 getPosition(vec2 pos_screen) return pos; } -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +float pcfShadow(sampler2DShadow shadowMap, vec4 stc) { stc.xyz /= stc.w; stc.z += shadow_bias; + + stc.x = floor(stc.x*shadow_res.x + fract(stc.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here - float cs = shadow2DRect(shadowMap, stc.xyz).x; + float cs = shadow2D(shadowMap, stc.xyz).x; float shadow = cs; - - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs); - - return shadow/5.0; + + shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + + return shadow*0.2; } @@ -91,7 +95,7 @@ void main() vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; - float shadow = 1.0; + float shadow = 0.0; vec4 pos = vec4(vary_position, 1.0); vec4 spos = pos; @@ -100,33 +104,64 @@ void main() { vec4 lpos; - if (spos.z < -shadow_clip.z) + vec4 near_split = shadow_clip*-0.75; + vec4 far_split = shadow_clip*-1.25; + vec4 transition_domain = near_split-far_split; + float weight = 0.0; + + if (spos.z < near_split.z) { lpos = shadow_matrix[3]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap3, lpos, 1.5); + + float w = 1.0; + w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap3, lpos)*w; + weight += w; shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); } - else if (spos.z < -shadow_clip.y) + + if (spos.z < near_split.y && spos.z > far_split.z) { lpos = shadow_matrix[2]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap2, lpos, 1.5); + + float w = 1.0; + w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; + w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap2, lpos)*w; + weight += w; } - else if (spos.z < -shadow_clip.x) + + if (spos.z < near_split.x && spos.z > far_split.y) { lpos = shadow_matrix[1]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap1, lpos, 1.5); + + float w = 1.0; + w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; + w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; + shadow += pcfShadow(shadowMap1, lpos)*w; + weight += w; } - else + + if (spos.z > far_split.x) { lpos = shadow_matrix[0]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap0, lpos, 1.5); + + float w = 1.0; + w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; + + shadow += pcfShadow(shadowMap0, lpos)*w; + weight += w; } + + + shadow /= weight; + } - + else + { + shadow = 1.0; + } + vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a); @@ -138,6 +173,6 @@ void main() color.rgb += diff.rgb * vary_pointlight_col.rgb; - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl index 331dbc7079..c3950a10e1 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl @@ -26,20 +26,23 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; +uniform float minimum_alpha; + +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; uniform sampler2DRect depthMap; uniform sampler2D diffuseMap; uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; uniform vec2 screen_res; -uniform vec2 shadow_res; vec3 atmosLighting(vec3 light); vec3 scaleSoftClip(vec3 light); @@ -51,6 +54,8 @@ VARYING vec3 vary_position; VARYING vec3 vary_pointlight_col; VARYING vec2 vary_texcoord0; +uniform vec2 shadow_res; + uniform float shadow_bias; uniform mat4 inv_proj; @@ -68,20 +73,22 @@ vec4 getPosition(vec2 pos_screen) return pos; } -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +float pcfShadow(sampler2DShadow shadowMap, vec4 stc) { stc.xyz /= stc.w; stc.z += shadow_bias; + + stc.x = floor(stc.x*shadow_res.x + fract(stc.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here + float cs = shadow2D(shadowMap, stc.xyz).x; - float cs = shadow2DRect(shadowMap, stc.xyz).x; float shadow = cs; - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs); - - return shadow/5.0; + shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + + return shadow*0.2; } @@ -90,44 +97,79 @@ void main() vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; - float shadow = 1.0; + float shadow = 0.0; vec4 pos = vec4(vary_position, 1.0); + vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); + + if (diff.a < minimum_alpha) + { + discard; + } + vec4 spos = pos; if (spos.z > -shadow_clip.w) { vec4 lpos; - if (spos.z < -shadow_clip.z) + vec4 near_split = shadow_clip*-0.75; + vec4 far_split = shadow_clip*-1.25; + vec4 transition_domain = near_split-far_split; + float weight = 0.0; + + if (spos.z < near_split.z) { lpos = shadow_matrix[3]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap3, lpos, 1.5); + + float w = 1.0; + w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap3, lpos)*w; + weight += w; shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); } - else if (spos.z < -shadow_clip.y) + + if (spos.z < near_split.y && spos.z > far_split.z) { lpos = shadow_matrix[2]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap2, lpos, 1.5); + + float w = 1.0; + w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; + w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap2, lpos)*w; + weight += w; } - else if (spos.z < -shadow_clip.x) + + if (spos.z < near_split.x && spos.z > far_split.y) { lpos = shadow_matrix[1]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap1, lpos, 1.5); + + float w = 1.0; + w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; + w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; + shadow += pcfShadow(shadowMap1, lpos)*w; + weight += w; } - else + + if (spos.z > far_split.x) { lpos = shadow_matrix[0]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap0, lpos, 1.5); + + float w = 1.0; + w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; + + shadow += pcfShadow(shadowMap0, lpos)*w; + weight += w; } + + + shadow /= weight; + } + else + { + shadow = 1.0; } - vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); - vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, 1.0); vec4 color = diff * col; @@ -137,6 +179,6 @@ void main() color.rgb += diff.rgb * vary_pointlight_col.rgb; - gl_FragColor = color; + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl index 5a3955ef00..9629cfe824 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl @@ -61,23 +61,29 @@ uniform vec3 light_direction[8]; uniform vec3 light_attenuation[8]; uniform vec3 light_diffuse[8]; +float calcDirectionalLight(vec3 n, vec3 l) +{ + float a = max(dot(n,l),0.0); + return a; +} + 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 +91,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..1586aab0f2 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -63,23 +63,29 @@ uniform vec3 light_direction[8]; uniform vec3 light_attenuation[8]; uniform vec3 light_diffuse[8]; +float calcDirectionalLight(vec3 n, vec3 l) +{ + float a = max(dot(n,l),0.0); + return a; +} + float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) { //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. @@ -87,7 +93,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..44aaa98b97 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl @@ -60,23 +60,29 @@ uniform vec3 light_direction[8]; uniform vec3 light_attenuation[8]; uniform vec3 light_diffuse[8]; +float calcDirectionalLight(vec3 n, vec3 l) +{ + float a = max(dot(n,l),0.0); + return a; +} + float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) { //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. @@ -84,7 +90,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/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index 14a683971a..5621e47ab7 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect diffuseRect; @@ -152,7 +154,7 @@ void main() } vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = (norm.xyz-0.5)*2.0; // unpack norm norm = normalize(norm); float l_dist = -dot(lv, proj_n); @@ -253,6 +255,6 @@ void main() } } - gl_FragColor.rgb = col; - gl_FragColor.a = 0.0; + frag_color.rgb = col; + frag_color.a = 0.0; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index eb367d4ad6..9df9d75905 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -26,7 +26,9 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif uniform sampler2DRect diffuseRect; @@ -34,7 +36,6 @@ uniform sampler2DRect specularRect; uniform sampler2DRect normalMap; uniform sampler2DRect lightMap; uniform sampler2DRect depthMap; -uniform sampler2D noiseMap; uniform samplerCube environmentMap; uniform sampler2D lightFunc; uniform vec3 gi_quad; @@ -52,15 +53,15 @@ uniform vec4 sunlight_color; uniform vec4 ambient; uniform vec4 blue_horizon; uniform vec4 blue_density; -uniform vec4 haze_horizon; -uniform vec4 haze_density; -uniform vec4 cloud_shadow; -uniform vec4 density_multiplier; -uniform vec4 distance_multiplier; -uniform vec4 max_y; +uniform float haze_horizon; +uniform float haze_density; +uniform float cloud_shadow; +uniform float density_multiplier; +uniform float distance_multiplier; +uniform float max_y; uniform vec4 glow; uniform float scene_light_strength; -uniform vec3 env_mat[3]; +uniform mat3 env_mat; uniform vec4 shadow_clip; uniform mat3 ssao_effect_mat; @@ -162,13 +163,13 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { //sunlight attenuation effect (hue and brightness) due to atmosphere //this is used later for sunlight modulation at various altitudes - light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); + light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); //I had thought blue_density and haze_density should have equal weighting, //but attenuation due to haze_density tends to seem too strong - temp1 = blue_density + vec4(haze_density.r); + temp1 = blue_density + vec4(haze_density); blue_weight = blue_density / temp1; - haze_weight = vec4(haze_density.r) / temp1; + haze_weight = vec4(haze_density) / temp1; //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) temp2.y = max(0.0, tmpLightnorm.y); @@ -176,12 +177,12 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { sunlight *= exp( - light_atten * temp2.y); // main atmospheric scattering line integral - temp2.z = Plen * density_multiplier.x; + temp2.z = Plen * density_multiplier; // Transparency (-> temp1) - // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati // compiler gets confused. - temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); + temp1 = exp(-temp1 * temp2.z * distance_multiplier); //final atmosphere attenuation factor setAtmosAttenuation(temp1.rgb); @@ -202,7 +203,7 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { temp2.x += .25; //increase ambient when there are more clouds - vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; + vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; /* decrease value and saturation (that in HSV, not HSL) for occluded areas * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html @@ -216,8 +217,8 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { //haze color setAdditiveColor( - vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) - + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) + + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x + tmpAmbient))); //brightness of surface both sunlight and ambient @@ -278,9 +279,8 @@ void main() float depth = texture2DRect(depthMap, tc.xy).r; vec3 pos = getPosition_d(tc, depth).xyz; vec3 norm = texture2DRect(normalMap, tc).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm - //vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; - + norm = (norm.xyz-0.5)*2.0; // unpack norm + float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); vec4 diffuse = texture2DRect(diffuseRect, tc); @@ -309,12 +309,17 @@ void main() // vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); float sa = dot(refnormpersp, sun_dir.xyz); - vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).r; + vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r); // add the two types of shiny together vec3 spec_contrib = dumbshiny * spec.rgb; - bloom = dot(spec_contrib, spec_contrib); + bloom = dot(spec_contrib, spec_contrib) / 4; col += spec_contrib; + + //add environmentmap + vec3 env_vec = env_mat * refnormpersp; + col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb, + max(spec.a-diffuse.a*2.0, 0.0)); } col = atmosLighting(col); @@ -327,6 +332,6 @@ void main() col = diffuse.rgb; } - gl_FragColor.rgb = col; - gl_FragColor.a = bloom; + frag_color.rgb = col; + frag_color.a = bloom; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index 31bd0c79da..6d6ad6d565 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -26,11 +26,11 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif -VARYING vec4 vertex_color; - uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; uniform sampler2DRect depthMap; @@ -47,6 +47,7 @@ uniform vec3 proj_n; uniform float proj_focus; //distance from plane to begin blurring uniform float proj_lod; //(number of mips in proj map) uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; uniform float proj_ambiance; uniform float near_clip; uniform float far_clip; @@ -56,16 +57,65 @@ uniform float sun_wash; uniform int proj_shadow_idx; uniform float shadow_fade; -VARYING vec4 vary_light; +uniform float size; +uniform vec3 color; +uniform float falloff; +VARYING vec3 trans_center; VARYING vec4 vary_fragcoord; uniform vec2 screen_res; uniform mat4 inv_proj; +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ + vec4 ret = texture2DLod(projectionMap, tc, lod); + + vec2 dist = tc-vec2(0.5); + + float det = max(1.0-lod/(proj_lod*0.5), 0.0); + + float d = dot(dist,dist); + + ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); + + return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ + vec4 ret = texture2DLod(projectionMap, tc, lod); + + vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); + + float det = min(lod/(proj_lod*0.5), 1.0); + + float d = min(dist.x, dist.y); + + float edge = 0.25*det; + + ret *= clamp(d/edge, 0.0, 1.0); + + return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ + vec4 ret = texture2DLod(projectionMap, tc, lod); + + vec2 dist = tc-vec2(0.5); + + float d = dot(dist,dist); + + ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); + + return ret; +} + + vec4 getPosition(vec2 pos_screen) { - float depth = texture2DRect(depthMap, pos_screen.xy).a; + float depth = texture2DRect(depthMap, pos_screen.xy).r; vec2 sc = pos_screen.xy*2.0; sc /= screen_res; sc -= vec2(1.0,1.0); @@ -83,6 +133,15 @@ void main() frag.xyz = frag.xyz*0.5+0.5; frag.xy *= screen_res; + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = trans_center.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= size; + if (dist2 > 1.0) + { + discard; + } + float shadow = 1.0; if (proj_shadow_idx >= 0) @@ -94,17 +153,8 @@ void main() shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); } - vec3 pos = getPosition(frag.xy).xyz; - vec3 lv = vary_light.xyz-pos.xyz; - float dist2 = dot(lv,lv); - dist2 /= vary_light.w; - if (dist2 > 1.0) - { - discard; - } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = (norm.xyz-0.5)*2.0; // unpack norm norm = normalize(norm); float l_dist = -dot(lv, proj_n); @@ -117,8 +167,12 @@ void main() proj_tc.xyz /= proj_tc.w; - float fa = vertex_color.a+1.0; - float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + float fa = falloff+1.0; + float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); + if (dist_atten <= 0.0) + { + discard; + } lv = proj_origin-pos.xyz; lv = normalize(lv); @@ -136,37 +190,33 @@ void main() proj_tc.y > 0.0) { float lit = 0.0; + float amb_da = proj_ambiance; + if (da > 0.0) { float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); float lod = diff * proj_lod; - vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); - vec3 lcol = vertex_color.rgb * plcol.rgb * plcol.a; + vec3 lcol = color.rgb * plcol.rgb * plcol.a; lit = da * dist_atten * noise; col = lcol*lit*diff_tex*shadow; - } - - float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); - float lod = diff * proj_lod; - vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod); - //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0)); - float amb_da = proj_ambiance; - if (da > 0.0) - { amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; } + //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); + amb_da += (da*da*0.5+0.5)*proj_ambiance; - + amb_da *= dist_atten * noise; - + amb_da = min(amb_da, 1.0-lit); - - col += amb_da*vertex_color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + + col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; } @@ -183,24 +233,28 @@ void main() { vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; - vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; + vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); if (stc.z > 0.0) { - stc.xy /= stc.z+proj_near; - + stc.xy /= stc.w; + + float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); + + stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); + if (stc.x < 1.0 && stc.y < 1.0 && stc.x > 0.0 && stc.y > 0.0) { - vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); - col += dist_atten*scol.rgb*vertex_color.rgb*scol.a*spec.rgb*shadow; + vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow; } } } } - gl_FragColor.rgb = col; - gl_FragColor.a = 0.0; + frag_color.rgb = col; + frag_color.a = 0.0; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index 229c2f4b67..890486c4b1 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -26,17 +26,19 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif //class 2, shadows, no SSAO uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; uniform sampler2DShadow shadowMap4; uniform sampler2DShadow shadowMap5; @@ -53,10 +55,10 @@ VARYING vec2 vary_fragcoord; uniform mat4 inv_proj; uniform vec2 screen_res; -uniform vec2 shadow_res; uniform vec2 proj_shadow_res; uniform vec3 sun_dir; +uniform vec2 shadow_res; uniform float shadow_bias; uniform float shadow_offset; @@ -76,42 +78,43 @@ vec4 getPosition(vec2 pos_screen) return pos; } -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) { stc.xyz /= stc.w; - stc.z += shadow_bias*scl; - - float cs = shadow2DRect(shadowMap, stc.xyz).x; + stc.z += shadow_bias; + + stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x; // add some jitter to X sample pos according to Y to disguise the snapping going on here + float cs = shadow2D(shadowMap, stc.xyz).x; + float shadow = cs; - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs); + shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + - return shadow/5.0; - - //return shadow; + return shadow*0.2; } -float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl) +float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) { stc.xyz /= stc.w; stc.z += spot_shadow_bias*scl; - + stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap + float cs = shadow2D(shadowMap, stc.xyz).x; float shadow = cs; - vec2 off = 1.5/proj_shadow_res; - - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs); - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs); - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs); - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); - - return shadow/5.0; + vec2 off = 1.0/proj_shadow_res; + off.y *= 1.5; - //return shadow; + shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x; + + return shadow*0.2; } void main() @@ -123,17 +126,17 @@ void main() vec4 pos = getPosition(pos_screen); vec4 nmap4 = texture2DRect(normalMap, pos_screen); - nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm + nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm float displace = nmap4.w; vec3 norm = nmap4.xyz; /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL { - gl_FragColor = vec4(0.0); // doesn't matter + frag_color = vec4(0.0); // doesn't matter return; }*/ - float shadow = 1.0; + float shadow = 0.0; float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz)); vec3 shadow_pos = pos.xyz + displace*norm; @@ -152,32 +155,58 @@ void main() { vec4 lpos; - if (spos.z < -shadow_clip.z) + vec4 near_split = shadow_clip*-0.75; + vec4 far_split = shadow_clip*-1.25; + vec4 transition_domain = near_split-far_split; + float weight = 0.0; + + if (spos.z < near_split.z) { lpos = shadow_matrix[3]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap3, lpos, 0.25); + + float w = 1.0; + w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w; + weight += w; shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); } - else if (spos.z < -shadow_clip.y) + + if (spos.z < near_split.y && spos.z > far_split.z) { lpos = shadow_matrix[2]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap2, lpos, 0.5); + + float w = 1.0; + w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; + w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap2, lpos, 0.5, pos_screen)*w; + weight += w; } - else if (spos.z < -shadow_clip.x) + + if (spos.z < near_split.x && spos.z > far_split.y) { lpos = shadow_matrix[1]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap1, lpos, 0.75); + + float w = 1.0; + w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; + w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; + shadow += pcfShadow(shadowMap1, lpos, 0.75, pos_screen)*w; + weight += w; } - else + + if (spos.z > far_split.x) { lpos = shadow_matrix[0]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap0, lpos, 1.0); + + float w = 1.0; + w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; + + shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w; + weight += w; } + + shadow /= weight; + // take the most-shadowed value out of these two: // * the blurred sun shadow in the light (shadow) map // * an unblurred dot product between the sun and this norm @@ -198,19 +227,19 @@ void main() shadow = 1.0; } - gl_FragColor[0] = shadow; - gl_FragColor[1] = 1.0; + frag_color[0] = shadow; + frag_color[1] = 1.0; spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0); //spotlight shadow 1 vec4 lpos = shadow_matrix[4]*spos; - gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.8); + frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen); //spotlight shadow 2 lpos = shadow_matrix[5]*spos; - gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.8); + frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen); - //gl_FragColor.rgb = pos.xyz; - //gl_FragColor.b = shadow; + //frag_color.rgb = pos.xyz; + //frag_color.b = shadow; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 6b420833b9..2dcd3d656f 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -25,17 +25,19 @@ #extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif //class 2 -- shadows and SSAO uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; uniform sampler2DShadow shadowMap4; uniform sampler2DShadow shadowMap5; uniform sampler2D noiseMap; @@ -53,10 +55,11 @@ VARYING vec2 vary_fragcoord; uniform mat4 inv_proj; uniform vec2 screen_res; -uniform vec2 shadow_res; uniform vec2 proj_shadow_res; uniform vec3 sun_dir; +uniform vec2 shadow_res; + uniform float shadow_bias; uniform float shadow_offset; @@ -88,7 +91,7 @@ vec2 getKern(int i) kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; - + return kern[i]; } @@ -137,42 +140,42 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) return min(ret, 1.0); } -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) { stc.xyz /= stc.w; - stc.z += shadow_bias*scl; + stc.z += shadow_bias; + + stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x; + float cs = shadow2D(shadowMap, stc.xyz).x; - float cs = shadow2DRect(shadowMap, stc.xyz).x; float shadow = cs; - - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs); - - return shadow/5.0; - //return shadow; + shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + + return shadow*0.2; } -float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl) +float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) { stc.xyz /= stc.w; stc.z += spot_shadow_bias*scl; - + stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap + float cs = shadow2D(shadowMap, stc.xyz).x; float shadow = cs; - vec2 off = 1.5/proj_shadow_res; - - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs); - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs); - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs); - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); + vec2 off = 1.0/proj_shadow_res; + off.y *= 1.5; - return shadow/5.0; - - //return shadow; + shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x; + + return shadow*0.2; } void main() @@ -184,17 +187,17 @@ void main() vec4 pos = getPosition(pos_screen); vec4 nmap4 = texture2DRect(normalMap, pos_screen); - nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm + nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm float displace = nmap4.w; vec3 norm = nmap4.xyz; /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL { - gl_FragColor = vec4(0.0); // doesn't matter + frag_color = vec4(0.0); // doesn't matter return; }*/ - float shadow = 1.0; + float shadow = 0.0; float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz)); vec3 shadow_pos = pos.xyz + displace*norm; @@ -212,33 +215,59 @@ void main() else { vec4 lpos; - - if (spos.z < -shadow_clip.z) + + vec4 near_split = shadow_clip*-0.75; + vec4 far_split = shadow_clip*-1.25; + vec4 transition_domain = near_split-far_split; + float weight = 0.0; + + if (spos.z < near_split.z) { lpos = shadow_matrix[3]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap3, lpos, 0.25); + + float w = 1.0; + w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w; + weight += w; shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); } - else if (spos.z < -shadow_clip.y) + + if (spos.z < near_split.y && spos.z > far_split.z) { lpos = shadow_matrix[2]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap2, lpos, 0.5); + + float w = 1.0; + w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; + w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap2, lpos, 0.5, pos_screen)*w; + weight += w; } - else if (spos.z < -shadow_clip.x) + + if (spos.z < near_split.x && spos.z > far_split.y) { lpos = shadow_matrix[1]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap1, lpos, 0.75); + + float w = 1.0; + w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; + w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; + shadow += pcfShadow(shadowMap1, lpos, 0.75, pos_screen)*w; + weight += w; } - else + + if (spos.z > far_split.x) { lpos = shadow_matrix[0]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap0, lpos, 1.0); + + float w = 1.0; + w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; + + shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w; + weight += w; } + + shadow /= weight; + // take the most-shadowed value out of these two: // * the blurred sun shadow in the light (shadow) map // * an unblurred dot product between the sun and this norm @@ -259,19 +288,19 @@ void main() shadow = 1.0; } - gl_FragColor[0] = shadow; - gl_FragColor[1] = calcAmbientOcclusion(pos, norm); + frag_color[0] = shadow; + frag_color[1] = calcAmbientOcclusion(pos, norm); spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0); //spotlight shadow 1 vec4 lpos = shadow_matrix[4]*spos; - gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.8); + frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen); //spotlight shadow 2 lpos = shadow_matrix[5]*spos; - gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.8); + frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen); - //gl_FragColor.rgb = pos.xyz; - //gl_FragColor.b = shadow; + //frag_color.rgb = pos.xyz; + //frag_color.b = shadow; } diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl index 6a83be1426..da3d922017 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl @@ -47,12 +47,12 @@ uniform vec4 sunlight_color; uniform vec4 ambient; uniform vec4 blue_horizon; uniform vec4 blue_density; -uniform vec4 haze_horizon; -uniform vec4 haze_density; -uniform vec4 cloud_shadow; -uniform vec4 density_multiplier; -uniform vec4 distance_multiplier; -uniform vec4 max_y; +uniform float haze_horizon; +uniform float haze_density; +uniform float cloud_shadow; +uniform float density_multiplier; +uniform float distance_multiplier; +uniform float max_y; uniform vec4 glow; void calcAtmospherics(vec3 inPositionEye) { @@ -61,8 +61,8 @@ void calcAtmospherics(vec3 inPositionEye) { setPositionEye(P); //(TERRAIN) limit altitude - if (P.y > max_y.x) P *= (max_y.x / P.y); - if (P.y < -max_y.x) P *= (-max_y.x / P.y); + if (P.y > max_y) P *= (max_y / P.y); + if (P.y < -max_y) P *= (-max_y / P.y); vec3 tmpLightnorm = lightnorm.xyz; @@ -78,13 +78,13 @@ void calcAtmospherics(vec3 inPositionEye) { //sunlight attenuation effect (hue and brightness) due to atmosphere //this is used later for sunlight modulation at various altitudes - light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); + light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); //I had thought blue_density and haze_density should have equal weighting, //but attenuation due to haze_density tends to seem too strong - temp1 = blue_density + vec4(haze_density.r); + temp1 = blue_density + vec4(haze_density); blue_weight = blue_density / temp1; - haze_weight = vec4(haze_density.r) / temp1; + haze_weight = vec4(haze_density) / temp1; //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) temp2.y = max(0.0, tmpLightnorm.y); @@ -92,12 +92,12 @@ void calcAtmospherics(vec3 inPositionEye) { sunlight *= exp( - light_atten * temp2.y); // main atmospheric scattering line integral - temp2.z = Plen * density_multiplier.x; + temp2.z = Plen * density_multiplier; // Transparency (-> temp1) - // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati // compiler gets confused. - temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); + temp1 = exp(-temp1 * temp2.z * distance_multiplier); //final atmosphere attenuation factor setAtmosAttenuation(temp1.rgb); @@ -122,12 +122,12 @@ void calcAtmospherics(vec3 inPositionEye) { //increase ambient when there are more clouds - vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; + vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; //haze color setAdditiveColor( - vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) - + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) + + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x + tmpAmbient))); //brightness of surface both sunlight and ambient diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl index 4ab06c6e21..96c70651b1 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif ///////////////////////////////////////////////////////////////////////// @@ -96,7 +98,7 @@ void main() color *= 2.; /// Gamma correct for WL (soft clip effect). - gl_FragColor.rgb = scaleSoftClip(color.rgb); - gl_FragColor.a = alpha1; + frag_color.rgb = scaleSoftClip(color.rgb); + frag_color.a = alpha1; } diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl index c5bb52169c..c1dd45cd67 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl @@ -49,18 +49,18 @@ uniform vec4 sunlight_color; uniform vec4 ambient; uniform vec4 blue_horizon; uniform vec4 blue_density; -uniform vec4 haze_horizon; -uniform vec4 haze_density; +uniform float haze_horizon; +uniform float haze_density; -uniform vec4 cloud_shadow; -uniform vec4 density_multiplier; -uniform vec4 max_y; +uniform float cloud_shadow; +uniform float density_multiplier; +uniform float max_y; uniform vec4 glow; uniform vec4 cloud_color; -uniform vec4 cloud_scale; +uniform float cloud_scale; void main() { @@ -76,7 +76,7 @@ void main() // Set altitude if (P.y > 0.) { - P *= (max_y.x / P.y); + P *= (max_y / P.y); } else { @@ -98,12 +98,12 @@ void main() // Sunlight attenuation effect (hue and brightness) due to atmosphere // this is used later for sunlight modulation at various altitudes - light_atten = (blue_density * 1.0 + haze_density.x * 0.25) * (density_multiplier.x * max_y.x); + light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); // Calculate relative weights - temp1 = blue_density + haze_density.x; + temp1 = blue_density + haze_density; blue_weight = blue_density / temp1; - haze_weight = haze_density.x / temp1; + haze_weight = haze_density / temp1; // Compute sunlight from P & lightnorm (for long rays like sky) temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); @@ -111,7 +111,7 @@ void main() sunlight *= exp( - light_atten * temp2.y); // Distance - temp2.z = Plen * density_multiplier.x; + temp2.z = Plen * density_multiplier; // Transparency (-> temp1) // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati @@ -135,14 +135,14 @@ void main() // Increase ambient when there are more clouds vec4 tmpAmbient = ambient; - tmpAmbient += (1. - tmpAmbient) * cloud_shadow.x * 0.5; + tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; // Dim sunlight by cloud shadow percentage - sunlight *= (1. - cloud_shadow.x); + sunlight *= (1. - cloud_shadow); // Haze color below cloud vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient) - + (haze_horizon.r * haze_weight) * (sunlight * temp2.x + tmpAmbient) + + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient) ); // CLOUDS @@ -163,13 +163,13 @@ void main() vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1); // Make a nice cloud density based on the cloud_shadow value that was passed in. - vary_CloudDensity = 2. * (cloud_shadow.x - 0.25); + vary_CloudDensity = 2. * (cloud_shadow - 0.25); // Texture coords vary_texcoord0 = texcoord0; vary_texcoord0.xy -= 0.5; - vary_texcoord0.xy /= cloud_scale.x; + vary_texcoord0.xy /= cloud_scale; vary_texcoord0.xy += 0.5; vary_texcoord1 = vary_texcoord0; diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl index c9d96b2cf4..e2a2367626 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl @@ -24,7 +24,9 @@ */ #ifdef DEFINE_GL_FRAGCOLOR -out vec4 gl_FragColor; +out vec4 frag_color; +#else +#define frag_color gl_FragColor #endif ///////////////////////////////////////////////////////////////////////// @@ -57,7 +59,7 @@ void main() color *= 2.; /// Gamma correct for WL (soft clip effect). - gl_FragColor.rgb = scaleSoftClip(color.rgb); - gl_FragColor.a = 1.0; + frag_color.rgb = scaleSoftClip(color.rgb); + frag_color.a = 1.0; } diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl index 46773cf89f..3788ddaf2d 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl @@ -42,19 +42,17 @@ uniform vec4 sunlight_color; uniform vec4 ambient; uniform vec4 blue_horizon; uniform vec4 blue_density; -uniform vec4 haze_horizon; -uniform vec4 haze_density; +uniform float haze_horizon; +uniform float haze_density; -uniform vec4 cloud_shadow; -uniform vec4 density_multiplier; -uniform vec4 max_y; +uniform float cloud_shadow; +uniform float density_multiplier; +uniform float max_y; uniform vec4 glow; uniform vec4 cloud_color; -uniform vec4 cloud_scale; - void main() { @@ -68,7 +66,7 @@ void main() // Set altitude if (P.y > 0.) { - P *= (max_y.x / P.y); + P *= (max_y / P.y); } else { @@ -87,15 +85,14 @@ void main() vec4 sunlight = sunlight_color; vec4 light_atten; - // Sunlight attenuation effect (hue and brightness) due to atmosphere // this is used later for sunlight modulation at various altitudes - light_atten = (blue_density * 1.0 + haze_density.x * 0.25) * (density_multiplier.x * max_y.x); + light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); // Calculate relative weights - temp1 = blue_density + haze_density.x; + temp1 = blue_density + haze_density; blue_weight = blue_density / temp1; - haze_weight = haze_density.x / temp1; + haze_weight = haze_density / temp1; // Compute sunlight from P & lightnorm (for long rays like sky) temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); @@ -103,7 +100,7 @@ void main() sunlight *= exp( - light_atten * temp2.y); // Distance - temp2.z = Plen * density_multiplier.x; + temp2.z = Plen * density_multiplier; // Transparency (-> temp1) // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati @@ -128,20 +125,20 @@ void main() // Haze color above cloud vary_HazeColor = ( blue_horizon * blue_weight * (sunlight + ambient) - + (haze_horizon.r * haze_weight) * (sunlight * temp2.x + ambient) + + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient) ); // Increase ambient when there are more clouds vec4 tmpAmbient = ambient; - tmpAmbient += (1. - tmpAmbient) * cloud_shadow.x * 0.5; + tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; // Dim sunlight by cloud shadow percentage - sunlight *= (1. - cloud_shadow.x); + sunlight *= (1. - cloud_shadow); // Haze color below cloud vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient) - + (haze_horizon.r * haze_weight) * (sunlight * temp2.x + tmpAmbient) + + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient) ); // Final atmosphere additive diff --git a/indra/newview/app_settings/toolbars.xml b/indra/newview/app_settings/toolbars.xml index f2192a75ad..29c019719d 100644 --- a/indra/newview/app_settings/toolbars.xml +++ b/indra/newview/app_settings/toolbars.xml @@ -7,8 +7,8 @@ <command name="destinations"/> <command name="people"/> <command name="profile"/> - <command name="view"/> <command name="move"/> + <command name="view"/> <command name="howto"/> </bottom_toolbar> <left_toolbar @@ -20,5 +20,6 @@ <command name="places"/> <command name="voice"/> <command name="minimap"/> + <command name="snapshot"/> </left_toolbar> </toolbars> diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 6641c80b94..99dbfcae51 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -395,7 +395,7 @@ <attachment_point id="39" - group="9" + group="6" pie_slice="1" name="Neck" joint="mNeck" @@ -405,7 +405,7 @@ <attachment_point id="40" - group="9" + group="6" pie_slice="2" name="Avatar Center" joint="mRoot" diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING.tif Binary files differnew file mode 100644 index 0000000000..ba6f30fa0e --- /dev/null +++ b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING.tif diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END.tif Binary files differnew file mode 100644 index 0000000000..830d5692fd --- /dev/null +++ b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END.tif diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END_ADD.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END_ADD.tif Binary files differnew file mode 100644 index 0000000000..e05284214a --- /dev/null +++ b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END_ADD.tif diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START.tif Binary files differnew file mode 100644 index 0000000000..c4822adf64 --- /dev/null +++ b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START.tif diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START_ADD.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START_ADD.tif Binary files differnew file mode 100644 index 0000000000..5166af6e05 --- /dev/null +++ b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START_ADD.tif diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 0f33d40ac3..4030324ecb 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 32 +version 33 // The version number above should be implemented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -42,7 +42,6 @@ RenderGamma 1 0 RenderGlowResolutionPow 1 9 RenderGround 1 1 RenderMaxPartCount 1 8192 -RenderNightBrightness 1 1.0 RenderObjectBump 1 1 RenderLocalLights 1 1 RenderReflectionDetail 1 4 @@ -62,6 +61,7 @@ WLSkyDetail 1 128 Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 RenderTextureMemoryMultiple 1 1.0 +RenderCompressTextures 1 1 RenderShaderLightingMaxLevel 1 3 RenderDeferred 1 1 RenderDeferredSSAO 1 1 @@ -73,9 +73,9 @@ RenderMaxTextureIndex 1 16 // -// Low Graphics Settings +// Low Graphics Settings (fixed function) // -list Low +list LowFixedFunction RenderAnisotropic 1 0 RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 0 @@ -97,16 +97,48 @@ RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 +RenderShadowDetail 1 0 WLSkyDetail 1 48 +RenderFSAASamples 1 0 + + +// +// Low Graphics Settings +// +list Low +RenderAnisotropic 1 0 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 0 +RenderAvatarPhysicsLODFactor 1 0 +RenderAvatarMaxVisible 1 3 +RenderAvatarVP 1 0 +RenderFarClip 1 64 +RenderFlexTimeFactor 1 0 +RenderGlowResolutionPow 1 8 +RenderMaxPartCount 1 0 +RenderObjectBump 1 0 +RenderLocalLights 1 0 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 0 +RenderTerrainLODFactor 1 1 +RenderTransparentWater 1 0 +RenderTreeLODFactor 1 0 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +WLSkyDetail 1 48 RenderFSAASamples 1 0 // -// Mid Graphics Settings +// Medium Low Graphics Settings // -list Mid +list LowMid RenderAnisotropic 1 0 RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 0.5 @@ -127,16 +159,16 @@ RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 -WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +WLSkyDetail 1 48 RenderFSAASamples 1 0 // -// High Graphics Settings (purty) +// Medium Graphics Settings (standard) // -list High +list Mid RenderAnisotropic 1 1 RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 @@ -157,13 +189,104 @@ RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 -WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +WLSkyDetail 1 48 +RenderFSAASamples 1 2 + +// +// Medium High Graphics Settings (deferred enabled) +// +list MidHigh +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderLocalLights 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTransparentWater 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +RenderDeferred 1 1 +RenderDeferredSSAO 1 0 +RenderShadowDetail 1 0 +WLSkyDetail 1 48 RenderFSAASamples 1 2 // +// High Graphics Settings (deferred + SSAO) +// +list High +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderLocalLights 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTransparentWater 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +RenderShadowDetail 1 0 +WLSkyDetail 1 48 +RenderFSAASamples 1 2 + +// +// High Ultra Graphics Settings (deferred + SSAO + shadows) +// +list HighUltra +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderLocalLights 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTransparentWater 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +RenderShadowDetail 1 2 +WLSkyDetail 1 48 +RenderFSAASamples 1 2 + + +// // Ultra graphics (REALLY PURTY!) // list Ultra @@ -198,6 +321,9 @@ RenderFSAASamples 1 2 // list Unknown RenderVBOEnable 1 0 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 // // Class 0 Hardware (just old) @@ -212,18 +338,36 @@ list Class1 RenderVBOEnable 1 1 // -// Class 2 Hardware (make it purty) +// Class 2 Hardware // list Class2 RenderVBOEnable 1 1 // -// Class 3 Hardware (make it purty) +// Class 3 Hardware // list Class3 RenderVBOEnable 1 1 // +// Class 4 Hardware +// +list Class4 +RenderVBOEnable 1 1 + +// +// Class 5 Hardware +// +list Class5 +RenderVBOEnable 1 1 + +// +// VRAM > 512MB +// +list VRAMGT512 +RenderCompressTextures 1 0 + +// // No Pixel Shaders available // list NoPixelShaders @@ -303,6 +447,7 @@ RenderMaxTextureIndex 1 1 list Intel RenderAnisotropic 1 0 RenderVBOEnable 1 0 +RenderFSAASamples 1 0 list GeForce2 RenderAnisotropic 1 0 @@ -481,6 +626,7 @@ Disregard128DefaultDrawDistance 1 0 list ATIOldDriver RenderAvatarVP 0 0 RenderAvatarCloth 0 0 +RenderVBOEnable 1 0 // ATI cards generally perform better when not using VBOs for streaming data diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 8142311a55..6d5284c602 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 27 +version 28 // The version number above should be implemented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -43,7 +43,6 @@ RenderGlowResolutionPow 1 9 RenderGround 1 1 RenderLocalLights 1 1 RenderMaxPartCount 1 8192 -RenderNightBrightness 1 1.0 RenderObjectBump 1 1 RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 @@ -62,6 +61,7 @@ WLSkyDetail 1 128 Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 RenderTextureMemoryMultiple 1 1.0 +RenderCompressTextures 1 1 RenderShaderLightingMaxLevel 1 3 RenderDeferred 1 1 RenderDeferredSSAO 1 1 @@ -70,6 +70,37 @@ RenderFSAASamples 1 16 RenderMaxTextureIndex 1 16 // +// Low Graphics Settings (fixed function) +// +list LowFixedFunction +RenderAnisotropic 1 0 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 0 +RenderAvatarPhysicsLODFactor 1 0 +RenderAvatarMaxVisible 1 3 +RenderAvatarVP 1 0 +RenderFarClip 1 64 +RenderFlexTimeFactor 1 0 +RenderGlowResolutionPow 1 8 +RenderLocalLights 1 0 +RenderMaxPartCount 1 0 +RenderObjectBump 1 0 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 0 +RenderTerrainLODFactor 1 1 +RenderTransparentWater 1 0 +RenderTreeLODFactor 1 0 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 0.5 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 +RenderShadowDetail 1 0 +WLSkyDetail 1 48 +RenderFSAASamples 1 0 + +// // Low Graphics Settings // list Low @@ -94,16 +125,16 @@ RenderUseImpostors 1 1 RenderVolumeLODFactor 1 0.5 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 -WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +WLSkyDetail 1 48 RenderFSAASamples 1 0 // -// Mid Graphics Settings +// Medium Low Graphics Settings // -list Mid +list LowMid RenderAnisotropic 1 0 RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 0.5 @@ -112,9 +143,9 @@ RenderAvatarVP 1 1 RenderFarClip 1 96 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 8 -RenderLocalLights 1 1 RenderMaxPartCount 1 2048 RenderObjectBump 1 1 +RenderLocalLights 1 1 RenderReflectionDetail 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 1.0 @@ -124,16 +155,16 @@ RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 -WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +WLSkyDetail 1 48 RenderFSAASamples 1 0 // -// High Graphics Settings (purty) +// Medium Graphics Settings (standard) // -list High +list Mid RenderAnisotropic 1 1 RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 @@ -142,9 +173,9 @@ RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 -RenderLocalLights 1 1 RenderMaxPartCount 1 4096 RenderObjectBump 1 1 +RenderLocalLights 1 1 RenderReflectionDetail 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 @@ -154,10 +185,100 @@ RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 -WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +WLSkyDetail 1 48 +RenderFSAASamples 1 2 + +// +// Medium High Graphics Settings (deferred enabled) +// +list MidHigh +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderLocalLights 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTransparentWater 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +RenderDeferred 1 1 +RenderDeferredSSAO 1 0 +RenderShadowDetail 1 0 +WLSkyDetail 1 48 +RenderFSAASamples 1 2 + +// +// High Graphics Settings (deferred + SSAO) +// +list High +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderLocalLights 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTransparentWater 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +RenderShadowDetail 1 0 +WLSkyDetail 1 48 +RenderFSAASamples 1 2 + +// +// High Ultra Graphics Settings (deferred + SSAO + shadows) +// +list HighUltra +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderLocalLights 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTransparentWater 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +RenderShadowDetail 1 2 +WLSkyDetail 1 48 RenderFSAASamples 1 2 // @@ -195,6 +316,9 @@ RenderFSAASamples 1 2 // list Unknown RenderVBOEnable 1 0 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 // // Class 0 Hardware (just old) @@ -209,18 +333,36 @@ list Class1 RenderVBOEnable 1 1 // -// Class 2 Hardware (make it purty) +// Class 2 Hardware // list Class2 RenderVBOEnable 1 1 // -// Class 3 Hardware (make it purty) +// Class 3 Hardware // list Class3 RenderVBOEnable 1 1 // +// Class 4 Hardware +// +list Class4 +RenderVBOEnable 1 1 + +// +// Class 5 Hardware +// +list Class5 +RenderVBOEnable 1 1 + +// +// VRAM > 512MB +// +list VRAMGT512 +RenderCompressTextures 1 0 + +// // No Pixel Shaders available // list NoPixelShaders @@ -292,10 +434,15 @@ RenderObjectBump 0 0 list OpenGLPre15 RenderVBOEnable 1 0 +list OpenGLPre30 +RenderDeferred 0 0 +RenderMaxTextureIndex 1 1 + list Intel RenderAnisotropic 1 0 // Avoid some Intel crashes on Linux RenderCubeMap 0 0 +RenderFSAASamples 1 0 list GeForce2 RenderAnisotropic 1 0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 390da2273d..1c0d45c11b 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 31 +version 35 // The version number above should be implemented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -43,7 +43,6 @@ RenderGlowResolutionPow 1 9 RenderGround 1 1 RenderLocalLights 1 1 RenderMaxPartCount 1 8192 -RenderNightBrightness 1 1.0 RenderObjectBump 1 1 RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 @@ -51,7 +50,7 @@ RenderTerrainLODFactor 1 2.0 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 -RenderVBOEnable 1 0 +RenderVBOEnable 1 1 RenderVBOMappingDisable 1 1 RenderVolumeLODFactor 1 2.0 UseStartScreen 1 1 @@ -62,19 +61,20 @@ WLSkyDetail 1 128 Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 RenderTextureMemoryMultiple 1 0.5 +RenderCompressTextures 1 1 RenderShaderLightingMaxLevel 1 3 RenderDeferred 1 1 RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 WatchdogDisabled 1 1 -RenderUseStreamVBO 1 0 +RenderUseStreamVBO 1 1 RenderFSAASamples 1 16 RenderMaxTextureIndex 1 16 // -// Low Graphics Settings +// Low Graphics Settings (fixed function) // -list Low +list LowFixedFunction RenderAnisotropic 1 0 RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 0 @@ -96,16 +96,47 @@ RenderUseImpostors 1 1 RenderVolumeLODFactor 1 0.5 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 +RenderShadowDetail 1 0 WLSkyDetail 1 48 +RenderFSAASamples 1 0 + +// +// Low Graphics Settings +// +list Low +RenderAnisotropic 1 0 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 0 +RenderAvatarPhysicsLODFactor 1 0 +RenderAvatarMaxVisible 1 3 +RenderAvatarVP 1 0 +RenderFarClip 1 64 +RenderFlexTimeFactor 1 0 +RenderGlowResolutionPow 1 8 +RenderLocalLights 1 0 +RenderMaxPartCount 1 0 +RenderObjectBump 1 0 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 0 +RenderTerrainLODFactor 1 1 +RenderTransparentWater 1 0 +RenderTreeLODFactor 1 0 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 0.5 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +WLSkyDetail 1 48 RenderFSAASamples 1 0 // -// Mid Graphics Settings +// Medium Low Graphics Settings // -list Mid +list LowMid RenderAnisotropic 1 0 RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 0.5 @@ -114,9 +145,9 @@ RenderAvatarVP 1 1 RenderFarClip 1 96 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 8 -RenderLocalLights 1 1 RenderMaxPartCount 1 2048 RenderObjectBump 1 1 +RenderLocalLights 1 1 RenderReflectionDetail 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 1.0 @@ -126,16 +157,16 @@ RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 -WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +WLSkyDetail 1 48 RenderFSAASamples 1 0 // -// High Graphics Settings (purty) +// Medium Graphics Settings (standard) // -list High +list Mid RenderAnisotropic 1 1 RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 @@ -144,9 +175,9 @@ RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 -RenderLocalLights 1 1 RenderMaxPartCount 1 4096 RenderObjectBump 1 1 +RenderLocalLights 1 1 RenderReflectionDetail 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 @@ -156,12 +187,103 @@ RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 -WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 +RenderShadowDetail 1 0 +WLSkyDetail 1 48 +RenderFSAASamples 1 2 + +// +// Medium High Graphics Settings (deferred enabled) +// +list MidHigh +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderLocalLights 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTransparentWater 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +RenderDeferred 1 1 +RenderDeferredSSAO 1 0 +RenderShadowDetail 1 0 +WLSkyDetail 1 48 +RenderFSAASamples 1 2 + +// +// High Graphics Settings (deferred + SSAO) +// +list High +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderLocalLights 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTransparentWater 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +RenderShadowDetail 1 0 +WLSkyDetail 1 48 +RenderFSAASamples 1 2 + +// +// High Ultra Graphics Settings (deferred + SSAO + shadows) +// +list HighUltra +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderLocalLights 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTransparentWater 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 +WLSkyDetail 1 48 RenderFSAASamples 1 2 + // // Ultra graphics (REALLY PURTY!) // @@ -211,16 +333,27 @@ list Class1 RenderVBOEnable 1 1 // -// Class 2 Hardware (make it purty) +// Class 2 Hardware // list Class2 RenderVBOEnable 1 1 // -// Class 3 Hardware (make it purty) +// Class 3 Hardware // list Class3 RenderVBOEnable 1 1 +// +// Class 4 Hardware +// +list Class4 +RenderVBOEnable 1 1 + +// +// Class 5 Hardware +// +list Class5 +RenderVBOEnable 1 1 // // No Pixel Shaders available @@ -249,6 +382,12 @@ RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 // +// VRAM > 512MB +// +list VRAMGT512 +RenderCompressTextures 1 0 + +// // "Default" setups for safe, low, medium, high // list safe @@ -287,6 +426,7 @@ RenderObjectBump 0 0 list OpenGLPre15 RenderVBOEnable 1 0 + list TexUnit8orLess RenderDeferredSSAO 0 0 @@ -296,6 +436,7 @@ RenderDeferredSSAO 1 0 list Intel RenderAnisotropic 1 0 RenderLocalLights 1 0 +RenderFSAASamples 1 0 list GeForce2 RenderAnisotropic 1 0 diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index 278d601860..68e09d010e 100644 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -1,4 +1,4 @@ -version 31 +version 32 // The version number above should be implemented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -43,7 +43,6 @@ RenderGlowResolutionPow 1 9 RenderGround 1 1 RenderLocalLights 1 1 RenderMaxPartCount 1 8192 -RenderNightBrightness 1 1.0 RenderObjectBump 1 1 RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 @@ -62,19 +61,20 @@ WLSkyDetail 1 128 Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 RenderTextureMemoryMultiple 1 1.0 +RenderCompressTextures 1 1 RenderShaderLightingMaxLevel 1 3 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +RenderShadowDetail 1 2 WatchdogDisabled 1 1 RenderUseStreamVBO 1 1 RenderFSAASamples 1 16 RenderMaxTextureIndex 1 16 // -// Low Graphics Settings +// Low Graphics Settings (fixed function) // -list Low +list LowFixedFunction RenderAnisotropic 1 0 RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 0 @@ -96,16 +96,47 @@ RenderUseImpostors 1 1 RenderVolumeLODFactor 1 0.5 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 +RenderShadowDetail 1 0 WLSkyDetail 1 48 +RenderFSAASamples 1 0 + +// +// Low Graphics Settings +// +list Low +RenderAnisotropic 1 0 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 0 +RenderAvatarPhysicsLODFactor 1 0 +RenderAvatarMaxVisible 1 3 +RenderAvatarVP 1 0 +RenderFarClip 1 64 +RenderFlexTimeFactor 1 0 +RenderGlowResolutionPow 1 8 +RenderLocalLights 1 0 +RenderMaxPartCount 1 0 +RenderObjectBump 1 0 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 0 +RenderTerrainLODFactor 1 1 +RenderTransparentWater 1 0 +RenderTreeLODFactor 1 0 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 0.5 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +WLSkyDetail 1 48 RenderFSAASamples 1 0 // -// Mid Graphics Settings +// Medium Low Graphics Settings // -list Mid +list LowMid RenderAnisotropic 1 0 RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 0.5 @@ -114,9 +145,9 @@ RenderAvatarVP 1 1 RenderFarClip 1 96 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 8 -RenderLocalLights 1 1 RenderMaxPartCount 1 2048 RenderObjectBump 1 1 +RenderLocalLights 1 1 RenderReflectionDetail 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 1.0 @@ -126,16 +157,16 @@ RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 -WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +WLSkyDetail 1 48 RenderFSAASamples 1 0 // -// High Graphics Settings (purty) +// Medium Graphics Settings (standard) // -list High +list Mid RenderAnisotropic 1 1 RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 @@ -144,9 +175,9 @@ RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 -RenderLocalLights 1 1 RenderMaxPartCount 1 4096 RenderObjectBump 1 1 +RenderLocalLights 1 1 RenderReflectionDetail 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 @@ -156,10 +187,100 @@ RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 -WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 +RenderShadowDetail 1 0 +WLSkyDetail 1 48 +RenderFSAASamples 1 2 + +// +// Medium High Graphics Settings (deferred enabled) +// +list MidHigh +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderLocalLights 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTransparentWater 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +RenderDeferred 1 1 +RenderDeferredSSAO 1 0 +RenderShadowDetail 1 0 +WLSkyDetail 1 48 +RenderFSAASamples 1 2 + +// +// High Graphics Settings (deferred + SSAO) +// +list High +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderLocalLights 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTransparentWater 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +RenderShadowDetail 1 0 +WLSkyDetail 1 48 +RenderFSAASamples 1 2 + +// +// High Ultra Graphics Settings (deferred + SSAO + shadows) +// +list HighUltra +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderLocalLights 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTransparentWater 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 +WLSkyDetail 1 48 RenderFSAASamples 1 2 // @@ -211,18 +332,36 @@ list Class1 RenderVBOEnable 1 1 // -// Class 2 Hardware (make it purty) +// Class 2 Hardware // list Class2 RenderVBOEnable 1 1 // -// Class 3 Hardware (make it purty) +// Class 3 Hardware // list Class3 RenderVBOEnable 1 1 // +// Class 4 Hardware (deferred + SSAO) +// +list Class4 +RenderVBOEnable 1 1 + +// +// Class 5 Hardware +// +list Class5 +RenderVBOEnable 1 1 + +// +// VRAM > 512MB +// +list VRAMGT512 +RenderCompressTextures 1 0 + +// // No Pixel Shaders available // list NoPixelShaders @@ -300,6 +439,7 @@ RenderMaxTextureIndex 1 1 list Intel RenderAnisotropic 1 0 RenderVBOEnable 1 0 +RenderFSAASamples 1 0 list GeForce2 RenderAnisotropic 1 0 @@ -479,6 +619,7 @@ Disregard128DefaultDrawDistance 1 0 list ATIOldDriver RenderAvatarVP 0 0 RenderAvatarCloth 0 0 +RenderVBOEnable 1 0 // ATI cards generally perform better when not using VBOs for streaming data diff --git a/indra/newview/generate_breakpad_symbols.py b/indra/newview/generate_breakpad_symbols.py index 5ebec1563e..4181e4ebb3 100644 --- a/indra/newview/generate_breakpad_symbols.py +++ b/indra/newview/generate_breakpad_symbols.py @@ -39,17 +39,20 @@ import shlex import subprocess import tarfile import StringIO +import pprint + +DEBUG=False def usage(): - print >>sys.stderr, "usage: %s viewer_dir viewer_exes libs_suffix dump_syms_tool viewer_symbol_file" % sys.argv[0] + print >>sys.stderr, "usage: %s search_dirs viewer_exes libs_suffix dump_syms_tool viewer_symbol_file" % sys.argv[0] class MissingModuleError(Exception): def __init__(self, modules): Exception.__init__(self, "Failed to find required modules: %r" % modules) self.modules = modules -def main(configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file): - print "generate_breakpad_symbols run with args: %s" % str((configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file)) +def main(configuration, search_dirs, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file): + print "generate_breakpad_symbols run with args: %s" % str((configuration, search_dirs, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file)) if not re.match("release", configuration, re.IGNORECASE): print "skipping breakpad symbol generation for non-release build." @@ -67,21 +70,49 @@ def main(configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, vi return True return fnmatch.fnmatch(f, libs_suffix) + search_dirs = search_dirs.split(";") + def list_files(): - for (dirname, subdirs, filenames) in os.walk(viewer_dir): - #print "scanning '%s' for modules..." % dirname - for f in itertools.ifilter(matches, filenames): - yield os.path.join(dirname, f) + for search_dir in search_dirs: + for (dirname, subdirs, filenames) in os.walk(search_dir): + if DEBUG: + print "scanning '%s' for modules..." % dirname + for f in itertools.ifilter(matches, filenames): + yield os.path.join(dirname, f) def dump_module(m): print "dumping module '%s' with '%s'..." % (m, dump_syms_tool) - child = subprocess.Popen([dump_syms_tool, m] , stdout=subprocess.PIPE) + dsym_full_path = m + child = subprocess.Popen([dump_syms_tool, dsym_full_path] , stdout=subprocess.PIPE) out, err = child.communicate() return (m,child.returncode, out, err) - out = tarfile.open(viewer_symbol_file, 'w:bz2') + + modules = {} + + for m in list_files(): + if DEBUG: + print "examining module '%s' ... " % m, + filename=os.path.basename(m) + if -1 != m.find("DWARF"): + # Just use this module; it has the symbols we want. + modules[filename] = m + if DEBUG: + print "found dSYM entry" + elif filename not in modules: + # Only use this if we don't already have a (possibly better) entry. + modules[filename] = m + if DEBUG: + print "found new entry" + elif DEBUG: + print "ignoring entry" + + + print "Found these following modules:" + pprint.pprint( modules ) - for (filename,status,symbols,err) in itertools.imap(dump_module, list_files()): + out = tarfile.open(viewer_symbol_file, 'w:bz2') + for (filename,status,symbols,err) in itertools.imap(dump_module, modules.values()): if status == 0: module_line = symbols[:symbols.index('\n')] module_line = module_line.split() diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt index 198e702459..4c39014c8b 100644 --- a/indra/newview/gpu_table.txt +++ b/indra/newview/gpu_table.txt @@ -17,519 +17,582 @@ // // Format: // Fields are separated by one or more tab (not space) characters -// <recognizer name> <regular expression> <class> <supported> +// <recognizer name> <regular expression> <class> <supported> <stats based> <expected OpenGL version> // // Class Numbers: // 0 - Defaults to low graphics settings. No shaders on by default // 1 - Defaults to mid graphics settings. Basic shaders on by default // 2 - Defaults to high graphics settings. Atmospherics on by default. -// 3 - Same as class 2 for now. +// 3 - Same as 2, but with lighting and shadows enabled. +// 4 - Same as 3, but with ambient occlusion enabled. +// 5 - Same as 4, but with shadows set to "Sun/Moon+Projectors." // // Supported Number: // 0 - We claim to not support this card. // 1 - We claim to support this card. // -3Dfx .*3Dfx.* 0 0 -3Dlabs .*3Dlabs.* 0 0 -ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 -ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 -ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 -ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 -ATI All-in-Wonder 9xxx .*ATI.*All-in-Wonder 9.* 1 1 -ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 -ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 -ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 2 1 -ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 -ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 -ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 -ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 -ATI ASUS ARES .*ATI.*ASUS.*ARES.* 3 1 -ATI ASUS A9xxx .*ATI.*ASUS.*A9.* 1 1 -ATI ASUS AH24xx .*ATI.*ASUS.*AH24.* 1 1 -ATI ASUS AH26xx .*ATI.*ASUS.*AH26.* 3 1 -ATI ASUS AH34xx .*ATI.*ASUS.*AH34.* 1 1 -ATI ASUS AH36xx .*ATI.*ASUS.*AH36.* 3 1 -ATI ASUS AH46xx .*ATI.*ASUS.*AH46.* 3 1 -ATI ASUS AX3xx .*ATI.*ASUS.*AX3.* 1 1 -ATI ASUS AX5xx .*ATI.*ASUS.*AX5.* 1 1 -ATI ASUS AX8xx .*ATI.*ASUS.*AX8.* 2 1 -ATI ASUS EAH24xx .*ATI.*ASUS.*EAH24.* 2 1 -ATI ASUS EAH26xx .*ATI.*ASUS.*EAH26.* 3 1 -ATI ASUS EAH29xx .*ATI.*ASUS.*EAH29.* 3 1 -ATI ASUS EAH34xx .*ATI.*ASUS.*EAH34.* 1 1 -ATI ASUS EAH36xx .*ATI.*ASUS.*EAH36.* 3 1 -ATI ASUS EAH38xx .*ATI.*ASUS.*EAH38.* 3 1 -ATI ASUS EAH43xx .*ATI.*ASUS.*EAH43.* 1 1 -ATI ASUS EAH45xx .*ATI.*ASUS.*EAH45.* 1 1 -ATI ASUS EAH48xx .*ATI.*ASUS.*EAH48.* 3 1 -ATI ASUS EAH57xx .*ATI.*ASUS.*EAH57.* 3 1 -ATI ASUS EAH58xx .*ATI.*ASUS.*EAH58.* 3 1 -ATI ASUS EAH6xxx .*ATI.*ASUS.*EAH6.* 3 1 -ATI ASUS Radeon X1xxx .*ATI.*ASUS.*X1.* 3 1 -ATI Radeon X7xx .*ATI.*ASUS.*X7.* 1 1 -ATI Radeon X19xx .*ATI.*(Radeon|Diamond) X19.* ?.* 3 1 -ATI Radeon X18xx .*ATI.*(Radeon|Diamond) X18.* ?.* 3 1 -ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 2 1 -ATI Radeon X16xx .*ATI.*(Radeon|Diamond) X16.* ?.* 2 1 -ATI Radeon X15xx .*ATI.*(Radeon|Diamond) X15.* ?.* 2 1 -ATI Radeon X13xx .*ATI.*(Radeon|Diamond) X13.* ?.* 1 1 -ATI Radeon X1xxx .*ATI.*(Radeon|Diamond) X1.. ?.* 1 1 -ATI Radeon X2xxx .*ATI.*(Radeon|Diamond) X2.. ?.* 1 1 -ATI Display Adapter .*ATI.*display adapter.* 0 1 -ATI FireGL 5200 .*ATI.*FireGL V52.* 0 1 -ATI FireGL 5xxx .*ATI.*FireGL V5.* 1 1 -ATI FireGL .*ATI.*Fire.*GL.* 0 1 -ATI FirePro M3900 .*ATI.*FirePro.*M39.* 2 1 -ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1 -ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1 -ATI FirePro M7820 .*ATI.*FirePro.*M78.* 3 1 -ATI FireMV .*ATI.*FireMV.* 0 1 -ATI Geforce 9500 GT .*ATI.*Geforce 9500 *GT.* 2 1 -ATI Geforce 9600 GT .*ATI.*Geforce 9600 *GT.* 2 1 -ATI Geforce 9800 GT .*ATI.*Geforce 9800 *GT.* 2 1 -ATI Generic .*ATI.*Generic.* 0 0 -ATI Hercules 9800 .*ATI.*Hercules.*9800.* 1 1 -ATI IGP 340M .*ATI.*IGP.*340M.* 0 0 -ATI M52 .*ATI.*M52.* 1 1 -ATI M54 .*ATI.*M54.* 1 1 -ATI M56 .*ATI.*M56.* 1 1 -ATI M71 .*ATI.*M71.* 1 1 -ATI M72 .*ATI.*M72.* 1 1 -ATI M76 .*ATI.*M76.* 3 1 -ATI Radeon HD 64xx .*ATI.*AMD Radeon.* HD [67]4..[MG] 3 1 -ATI Radeon HD 65xx .*ATI.*AMD Radeon.* HD [67]5..[MG] 3 1 -ATI Radeon HD 66xx .*ATI.*AMD Radeon.* HD [67]6..[MG] 3 1 -ATI Mobility Radeon 4100 .*ATI.*Mobility.*41.. 1 1 -ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1 -ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1 -ATI Mobility Radeon 9800 .*ATI.*Mobility.*98.* 1 1 -ATI Mobility Radeon 9700 .*ATI.*Mobility.*97.* 1 1 -ATI Mobility Radeon 9600 .*ATI.*Mobility.*96.* 0 1 -ATI Mobility Radeon HD 530v .*ATI.*Mobility.*HD *530v.* 1 1 -ATI Mobility Radeon HD 540v .*ATI.*Mobility.*HD *540v.* 2 1 -ATI Mobility Radeon HD 545v .*ATI.*Mobility.*HD *545v.* 2 1 -ATI Mobility Radeon HD 550v .*ATI.*Mobility.*HD *550v.* 2 1 -ATI Mobility Radeon HD 560v .*ATI.*Mobility.*HD *560v.* 2 1 -ATI Mobility Radeon HD 565v .*ATI.*Mobility.*HD *565v.* 2 1 -ATI Mobility Radeon HD 2300 .*ATI.*Mobility.*HD *23.* 2 1 -ATI Mobility Radeon HD 2400 .*ATI.*Mobility.*HD *24.* 2 1 -ATI Mobility Radeon HD 2600 .*ATI.*Mobility.*HD *26.* 3 1 -ATI Mobility Radeon HD 2700 .*ATI.*Mobility.*HD *27.* 3 1 -ATI Mobility Radeon HD 3100 .*ATI.*Mobility.*HD *31.* 0 1 -ATI Mobility Radeon HD 3200 .*ATI.*Mobility.*HD *32.* 0 1 -ATI Mobility Radeon HD 3400 .*ATI.*Mobility.*HD *34.* 2 1 -ATI Mobility Radeon HD 3600 .*ATI.*Mobility.*HD *36.* 3 1 -ATI Mobility Radeon HD 3800 .*ATI.*Mobility.*HD *38.* 3 1 -ATI Mobility Radeon HD 4200 .*ATI.*Mobility.*HD *42.* 2 1 -ATI Mobility Radeon HD 4300 .*ATI.*Mobility.*HD *43.* 2 1 -ATI Mobility Radeon HD 4500 .*ATI.*Mobility.*HD *45.* 3 1 -ATI Mobility Radeon HD 4600 .*ATI.*Mobility.*HD *46.* 3 1 -ATI Mobility Radeon HD 4800 .*ATI.*Mobility.*HD *48.* 3 1 -ATI Mobility Radeon HD 5100 .*ATI.*Mobility.*HD *51.* 3 1 -ATI Mobility Radeon HD 5300 .*ATI.*Mobility.*HD *53.* 3 1 -ATI Mobility Radeon HD 5400 .*ATI.*Mobility.*HD *54.* 3 1 -ATI Mobility Radeon HD 5500 .*ATI.*Mobility.*HD *55.* 3 1 -ATI Mobility Radeon HD 5600 .*ATI.*Mobility.*HD *56.* 3 1 -ATI Mobility Radeon HD 5700 .*ATI.*Mobility.*HD *57.* 3 1 -ATI Mobility Radeon HD 6200 .*ATI.*Mobility.*HD *62.* 3 1 -ATI Mobility Radeon HD 6300 .*ATI.*Mobility.*HD *63.* 3 1 -ATI Mobility Radeon HD 6400M .*ATI.*Mobility.*HD *64.* 3 1 -ATI Mobility Radeon HD 6500M .*ATI.*Mobility.*HD *65.* 3 1 -ATI Mobility Radeon HD 6600M .*ATI.*Mobility.*HD *66.* 3 1 -ATI Mobility Radeon HD 6700M .*ATI.*Mobility.*HD *67.* 3 1 -ATI Mobility Radeon HD 6800M .*ATI.*Mobility.*HD *68.* 3 1 -ATI Mobility Radeon HD 6900M .*ATI.*Mobility.*HD *69.* 3 1 -ATI Radeon HD 2300 .*ATI.*Radeon HD *23.. 2 1 -ATI Radeon HD 2400 .*ATI.*Radeon HD *24.. 2 1 -ATI Radeon HD 2600 .*ATI.*Radeon HD *26.. 2 1 -ATI Radeon HD 2900 .*ATI.*Radeon HD *29.. 3 1 -ATI Radeon HD 3000 .*ATI.*Radeon HD *30.. 0 1 -ATI Radeon HD 3100 .*ATI.*Radeon HD *31.. 1 1 -ATI Radeon HD 3200 .*ATI.*Radeon HD *32.. 1 1 -ATI Radeon HD 3300 .*ATI.*Radeon HD *33.. 2 1 -ATI Radeon HD 3400 .*ATI.*Radeon HD *34.. 2 1 -ATI Radeon HD 3500 .*ATI.*Radeon HD *35.. 2 1 -ATI Radeon HD 3600 .*ATI.*Radeon HD *36.. 3 1 -ATI Radeon HD 3700 .*ATI.*Radeon HD *37.. 3 1 -ATI Radeon HD 3800 .*ATI.*Radeon HD *38.. 3 1 -ATI Radeon HD 4100 .*ATI.*Radeon HD *41.. 1 1 -ATI Radeon HD 4200 .*ATI.*Radeon HD *42.. 1 1 -ATI Radeon HD 4300 .*ATI.*Radeon HD *43.. 2 1 -ATI Radeon HD 4400 .*ATI.*Radeon HD *44.. 2 1 -ATI Radeon HD 4500 .*ATI.*Radeon HD *45.. 3 1 -ATI Radeon HD 4600 .*ATI.*Radeon HD *46.. 3 1 -ATI Radeon HD 4700 .*ATI.*Radeon HD *47.. 3 1 -ATI Radeon HD 4800 .*ATI.*Radeon HD *48.. 3 1 -ATI Radeon HD 5400 .*ATI.*Radeon HD *54.. 3 1 -ATI Radeon HD 5500 .*ATI.*Radeon HD *55.. 3 1 -ATI Radeon HD 5600 .*ATI.*Radeon HD *56.. 3 1 -ATI Radeon HD 5700 .*ATI.*Radeon HD *57.. 3 1 -ATI Radeon HD 5800 .*ATI.*Radeon HD *58.. 3 1 -ATI Radeon HD 5900 .*ATI.*Radeon HD *59.. 3 1 -ATI Radeon HD 6200 .*ATI.*Radeon HD *62.. 3 1 -ATI Radeon HD 6300 .*ATI.*Radeon HD *63.. 3 1 -ATI Radeon HD 6400 .*ATI.*Radeon HD *64.. 3 1 -ATI Radeon HD 6500 .*ATI.*Radeon HD *65.. 3 1 -ATI Radeon HD 6600 .*ATI.*Radeon HD *66.. 3 1 -ATI Radeon HD 6700 .*ATI.*Radeon HD *67.. 3 1 -ATI Radeon HD 6800 .*ATI.*Radeon HD *68.. 3 1 -ATI Radeon HD 6900 .*ATI.*Radeon HD *69.. 3 1 -ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 -ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1 -ATI Radeon 3000 .*ATI.*Radeon 30.. 0 1 -ATI Radeon 3100 .*ATI.*Radeon 31.. 1 1 -ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1 -ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1 -ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1 -ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1 -ATI Radeon 9100 .*ATI.*Radeon 91.. 0 1 -ATI Radeon 9200 .*ATI.*Radeon 92.. 0 1 -ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1 -ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1 -ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1 -ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1 -ATI Radeon RV250 .*ATI.*RV250.* 0 1 -ATI Radeon RV600 .*ATI.*RV6.* 1 1 -ATI Radeon RX700 .*ATI.*RX70.* 1 1 -ATI Radeon RX800 .*ATI.*Radeon *RX80.* 2 1 -ATI RS880M .*ATI.*RS880M 1 1 -ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 -ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 -ATI Radeon X300 .*ATI.*Radeon *X3.* 0 1 -ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1 -ATI Radeon X500 .*ATI.*Radeon ?X5.* 0 1 -ATI Radeon X600 .*ATI.*Radeon ?X6.* 1 1 -ATI Radeon X700 .*ATI.*Radeon ?X7.* 1 1 -ATI Radeon X800 .*ATI.*Radeon ?X8.* 2 1 -ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1 -ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1 -ATI Rage 128 .*ATI.*Rage 128.* 0 1 -ATI R350 (9800) .*R350.* 1 1 -ATI R580 (X1900) .*R580.* 3 1 -ATI RC410 (Xpress 200) .*RC410.* 0 0 -ATI RS48x (Xpress 200x) .*RS48.* 0 0 -ATI RS600 (Xpress 3200) .*RS600.* 0 0 -ATI RV350 (9600) .*RV350.* 0 1 -ATI RV370 (X300) .*RV370.* 0 1 -ATI RV410 (X700) .*RV410.* 1 1 -ATI RV515 .*RV515.* 1 1 -ATI RV570 (X1900 GT/PRO) .*RV570.* 3 1 -ATI RV380 .*RV380.* 0 1 -ATI RV530 .*RV530.* 1 1 -ATI RX480 (Xpress 200P) .*RX480.* 0 1 -ATI RX700 .*RX700.* 1 1 -AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1 -AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 -AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1 -AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1 -AMD CEDAR (HD 5450) .*(AMD|ATI).*Cedar.* 2 1 -AMD CYPRESS (HD 5800) .*(AMD|ATI).*Cypress.* 3 1 -AMD HEMLOCK (HD 5970) .*(AMD|ATI).*Hemlock.* 3 1 -AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1 -AMD PARK .*(AMD|ATI).*Park.* 3 1 -AMD REDWOOD (HD 5500/5600) .*(AMD|ATI).*Redwood.* 3 1 -AMD TURKS (HD 6500/6600) .*(AMD|ATI).*Turks.* 3 1 -AMD RS780 (HD 3200) .*RS780.* 0 1 -AMD RS880 (HD 4200) .*RS880.* 1 1 -AMD RV610 (HD 2400) .*RV610.* 1 1 -AMD RV620 (HD 3400) .*RV620.* 1 1 -AMD RV630 (HD 2600) .*RV630.* 2 1 -AMD RV635 (HD 3600) .*RV635.* 3 1 -AMD RV670 (HD 3800) .*RV670.* 3 1 -AMD R680 (HD 3870 X2) .*R680.* 3 1 -AMD R700 (HD 4800 X2) .*R700.* 3 1 -AMD RV710 (HD 4300) .*RV710.* 1 1 -AMD RV730 (HD 4600) .*RV730.* 3 1 -AMD RV740 (HD 4700) .*RV740.* 3 1 -AMD RV770 (HD 4800) .*RV770.* 3 1 -AMD RV790 (HD 4800) .*RV790.* 3 1 -ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 -ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 -ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 -ATI FirePro 2000 .*ATI.*FirePro 2.* 1 1 -ATI FirePro 3000 .*ATI.*FirePro V3.* 1 1 -ATI FirePro 4000 .*ATI.*FirePro V4.* 2 1 -ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 -ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 -ATI FirePro M .*ATI.*FirePro M.* 3 1 -ATI Technologies .*ATI *Technologies.* 0 1 -// This entry is last to work around the "R300" driver problem. -ATI R300 (9700) .*R300.* 1 1 -ATI Radeon .*ATI.*(Diamond|Radeon).* 0 1 -Intel X3100 .*Intel.*X3100.* 0 1 -Intel 830M .*Intel.*830M 0 0 -Intel 845G .*Intel.*845G 0 0 -Intel 855GM .*Intel.*855GM 0 0 -Intel 865G .*Intel.*865G 0 0 -Intel 900 .*Intel.*900.*900 0 0 -Intel 915GM .*Intel.*915GM 0 0 -Intel 915G .*Intel.*915G 0 0 -Intel 945GM .*Intel.*945GM.* 0 1 -Intel 945G .*Intel.*945G.* 0 1 -Intel 950 .*Intel.*950.* 0 1 -Intel 965 .*Intel.*965.* 0 1 -Intel G33 .*Intel.*G33.* 0 0 -Intel G41 .*Intel.*G41.* 0 1 -Intel G45 .*Intel.*G45.* 0 1 -Intel Bear Lake .*Intel.*Bear Lake.* 0 0 -Intel Broadwater .*Intel.*Broadwater.* 0 0 -Intel Brookdale .*Intel.*Brookdale.* 0 0 -Intel Cantiga .*Intel.*Cantiga.* 0 0 -Intel Eaglelake .*Intel.*Eaglelake.* 0 1 -Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 0 1 -Intel HD Graphics .*Intel.*HD Graphics.* 2 1 -Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 -Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 -Intel Montara .*Intel.*Montara.* 0 0 -Intel Pineview .*Intel.*Pineview.* 0 1 -Intel Springdale .*Intel.*Springdale.* 0 0 -Intel HD Graphics 2000 .*Intel.*HD2000.* 1 1 -Intel HD Graphics 3000 .*Intel.*HD3000.* 2 1 -Matrox .*Matrox.* 0 0 -Mesa .*Mesa.* 0 0 -NVIDIA 205 .*NVIDIA .*GeForce 205.* 2 1 -NVIDIA 210 .*NVIDIA .*GeForce 210.* 2 1 -NVIDIA 310M .*NVIDIA .*GeForce 310M.* 1 1 -NVIDIA 310 .*NVIDIA .*GeForce 310.* 3 1 -NVIDIA 315M .*NVIDIA .*GeForce 315M.* 2 1 -NVIDIA 315 .*NVIDIA .*GeForce 315.* 3 1 -NVIDIA 320M .*NVIDIA .*GeForce 320M.* 2 1 -NVIDIA G100M .*NVIDIA .*100M.* 0 1 -NVIDIA G100 .*NVIDIA .*100.* 0 1 -NVIDIA G102M .*NVIDIA .*102M.* 0 1 -NVIDIA G103M .*NVIDIA .*103M.* 0 1 -NVIDIA G105M .*NVIDIA .*105M.* 0 1 -NVIDIA G 110M .*NVIDIA .*110M.* 0 1 -NVIDIA G 120M .*NVIDIA .*120M.* 1 1 -NVIDIA G 200 .*NVIDIA .*200(M)?.* 0 1 -NVIDIA G 205M .*NVIDIA .*205(M)?.* 0 1 -NVIDIA G 210 .*NVIDIA .*210(M)?.* 1 1 -NVIDIA 305M .*NVIDIA .*305(M)?.* 1 1 -NVIDIA G 310M .*NVIDIA .*310(M)?.* 2 1 -NVIDIA G 315 .*NVIDIA .*315(M)?.* 2 1 -NVIDIA G 320M .*NVIDIA .*320(M)?.* 2 1 -NVIDIA G 405 .*NVIDIA .*405(M)?.* 1 1 -NVIDIA G 410M .*NVIDIA .*410(M)?.* 1 1 -NVIDIA GT 120M .*NVIDIA .*GT *120(M)?.* 2 1 -NVIDIA GT 120 .*NVIDIA .*GT.*120 2 1 -NVIDIA GT 130M .*NVIDIA .*GT *130(M)?.* 2 1 -NVIDIA GT 140M .*NVIDIA .*GT *140(M)?.* 2 1 -NVIDIA GT 150M .*NVIDIA .*GT(S)? *150(M)?.* 2 1 -NVIDIA GT 160M .*NVIDIA .*GT *160(M)?.* 2 1 -NVIDIA GT 220M .*NVIDIA .*GT *220(M)?.* 2 1 -NVIDIA GT 230M .*NVIDIA .*GT *230(M)?.* 2 1 -NVIDIA GT 240M .*NVIDIA .*GT *240(M)?.* 2 1 -NVIDIA GT 250M .*NVIDIA .*GT *250(M)?.* 2 1 -NVIDIA GT 260M .*NVIDIA .*GT *260(M)?.* 2 1 -NVIDIA GT 320M .*NVIDIA .*GT *320(M)?.* 2 1 -NVIDIA GT 325M .*NVIDIA .*GT *325(M)?.* 0 1 -NVIDIA GT 330M .*NVIDIA .*GT *330(M)?.* 3 1 -NVIDIA GT 335M .*NVIDIA .*GT *335(M)?.* 1 1 -NVIDIA GT 340M .*NVIDIA .*GT *340(M)?.* 2 1 -NVIDIA GT 415M .*NVIDIA .*GT *415(M)?.* 2 1 -NVIDIA GT 420M .*NVIDIA .*GT *420(M)?.* 2 1 -NVIDIA GT 425M .*NVIDIA .*GT *425(M)?.* 3 1 -NVIDIA GT 430M .*NVIDIA .*GT *430(M)?.* 3 1 -NVIDIA GT 435M .*NVIDIA .*GT *435(M)?.* 3 1 -NVIDIA GT 440M .*NVIDIA .*GT *440(M)?.* 3 1 -NVIDIA GT 445M .*NVIDIA .*GT *445(M)?.* 3 1 -NVIDIA GT 450M .*NVIDIA .*GT *450(M)?.* 3 1 -NVIDIA GT 520M .*NVIDIA .*GT *52.(M)?.* 3 1 -NVIDIA GT 530M .*NVIDIA .*GT *530(M)?.* 3 1 -NVIDIA GT 540M .*NVIDIA .*GT *54.(M)?.* 3 1 -NVIDIA GT 550M .*NVIDIA .*GT *550(M)?.* 3 1 -NVIDIA GT 555M .*NVIDIA .*GT *555(M)?.* 3 1 -NVIDIA GTS 160M .*NVIDIA .*GT(S)? *160(M)?.* 2 1 -NVIDIA GTS 240 .*NVIDIA .*GTS *24.* 3 1 -NVIDIA GTS 250 .*NVIDIA .*GTS *25.* 3 1 -NVIDIA GTS 350M .*NVIDIA .*GTS *350M.* 3 1 -NVIDIA GTS 360M .*NVIDIA .*GTS *360M.* 3 1 -NVIDIA GTS 360 .*NVIDIA .*GTS *360.* 3 1 -NVIDIA GTS 450 .*NVIDIA .*GTS *45.* 3 1 -NVIDIA GTX 260 .*NVIDIA .*GTX *26.* 3 1 -NVIDIA GTX 275 .*NVIDIA .*GTX *275.* 3 1 -NVIDIA GTX 270 .*NVIDIA .*GTX *27.* 3 1 -NVIDIA GTX 285 .*NVIDIA .*GTX *285.* 3 1 -NVIDIA GTX 280 .*NVIDIA .*GTX *280.* 3 1 -NVIDIA GTX 290 .*NVIDIA .*GTX *290.* 3 1 -NVIDIA GTX 295 .*NVIDIA .*GTX *295.* 3 1 -NVIDIA GTX 460M .*NVIDIA .*GTX *460M.* 3 1 -NVIDIA GTX 465 .*NVIDIA .*GTX *465.* 3 1 -NVIDIA GTX 460 .*NVIDIA .*GTX *46.* 3 1 -NVIDIA GTX 470M .*NVIDIA .*GTX *470M.* 3 1 -NVIDIA GTX 470 .*NVIDIA .*GTX *47.* 3 1 -NVIDIA GTX 480M .*NVIDIA .*GTX *480M.* 3 1 -NVIDIA GTX 485M .*NVIDIA .*GTX *485M.* 3 1 -NVIDIA GTX 480 .*NVIDIA .*GTX *48.* 3 1 -NVIDIA GTX 530 .*NVIDIA .*GTX *53.* 3 1 -NVIDIA GTX 550 .*NVIDIA .*GTX *55.* 3 1 -NVIDIA GTX 560 .*NVIDIA .*GTX *56.* 3 1 -NVIDIA GTX 570 .*NVIDIA .*GTX *57.* 3 1 -NVIDIA GTX 580M .*NVIDIA .*GTX *580M.* 3 1 -NVIDIA GTX 580 .*NVIDIA .*GTX *58.* 3 1 -NVIDIA GTX 590 .*NVIDIA .*GTX *59.* 3 1 -NVIDIA C51 .*NVIDIA .*C51.* 0 1 -NVIDIA G72 .*NVIDIA .*G72.* 1 1 -NVIDIA G73 .*NVIDIA .*G73.* 1 1 -NVIDIA G84 .*NVIDIA .*G84.* 2 1 -NVIDIA G86 .*NVIDIA .*G86.* 3 1 -NVIDIA G92 .*NVIDIA .*G92.* 3 1 -NVIDIA GeForce .*GeForce 256.* 0 0 -NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 -NVIDIA GeForce 3 .*GeForce ?3 ?.* 0 1 -NVIDIA GeForce 3 Ti .*GeForce ?3 Ti.* 0 1 -NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 -NVIDIA GeForce 4 Go .*NVIDIA .*GeForce ?4.*Go.* 0 1 -NVIDIA GeForce 4 MX .*NVIDIA .*GeForce ?4 MX.* 0 1 -NVIDIA GeForce 4 PCX .*NVIDIA .*GeForce ?4 PCX.* 0 1 -NVIDIA GeForce 4 Ti .*NVIDIA .*GeForce ?4 Ti.* 0 1 -NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 0 1 -NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1 -NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 0 1 -NVIDIA GeForce 6600 .*NVIDIA .*GeForce 66.* 1 1 -NVIDIA GeForce 6700 .*NVIDIA .*GeForce 67.* 2 1 -NVIDIA GeForce 6800 .*NVIDIA .*GeForce 68.* 2 1 -NVIDIA GeForce 7000 .*NVIDIA .*GeForce 70.* 0 1 -NVIDIA GeForce 7100 .*NVIDIA .*GeForce 71.* 0 1 -NVIDIA GeForce 7200 .*NVIDIA .*GeForce 72.* 1 1 -NVIDIA GeForce 7300 .*NVIDIA .*GeForce 73.* 1 1 -NVIDIA GeForce 7500 .*NVIDIA .*GeForce 75.* 1 1 -NVIDIA GeForce 7600 .*NVIDIA .*GeForce 76.* 2 1 -NVIDIA GeForce 7800 .*NVIDIA .*GeForce 78.* 2 1 -NVIDIA GeForce 7900 .*NVIDIA .*GeForce 79.* 2 1 -NVIDIA GeForce 8100 .*NVIDIA .*GeForce 81.* 1 1 -NVIDIA GeForce 8200M .*NVIDIA .*GeForce 8200M.* 1 1 -NVIDIA GeForce 8200 .*NVIDIA .*GeForce 82.* 1 1 -NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 2 1 -NVIDIA GeForce 8400M .*NVIDIA .*GeForce 8400M.* 2 1 -NVIDIA GeForce 8400 .*NVIDIA .*GeForce 84.* 2 1 -NVIDIA GeForce 8500 .*NVIDIA .*GeForce 85.* 3 1 -NVIDIA GeForce 8600M .*NVIDIA .*GeForce 8600M.* 2 1 -NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1 -NVIDIA GeForce 8700M .*NVIDIA .*GeForce 8700M.* 3 1 -NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1 -NVIDIA GeForce 8800M .*NVIDIA .*GeForce 8800M.* 3 1 -NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1 -NVIDIA GeForce 9100M .*NVIDIA .*GeForce 9100M.* 0 1 -NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1 -NVIDIA GeForce 9200M .*NVIDIA .*GeForce 9200M.* 1 1 -NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1 -NVIDIA GeForce 9300M .*NVIDIA .*GeForce 9300M.* 2 1 -NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 2 1 -NVIDIA GeForce 9400M .*NVIDIA .*GeForce 9400M.* 2 1 -NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 2 1 -NVIDIA GeForce 9500M .*NVIDIA .*GeForce 9500M.* 2 1 -NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 2 1 -NVIDIA GeForce 9600M .*NVIDIA .*GeForce 9600M.* 3 1 -NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 2 1 -NVIDIA GeForce 9700M .*NVIDIA .*GeForce 9700M.* 2 1 -NVIDIA GeForce 9800M .*NVIDIA .*GeForce 9800M.* 3 1 -NVIDIA GeForce 9800 .*NVIDIA .*GeForce 98.* 3 1 -NVIDIA GeForce FX 5100 .*NVIDIA .*GeForce FX 51.* 0 1 -NVIDIA GeForce FX 5200 .*NVIDIA .*GeForce FX 52.* 0 1 -NVIDIA GeForce FX 5300 .*NVIDIA .*GeForce FX 53.* 0 1 -NVIDIA GeForce FX 5500 .*NVIDIA .*GeForce FX 55.* 0 1 -NVIDIA GeForce FX 5600 .*NVIDIA .*GeForce FX 56.* 0 1 -NVIDIA GeForce FX 5700 .*NVIDIA .*GeForce FX 57.* 1 1 -NVIDIA GeForce FX 5800 .*NVIDIA .*GeForce FX 58.* 1 1 -NVIDIA GeForce FX 5900 .*NVIDIA .*GeForce FX 59.* 1 1 -NVIDIA GeForce FX Go5100 .*NVIDIA .*GeForce FX Go51.* 0 1 -NVIDIA GeForce FX Go5200 .*NVIDIA .*GeForce FX Go52.* 0 1 -NVIDIA GeForce FX Go5300 .*NVIDIA .*GeForce FX Go53.* 0 1 -NVIDIA GeForce FX Go5500 .*NVIDIA .*GeForce FX Go55.* 0 1 -NVIDIA GeForce FX Go5600 .*NVIDIA .*GeForce FX Go56.* 0 1 -NVIDIA GeForce FX Go5700 .*NVIDIA .*GeForce FX Go57.* 1 1 -NVIDIA GeForce FX Go5800 .*NVIDIA .*GeForce FX Go58.* 1 1 -NVIDIA GeForce FX Go5900 .*NVIDIA .*GeForce FX Go59.* 1 1 -NVIDIA GeForce FX Go5xxx .*NVIDIA .*GeForce FX Go.* 0 1 -NVIDIA GeForce Go 6100 .*NVIDIA .*GeForce Go 61.* 0 1 -NVIDIA GeForce Go 6200 .*NVIDIA .*GeForce Go 62.* 0 1 -NVIDIA GeForce Go 6400 .*NVIDIA .*GeForce Go 64.* 1 1 -NVIDIA GeForce Go 6500 .*NVIDIA .*GeForce Go 65.* 1 1 -NVIDIA GeForce Go 6600 .*NVIDIA .*GeForce Go 66.* 1 1 -NVIDIA GeForce Go 6700 .*NVIDIA .*GeForce Go 67.* 1 1 -NVIDIA GeForce Go 6800 .*NVIDIA .*GeForce Go 68.* 1 1 -NVIDIA GeForce Go 7200 .*NVIDIA .*GeForce Go 72.* 1 1 -NVIDIA GeForce Go 7300 LE .*NVIDIA .*GeForce Go 73.*LE.* 0 1 -NVIDIA GeForce Go 7300 .*NVIDIA .*GeForce Go 73.* 1 1 -NVIDIA GeForce Go 7400 .*NVIDIA .*GeForce Go 74.* 1 1 -NVIDIA GeForce Go 7600 .*NVIDIA .*GeForce Go 76.* 2 1 -NVIDIA GeForce Go 7700 .*NVIDIA .*GeForce Go 77.* 2 1 -NVIDIA GeForce Go 7800 .*NVIDIA .*GeForce Go 78.* 2 1 -NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 2 1 -NVIDIA D9M .*NVIDIA .*D9M.* 1 1 -NVIDIA G94 .*NVIDIA .*G94.* 3 1 -NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 -NVIDIA ION 2 .*NVIDIA .*ION 2.* 2 1 -NVIDIA ION .*NVIDIA .*ION.* 2 1 -NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1 -NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1 -NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1 -NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1 -NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1 -NVIDIA N10 .*NVIDIA .*N10.* 1 1 -NVIDIA GeForce PCX .*GeForce PCX.* 0 1 -NVIDIA Generic .*NVIDIA .*Unknown.* 0 0 -NVIDIA NV17 .*NVIDIA .*NV17.* 0 1 -NVIDIA NV34 .*NVIDIA .*NV34.* 0 1 -NVIDIA NV35 .*NVIDIA .*NV35.* 0 1 -NVIDIA NV36 .*NVIDIA .*NV36.* 1 1 -NVIDIA NV41 .*NVIDIA .*NV41.* 1 1 -NVIDIA NV43 .*NVIDIA .*NV43.* 1 1 -NVIDIA NV44 .*NVIDIA .*NV44.* 1 1 -NVIDIA nForce .*NVIDIA .*nForce.* 0 0 -NVIDIA MCP51 .*NVIDIA .*MCP51.* 1 1 -NVIDIA MCP61 .*NVIDIA .*MCP61.* 1 1 -NVIDIA MCP67 .*NVIDIA .*MCP67.* 1 1 -NVIDIA MCP68 .*NVIDIA .*MCP68.* 1 1 -NVIDIA MCP73 .*NVIDIA .*MCP73.* 1 1 -NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1 -NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1 -NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1 -NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1 -NVIDIA Quadro2 .*Quadro2.* 0 1 -NVIDIA Quadro 1000M .*Quadro.*1000M.* 2 1 -NVIDIA Quadro 2000 M/D .*Quadro.*2000.* 3 1 -NVIDIA Quadro 3000M .*Quadro.*3000M.* 3 1 -NVIDIA Quadro 4000M .*Quadro.*4000M.* 3 1 -NVIDIA Quadro 4000 .*Quadro *4000.* 3 1 -NVIDIA Quadro 50x0 M .*Quadro.*50.0.* 3 1 -NVIDIA Quadro 6000 .*Quadro.*6000.* 3 1 -NVIDIA Quadro 400 .*Quadro.*400.* 2 1 -NVIDIA Quadro 600 .*Quadro.*600.* 2 1 -NVIDIA Quadro4 .*Quadro4.* 0 1 -NVIDIA Quadro DCC .*Quadro DCC.* 0 1 -NVIDIA Quadro CX .*Quadro.*CX.* 3 1 -NVIDIA Quadro FX 770M .*Quadro.*FX *770M.* 2 1 -NVIDIA Quadro FX 1500M .*Quadro.*FX *1500M.* 1 1 -NVIDIA Quadro FX 1600M .*Quadro.*FX *1600M.* 2 1 -NVIDIA Quadro FX 2500M .*Quadro.*FX *2500M.* 2 1 -NVIDIA Quadro FX 2700M .*Quadro.*FX *2700M.* 3 1 -NVIDIA Quadro FX 2800M .*Quadro.*FX *2800M.* 3 1 -NVIDIA Quadro FX 3500 .*Quadro.*FX *3500.* 2 1 -NVIDIA Quadro FX 3600 .*Quadro.*FX *3600.* 3 1 -NVIDIA Quadro FX 3700 .*Quadro.*FX *3700.* 3 1 -NVIDIA Quadro FX 3800 .*Quadro.*FX *3800.* 3 1 -NVIDIA Quadro FX 4500 .*Quadro.*FX *45.* 3 1 -NVIDIA Quadro FX 880M .*Quadro.*FX *880M.* 3 1 -NVIDIA Quadro FX 4800 .*NVIDIA .*Quadro *FX *4800.* 3 1 -NVIDIA Quadro FX .*Quadro FX.* 1 1 -NVIDIA Quadro NVS 1xxM .*Quadro NVS *1.[05]M.* 0 1 -NVIDIA Quadro NVS 300M .*NVIDIA .*NVS *300M.* 2 1 -NVIDIA Quadro NVS 320M .*NVIDIA .*NVS *320M.* 2 1 -NVIDIA Quadro NVS 2100M .*NVIDIA .*NVS *2100M.* 2 1 -NVIDIA Quadro NVS 3100M .*NVIDIA .*NVS *3100M.* 2 1 -NVIDIA Quadro NVS 4200M .*NVIDIA .*NVS *4200M.* 2 1 -NVIDIA Quadro NVS 5100M .*NVIDIA .*NVS *5100M.* 2 1 -NVIDIA Quadro NVS .*NVIDIA .*NVS 0 1 -NVIDIA RIVA TNT .*RIVA TNT.* 0 0 -S3 .*S3 Graphics.* 0 0 -SiS SiS.* 0 0 -Trident Trident.* 0 0 -Tungsten Graphics Tungsten.* 0 0 -XGI XGI.* 0 0 -VIA VIA.* 0 0 -Apple Generic Apple.*Generic.* 0 0 -Apple Software Renderer Apple.*Software Renderer.* 0 0 -Humper Humper.* 0 1 +3Dfx .*3Dfx.* 0 0 0 0 +3Dlabs .*3Dlabs.* 0 0 0 0 +ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 0 0 +ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 0 0 +ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 0 0 +ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 0 0 +ATI All-in-Wonder 9xxx .*ATI.*All-in-Wonder 9.* 1 1 0 0 +ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 1 3.3 +ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 0 0 +ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 1 1 1 2.1 +ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 0 0 +ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 0 0 +ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 0 0 +ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 0 0 +ATI ASUS ARES .*ATI.*ASUS.*ARES.* 3 1 0 0 +ATI ASUS A9xxx .*ATI.*ASUS.*A9.* 1 1 0 0 +ATI ASUS AH24xx .*ATI.*ASUS.*AH24.* 1 1 1 3.3 +ATI ASUS AH26xx .*ATI.*ASUS.*AH26.* 1 1 1 3.3 +ATI ASUS AH34xx .*ATI.*ASUS.*AH34.* 1 1 1 3.3 +ATI ASUS AH36xx .*ATI.*ASUS.*AH36.* 1 1 1 3.3 +ATI ASUS AH46xx .*ATI.*ASUS.*AH46.* 2 1 1 3.3 +ATI ASUS AX3xx .*ATI.*ASUS.*AX3.* 1 1 0 0 +ATI ASUS AX5xx .*ATI.*ASUS.*AX5.* 1 1 0 0 +ATI ASUS AX8xx .*ATI.*ASUS.*AX8.* 2 1 0 0 +ATI ASUS EAH24xx .*ATI.*ASUS.*EAH24.* 2 1 0 0 +ATI ASUS EAH26xx .*ATI.*ASUS.*EAH26.* 3 1 0 0 +ATI ASUS EAH29xx .*ATI.*ASUS.*EAH29.* 3 1 0 0 +ATI ASUS EAH34xx .*ATI.*ASUS.*EAH34.* 1 1 0 0 +ATI ASUS EAH36xx .*ATI.*ASUS.*EAH36.* 2 1 0 0 +ATI ASUS EAH38xx .*ATI.*ASUS.*EAH38.* 2 1 1 3.3 +ATI ASUS EAH43xx .*ATI.*ASUS.*EAH43.* 2 1 1 3.3 +ATI ASUS EAH45xx .*ATI.*ASUS.*EAH45.* 2 1 0 0 +ATI ASUS EAH48xx .*ATI.*ASUS.*EAH48.* 3 1 1 3.3 +ATI ASUS EAH57xx .*ATI.*ASUS.*EAH57.* 3 1 1 4.1 +ATI ASUS EAH58xx .*ATI.*ASUS.*EAH58.* 5 1 1 4.1 +ATI ASUS EAH62xx .*ATI.*ASUS.*EAH62.* 2 1 0 0 +ATI ASUS EAH63xx .*ATI.*ASUS.*EAH63.* 2 1 0 0 +ATI ASUS EAH64xx .*ATI.*ASUS.*EAH64.* 2 1 0 0 +ATI ASUS EAH65xx .*ATI.*ASUS.*EAH65.* 2 1 0 4.1 +ATI ASUS EAH66xx .*ATI.*ASUS.*EAH66.* 3 1 0 4.1 +ATI ASUS EAH67xx .*ATI.*ASUS.*EAH67.* 3 1 0 0 +ATI ASUS EAH68xx .*ATI.*ASUS.*EAH68.* 5 1 0 4 +ATI ASUS EAH69xx .*ATI.*ASUS.*EAH69.* 5 1 0 4.1 +ATI ASUS Radeon X1xxx .*ATI.*ASUS.*X1.* 2 1 1 2.1 +ATI Radeon X7xx .*ATI.*ASUS.*X7.* 1 1 0 0 +ATI Radeon X19xx .*ATI.*(Radeon|Diamond) X19.* ?.* 2 1 1 2.1 +ATI Radeon X18xx .*ATI.*(Radeon|Diamond) X18.* ?.* 3 1 1 2.1 +ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 1 1 1 2.1 +ATI Radeon X16xx .*ATI.*(Radeon|Diamond) X16.* ?.* 1 1 1 2.1 +ATI Radeon X15xx .*ATI.*(Radeon|Diamond) X15.* ?.* 1 1 1 2.1 +ATI Radeon X13xx .*ATI.*(Radeon|Diamond) X13.* ?.* 1 1 1 2.1 +ATI Radeon X1xxx .*ATI.*(Radeon|Diamond) X1.. ?.* 0 1 1 2.1 +ATI Radeon X2xxx .*ATI.*(Radeon|Diamond) X2.. ?.* 1 1 1 2.1 +ATI Display Adapter .*ATI.*display adapter.* 1 1 1 4.1 +ATI FireGL 5200 .*ATI.*FireGL V52.* 1 1 1 2.1 +ATI FireGL 5xxx .*ATI.*FireGL V5.* 2 1 1 3.3 +ATI FireGL .*ATI.*Fire.*GL.* 4 1 1 4.2 +ATI FirePro M3900 .*ATI.*FirePro.*M39.* 2 1 0 0 +ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1 0 0 +ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1 0 0 +ATI FirePro M7820 .*ATI.*FirePro.*M78.* 5 1 1 4.2 +ATI FireMV .*ATI.*FireMV.* 0 1 1 1.3 +ATI Generic .*ATI.*Generic.* 0 0 0 0 +ATI Hercules 9800 .*ATI.*Hercules.*9800.* 1 1 0 0 +ATI IGP 340M .*ATI.*IGP.*340M.* 0 0 0 0 +ATI M52 .*ATI.*M52.* 1 1 0 0 +ATI M54 .*ATI.*M54.* 1 1 0 0 +ATI M56 .*ATI.*M56.* 1 1 0 0 +ATI M71 .*ATI.*M71.* 1 1 0 0 +ATI M72 .*ATI.*M72.* 1 1 0 0 +ATI M76 .*ATI.*M76.* 3 1 0 0 +ATI Radeon HD 64xx .*ATI.*AMD Radeon.* HD [67]4..[MG] 2 1 1 4.2 +ATI Radeon HD 65xx .*ATI.*AMD Radeon.* HD [67]5..[MG] 2 1 1 4.2 +ATI Radeon HD 66xx .*ATI.*AMD Radeon.* HD [67]6..[MG] 3 1 1 4.2 +ATI Radeon HD 7100 .*ATI.*AMD Radeon.* HD 71.* 2 1 0 0 +ATI Radeon HD 7200 .*ATI.*AMD Radeon.* HD 72.* 2 1 0 0 +ATI Radeon HD 7300 .*ATI.*AMD Radeon.* HD 73.* 2 1 0 4.2 +ATI Radeon HD 7400 .*ATI.*AMD Radeon.* HD 74.* 2 1 0 4.2 +ATI Radeon HD 7500 .*ATI.*AMD Radeon.* HD 75.* 3 1 1 4.2 +ATI Radeon HD 7600 .*ATI.*AMD Radeon.* HD 76.* 3 1 0 4.2 +ATI Radeon HD 7700 .*ATI.*AMD Radeon.* HD 77.* 4 1 1 4.2 +ATI Radeon HD 7800 .*ATI.*AMD Radeon.* HD 78.* 5 1 1 4.2 +ATI Radeon HD 7900 .*ATI.*AMD Radeon.* HD 79.* 5 1 1 4.2 +ATI ASUS HD7100 .*ATI.*ASUS.* HD71.* 2 1 0 0 +ATI ASUS HD7200 .*ATI.*ASUS.* HD72.* 2 1 0 0 +ATI ASUS HD7300 .*ATI.*ASUS.* HD73.* 2 1 0 0 +ATI ASUS HD7400 .*ATI.*ASUS.* HD74.* 2 1 0 0 +ATI ASUS HD7500 .*ATI.*ASUS.* HD75.* 3 1 1 4.2 +ATI ASUS HD7600 .*ATI.*ASUS.* HD76.* 3 1 0 0 +ATI ASUS HD7700 .*ATI.*ASUS.* HD77.* 4 1 1 4.2 +ATI ASUS HD7800 .*ATI.*ASUS.* HD78.* 5 1 1 4.2 +ATI ASUS HD7900 .*ATI.*ASUS.* HD79.* 5 1 1 4.2 +ATI Mobility Radeon 4100 .*ATI.*Mobility.*41.. 1 1 1 3.3 +ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1 1 1.3 +ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1 0 0 +ATI Mobility Radeon 9800 .*ATI.*Mobility.*98.* 1 1 0 0 +ATI Mobility Radeon 9700 .*ATI.*Mobility.*97.* 0 1 1 2.1 +ATI Mobility Radeon 9600 .*ATI.*Mobility.*96.* 1 1 1 2.1 +ATI Mobility Radeon HD 530v .*ATI.*Mobility.*HD *530v.* 1 1 1 3.3 +ATI Mobility Radeon HD 540v .*ATI.*Mobility.*HD *540v.* 1 1 1 3.3 +ATI Mobility Radeon HD 545v .*ATI.*Mobility.*HD *545v.* 2 1 1 4 +ATI Mobility Radeon HD 550v .*ATI.*Mobility.*HD *550v.* 3 1 1 4 +ATI Mobility Radeon HD 560v .*ATI.*Mobility.*HD *560v.* 3 1 1 3.2 +ATI Mobility Radeon HD 565v .*ATI.*Mobility.*HD *565v.* 3 1 1 3.3 +ATI Mobility Radeon HD 2300 .*ATI.*Mobility.*HD *23.* 0 1 1 2.1 +ATI Mobility Radeon HD 2400 .*ATI.*Mobility.*HD *24.* 1 1 1 3.3 +ATI Mobility Radeon HD 2600 .*ATI.*Mobility.*HD *26.* 1 1 1 3.3 +ATI Mobility Radeon HD 2700 .*ATI.*Mobility.*HD *27.* 3 1 0 0 +ATI Mobility Radeon HD 3100 .*ATI.*Mobility.*HD *31.* 0 1 0 0 +ATI Mobility Radeon HD 3200 .*ATI.*Mobility.*HD *32.* 0 1 0 0 +ATI Mobility Radeon HD 3400 .*ATI.*Mobility.*HD *34.* 1 1 1 3.3 +ATI Mobility Radeon HD 3600 .*ATI.*Mobility.*HD *36.* 1 1 1 4 +ATI Mobility Radeon HD 3800 .*ATI.*Mobility.*HD *38.* 3 1 1 3.3 +ATI Mobility Radeon HD 4200 .*ATI.*Mobility.*HD *42.* 1 1 1 4 +ATI Mobility Radeon HD 4300 .*ATI.*Mobility.*HD *43.* 1 1 1 4 +ATI Mobility Radeon HD 4500 .*ATI.*Mobility.*HD *45.* 1 1 1 4 +ATI Mobility Radeon HD 4600 .*ATI.*Mobility.*HD *46.* 2 1 1 3.3 +ATI Mobility Radeon HD 4800 .*ATI.*Mobility.*HD *48.* 3 1 1 3.3 +ATI Mobility Radeon HD 5100 .*ATI.*Mobility.*HD *51.* 3 1 1 3.2 +ATI Mobility Radeon HD 5300 .*ATI.*Mobility.*HD *53.* 3 1 0 0 +ATI Mobility Radeon HD 5400 .*ATI.*Mobility.*HD *54.* 2 1 1 4.2 +ATI Mobility Radeon HD 5500 .*ATI.*Mobility.*HD *55.* 3 1 0 0 +ATI Mobility Radeon HD 5600 .*ATI.*Mobility.*HD *56.* 3 1 1 4.2 +ATI Mobility Radeon HD 5700 .*ATI.*Mobility.*HD *57.* 3 1 1 4.1 +ATI Mobility Radeon HD 6200 .*ATI.*Mobility.*HD *62.* 3 1 0 0 +ATI Mobility Radeon HD 6300 .*ATI.*Mobility.*HD *63.* 3 1 1 4.2 +ATI Mobility Radeon HD 6400M .*ATI.*Mobility.*HD *64.* 3 1 0 0 +ATI Mobility Radeon HD 6500M .*ATI.*Mobility.*HD *65.* 5 1 1 4.2 +ATI Mobility Radeon HD 6600M .*ATI.*Mobility.*HD *66.* 5 1 0 0 +ATI Mobility Radeon HD 6700M .*ATI.*Mobility.*HD *67.* 5 1 0 0 +ATI Mobility Radeon HD 6800M .*ATI.*Mobility.*HD *68.* 5 1 0 0 +ATI Mobility Radeon HD 6900M .*ATI.*Mobility.*HD *69.* 5 1 0 0 +ATI Radeon HD 2300 .*ATI.*Radeon HD *23.. 0 1 1 3.3 +ATI Radeon HD 2400 .*ATI.*Radeon HD *24.. 1 1 1 4 +ATI Radeon HD 2600 .*ATI.*Radeon HD *26.. 2 1 1 3.3 +ATI Radeon HD 2900 .*ATI.*Radeon HD *29.. 3 1 1 3.3 +ATI Radeon HD 3000 .*ATI.*Radeon HD *30.. 0 1 0 0 +ATI Radeon HD 3100 .*ATI.*Radeon HD *31.. 1 1 0 0 +ATI Radeon HD 3200 .*ATI.*Radeon HD *32.. 1 1 1 4 +ATI Radeon HD 3300 .*ATI.*Radeon HD *33.. 1 1 1 3.3 +ATI Radeon HD 3400 .*ATI.*Radeon HD *34.. 1 1 1 4 +ATI Radeon HD 3500 .*ATI.*Radeon HD *35.. 2 1 0 0 +ATI Radeon HD 3600 .*ATI.*Radeon HD *36.. 3 1 1 3.3 +ATI Radeon HD 3700 .*ATI.*Radeon HD *37.. 3 1 0 0 +ATI HD3700 .*ATI.* HD37.. 3 1 0 3.3 +ATI Radeon HD 3800 .*ATI.*Radeon HD *38.. 3 1 1 4 +ATI Radeon HD 4100 .*ATI.*Radeon HD *41.. 1 1 0 0 +ATI Radeon HD 4200 .*ATI.*Radeon HD *42.. 1 1 1 4 +ATI Radeon HD 4300 .*ATI.*Radeon HD *43.. 2 1 1 4 +ATI Radeon HD 4400 .*ATI.*Radeon HD *44.. 2 1 0 0 +ATI Radeon HD 4500 .*ATI.*Radeon HD *45.. 2 1 1 3.3 +ATI Radeon HD 4600 .*ATI.*Radeon HD *46.. 3 1 1 4 +ATI Radeon HD 4700 .*ATI.*Radeon HD *47.. 3 1 1 3.3 +ATI Radeon HD 4800 .*ATI.*Radeon HD *48.. 3 1 1 4 +ATI ASUS EAH5400 .*ATI.*ASUS EAH54.. 3 1 1 4.2 +ATI Radeon HD 5400 .*ATI.*Radeon HD *54.. 3 1 1 4.2 +ATI Radeon HD 5500 .*ATI.*Radeon HD *55.. 3 1 1 4.2 +ATI ASUS EAH5500 .*ATI.*ASUS EAH55.. 3 1 1 4.2 +ATI Radeon HD 5600 .*ATI.*Radeon HD *56.. 3 1 1 4.2 +ATI Radeon HD 5700 .*ATI.*Radeon HD *57.. 3 1 1 4.2 +ATI Radeon HD 5800 .*ATI.*Radeon HD *58.. 4 1 1 4.2 +ATI Radeon HD 5900 .*ATI.*Radeon HD *59.. 4 1 1 4.2 +ATI Radeon HD 6200 .*ATI.*Radeon HD *62.. 0 1 1 4.2 +ATI Radeon HD 6300 .*ATI.*Radeon HD *63.. 1 1 1 4.2 +ATI Radeon HD 6400 .*ATI.*Radeon HD *64.. 3 1 1 4.2 +ATI Radeon HD 6500 .*ATI.*Radeon HD *65.. 3 1 1 4.2 +ATI Radeon HD 6600 .*ATI.*Radeon HD *66.. 3 1 1 4.2 +ATI Radeon HD 6700 .*ATI.*Radeon HD *67.. 3 1 1 4.2 +ATI Radeon HD 6800 .*ATI.*Radeon HD *68.. 4 1 1 4.2 +ATI Radeon HD 6900 .*ATI.*Radeon HD *69.. 5 1 1 4.2 +ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 0 0 +ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1 1 2.1 +ATI Radeon 3000 .*ATI.*Radeon 30.. 1 1 1 4 +ATI Radeon 3100 .*ATI.*Radeon 31.. 0 1 1 3.3 +ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1 0 0 +ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1 1 2 +ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1 0 0 +ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1 1 1.3 +ATI Radeon 9100 .*ATI.*Radeon 91.. 0 1 0 0 +ATI Radeon 9200 .*ATI.*Radeon 92.. 0 1 1 1.3 +ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1 1 2.1 +ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1 1 2.1 +ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1 0 0 +ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1 1 2.1 +ATI Radeon RV250 .*ATI.*RV250.* 0 1 0 0 +ATI Radeon RV600 .*ATI.*RV6.* 1 1 0 0 +ATI Radeon RX700 .*ATI.*RX70.* 1 1 0 0 +ATI Radeon RX800 .*ATI.*Radeon *RX80.* 2 1 0 0 +ATI RS880M .*ATI.*RS880M 1 1 0 0 +ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 0 0 +ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 0 0 +ATI Radeon X300 .*ATI.*Radeon *X3.* 1 1 1 2.1 +ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1 0 0 +ATI Radeon X500 .*ATI.*Radeon ?X5.* 1 1 1 2.1 +ATI Radeon X600 .*ATI.*Radeon ?X6.* 1 1 1 2.1 +ATI Radeon X700 .*ATI.*Radeon ?X7.* 2 1 1 2.1 +ATI Radeon X800 .*ATI.*Radeon ?X8.* 1 1 1 2.1 +ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1 0 0 +ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1 1 2.1 +ATI Rage 128 .*ATI.*Rage 128.* 0 1 0 0 +ATI R300 (9700) .*R300.* 0 1 1 2.1 +ATI R350 (9800) .*R350.* 1 1 0 0 +ATI R580 (X1900) .*R580.* 3 1 0 0 +ATI RC410 (Xpress 200) .*RC410.* 0 0 0 0 +ATI RS48x (Xpress 200x) .*RS48.* 0 0 0 0 +ATI RS600 (Xpress 3200) .*RS600.* 0 0 0 0 +ATI RV350 (9600) .*RV350.* 0 1 0 0 +ATI RV370 (X300) .*RV370.* 0 1 0 0 +ATI RV410 (X700) .*RV410.* 1 1 0 0 +ATI RV515 .*RV515.* 1 1 0 0 +ATI RV570 (X1900 GT/PRO) .*RV570.* 3 1 0 0 +ATI RV380 .*RV380.* 0 1 0 0 +ATI RV530 .*RV530.* 1 1 0 0 +ATI RX480 (Xpress 200P) .*RX480.* 0 1 0 0 +ATI RX700 .*RX700.* 1 1 0 0 +AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1 0 0 +AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 1 2.1 +AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1 0 0 +AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1 0 0 +AMD CEDAR (HD 5450) .*(AMD|ATI).*Cedar.* 2 1 0 0 +AMD CYPRESS (HD 5800) .*(AMD|ATI).*Cypress.* 3 1 0 0 +AMD HEMLOCK (HD 5970) .*(AMD|ATI).*Hemlock.* 3 1 0 0 +AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1 0 0 +AMD PARK .*(AMD|ATI).*Park.* 3 1 0 0 +AMD REDWOOD (HD 5500/5600) .*(AMD|ATI).*Redwood.* 3 1 0 0 +AMD TURKS (HD 6500/6600) .*(AMD|ATI).*Turks.* 3 1 0 0 +AMD RS780 (HD 3200) .*RS780.* 0 1 1 2.1 +AMD RS880 (HD 4200) .*RS880.* 0 1 1 3.2 +AMD RV610 (HD 2400) .*RV610.* 1 1 0 0 +AMD RV620 (HD 3400) .*RV620.* 1 1 0 0 +AMD RV630 (HD 2600) .*RV630.* 2 1 0 0 +AMD RV635 (HD 3600) .*RV635.* 3 1 0 0 +AMD RV670 (HD 3800) .*RV670.* 3 1 0 0 +AMD R680 (HD 3870 X2) .*R680.* 3 1 0 0 +AMD R700 (HD 4800 X2) .*R700.* 3 1 0 0 +AMD RV710 (HD 4300) .*RV710.* 0 1 1 1.4 +AMD RV730 (HD 4600) .*RV730.* 3 1 0 0 +AMD RV740 (HD 4700) .*RV740.* 3 1 0 0 +AMD RV770 (HD 4800) .*RV770.* 3 1 0 0 +AMD RV790 (HD 4800) .*RV790.* 3 1 0 0 +ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 1 3.3 +ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 0 0 +ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 0 0 +ATI FirePro 2000 .*ATI.*FirePro 2.* 2 1 1 4.1 +ATI FirePro 3000 .*ATI.*FirePro V3.* 2 1 0 0 +ATI FirePro 4000 .*ATI.*FirePro V4.* 2 1 0 0 +ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 0 0 +ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 0 0 +ATI FirePro M .*ATI.*FirePro M.* 3 1 1 4.2 +ATI R300 (9700) .*R300.* 0 1 1 2.1 +ATI Radeon .*ATI.*(Diamond|Radeon).* 0 1 0 4.2 +Intel X3100 .*Intel.*X3100.* 1 1 1 2.1 +Intel GMA 3600 .*Intel.* 3600.* 0 1 1 3 +Intel 830M .*Intel.*830M 0 0 0 0 +Intel 845G .*Intel.*845G 0 0 1 1.4 +Intel 855GM .*Intel.*855GM 0 0 1 1.4 +Intel 865G .*Intel.*865G 0 0 1 1.4 +Intel 900 .*Intel.*900.*900 0 0 0 0 +Intel 915GM .*Intel.*915GM 0 0 1 1.4 +Intel 915G .*Intel.*915G 0 0 1 1.4 +Intel 945GM .*Intel.*945GM.* 0 1 1 1.4 +Intel 945G .*Intel.*945G.* 0 1 1 1.4 +Intel 950 .*Intel.*950.* 0 1 1 1.4 +Intel 965 .*Intel.*965.* 0 1 1 2.1 +Intel G33 .*Intel.*G33.* 1 0 1 1.4 +Intel G41 .*Intel.*G41.* 1 1 1 2.1 +Intel G45 .*Intel.*G45.* 1 1 1 2.1 +Intel Bear Lake .*Intel.*Bear Lake.* 1 0 1 1.4 +Intel Broadwater .*Intel.*Broadwater.* 0 0 1 1.4 +Intel Brookdale .*Intel.*Brookdale.* 0 0 1 1.3 +Intel Cantiga .*Intel.*Cantiga.* 0 0 1 2 +Intel Eaglelake .*Intel.*Eaglelake.* 1 1 1 2 +Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 1 1 1 2.1 +Intel HD Graphics 2000 .*Intel.*HD Graphics 2.* 2 1 0 4 +Intel HD Graphics 3000 .*Intel.*HD Graphics 3.* 3 1 1 3.1 +Intel HD Graphics 4000 .*Intel.*HD Graphics 4.* 3 1 1 4 +Intel HD2000 .*Intel.*HD2000.* 2 1 0 0 +Intel HD3000 .*Intel.*HD3000.* 3 1 0 0 +Intel HD Graphics .*Intel.*HD Graphics.* 2 1 1 4 +Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 1 2.1 +Intel 4 Series Internal .*Intel.* 4 Series Internal.* 1 1 1 2.1 +Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 0 0 +Intel Montara .*Intel.*Montara.* 0 0 1 1.3 +Intel Pineview .*Intel.*Pineview.* 0 1 1 1.4 +Intel Springdale .*Intel.*Springdale.* 0 0 1 1.3 +Intel Grantsdale .*Intel.*Grantsdale.* 1 1 0 0 +Intel Q45/Q43 .*Intel.*Q4.* 1 1 1 2.1 +Intel B45/B43 .*Intel.*B4.* 1 1 1 2.1 +Intel 3D-Analyze .*Intel.*3D-Analyze.* 2 1 0 0 +Matrox .*Matrox.* 0 0 0 0 +Mesa .*Mesa.* 1 0 1 2.1 +Gallium .*Gallium.* 1 1 1 2.1 +NVIDIA G100M .*NVIDIA .*100M.* 4 1 1 3.3 +NVIDIA G102M .*NVIDIA .*102M.* 1 1 1 3.3 +NVIDIA G103M .*NVIDIA .*103M.* 2 1 1 3.3 +NVIDIA G105M .*NVIDIA .*105M.* 2 1 1 3.3 +NVIDIA G 110M .*NVIDIA .*110M.* 1 1 1 3.3 +NVIDIA G 120M .*NVIDIA .*120M.* 1 1 1 3.3 +NVIDIA G 205M .*NVIDIA .*205M.* 1 1 0 0 +NVIDIA G 410M .*NVIDIA .*410M.* 3 1 1 4.2 +NVIDIA GT 120M .*NVIDIA .*GT *12*M.* 3 1 1 3.3 +NVIDIA GT 130M .*NVIDIA .*GT *13*M.* 3 1 1 3.3 +NVIDIA GT 140M .*NVIDIA .*GT *14*M.* 3 1 1 3.3 +NVIDIA GT 150M .*NVIDIA .*GTS *15*M.* 2 1 0 0 +NVIDIA GTS 160M .*NVIDIA .*GTS *16*M.* 2 1 0 0 +NVIDIA G210M .*NVIDIA .*G21*M.* 3 1 0 0 +NVIDIA GT 220M .*NVIDIA .*GT *22*M.* 3 1 1 3.3 +NVIDIA GT 230M .*NVIDIA .*GT *23*M.* 3 1 1 3.3 +NVIDIA GT 240M .*NVIDIA .*GT *24*M.* 3 1 1 3.3 +NVIDIA GTS 250M .*NVIDIA .*GTS *25*M.* 3 1 0 0 +NVIDIA GTS 260M .*NVIDIA .*GTS *26*M.* 3 1 0 0 +NVIDIA GTX 260M .*NVIDIA .*GTX *26*M.* 3 1 0 0 +NVIDIA GTX 270M .*NVIDIA .*GTX *27*M.* 3 1 0 0 +NVIDIA GTX 280M .*NVIDIA .*GTX *28*M.* 3 1 0 0 +NVIDIA 300M .*NVIDIA .*30*M.* 3 1 1 4.2 +NVIDIA G 310M .*NVIDIA .*31*M.* 2 1 0 0 +NVIDIA GT 320M .*NVIDIA .*GT *32*M.* 3 1 0 0 +NVIDIA GT 325M .*NVIDIA .*GT *32*M.* 3 1 1 3.3 +NVIDIA GT 330M .*NVIDIA .*GT *33*M.* 3 1 1 3.3 +NVIDIA GT 340M .*NVIDIA .*GT *34*M.* 4 1 1 3.3 +NVIDIA GTS 350M .*NVIDIA .*GTS *35*M.* 4 1 1 3.3 +NVIDIA GTS 360M .*NVIDIA .*GTS *360M.* 5 1 1 3.3 +NVIDIA 405M .*NVIDIA .* 40*M.* 2 1 0 4.2 +NVIDIA 410M .*NVIDIA .* 41*M.* 3 1 0 0 +NVIDIA GT 415M .*NVIDIA .*GT *41*M.* 3 1 1 4.2 +NVIDIA GT 420M .*NVIDIA .*GT *42*M.* 3 1 1 4.2 +NVIDIA GT 430M .*NVIDIA .*GT *43*M.* 3 1 1 4.2 +NVIDIA GT 440M .*NVIDIA .*GT *44*M.* 3 1 1 4.2 +NVIDIA GT 450M .*NVIDIA .*GT *45*M.* 3 1 0 0 +NVIDIA GTX 460M .*NVIDIA .*GTX *46*M.* 4 1 1 4.2 +NVIDIA GTX 470M .*NVIDIA .*GTX *47*M.* 3 1 0 0 +NVIDIA GTX 480M .*NVIDIA .*GTX *48*M.* 3 1 1 4.2 +NVIDIA GT 520M .*NVIDIA .*GT *52*M.* 3 1 1 4.2 +NVIDIA GT 530M .*NVIDIA .*GT *53*M.* 3 1 1 4.2 +NVIDIA GT 540M .*NVIDIA .*GT *54*M.* 3 1 1 4.2 +NVIDIA GT 550M .*NVIDIA .*GT *55*M.* 3 1 1 4.2 +NVIDIA GTX 560M .*NVIDIA .*GTX *56*M.* 3 1 0 0 +NVIDIA GTX 570M .*NVIDIA .*GTX *57*M.* 5 1 0 0 +NVIDIA GTX 580M .*NVIDIA .*GTX *58*M.* 5 1 1 4.2 +NVIDIA 610M .*NVIDIA.* 61*M.* 3 1 1 4.2 +NVIDIA GT 620M .*NVIDIA .*GT *62*M.* 3 1 0 0 +NVIDIA GT 630M .*NVIDIA .*GT *63*M.* 3 1 0 0 +NVIDIA GT 640M .*NVIDIA .*GT *64*M.* 3 1 0 0 +NVIDIA GT 650M .*NVIDIA .*GT *65*M.* 3 1 0 0 +NVIDIA GTX 660M .*NVIDIA .*GTX *66*M.* 5 1 0 0 +NVIDIA GTX 670M .*NVIDIA .*GTX *67*M.* 5 1 1 4.2 +NVIDIA GTX 680M .*NVIDIA .*GTX *68*M.* 5 1 0 0 +NVIDIA GTX 690M .*NVIDIA .*GTX *69*M.* 5 1 0 0 +NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 4.2 +NVIDIA GT 120 .*NVIDIA .*GT *12.* 2 1 0 3 +NVIDIA GT 130 .*NVIDIA .*GT *13.* 2 1 0 3.3 +NVIDIA GTS 150 .*NVIDIA .*GTS *15.* 2 1 0 0 +NVIDIA 200 .*NVIDIA .*GeForce 20.* 2 1 1 3.3 +NVIDIA G200 .*NVIDIA .*GeForce G20.* 2 1 1 3.3 +NVIDIA G210 .*NVIDIA .*GeForce G210.* 3 1 1 3.3 +NVIDIA 210 .*NVIDIA .*GeForce 210.* 3 1 1 3.3 +NVIDIA GT 220 .*NVIDIA .*GT *22.* 2 1 1 3.3 +NVIDIA GT 230 .*NVIDIA .*GT *23.* 2 1 1 3.3 +NVIDIA GT 240 .*NVIDIA .*GT *24.* 4 1 1 3.3 +NVIDIA GTS 240 .*NVIDIA .*GTS *24.* 4 1 1 3.3 +NVIDIA GTS 250 .*NVIDIA .*GTS *25.* 4 1 1 3.3 +NVIDIA GTX 260 .*NVIDIA .*GTX *26.* 4 1 1 3.3 +NVIDIA GTX 270 .*NVIDIA .*GTX *27.* 4 1 0 3.3 +NVIDIA GTX 280 .*NVIDIA .*GTX *28.* 4 1 1 3.3 +NVIDIA GTX 290 .*NVIDIA .*GTX *29.* 5 1 0 3.3 +NVIDIA 310 .*NVIDIA .*GeForce 310.* 3 1 1 3.3 +NVIDIA 315 .*NVIDIA .*GeForce 315.* 3 1 1 3.3 +NVIDIA GT 320 .*NVIDIA .*GT *32.* 3 1 0 3.3 +NVIDIA GT 330 .*NVIDIA .*GT *33.* 3 1 0 3.3 +NVIDIA GT 340 .*NVIDIA .*GT *34.* 3 1 0 0 +NVIDIA 405 .*NVIDIA .* 405.* 3 1 0 3.3 +NVIDIA GT 420 .*NVIDIA .*GT *42.* 3 1 1 4.2 +NVIDIA GT 430 .*NVIDIA .*GT *43.* 3 1 1 4.2 +NVIDIA GT 440 .*NVIDIA .*GT *44.* 4 1 0 4.2 +NVIDIA GTS 450 .*NVIDIA .*GTS *45.* 4 1 1 4.2 +NVIDIA GTX 460 .*NVIDIA .*GTX *46.* 5 1 1 4.3 +NVIDIA GTX 470 .*NVIDIA .*GTX *47.* 5 1 1 4.2 +NVIDIA GTX 480 .*NVIDIA .*GTX *48.* 5 1 1 4.2 +NVIDIA 510 .*NVIDIA .* 510.* 3 1 0 0 +NVIDIA GT 520 .*NVIDIA .*GT *52.* 3 1 1 4.2 +NVIDIA GT 530 .*NVIDIA .*GT *53.* 3 1 1 4.2 +NVIDIA GT 540 .*NVIDIA .*GT *54.* 3 1 1 4.2 +NVIDIA GTX 550 .*NVIDIA .*GTX *55.* 5 1 1 4.3 +NVIDIA GTX 560 .*NVIDIA .*GTX *56.* 5 1 1 4.2 +NVIDIA GTX 570 .*NVIDIA .*GTX *57.* 5 1 1 4.2 +NVIDIA GTX 580 .*NVIDIA .*GTX *58.* 5 1 1 4.3 +NVIDIA GTX 590 .*NVIDIA .*GTX *59.* 5 1 1 4.2 +NVIDIA GT 610 .*NVIDIA .*GT *61.* 3 1 1 4.2 +NVIDIA GT 620 .*NVIDIA .*GT *62.* 3 1 0 4.2 +NVIDIA GT 630 .*NVIDIA .*GT *63.* 3 1 0 4.2 +NVIDIA GT 640 .*NVIDIA .*GT *64.* 3 1 0 4.3 +NVIDIA GT 650 .*NVIDIA .*GT *65.* 3 1 1 4.2 +NVIDIA GTX 650 .*NVIDIA .*GTX *65.* 3 1 1 4.2 +NVIDIA GTX 660 .*NVIDIA .*GTX *66.* 5 1 0 4.3 +NVIDIA GTX 670 .*NVIDIA .*GTX *67.* 5 1 1 4.2 +NVIDIA GTX 680 .*NVIDIA .*GTX *68.* 5 1 1 4.2 +NVIDIA GTX 690 .*NVIDIA .*GTX *69.* 5 1 1 4.2 +NVIDIA C51 .*NVIDIA .*C51.* 0 1 1 2 +NVIDIA G72 .*NVIDIA .*G72.* 1 1 0 0 +NVIDIA G73 .*NVIDIA .*G73.* 1 1 0 0 +NVIDIA G84 .*NVIDIA .*G84.* 2 1 0 0 +NVIDIA G86 .*NVIDIA .*G86.* 3 1 0 0 +NVIDIA G92 .*NVIDIA .*G92.* 3 1 0 0 +NVIDIA GeForce .*GeForce 256.* 0 0 0 0 +NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 1 1.5 +NVIDIA GeForce 3 .*GeForce ?3 ?.* 2 1 1 2.1 +NVIDIA GeForce 3 Ti .*GeForce ?3 Ti.* 0 1 0 0 +NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 1 1.5 +NVIDIA GeForce 4 Go .*NVIDIA .*GeForce ?4.*Go.* 0 1 0 0 +NVIDIA GeForce 4 MX .*NVIDIA .*GeForce ?4 MX.* 0 1 0 0 +NVIDIA GeForce 4 PCX .*NVIDIA .*GeForce ?4 PCX.* 0 1 0 0 +NVIDIA GeForce 4 Ti .*NVIDIA .*GeForce ?4 Ti.* 0 1 0 0 +NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 3 1 1 4.2 +NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1 1 2.1 +NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 1 1 1 2.1 +NVIDIA GeForce 6600 .*NVIDIA .*GeForce 66.* 2 1 1 2.1 +NVIDIA GeForce 6700 .*NVIDIA .*GeForce 67.* 2 1 1 2.1 +NVIDIA GeForce 6800 .*NVIDIA .*GeForce 68.* 1 1 1 2.1 +NVIDIA GeForce 7000 .*NVIDIA .*GeForce 70.* 1 1 1 2.1 +NVIDIA GeForce 7100 .*NVIDIA .*GeForce 71.* 1 1 1 2.1 +NVIDIA GeForce 7200 .*NVIDIA .*GeForce 72.* 1 1 0 0 +NVIDIA GeForce 7300 .*NVIDIA .*GeForce 73.* 1 1 1 2.1 +NVIDIA GeForce 7500 .*NVIDIA .*GeForce 75.* 2 1 1 2.1 +NVIDIA GeForce 7600 .*NVIDIA .*GeForce 76.* 2 1 1 2.1 +NVIDIA GeForce 7800 .*NVIDIA .*GeForce 78.* 2 1 1 2.1 +NVIDIA GeForce 7900 .*NVIDIA .*GeForce 79.* 3 1 1 2.1 +NVIDIA GeForce 8100 .*NVIDIA .*GeForce 81.* 1 1 0 0 +NVIDIA GeForce 8200M .*NVIDIA .*GeForce 8200M.* 1 1 0 3.3 +NVIDIA GeForce 8200 .*NVIDIA .*GeForce 82.* 1 1 0 2.1 +NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 3 1 1 3.3 +NVIDIA GeForce 8400M .*NVIDIA .*GeForce 8400M.* 1 1 1 3.3 +NVIDIA GeForce 8400 .*NVIDIA .*GeForce 84.* 2 1 1 3.3 +NVIDIA GeForce 8500 .*NVIDIA .*GeForce 85.* 2 1 1 3.3 +NVIDIA GeForce 8600M .*NVIDIA .*GeForce 8600M.* 2 1 1 3.3 +NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1 1 3.3 +NVIDIA GeForce 8700M .*NVIDIA .*GeForce 8700M.* 2 1 1 3.3 +NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1 0 0 +NVIDIA GeForce 8800M .*NVIDIA .*GeForce 8800M.* 2 1 1 3.3 +NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1 1 3.3 +NVIDIA GeForce 9100M .*NVIDIA .*GeForce 9100M.* 0 1 0 0 +NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1 0 3.3 +NVIDIA GeForce 9200M .*NVIDIA .*GeForce 9200M.* 1 1 0 3.1 +NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1 0 3.3 +NVIDIA GeForce 9300M .*NVIDIA .*GeForce 9300M.* 1 1 1 3.3 +NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 1 1 1 3.3 +NVIDIA GeForce 9400M .*NVIDIA .*GeForce 9400M.* 2 1 1 3.3 +NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 3 1 1 3.3 +NVIDIA GeForce 9500M .*NVIDIA .*GeForce 9500M.* 1 1 1 3.3 +NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 3 1 1 3.3 +NVIDIA GeForce 9600M .*NVIDIA .*GeForce 9600M.* 2 1 1 3.3 +NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 3 1 1 3.3 +NVIDIA GeForce 9700M .*NVIDIA .*GeForce 9700M.* 0 1 1 3.3 +NVIDIA GeForce 9800M .*NVIDIA .*GeForce 9800M.* 2 1 1 3.3 +NVIDIA GeForce 9800 .*NVIDIA .*GeForce 98.* 3 1 1 3.3 +NVIDIA GeForce FX 5100 .*NVIDIA .*GeForce FX 51.* 0 1 0 0 +NVIDIA GeForce FX 5200 .*NVIDIA .*GeForce FX 52.* 0 1 0 2.1 +NVIDIA GeForce FX 5300 .*NVIDIA .*GeForce FX 53.* 0 1 0 0 +NVIDIA GeForce FX 5500 .*NVIDIA .*GeForce FX 55.* 0 1 1 2.1 +NVIDIA GeForce FX 5600 .*NVIDIA .*GeForce FX 56.* 1 1 1 2.1 +NVIDIA GeForce FX 5700 .*NVIDIA .*GeForce FX 57.* 0 1 1 2.1 +NVIDIA GeForce FX 5800 .*NVIDIA .*GeForce FX 58.* 1 1 0 0 +NVIDIA GeForce FX 5900 .*NVIDIA .*GeForce FX 59.* 1 1 1 2.1 +NVIDIA GeForce FX Go5100 .*NVIDIA .*GeForce FX Go51.* 0 1 0 0 +NVIDIA GeForce FX Go5200 .*NVIDIA .*GeForce FX Go52.* 0 1 0 0 +NVIDIA GeForce FX Go5300 .*NVIDIA .*GeForce FX Go53.* 0 1 0 0 +NVIDIA GeForce FX Go5500 .*NVIDIA .*GeForce FX Go55.* 0 1 0 0 +NVIDIA GeForce FX Go5600 .*NVIDIA .*GeForce FX Go56.* 0 1 1 2.1 +NVIDIA GeForce FX Go5700 .*NVIDIA .*GeForce FX Go57.* 1 1 1 1.5 +NVIDIA GeForce FX Go5800 .*NVIDIA .*GeForce FX Go58.* 1 1 0 0 +NVIDIA GeForce FX Go5900 .*NVIDIA .*GeForce FX Go59.* 1 1 0 0 +NVIDIA GeForce FX Go5xxx .*NVIDIA .*GeForce FX Go.* 0 1 0 0 +NVIDIA GeForce Go 6100 .*NVIDIA .*GeForce Go 61.* 0 1 1 2.1 +NVIDIA GeForce Go 6200 .*NVIDIA .*GeForce Go 62.* 0 1 0 0 +NVIDIA GeForce Go 6400 .*NVIDIA .*GeForce Go 64.* 1 1 1 2 +NVIDIA GeForce Go 6500 .*NVIDIA .*GeForce Go 65.* 1 1 0 0 +NVIDIA GeForce Go 6600 .*NVIDIA .*GeForce Go 66.* 0 1 1 2.1 +NVIDIA GeForce Go 6700 .*NVIDIA .*GeForce Go 67.* 1 1 0 0 +NVIDIA GeForce Go 6800 .*NVIDIA .*GeForce Go 68.* 0 1 1 2.1 +NVIDIA GeForce Go 7200 .*NVIDIA .*GeForce Go 72.* 1 1 0 0 +NVIDIA GeForce Go 7300 LE .*NVIDIA .*GeForce Go 73.*LE.* 1 1 0 0 +NVIDIA GeForce Go 7300 .*NVIDIA .*GeForce Go 73.* 1 1 1 2.1 +NVIDIA GeForce Go 7400 .*NVIDIA .*GeForce Go 74.* 1 1 1 2.1 +NVIDIA GeForce Go 7600 .*NVIDIA .*GeForce Go 76.* 1 1 1 2.1 +NVIDIA GeForce Go 7700 .*NVIDIA .*GeForce Go 77.* 0 1 1 2.1 +NVIDIA GeForce Go 7800 .*NVIDIA .*GeForce Go 78.* 2 1 0 0 +NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 1 1 1 2.1 +NVIDIA D9M .*NVIDIA .*D9M.* 1 1 0 0 +NVIDIA G94 .*NVIDIA .*G94.* 3 1 0 0 +NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 0 0 +NVIDIA ION 2 .*NVIDIA .*ION 2.* 2 1 0 0 +NVIDIA ION .*NVIDIA Corporation.*ION.* 2 1 1 3.3 +NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1 0 0 +NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1 0 0 +NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1 0 0 +NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1 0 0 +NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1 0 0 +NVIDIA N10 .*NVIDIA .*N10.* 1 1 0 0 +NVIDIA GeForce PCX .*GeForce PCX.* 0 1 0 0 +NVIDIA Generic .*NVIDIA .*Unknown.* 0 0 0 3 +NVIDIA NV17 .*NVIDIA .*NV17.* 0 1 0 0 +NVIDIA NV34 .*NVIDIA .*NV34.* 0 1 0 0 +NVIDIA NV35 .*NVIDIA .*NV35.* 0 1 0 0 +NVIDIA NV36 .*NVIDIA .*NV36.* 1 1 0 0 +NVIDIA NV41 .*NVIDIA .*NV41.* 1 1 0 0 +NVIDIA NV43 .*NVIDIA .*NV43.* 1 1 0 0 +NVIDIA NV44 .*NVIDIA .*NV44.* 1 1 0 0 +NVIDIA nForce .*NVIDIA .*nForce.* 0 0 0 3.3 +NVIDIA MCP51 .*NVIDIA .*MCP51.* 1 1 0 0 +NVIDIA MCP61 .*NVIDIA .*MCP61.* 1 1 0 0 +NVIDIA MCP67 .*NVIDIA .*MCP67.* 1 1 0 0 +NVIDIA MCP68 .*NVIDIA .*MCP68.* 1 1 0 0 +NVIDIA MCP73 .*NVIDIA .*MCP73.* 1 1 0 0 +NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1 0 0 +NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1 0 0 +NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1 0 0 +NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1 0 0 +NVIDIA Quadro2 .*Quadro2.* 0 1 0 0 +NVIDIA Quadro 1000M .*Quadro.*1000M.* 2 1 0 4.2 +NVIDIA Quadro 2000 M/D .*Quadro.*2000.* 3 1 0 4.2 +NVIDIA Quadro 3000M .*Quadro.*3000M.* 3 1 0 0 +NVIDIA Quadro 4000M .*Quadro.*4000M.* 3 1 0 0 +NVIDIA Quadro 4000 .*Quadro *4000.* 3 1 0 4.2 +NVIDIA Quadro 50x0 M .*Quadro.*50.0.* 3 1 0 0 +NVIDIA Quadro 6000 .*Quadro.*6000.* 3 1 0 0 +NVIDIA Quadro 400 .*Quadro.*400.* 2 1 0 3.3 +NVIDIA Quadro 600 .*Quadro.*600.* 2 1 0 3.3 +NVIDIA Quadro4 .*Quadro4.* 0 1 0 0 +NVIDIA Quadro DCC .*Quadro DCC.* 0 1 0 0 +NVIDIA Quadro CX .*Quadro.*CX.* 3 1 0 0 +NVIDIA Quadro FX 770M .*Quadro.*FX *770M.* 2 1 0 0 +NVIDIA Quadro FX 1500M .*Quadro.*FX *1500M.* 1 1 0 2.1 +NVIDIA Quadro FX 1600M .*Quadro.*FX *1600M.* 2 1 0 0 +NVIDIA Quadro FX 2500M .*Quadro.*FX *2500M.* 2 1 0 0 +NVIDIA Quadro FX 2700M .*Quadro.*FX *2700M.* 3 1 0 0 +NVIDIA Quadro FX 2800M .*Quadro.*FX *2800M.* 3 1 0 3.3 +NVIDIA Quadro FX 3500 .*Quadro.*FX *3500.* 2 1 0 2.1 +NVIDIA Quadro FX 3600 .*Quadro.*FX *3600.* 3 1 0 0 +NVIDIA Quadro FX 3700 .*Quadro.*FX *3700.* 3 1 0 3.3 +NVIDIA Quadro FX 3800 .*Quadro.*FX *3800.* 3 1 0 3.2 +NVIDIA Quadro FX 4500 .*Quadro.*FX *45.* 3 1 0 0 +NVIDIA Quadro FX 880M .*Quadro.*FX *880M.* 3 1 0 3.3 +NVIDIA Quadro FX 4800 .*NVIDIA .*Quadro *FX *4800.* 3 1 0 0 +NVIDIA Quadro FX .*Quadro FX.* 1 1 0 3.3 +NVIDIA Quadro NVS 1xxM .*Quadro NVS *1.[05]M.* 0 1 1 3.3 +NVIDIA Quadro NVS 300M .*NVIDIA .*NVS *300M.* 2 1 0 0 +NVIDIA Quadro NVS 320M .*NVIDIA .*NVS *320M.* 2 1 0 0 +NVIDIA Quadro NVS 2100M .*NVIDIA .*NVS *2100M.* 2 1 0 0 +NVIDIA Quadro NVS 3100M .*NVIDIA .*NVS *3100M.* 2 1 0 0 +NVIDIA Quadro NVS 4200M .*NVIDIA .*NVS *4200M.* 2 1 0 4.1 +NVIDIA Quadro NVS 5100M .*NVIDIA .*NVS *5100M.* 2 1 0 0 +NVIDIA Quadro NVS .*NVIDIA .*NVS 0 1 0 3.2 +NVIDIA Corporation N12P .*NVIDIA .*N12P.* 1 1 1 4.1 +NVIDIA Corporation N11M .*NVIDIA .*N11M.* 2 1 0 0 +NVIDIA RIVA TNT .*RIVA TNT.* 0 0 0 0 +S3 .*S3 Graphics.* 0 0 1 1.4 +SiS SiS.* 0 0 1 1.5 +Trident Trident.* 0 0 0 0 +Tungsten Graphics Tungsten.* 0 0 0 0 +XGI XGI.* 0 0 0 0 +VIA VIA.* 0 0 0 0 +Apple Generic Apple.*Generic.* 0 0 0 0 +Apple Software Renderer Apple.*Software Renderer.* 0 0 0 0 +Humper Humper.* 0 1 1 2.1 +PowerVR SGX545 .*PowerVR SGX.* 1 1 1 3 diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index 283a28a0aa..20936c6460 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -110,22 +110,34 @@ export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" # fi #fi -export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib:"${LD_LIBRARY_PATH}"' -export SL_CMD='$LL_WRAPPER bin/do-not-directly-run-secondlife-bin' -export SL_OPT="`cat etc/gridargs.dat` $@" - -# Run the program -eval ${SL_ENV} ${SL_CMD} ${SL_OPT} || LL_RUN_ERR=runerr +export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}" + +# Have to deal specially with gridargs.dat; typical contents look like: +# --channel "Second Life Developer" --settings settings_developer.xml +# Simply embedding $(<etc/gridargs.dat) into a command line treats each of +# Second, Life and Developer as separate args -- no good. We need bash to +# process quotes using eval. +# First read it without scanning, then scan that string. Break quoted words +# into a bash array. Note that if gridargs.dat is empty, or contains only +# whitespace, the resulting gridargs array will be empty -- zero entries -- +# therefore "${gridargs[@]}" entirely vanishes from the command line below, +# just as we want. +eval gridargs=("$(<etc/gridargs.dat)") + +# Run the program. +# Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the +# command line. But DO quote "$@": preserve separate args as individually +# quoted. Similar remarks about the contents of gridargs. +$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "$@" +LL_RUN_ERR=$? # Handle any resulting errors -if [ -n "$LL_RUN_ERR" ]; then - LL_RUN_ERR_MSG="" - if [ "$LL_RUN_ERR" = "runerr" ]; then - # generic error running the binary - echo '*** Bad shutdown. ***' - if [ "`uname -m`" = "x86_64" ]; then - echo - cat << EOFMARKER +if [ $LL_RUN_ERR -ne 0 ]; then + # generic error running the binary + echo '*** Bad shutdown ($LL_RUN_ERR). ***' + if [ "$(uname -m)" = "x86_64" ]; then + echo + cat << EOFMARKER You are running the Second Life Viewer on a x86_64 platform. The most common problems when launching the Viewer (particularly 'bin/do-not-directly-run-secondlife-bin: not found' and 'error while @@ -134,10 +146,8 @@ distribution's 32-bit compatibility packages. For example, on Ubuntu and other Debian-based Linuxes you might run: $ sudo apt-get install ia32-libs ia32-libs-gtk ia32-libs-kde ia32-libs-sdl EOFMARKER - fi fi fi - echo echo '*******************************************************' diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index cd56b04258..094d502078 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -41,6 +41,7 @@ #include "llchannelmanager.h" #include "llchicletbar.h" #include "llconsole.h" +#include "lldonotdisturbnotificationstorage.h" #include "llenvmanager.h" #include "llfirstuse.h" #include "llfloatercamera.h" @@ -54,7 +55,7 @@ #include "llmorphview.h" #include "llmoveview.h" #include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state -#include "llnearbychatbar.h" +#include "llfloaterimnearbychat.h" #include "llnotificationsutil.h" #include "llpaneltopinfobar.h" #include "llparcel.h" @@ -81,6 +82,7 @@ #include "llviewermenu.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" +#include "llviewerregion.h" #include "llviewerstats.h" #include "llviewerwindow.h" #include "llvoavatarself.h" @@ -112,6 +114,105 @@ const F32 MAX_FIDGET_TIME = 20.f; // seconds // The agent instance. LLAgent gAgent; +class LLTeleportRequest +{ +public: + enum EStatus + { + kPending, + kStarted, + kFailed, + kRestartPending + }; + + LLTeleportRequest(); + virtual ~LLTeleportRequest(); + + EStatus getStatus() const {return mStatus;}; + void setStatus(EStatus pStatus) {mStatus = pStatus;}; + + virtual bool canRestartTeleport(); + + virtual void startTeleport() = 0; + virtual void restartTeleport(); + +protected: + +private: + EStatus mStatus; +}; + +class LLTeleportRequestViaLandmark : public LLTeleportRequest +{ +public: + LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId); + virtual ~LLTeleportRequestViaLandmark(); + + virtual bool canRestartTeleport(); + + virtual void startTeleport(); + virtual void restartTeleport(); + +protected: + inline const LLUUID &getLandmarkId() const {return mLandmarkId;}; + +private: + LLUUID mLandmarkId; +}; + +class LLTeleportRequestViaLure : public LLTeleportRequestViaLandmark +{ +public: + LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike); + virtual ~LLTeleportRequestViaLure(); + + virtual bool canRestartTeleport(); + + virtual void startTeleport(); + +protected: + inline BOOL isLureGodLike() const {return mIsLureGodLike;}; + +private: + BOOL mIsLureGodLike; +}; + +class LLTeleportRequestViaLocation : public LLTeleportRequest +{ +public: + LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal); + virtual ~LLTeleportRequestViaLocation(); + + virtual bool canRestartTeleport(); + + virtual void startTeleport(); + virtual void restartTeleport(); + +protected: + inline const LLVector3d &getPosGlobal() const {return mPosGlobal;}; + +private: + LLVector3d mPosGlobal; +}; + + +class LLTeleportRequestViaLocationLookAt : public LLTeleportRequestViaLocation +{ +public: + LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal); + virtual ~LLTeleportRequestViaLocationLookAt(); + + virtual bool canRestartTeleport(); + + virtual void startTeleport(); + virtual void restartTeleport(); + +protected: + +private: + +}; + //-------------------------------------------------------------------- // Statics // @@ -169,11 +270,7 @@ bool LLAgent::isActionAllowed(const LLSD& sdname) const std::string& param = sdname.asString(); - if (param == "build") - { - retval = gAgent.canEditParcel(); - } - else if (param == "speak") + if (param == "speak") { if ( gAgent.isVoiceConnected() && LLViewerParcelMgr::getInstance()->allowAgentVoice() && @@ -205,6 +302,12 @@ void LLAgent::releaseMicrophone(const LLSD& name) } // static +void LLAgent::toggleMicrophone(const LLSD& name) +{ + LLVoiceClient::getInstance()->toggleUserPTTState(); +} + +// static bool LLAgent::isMicrophoneOn(const LLSD& sdname) { return LLVoiceClient::getInstance()->getUserPTTState(); @@ -241,8 +344,20 @@ LLAgent::LLAgent() : mbTeleportKeepsLookAt(false), mAgentAccess(new LLAgentAccess(gSavedSettings)), + mGodLevelChangeSignal(), mCanEditParcel(false), mTeleportSourceSLURL(new LLSLURL), + mTeleportRequest(), + mTeleportFinishedSlot(), + mTeleportFailedSlot(), + mIsMaturityRatingChangingDuringTeleport(false), + mMaturityRatingChange(0U), + mIsDoSendMaturityPreferenceToServer(false), + mMaturityPreferenceRequestId(0U), + mMaturityPreferenceResponseId(0U), + mMaturityPreferenceNumRetries(0U), + mLastKnownRequestMaturity(SIM_ACCESS_MIN), + mLastKnownResponseMaturity(SIM_ACCESS_MIN), mTeleportState( TELEPORT_NONE ), mRegionp(NULL), @@ -261,7 +376,7 @@ LLAgent::LLAgent() : mShowAvatar(TRUE), mFrameAgent(), - mIsBusy(FALSE), + mIsDoNotDisturb(false), mControlFlags(0x00000000), mbFlagsDirty(FALSE), @@ -328,15 +443,21 @@ void LLAgent::init() gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2)); gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2)); + mLastKnownResponseMaturity = static_cast<U8>(gSavedSettings.getU32("PreferredMaturity")); + mLastKnownRequestMaturity = mLastKnownResponseMaturity; + mIsDoSendMaturityPreferenceToServer = true; LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback)); - LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Agent.IsActionAllowed", boost::bind(&LLAgent::isActionAllowed, _2)); - LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Agent.PressMicrophone", boost::bind(&LLAgent::pressMicrophone, _2)); - LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Agent.ReleaseMicrophone", boost::bind(&LLAgent::releaseMicrophone, _2)); - LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Agent.IsMicrophoneOn", boost::bind(&LLAgent::isMicrophoneOn, _2)); + if (!mTeleportFinishedSlot.connected()) + { + mTeleportFinishedSlot = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLAgent::handleTeleportFinished, this)); + } + if (!mTeleportFailedSlot.connected()) + { + mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLAgent::handleTeleportFailed, this)); + } - mInitialized = TRUE; } @@ -346,6 +467,14 @@ void LLAgent::init() void LLAgent::cleanup() { mRegionp = NULL; + if (mTeleportFinishedSlot.connected()) + { + mTeleportFinishedSlot.disconnect(); + } + if (mTeleportFailedSlot.connected()) + { + mTeleportFailedSlot.disconnect(); + } } //----------------------------------------------------------------------------- @@ -1227,12 +1356,7 @@ void LLAgent::setAFK() { sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_START); setControlFlags(AGENT_CONTROL_AWAY | AGENT_CONTROL_STOP); - LL_INFOS("AFK") << "Setting Away" << LL_ENDL; gAwayTimer.start(); - if (gAFKMenu) - { - gAFKMenu->setLabel(LLTrans::getString("AvatarSetNotAway")); - } } } @@ -1251,11 +1375,6 @@ void LLAgent::clearAFK() { sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_STOP); clearControlFlags(AGENT_CONTROL_AWAY); - LL_INFOS("AFK") << "Clearing Away" << LL_ENDL; - if (gAFKMenu) - { - gAFKMenu->setLabel(LLTrans::getString("AvatarSetAway")); - } } } @@ -1268,39 +1387,26 @@ BOOL LLAgent::getAFK() const } //----------------------------------------------------------------------------- -// setBusy() +// setDoNotDisturb() //----------------------------------------------------------------------------- -void LLAgent::setBusy() +void LLAgent::setDoNotDisturb(bool pIsDoNotDisturb) { - sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_START); - mIsBusy = TRUE; - if (gBusyMenu) + bool isDoNotDisturbSwitchedOff = (mIsDoNotDisturb && !pIsDoNotDisturb); + mIsDoNotDisturb = pIsDoNotDisturb; + sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, (pIsDoNotDisturb ? ANIM_REQUEST_START : ANIM_REQUEST_STOP)); + LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(pIsDoNotDisturb); + if (isDoNotDisturbSwitchedOff) { - gBusyMenu->setLabel(LLTrans::getString("AvatarSetNotBusy")); + LLDoNotDisturbNotificationStorage::getInstance()->updateNotifications(); } - LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(true); } //----------------------------------------------------------------------------- -// clearBusy() +// isDoNotDisturb() //----------------------------------------------------------------------------- -void LLAgent::clearBusy() +bool LLAgent::isDoNotDisturb() const { - mIsBusy = FALSE; - sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_STOP); - if (gBusyMenu) - { - gBusyMenu->setLabel(LLTrans::getString("AvatarSetBusy")); - } - LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(false); -} - -//----------------------------------------------------------------------------- -// getBusy() -//----------------------------------------------------------------------------- -BOOL LLAgent::getBusy() const -{ - return mIsBusy; + return mIsDoNotDisturb; } @@ -1782,7 +1888,8 @@ void LLAgent::startTyping() { sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START); } - LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE); + (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))-> + sendChatFromViewer("", CHAT_TYPE_START, FALSE); } //----------------------------------------------------------------------------- @@ -1794,7 +1901,8 @@ void LLAgent::stopTyping() { clearRenderState(AGENT_STATE_TYPING); sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP); - LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE); + (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))-> + sendChatFromViewer("", CHAT_TYPE_STOP, FALSE); } } @@ -2375,49 +2483,248 @@ bool LLAgent::isAdult() const return mAgentAccess->isAdult(); } -void LLAgent::setTeen(bool teen) -{ - mAgentAccess->setTeen(teen); -} - //static int LLAgent::convertTextToMaturity(char text) { return LLAgentAccess::convertTextToMaturity(text); } -bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity) +class LLMaturityPreferencesResponder : public LLHTTPClient::Responder { - if (!getRegion()) - return false; - - // Update agent access preference on the server - std::string url = getRegion()->getCapability("UpdateAgentInformation"); - if (!url.empty()) +public: + LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity); + virtual ~LLMaturityPreferencesResponder(); + + virtual void result(const LLSD &pContent); + virtual void error(U32 pStatus, const std::string& pReason); + +protected: + +private: + U8 parseMaturityFromServerResponse(const LLSD &pContent); + + LLAgent *mAgent; + U8 mPreferredMaturity; + U8 mPreviousMaturity; +}; + +LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity) + : LLHTTPClient::Responder(), + mAgent(pAgent), + mPreferredMaturity(pPreferredMaturity), + mPreviousMaturity(pPreviousMaturity) +{ +} + +LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder() +{ +} + +void LLMaturityPreferencesResponder::result(const LLSD &pContent) +{ + U8 actualMaturity = parseMaturityFromServerResponse(pContent); + + if (actualMaturity != mPreferredMaturity) + { + llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity) + << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', the server responded with '" + << LLViewerRegion::accessToString(actualMaturity) << "' [value:" << static_cast<U32>(actualMaturity) << ", llsd:" + << pContent << "]" << llendl; + } + mAgent->handlePreferredMaturityResult(actualMaturity); +} + +void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReason) +{ + llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity) + << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error because '" + << pReason << "' [status:" << pStatus << "]" << llendl; + mAgent->handlePreferredMaturityError(); +} + +U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent) +{ + U8 maturity = SIM_ACCESS_MIN; + + llassert(!pContent.isUndefined()); + llassert(pContent.isMap()); + llassert(pContent.has("access_prefs")); + llassert(pContent.get("access_prefs").isMap()); + llassert(pContent.get("access_prefs").has("max")); + llassert(pContent.get("access_prefs").get("max").isString()); + if (!pContent.isUndefined() && pContent.isMap() && pContent.has("access_prefs") + && pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max") + && pContent.get("access_prefs").get("max").isString()) + { + LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString(); + LLStringUtil::trim(actualPreference); + maturity = LLViewerRegion::shortStringToAccess(actualPreference); + } + + return maturity; +} + +void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity) +{ + // Update the number of responses received + ++mMaturityPreferenceResponseId; + llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId); + + // Update the last known server maturity response + mLastKnownResponseMaturity = pServerMaturity; + + // Ignore all responses if we know there are more unanswered requests that are expected + if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId) { - // Set new access preference - LLSD access_prefs = LLSD::emptyMap(); - if (preferredMaturity == SIM_ACCESS_PG) + // If we received a response that matches the last known request, then we are good + if (mLastKnownRequestMaturity == mLastKnownResponseMaturity) { - access_prefs["max"] = "PG"; + mMaturityPreferenceNumRetries = 0; + reportPreferredMaturitySuccess(); + llassert(static_cast<U8>(gSavedSettings.getU32("PreferredMaturity")) == mLastKnownResponseMaturity); } - else if (preferredMaturity == SIM_ACCESS_MATURE) + // Else, the viewer is out of sync with the server, so let's try to re-sync with the + // server by re-sending our last known request. Cap the re-tries at 3 just to be safe. + else if (++mMaturityPreferenceNumRetries <= 3) { - access_prefs["max"] = "M"; + llinfos << "Retrying attempt #" << mMaturityPreferenceNumRetries << " to set viewer preferred maturity to '" + << LLViewerRegion::accessToString(mLastKnownRequestMaturity) << "'" << llendl; + sendMaturityPreferenceToServer(mLastKnownRequestMaturity); } - if (preferredMaturity == SIM_ACCESS_ADULT) + // Else, the viewer is style out of sync with the server after 3 retries, so inform the user + else { - access_prefs["max"] = "A"; + mMaturityPreferenceNumRetries = 0; + reportPreferredMaturityError(); + } + } +} + +void LLAgent::handlePreferredMaturityError() +{ + // Update the number of responses received + ++mMaturityPreferenceResponseId; + llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId); + + // Ignore all responses if we know there are more unanswered requests that are expected + if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId) + { + mMaturityPreferenceNumRetries = 0; + + // If we received a response that matches the last known request, then we are synced with + // the server, but not quite sure why we are + if (mLastKnownRequestMaturity == mLastKnownResponseMaturity) + { + llwarns << "Got an error but maturity preference '" << LLViewerRegion::accessToString(mLastKnownRequestMaturity) + << "' seems to be in sync with the server" << llendl; + reportPreferredMaturitySuccess(); + } + // Else, the more likely case is that the last request does not match the last response, + // so inform the user + else + { + reportPreferredMaturityError(); + } + } +} + +void LLAgent::reportPreferredMaturitySuccess() +{ + // If there is a pending teleport request waiting for the maturity preference to be synced with + // the server, let's start the pending request + if (hasPendingTeleportRequest()) + { + startTeleportRequest(); + } +} + +void LLAgent::reportPreferredMaturityError() +{ + // If there is a pending teleport request waiting for the maturity preference to be synced with + // the server, we were unable to successfully sync with the server on maturity preference, so let's + // just raise the screen. + mIsMaturityRatingChangingDuringTeleport = false; + if (hasPendingTeleportRequest()) + { + setTeleportState(LLAgent::TELEPORT_NONE); + } + + // Get the last known maturity request from the user activity + std::string preferredMaturity = LLViewerRegion::accessToString(mLastKnownRequestMaturity); + LLStringUtil::toLower(preferredMaturity); + + // Get the last known maturity response from the server + std::string actualMaturity = LLViewerRegion::accessToString(mLastKnownResponseMaturity); + LLStringUtil::toLower(actualMaturity); + + // Notify the user + LLSD args = LLSD::emptyMap(); + args["PREFERRED_MATURITY"] = preferredMaturity; + args["ACTUAL_MATURITY"] = actualMaturity; + LLNotificationsUtil::add("MaturityChangeError", args); + + // Check the saved settings to ensure that we are consistent. If we are not consistent, update + // the viewer, but do not send anything to server + U8 localMaturity = static_cast<U8>(gSavedSettings.getU32("PreferredMaturity")); + if (localMaturity != mLastKnownResponseMaturity) + { + bool tmpIsDoSendMaturityPreferenceToServer = mIsDoSendMaturityPreferenceToServer; + mIsDoSendMaturityPreferenceToServer = false; + llinfos << "Setting viewer preferred maturity to '" << LLViewerRegion::accessToString(mLastKnownResponseMaturity) << "'" << llendl; + gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(mLastKnownResponseMaturity)); + mIsDoSendMaturityPreferenceToServer = tmpIsDoSendMaturityPreferenceToServer; + } +} + +bool LLAgent::isMaturityPreferenceSyncedWithServer() const +{ + return (mMaturityPreferenceRequestId == mMaturityPreferenceResponseId); +} + +void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity) +{ + // Only send maturity preference to the server if enabled + if (mIsDoSendMaturityPreferenceToServer) + { + // Increment the number of requests. The handlers manage a separate count of responses. + ++mMaturityPreferenceRequestId; + + // Update the last know maturity request + mLastKnownRequestMaturity = pPreferredMaturity; + + // Create a response handler + LLHTTPClient::ResponderPtr responderPtr = LLHTTPClient::ResponderPtr(new LLMaturityPreferencesResponder(this, pPreferredMaturity, mLastKnownResponseMaturity)); + + // If we don't have a region, report it as an error + if (getRegion() == NULL) + { + responderPtr->error(0U, "region is not defined"); + } + else + { + // Find the capability to send maturity preference + std::string url = getRegion()->getCapability("UpdateAgentInformation"); + + // If the capability is not defined, report it as an error + if (url.empty()) + { + responderPtr->error(0U, "capability 'UpdateAgentInformation' is not defined for region"); + } + else + { + // Set new access preference + LLSD access_prefs = LLSD::emptyMap(); + access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity); + + LLSD body = LLSD::emptyMap(); + body["access_prefs"] = access_prefs; + llinfos << "Sending viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreferredMaturity) + << "' via capability to: " << url << llendl; + LLSD headers; + LLHTTPClient::post(url, body, responderPtr, headers, 30.0f); + } } - - LLSD body = LLSD::emptyMap(); - body["access_prefs"] = access_prefs; - llinfos << "Sending access prefs update to " << (access_prefs["max"].asString()) << " via capability to: " - << url << llendl; - LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); // Ignore response - return true; } - return false; } BOOL LLAgent::getAdminOverride() const @@ -2438,11 +2745,12 @@ void LLAgent::setAdminOverride(BOOL b) void LLAgent::setGodLevel(U8 god_level) { mAgentAccess->setGodLevel(god_level); + mGodLevelChangeSignal(god_level); } -void LLAgent::setAOTransition() +LLAgent::god_level_change_slot_t LLAgent::registerGodLevelChanageListener(god_level_change_callback_t pGodLevelChangeCallback) { - mAgentAccess->setTransition(); + return mGodLevelChangeSignal.connect(pGodLevelChangeCallback); } const LLAgentAccess& LLAgent::getAgentAccess() @@ -2455,9 +2763,9 @@ bool LLAgent::validateMaturity(const LLSD& newvalue) return mAgentAccess->canSetMaturity(newvalue.asInteger()); } -void LLAgent::handleMaturity(const LLSD& newvalue) +void LLAgent::handleMaturity(const LLSD &pNewValue) { - sendMaturityPreferenceToServer(newvalue.asInteger()); + sendMaturityPreferenceToServer(static_cast<U8>(pNewValue.asInteger())); } //---------------------------------------------------------------------------- @@ -3257,6 +3565,10 @@ void LLAgent::processControlRelease(LLMessageSystem *msg, void **) void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data) { gAgentQueryManager.mNumPendingQueries--; + if (gAgentQueryManager.mNumPendingQueries == 0) + { + selfStopPhase("fetch_texture_cache_entries"); + } if (!isAgentAvatarValid() || gAgentAvatarp->isDead()) { @@ -3306,14 +3618,14 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void * else { // no cache of this bake. request upload. - gAgentAvatarp->requestLayerSetUpload(baked_index); + gAgentAvatarp->invalidateComposite(gAgentAvatarp->getLayerSet(baked_index),TRUE); } } } } } - llinfos << "Received cached texture response for " << num_results << " textures." << llendl; + gAgentAvatarp->outputRezTiming("Fetched agent wearables textures from cache. Will now load them"); gAgentAvatarp->updateMeshTextures(); @@ -3388,7 +3700,7 @@ void LLAgent::clearVisualParams(void *data) // protected bool LLAgent::teleportCore(bool is_local) { - if(TELEPORT_NONE != mTeleportState) + if ((TELEPORT_NONE != mTeleportState) && (mTeleportState != TELEPORT_PENDING)) { llwarns << "Attempt to teleport when already teleporting." << llendl; return false; @@ -3466,6 +3778,102 @@ bool LLAgent::teleportCore(bool is_local) return true; } +bool LLAgent::hasRestartableFailedTeleportRequest() +{ + return ((mTeleportRequest != NULL) && (mTeleportRequest->getStatus() == LLTeleportRequest::kFailed) && + mTeleportRequest->canRestartTeleport()); +} + +void LLAgent::restartFailedTeleportRequest() +{ + if (hasRestartableFailedTeleportRequest()) + { + mTeleportRequest->setStatus(LLTeleportRequest::kRestartPending); + startTeleportRequest(); + } +} + +void LLAgent::clearTeleportRequest() +{ + mTeleportRequest.reset(); +} + +void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange) +{ + mIsMaturityRatingChangingDuringTeleport = true; + mMaturityRatingChange = pMaturityRatingChange; +} + +bool LLAgent::hasPendingTeleportRequest() +{ + return ((mTeleportRequest != NULL) && + ((mTeleportRequest->getStatus() == LLTeleportRequest::kPending) || + (mTeleportRequest->getStatus() == LLTeleportRequest::kRestartPending))); +} + +void LLAgent::startTeleportRequest() +{ + if (hasPendingTeleportRequest()) + { + if (!isMaturityPreferenceSyncedWithServer()) + { + gTeleportDisplay = TRUE; + setTeleportState(TELEPORT_PENDING); + } + else + { + switch (mTeleportRequest->getStatus()) + { + case LLTeleportRequest::kPending : + mTeleportRequest->setStatus(LLTeleportRequest::kStarted); + mTeleportRequest->startTeleport(); + break; + case LLTeleportRequest::kRestartPending : + llassert(mTeleportRequest->canRestartTeleport()); + mTeleportRequest->setStatus(LLTeleportRequest::kStarted); + mTeleportRequest->restartTeleport(); + break; + default : + llassert(0); + break; + } + } + } +} + +void LLAgent::handleTeleportFinished() +{ + clearTeleportRequest(); + if (mIsMaturityRatingChangingDuringTeleport) + { + // notify user that the maturity preference has been changed + std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange); + LLStringUtil::toLower(maturityRating); + LLSD args; + args["RATING"] = maturityRating; + LLNotificationsUtil::add("PreferredMaturityChanged", args); + mIsMaturityRatingChangingDuringTeleport = false; + } +} + +void LLAgent::handleTeleportFailed() +{ + if (mTeleportRequest != NULL) + { + mTeleportRequest->setStatus(LLTeleportRequest::kFailed); + } + if (mIsMaturityRatingChangingDuringTeleport) + { + // notify user that the maturity preference has been changed + std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange); + LLStringUtil::toLower(maturityRating); + LLSD args; + args["RATING"] = maturityRating; + LLNotificationsUtil::add("PreferredMaturityChanged", args); + mIsMaturityRatingChangingDuringTeleport = false; + } +} + void LLAgent::teleportRequest( const U64& region_handle, const LLVector3& pos_local, @@ -3498,6 +3906,12 @@ void LLAgent::teleportRequest( // Landmark ID = LLUUID::null means teleport home void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id) { + mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLandmark(landmark_asset_id)); + startTeleportRequest(); +} + +void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id) +{ LLViewerRegion *regionp = getRegion(); if(regionp && teleportCore()) { @@ -3513,6 +3927,12 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id) void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike) { + mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLure(lure_id, godlike)); + startTeleportRequest(); +} + +void LLAgent::doTeleportViaLure(const LLUUID& lure_id, BOOL godlike) +{ LLViewerRegion* regionp = getRegion(); if(regionp && teleportCore()) { @@ -3544,25 +3964,40 @@ void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike) // James Cook, July 28, 2005 void LLAgent::teleportCancel() { - LLViewerRegion* regionp = getRegion(); - if(regionp) + if (!hasPendingTeleportRequest()) { - // send the message - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("TeleportCancel"); - msg->nextBlockFast(_PREHASH_Info); - msg->addUUIDFast(_PREHASH_AgentID, getID()); - msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); - sendReliableMessage(); - } - gTeleportDisplay = FALSE; + LLViewerRegion* regionp = getRegion(); + if(regionp) + { + // send the message + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("TeleportCancel"); + msg->nextBlockFast(_PREHASH_Info); + msg->addUUIDFast(_PREHASH_AgentID, getID()); + msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); + sendReliableMessage(); + } + } + clearTeleportRequest(); gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); } void LLAgent::teleportViaLocation(const LLVector3d& pos_global) { + mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocation(pos_global)); + startTeleportRequest(); +} + +void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global) +{ LLViewerRegion* regionp = getRegion(); + + if (!regionp) + { + return; + } + U64 handle = to_region_handle(pos_global); LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle); if(regionp && info) @@ -3604,6 +4039,12 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global) // Teleport to global position, but keep facing in the same direction void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global) { + mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocationLookAt(pos_global)); + startTeleportRequest(); +} + +void LLAgent::doTeleportViaLocationLookAt(const LLVector3d& pos_global) +{ mbTeleportKeepsLookAt = true; gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); // detach camera form avatar, so it keeps direction U64 region_handle = to_region_handle(pos_global); @@ -3778,7 +4219,15 @@ void LLAgent::sendAgentSetAppearance() return; } - llinfos << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << llendl; + if (!gAgentWearables.changeInProgress()) + { + // Change is fully resolved, can close some open phases. + gAgentAvatarp->getPhases().stopPhase("process_initial_wearables_update"); + gAgentAvatarp->getPhases().stopPhase("wear_inventory_category"); + } + + gAgentAvatarp->sendAppearanceChangeMetrics(); + LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL; //dumpAvatarTEs( "sendAgentSetAppearance()" ); LLMessageSystem* msg = gMessageSystem; @@ -3825,14 +4274,14 @@ void LLAgent::sendAgentSetAppearance() // only update cache entries if we have all our baked textures if (textures_current) { - llinfos << "TAT: Sending cached texture data" << llendl; + LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sending cached texture data" << LL_ENDL; for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { BOOL generate_valid_hash = TRUE; if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index)) { generate_valid_hash = FALSE; - llinfos << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << llendl; + LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << LL_ENDL; } const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash); @@ -4037,5 +4486,149 @@ LLAgentQueryManager::~LLAgentQueryManager() { } -// EOF +//----------------------------------------------------------------------------- +// LLTeleportRequest +//----------------------------------------------------------------------------- +LLTeleportRequest::LLTeleportRequest() + : mStatus(kPending) +{ +} + +LLTeleportRequest::~LLTeleportRequest() +{ +} + +bool LLTeleportRequest::canRestartTeleport() +{ + return false; +} + +void LLTeleportRequest::restartTeleport() +{ + llassert(0); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLandmark +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId) + : LLTeleportRequest(), + mLandmarkId(pLandmarkId) +{ +} + +LLTeleportRequestViaLandmark::~LLTeleportRequestViaLandmark() +{ +} + +bool LLTeleportRequestViaLandmark::canRestartTeleport() +{ + return true; +} + +void LLTeleportRequestViaLandmark::startTeleport() +{ + gAgent.doTeleportViaLandmark(getLandmarkId()); +} + +void LLTeleportRequestViaLandmark::restartTeleport() +{ + gAgent.doTeleportViaLandmark(getLandmarkId()); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLure +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLure::LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike) + : LLTeleportRequestViaLandmark(pLureId), + mIsLureGodLike(pIsLureGodLike) +{ +} + +LLTeleportRequestViaLure::~LLTeleportRequestViaLure() +{ +} + +bool LLTeleportRequestViaLure::canRestartTeleport() +{ + // stinson 05/17/2012 : cannot restart a teleport via lure because of server-side restrictions + // The current scenario is as follows: + // 1. User A initializes a request for User B to teleport via lure + // 2. User B accepts the teleport via lure request + // 3. The server sees the init request from User A and the accept request from User B and matches them up + // 4. The server then removes the paired requests up from the "queue" + // 5. The server then fails User B's teleport for reason of maturity level (for example) + // 6. User B's viewer prompts user to increase their maturity level profile value. + // 7. User B confirms and accepts increase in maturity level + // 8. User B's viewer then attempts to teleport via lure again + // 9. This request will time-out on the viewer-side because User A's initial request has been removed from the "queue" in step 4 + + return false; +} + +void LLTeleportRequestViaLure::startTeleport() +{ + gAgent.doTeleportViaLure(getLandmarkId(), isLureGodLike()); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLocation +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLocation::LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal) + : LLTeleportRequest(), + mPosGlobal(pPosGlobal) +{ +} + +LLTeleportRequestViaLocation::~LLTeleportRequestViaLocation() +{ +} + +bool LLTeleportRequestViaLocation::canRestartTeleport() +{ + return true; +} + +void LLTeleportRequestViaLocation::startTeleport() +{ + gAgent.doTeleportViaLocation(getPosGlobal()); +} + +void LLTeleportRequestViaLocation::restartTeleport() +{ + gAgent.doTeleportViaLocation(getPosGlobal()); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLocationLookAt +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLocationLookAt::LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal) + : LLTeleportRequestViaLocation(pPosGlobal) +{ +} + +LLTeleportRequestViaLocationLookAt::~LLTeleportRequestViaLocationLookAt() +{ +} + +bool LLTeleportRequestViaLocationLookAt::canRestartTeleport() +{ + return true; +} + +void LLTeleportRequestViaLocationLookAt::startTeleport() +{ + gAgent.doTeleportViaLocationLookAt(getPosGlobal()); +} + +void LLTeleportRequestViaLocationLookAt::restartTeleport() +{ + gAgent.doTeleportViaLocationLookAt(getPosGlobal()); +} + +// EOF diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 0f7ed9ce68..daa15b0c1a 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -35,6 +35,8 @@ #include "llcoordframe.h" // for mFrameAgent #include "llvoavatardefines.h" +#include <boost/function.hpp> +#include <boost/shared_ptr.hpp> #include <boost/signals2.hpp> extern const BOOL ANIMATE; @@ -56,6 +58,9 @@ class LLAgentAccess; class LLSLURL; class LLPauseRequestHandle; class LLUIColor; +class LLTeleportRequest; + +typedef boost::shared_ptr<LLTeleportRequest> LLTeleportRequestPtr; //-------------------------------------------------------------------- // Types @@ -292,7 +297,9 @@ public: static void pressMicrophone(const LLSD& name); static void releaseMicrophone(const LLSD& name); + static void toggleMicrophone(const LLSD& name); static bool isMicrophoneOn(const LLSD& sdname); + static bool isActionAllowed(const LLSD& sdname); private: bool mVoiceConnected; @@ -371,14 +378,13 @@ public: void sitDown(); //-------------------------------------------------------------------- - // Busy + // Do Not Disturb //-------------------------------------------------------------------- public: - void setBusy(); - void clearBusy(); - BOOL getBusy() const; + void setDoNotDisturb(bool pIsDoNotDisturb); + bool isDoNotDisturb() const; private: - BOOL mIsBusy; + bool mIsDoNotDisturb; //-------------------------------------------------------------------- // Grab @@ -537,7 +543,8 @@ public: TELEPORT_MOVING = 3, // Viewer has received destination location from source simulator TELEPORT_START_ARRIVAL = 4, // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator TELEPORT_ARRIVING = 5, // Make the user wait while content "pre-caches" - TELEPORT_LOCAL = 6 // Teleporting in-sim without showing the progress screen + TELEPORT_LOCAL = 6, // Teleporting in-sim without showing the progress screen + TELEPORT_PENDING = 7 }; public: @@ -554,9 +561,6 @@ private: // Teleport Actions //-------------------------------------------------------------------- public: - void teleportRequest(const U64& region_handle, - const LLVector3& pos_local, // Go to a named location home - bool look_at_from_camera = false); void teleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark void teleportHome() { teleportViaLandmark(LLUUID::null); } // Go home void teleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location @@ -570,6 +574,44 @@ protected: //-------------------------------------------------------------------- // Teleport State //-------------------------------------------------------------------- + +public: + bool hasRestartableFailedTeleportRequest(); + void restartFailedTeleportRequest(); + void clearTeleportRequest(); + void setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange); + +private: + friend class LLTeleportRequest; + friend class LLTeleportRequestViaLandmark; + friend class LLTeleportRequestViaLure; + friend class LLTeleportRequestViaLocation; + friend class LLTeleportRequestViaLocationLookAt; + + LLTeleportRequestPtr mTeleportRequest; + boost::signals2::connection mTeleportFinishedSlot; + boost::signals2::connection mTeleportFailedSlot; + + bool mIsMaturityRatingChangingDuringTeleport; + U8 mMaturityRatingChange; + + bool hasPendingTeleportRequest(); + void startTeleportRequest(); + + void teleportRequest(const U64& region_handle, + const LLVector3& pos_local, // Go to a named location home + bool look_at_from_camera = false); + void doTeleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark + void doTeleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location + void doTeleportViaLocation(const LLVector3d& pos_global); // To a global location - this will probably need to be deprecated + void doTeleportViaLocationLookAt(const LLVector3d& pos_global);// To a global location, preserving camera rotation + + void handleTeleportFinished(); + void handleTeleportFailed(); + + //-------------------------------------------------------------------- + // Teleport State + //-------------------------------------------------------------------- public: ETeleportState getTeleportState() const { return mTeleportState; } void setTeleportState(ETeleportState state); @@ -595,7 +637,6 @@ public: private: bool mCanEditParcel; - static bool isActionAllowed(const LLSD& sdname); static void parcelChangedCallback(); /******************************************************************************** @@ -613,8 +654,6 @@ public: const LLAgentAccess& getAgentAccess(); BOOL canManageEstate() const; BOOL getAdminOverride() const; - // ! BACKWARDS COMPATIBILITY ! This function can go away after the AO transition (see llstartup.cpp). - void setAOTransition(); private: LLAgentAccess * mAgentAccess; @@ -630,6 +669,16 @@ public: void requestEnterGodMode(); void requestLeaveGodMode(); + typedef boost::function<void (U8)> god_level_change_callback_t; + typedef boost::signals2::signal<void (U8)> god_level_change_signal_t; + typedef boost::signals2::connection god_level_change_slot_t; + + god_level_change_slot_t registerGodLevelChanageListener(god_level_change_callback_t pGodLevelChangeCallback); + +private: + god_level_change_signal_t mGodLevelChangeSignal; + + //-------------------------------------------------------------------- // Maturity //-------------------------------------------------------------------- @@ -649,13 +698,28 @@ public: bool isTeen() const; bool isMature() const; bool isAdult() const; - void setTeen(bool teen); void setMaturity(char text); - static int convertTextToMaturity(char text); - bool sendMaturityPreferenceToServer(int preferredMaturity); // ! "U8" instead of "int"? + static int convertTextToMaturity(char text); + +private: + bool mIsDoSendMaturityPreferenceToServer; + unsigned int mMaturityPreferenceRequestId; + unsigned int mMaturityPreferenceResponseId; + unsigned int mMaturityPreferenceNumRetries; + U8 mLastKnownRequestMaturity; + U8 mLastKnownResponseMaturity; + + bool isMaturityPreferenceSyncedWithServer() const; + void sendMaturityPreferenceToServer(U8 pPreferredMaturity); + + friend class LLMaturityPreferencesResponder; + void handlePreferredMaturityResult(U8 pServerMaturity); + void handlePreferredMaturityError(); + void reportPreferredMaturitySuccess(); + void reportPreferredMaturityError(); // Maturity callbacks for PreferredMaturity control variable - void handleMaturity(const LLSD& newvalue); + void handleMaturity(const LLSD &pNewValue); bool validateMaturity(const LLSD& newvalue); diff --git a/indra/newview/llagentaccess.cpp b/indra/newview/llagentaccess.cpp index 08a33ab04a..c4ee321e04 100644 --- a/indra/newview/llagentaccess.cpp +++ b/indra/newview/llagentaccess.cpp @@ -33,8 +33,7 @@ LLAgentAccess::LLAgentAccess(LLControlGroup& savedSettings) : mSavedSettings(savedSettings), mAccess(SIM_ACCESS_PG), mAdminOverride(false), - mGodLevel(GOD_NOT), - mAOTransition(false) + mGodLevel(GOD_NOT) { } @@ -133,18 +132,6 @@ bool LLAgentAccess::isAdult() const return mAccess >= SIM_ACCESS_ADULT; } -void LLAgentAccess::setTeen(bool teen) -{ - if (teen) - { - mAccess = SIM_ACCESS_PG; - } - else - { - mAccess = SIM_ACCESS_MATURE; - } -} - //static int LLAgentAccess::convertTextToMaturity(char text) { @@ -182,16 +169,6 @@ void LLAgentAccess::setMaturity(char text) mSavedSettings.setU32("PreferredMaturity", preferred_access); } -void LLAgentAccess::setTransition() -{ - mAOTransition = true; -} - -bool LLAgentAccess::isInTransition() const -{ - return mAOTransition; -} - bool LLAgentAccess::canSetMaturity(S32 maturity) { if (isGodlike()) // Gods can always set their Maturity level diff --git a/indra/newview/llagentaccess.h b/indra/newview/llagentaccess.h index 2e98e4eea1..4e851b0aa0 100644 --- a/indra/newview/llagentaccess.h +++ b/indra/newview/llagentaccess.h @@ -59,13 +59,10 @@ public: bool isMature() const; bool isAdult() const; - void setTeen(bool teen); void setMaturity(char text); static int convertTextToMaturity(char text); - void setTransition(); // sets the transition bit, which defaults to false - bool isInTransition() const; bool canSetMaturity(S32 maturity); private: @@ -73,13 +70,6 @@ private: U8 mGodLevel; bool mAdminOverride; - // this should be deleted after the 60-day AO transition. - // It should be safe to remove it in Viewer 2009 - // It's set by a special short-term flag in login.cgi - // called ao_transition. When that's gone, this can go, along with - // all of the code that depends on it. - bool mAOTransition; - LLControlGroup& mSavedSettings; }; diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 751b73e1eb..9025c7af8b 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -35,6 +35,7 @@ #include "llfloaterreg.h" #include "llhudmanager.h" #include "lljoystickbutton.h" +#include "llmoveview.h" #include "llselectmgr.h" #include "llsmoothstep.h" #include "lltoolmgr.h" @@ -2113,6 +2114,11 @@ void LLAgentCamera::changeCameraToDefault() { changeCameraToThirdPerson(); } + if (gSavedSettings.getBOOL("HideUIControls")) + { + gViewerWindow->setUIVisibility(false); + LLPanelStandStopFlying::getInstance()->setVisible(false); + } } diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index a8d2222c03..a4c0b056ac 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -126,6 +126,17 @@ LLAgentListener::LLAgentListener(LLAgent &agent) "[\"obj_uuid\"]: id of object to look at, use this or [\"position\"] to indicate the target\n" "[\"position\"]: region position {x, y, z} where to find closest object or avatar to look at", &LLAgentListener::lookAt); + add("getGroups", + "Send information about the agent's groups on [\"reply\"]:\n" + "[\"groups\"]: array of group information\n" + "[\"id\"]: group id\n" + "[\"name\"]: group name\n" + "[\"insignia\"]: group insignia texture id\n" + "[\"notices\"]: boolean indicating if this user accepts notices from this group\n" + "[\"display\"]: boolean indicating if this group is listed in the user's profile\n" + "[\"contrib\"]: user's land contribution to this group\n", + &LLAgentListener::getGroups, + LLSDMap("reply", LLSD())); } void LLAgentListener::requestTeleport(LLSD const & event_data) const diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 13b62cb019..e441f21f90 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(); } } @@ -816,7 +817,10 @@ void LLAgentWearables::popWearable(const LLWearableType::EType type, U32 index) if (wearable) { mWearableDatas[type].erase(mWearableDatas[type].begin() + index); + if (isAgentAvatarValid()) + { gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE); + } wearable->setLabelUpdated(); } } @@ -949,6 +953,13 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs if (mInitialWearablesUpdateReceived) return; + if (isAgentAvatarValid()) + { + //gAgentAvatarp->clearPhases(); // reset phase timers for outfit loading. + gAgentAvatarp->getPhases().startPhase("process_initial_wearables_update"); + 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() @@ -1439,7 +1450,16 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it { gAgentAvatarp->setCompositeUpdatesEnabled(TRUE); gAgentAvatarp->updateVisualParams(); - gAgentAvatarp->invalidateAll(); + + // If we have not yet declouded, we may want to use + // baked texture UUIDs sent from the first objectUpdate message + // don't overwrite these. If we have already declouded, we've saved + // these ids as the last known good textures and can invalidate without + // re-clouding. + if (!gAgentAvatarp->getIsCloud()) + { + gAgentAvatarp->invalidateAll(); + } } // Start rendering & update the server @@ -1619,7 +1639,13 @@ void LLAgentWearables::queryWearableCache() //VWR-22113: gAgent.getRegion() can return null if invalid, seen here on logout if(gAgent.getRegion()) { - llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl; + if (isAgentAvatarValid()) + { + selfStartPhase("fetch_texture_cache_entries"); + gAgentAvatarp->outputRezTiming("Fetching textures from cache"); + } + + LL_INFOS("Avatar") << gAgentAvatarp->avString() << "Requesting texture cache entry for " << num_queries << " baked textures" << LL_ENDL; gMessageSystem->sendReliable(gAgent.getRegion()->getHost()); gAgentQueryManager.mNumPendingQueries++; gAgentQueryManager.mWearablesCacheQueryID++; @@ -2067,6 +2093,11 @@ boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_ return mLoadedSignal.connect(cb); } +bool LLAgentWearables::changeInProgress() const +{ + return mCOFChangeInProgress; +} + void LLAgentWearables::notifyLoadingStarted() { mCOFChangeInProgress = true; diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 01cae3ffd8..5932be21c6 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -233,6 +233,7 @@ public: typedef boost::signals2::signal<void()> loaded_signal_t; boost::signals2::connection addLoadedCallback(loaded_callback_t cb); + bool changeInProgress() const; void notifyLoadingStarted(); void notifyLoadingFinished(); diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp index 1edc96e165..e31e39dca2 100644 --- a/indra/newview/llagentwearablesfetch.cpp +++ b/indra/newview/llagentwearablesfetch.cpp @@ -87,6 +87,11 @@ public: LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) : LLInventoryFetchDescendentsObserver(cof_id) { + if (isAgentAvatarValid()) + { + gAgentAvatarp->getPhases().startPhase("initial_wearables_fetch"); + gAgentAvatarp->outputRezTiming("Initial wearables fetch started"); + } } LLInitialWearablesFetch::~LLInitialWearablesFetch() @@ -101,6 +106,11 @@ void LLInitialWearablesFetch::done() // idle tick instead. gInventory.removeObserver(this); doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this)); + if (isAgentAvatarValid()) + { + gAgentAvatarp->getPhases().stopPhase("initial_wearables_fetch"); + gAgentAvatarp->outputRezTiming("Initial wearables fetch done"); + } } void LLInitialWearablesFetch::add(InitialWearableData &data) @@ -111,6 +121,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; @@ -326,7 +342,7 @@ void LLLibraryOutfitsFetch::folderDone() } mClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING); - mLibraryClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true); + mLibraryClothingID = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_CLOTHING, false); // If Library->Clothing->Initial Outfits exists, use that. LLNameCategoryCollector matchFolderFunctor("Initial Outfits"); 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/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp new file mode 100644 index 0000000000..0d7d41304d --- /dev/null +++ b/indra/newview/llappcorehttp.cpp @@ -0,0 +1,192 @@ +/** + * @file llappcorehttp.cpp + * @brief + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "llappcorehttp.h" + +#include "llviewercontrol.h" + + +const F64 LLAppCoreHttp::MAX_THREAD_WAIT_TIME(10.0); + +LLAppCoreHttp::LLAppCoreHttp() + : mRequest(NULL), + mStopHandle(LLCORE_HTTP_HANDLE_INVALID), + mStopRequested(0.0), + mStopped(false), + mPolicyDefault(-1) +{} + + +LLAppCoreHttp::~LLAppCoreHttp() +{ + delete mRequest; + mRequest = NULL; +} + + +void LLAppCoreHttp::init() +{ + LLCore::HttpStatus status = LLCore::HttpRequest::createService(); + if (! status) + { + LL_ERRS("Init") << "Failed to initialize HTTP services. Reason: " + << status.toString() + << LL_ENDL; + } + + // Point to our certs or SSH/https: will fail on connect + status = LLCore::HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_CA_FILE, + gDirUtilp->getCAFile()); + if (! status) + { + LL_ERRS("Init") << "Failed to set CA File for HTTP services. Reason: " + << status.toString() + << LL_ENDL; + } + + // Establish HTTP Proxy. "LLProxy" is a special string which directs + // the code to use LLProxy::applyProxySettings() to establish any + // HTTP or SOCKS proxy for http operations. + status = LLCore::HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_LLPROXY, 1); + if (! status) + { + LL_ERRS("Init") << "Failed to set HTTP proxy for HTTP services. Reason: " + << status.toString() + << LL_ENDL; + } + + // Tracing levels for library & libcurl (note that 2 & 3 are beyond spammy): + // 0 - None + // 1 - Basic start, stop simple transitions + // 2 - libcurl CURLOPT_VERBOSE mode with brief lines + // 3 - with partial data content + static const std::string http_trace("QAModeHttpTrace"); + if (gSavedSettings.controlExists(http_trace)) + { + long trace_level(0L); + trace_level = long(gSavedSettings.getU32(http_trace)); + status = LLCore::HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_TRACE, trace_level); + } + + // Setup default policy and constrain if directed to + mPolicyDefault = LLCore::HttpRequest::DEFAULT_POLICY_ID; + static const std::string texture_concur("TextureFetchConcurrency"); + if (gSavedSettings.controlExists(texture_concur)) + { + U32 concur(llmin(gSavedSettings.getU32(texture_concur), U32(12))); + + if (concur > 0) + { + LLCore::HttpStatus status; + status = LLCore::HttpRequest::setPolicyClassOption(mPolicyDefault, + LLCore::HttpRequest::CP_CONNECTION_LIMIT, + concur); + if (! status) + { + LL_WARNS("Init") << "Unable to set texture fetch concurrency. Reason: " + << status.toString() + << LL_ENDL; + } + else + { + LL_INFOS("Init") << "Application settings overriding default texture fetch concurrency. New value: " + << concur + << LL_ENDL; + } + } + } + + // Kick the thread + status = LLCore::HttpRequest::startThread(); + if (! status) + { + LL_ERRS("Init") << "Failed to start HTTP servicing thread. Reason: " + << status.toString() + << LL_ENDL; + } + + mRequest = new LLCore::HttpRequest; +} + + +void LLAppCoreHttp::requestStop() +{ + llassert_always(mRequest); + + mStopHandle = mRequest->requestStopThread(this); + if (LLCORE_HTTP_HANDLE_INVALID != mStopHandle) + { + mStopRequested = LLTimer::getTotalSeconds(); + } +} + + +void LLAppCoreHttp::cleanup() +{ + if (LLCORE_HTTP_HANDLE_INVALID == mStopHandle) + { + // Should have been started already... + requestStop(); + } + + if (LLCORE_HTTP_HANDLE_INVALID == mStopHandle) + { + LL_WARNS("Cleanup") << "Attempting to cleanup HTTP services without thread shutdown" + << LL_ENDL; + } + else + { + while (! mStopped && LLTimer::getTotalSeconds() < (mStopRequested + MAX_THREAD_WAIT_TIME)) + { + mRequest->update(200000); + ms_sleep(50); + } + if (! mStopped) + { + LL_WARNS("Cleanup") << "Attempting to cleanup HTTP services with thread shutdown incomplete" + << LL_ENDL; + } + } + + delete mRequest; + mRequest = NULL; + + LLCore::HttpStatus status = LLCore::HttpRequest::destroyService(); + if (! status) + { + LL_WARNS("Cleanup") << "Failed to shutdown HTTP services, continuing. Reason: " + << status.toString() + << LL_ENDL; + } +} + + +void LLAppCoreHttp::onCompleted(LLCore::HttpHandle, LLCore::HttpResponse *) +{ + mStopped = true; +} diff --git a/indra/newview/llappcorehttp.h b/indra/newview/llappcorehttp.h new file mode 100644 index 0000000000..241d73ad52 --- /dev/null +++ b/indra/newview/llappcorehttp.h @@ -0,0 +1,86 @@ +/** + * @file llappcorehttp.h + * @brief Singleton initialization/shutdown class for llcorehttp library + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_APP_COREHTTP_H_ +#define _LL_APP_COREHTTP_H_ + + +#include "httprequest.h" +#include "httphandler.h" +#include "httpresponse.h" + + +// This class manages the lifecyle of the core http library. +// Slightly different style than traditional code but reflects +// the use of handler classes and light-weight interface +// object instances of the new libraries. To be used +// as a singleton and static construction is fine. +class LLAppCoreHttp : public LLCore::HttpHandler +{ +public: + LLAppCoreHttp(); + ~LLAppCoreHttp(); + + // Initialize the LLCore::HTTP library creating service classes + // and starting the servicing thread. Caller is expected to do + // other initializations (SSL mutex, thread hash function) appropriate + // for the application. + void init(); + + // Request that the servicing thread stop servicing requests, + // release resource references and stop. Request is asynchronous + // and @see cleanup() will perform a limited wait loop for this + // request to stop the thread. + void requestStop(); + + // Terminate LLCore::HTTP library services. Caller is expected + // to have made a best-effort to shutdown the servicing thread + // by issuing a requestThreadStop() and waiting for completion + // notification that the stop has completed. + void cleanup(); + + // Notification when the stop request is complete. + virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); + + // Retrieve the policy class for default operations. + int getPolicyDefault() const + { + return mPolicyDefault; + } + +private: + static const F64 MAX_THREAD_WAIT_TIME; + +private: + LLCore::HttpRequest * mRequest; + LLCore::HttpHandle mStopHandle; + F64 mStopRequested; + bool mStopped; + int mPolicyDefault; +}; + + +#endif // _LL_APP_COREHTTP_H_ diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 663257042e..769b4eafe1 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -50,6 +50,12 @@ #include "llviewerregion.h" #include "llwearablelist.h" +std::string self_av_string() +{ + // On logout gAgentAvatarp can already be invalid + return isAgentAvatarValid() ? gAgentAvatarp->avString() : ""; +} + // RAII thingy to guarantee that a variable gets reset when the Setter // goes out of scope. More general utility would be handy - TODO: // check boost. @@ -156,6 +162,10 @@ public: { mCatID = cat_id; mAppend = append; + + LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; + + selfStartPhase("wear_inventory_category_callback"); } void fire(const LLUUID& item_id) { @@ -167,13 +177,16 @@ public: * after the last item has fired the event and dereferenced it -- if all * the events actually fire! */ + LL_DEBUGS("Avatar") << self_av_string() << " fired on copied item, id " << item_id << LL_ENDL; } protected: ~LLWearInventoryCategoryCallback() { - llinfos << "done all inventory callbacks" << llendl; + LL_INFOS("Avatar") << self_av_string() << "done all inventory callbacks" << LL_ENDL; + selfStopPhase("wear_inventory_category_callback"); + // Is the destructor called by ordinary dereference, or because the app's shutting down? // If the inventory callback manager goes away, we're shutting down, no longer want the callback. if( LLInventoryCallbackManager::is_instantiated() ) @@ -182,7 +195,7 @@ protected: } else { - llwarns << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl; + llwarns << self_av_string() << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl; } } @@ -212,14 +225,18 @@ LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(bool update_base_outfit mFireCount(0), mUpdateBaseOrder(update_base_outfit_ordering) { + selfStartPhase("update_appearance_on_destroy"); } LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy() { - llinfos << "done update appearance on destroy" << llendl; - if (!LLApp::isExiting()) { + // speculative fix for MAINT-1150 + LL_INFOS("Avatar") << self_av_string() << "done update appearance on destroy" << LL_ENDL; + + selfStopPhase("update_appearance_on_destroy"); + LLAppearanceMgr::instance().updateAppearanceFromCOF(mUpdateBaseOrder); } } @@ -229,7 +246,7 @@ void LLUpdateAppearanceOnDestroy::fire(const LLUUID& inv_item) LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(inv_item); const std::string item_name = item ? item->getName() : "ITEM NOT FOUND"; #ifndef LL_RELEASE_FOR_DOWNLOAD - llinfos << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << LL_ENDL; #endif mFireCount++; } @@ -268,6 +285,8 @@ struct LLFoundData class LLWearableHoldingPattern { + LOG_CLASS(LLWearableHoldingPattern); + public: LLWearableHoldingPattern(); ~LLWearableHoldingPattern(); @@ -337,11 +356,16 @@ LLWearableHoldingPattern::LLWearableHoldingPattern(): } sActiveHoldingPatterns.insert(this); + selfStartPhase("holding_pattern"); } LLWearableHoldingPattern::~LLWearableHoldingPattern() { sActiveHoldingPatterns.erase(this); + if (isMostRecent()) + { + selfStopPhase("holding_pattern"); + } } bool LLWearableHoldingPattern::isMostRecent() @@ -388,9 +412,10 @@ void LLWearableHoldingPattern::checkMissingWearables() { if (!isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway why don't we actually skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } - + std::vector<S32> found_by_type(LLWearableType::WT_COUNT,0); std::vector<S32> requested_by_type(LLWearableType::WT_COUNT,0); for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it) @@ -406,7 +431,7 @@ void LLWearableHoldingPattern::checkMissingWearables() { if (requested_by_type[type] > found_by_type[type]) { - llwarns << "got fewer wearables than requested, type " << type << ": requested " << requested_by_type[type] << ", found " << found_by_type[type] << llendl; + llwarns << self_av_string() << "got fewer wearables than requested, type " << type << ": requested " << requested_by_type[type] << ", found " << found_by_type[type] << llendl; } if (found_by_type[type] > 0) continue; @@ -423,11 +448,13 @@ void LLWearableHoldingPattern::checkMissingWearables() mTypesToRecover.insert(type); mTypesToLink.insert(type); recoverMissingWearable((LLWearableType::EType)type); - llwarns << "need to replace " << type << llendl; + llwarns << self_av_string() << "need to replace " << type << llendl; } } resetTime(60.0F); + + selfStartPhase("get_missing_wearables"); if (!pollMissingWearables()) { doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollMissingWearables,this)); @@ -436,15 +463,21 @@ 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; + // runway need to skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } // Activate all gestures in this folder if (mGestItems.count() > 0) { - llinfos << "Activating " << mGestItems.count() << " gestures" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Activating " << mGestItems.count() << " gestures" << LL_ENDL; LLGestureMgr::instance().activateGestures(mGestItems); @@ -461,13 +494,13 @@ void LLWearableHoldingPattern::onAllComplete() } // Update wearables. - llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl; + LL_INFOS("Avatar") << self_av_string() << "Updating agent wearables with " << mResolved << " wearable items " << LL_ENDL; LLAppearanceMgr::instance().updateAgentWearables(this, false); // Update attachments to match those requested. if (isAgentAvatarValid()) { - llinfos << "Updating " << mObjItems.count() << " attachments" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.count() << " attachments" << LL_ENDL; LLAgentWearables::userUpdateAttachments(mObjItems); } @@ -485,9 +518,12 @@ void LLWearableHoldingPattern::onAllComplete() void LLWearableHoldingPattern::onFetchCompletion() { + selfStopPhase("get_wearables"); + if (!isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } checkMissingWearables(); @@ -498,7 +534,8 @@ bool LLWearableHoldingPattern::pollFetchCompletion() { if (!isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } bool completed = isFetchCompleted(); @@ -507,14 +544,14 @@ bool LLWearableHoldingPattern::pollFetchCompletion() if (done) { - llinfos << "polling, done status: " << completed << " timed out " << timed_out - << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; + LL_INFOS("Avatar") << self_av_string() << "polling, done status: " << completed << " timed out " << timed_out + << " elapsed " << mWaitTime.getElapsedTimeF32() << LL_ENDL; mFired = true; if (timed_out) { - llwarns << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl; + llwarns << self_av_string() << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl; } onFetchCompletion(); @@ -536,6 +573,7 @@ public: if (!mHolder->isMostRecent()) { llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? } llinfos << "Recovered item link for type " << mType << llendl; @@ -562,12 +600,12 @@ public: } else { - llwarns << "inventory item not found for recovered wearable" << llendl; + llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl; } } else { - llwarns << "inventory link not found for recovered wearable" << llendl; + llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl; } } private: @@ -589,10 +627,11 @@ public: { if (!mHolder->isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } - llinfos << "Recovered item for type " << mType << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << mType << LL_ENDL; LLViewerInventoryItem *itemp = gInventory.getItem(item_id); mWearable->setItemID(item_id); LLPointer<LLInventoryCallback> cb = new RecoveredItemLinkCB(mType,mWearable,mHolder); @@ -619,7 +658,8 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type { if (!isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } // Try to recover by replacing missing wearable with a new one. @@ -658,7 +698,7 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables() if ((data.mWearableType < LLWearableType::WT_COUNT) && (!data.mWearable)) { // Wearable link that was never resolved; remove links to it from COF - llinfos << "removing link for unresolved item " << data.mItemID.asString() << llendl; + LL_INFOS("Avatar") << self_av_string() << "removing link for unresolved item " << data.mItemID.asString() << LL_ENDL; LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false); } } @@ -668,7 +708,8 @@ bool LLWearableHoldingPattern::pollMissingWearables() { if (!isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } bool timed_out = isTimedOut(); @@ -677,15 +718,17 @@ bool LLWearableHoldingPattern::pollMissingWearables() if (!done) { - llinfos << "polling missing wearables, waiting for items " << mTypesToRecover.size() + LL_INFOS("Avatar") << self_av_string() << "polling missing wearables, waiting for items " << mTypesToRecover.size() << " links " << mTypesToLink.size() << " wearables, timed out " << timed_out << " elapsed " << mWaitTime.getElapsedTimeF32() - << " done " << done << llendl; + << " done " << done << LL_ENDL; } if (done) { + selfStopPhase("get_missing_wearables"); + gAgentAvatarp->debugWearablesLoaded(); // BAP - if we don't call clearCOFLinksForMissingWearables() @@ -715,14 +758,14 @@ void LLWearableHoldingPattern::handleLateArrivals() } if (!isMostRecent()) { - llwarns << "Late arrivals not handled - outfit change no longer valid" << llendl; + llwarns << self_av_string() << "Late arrivals not handled - outfit change no longer valid" << llendl; } if (!mIsAllComplete) { - llwarns << "Late arrivals not handled - in middle of missing wearables processing" << llendl; + llwarns << self_av_string() << "Late arrivals not handled - in middle of missing wearables processing" << llendl; } - llinfos << "Need to handle " << mLateArrivals.size() << " late arriving wearables" << llendl; + LL_INFOS("Avatar") << self_av_string() << "Need to handle " << mLateArrivals.size() << " late arriving wearables" << LL_ENDL; // Update mFoundList using late-arriving wearables. std::set<LLWearableType::EType> replaced_types; @@ -798,19 +841,19 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable) { if (!isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } mResolved += 1; // just counting callbacks, not successes. - llinfos << "resolved " << mResolved << "/" << getFoundList().size() << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "resolved " << mResolved << "/" << getFoundList().size() << LL_ENDL; if (!wearable) { - llwarns << "no wearable found" << llendl; + llwarns << self_av_string() << "no wearable found" << llendl; } if (mFired) { - llwarns << "called after holder fired" << llendl; + llwarns << self_av_string() << "called after holder fired" << llendl; if (wearable) { mLateArrivals.insert(wearable); @@ -836,7 +879,7 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable) // Failing this means inventory or asset server are corrupted in a way we don't handle. if ((data.mWearableType >= LLWearableType::WT_COUNT) || (wearable->getType() != data.mWearableType)) { - llwarns << "recovered wearable but type invalid. inventory wearable type: " << data.mWearableType << " asset wearable type: " << wearable->getType() << llendl; + llwarns << self_av_string() << "recovered wearable but type invalid. inventory wearable type: " << data.mWearableType << " asset wearable type: " << wearable->getType() << llendl; break; } @@ -1384,8 +1427,8 @@ void LLAppearanceMgr::filterWearableItems( // Create links to all listed items. void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid, - LLInventoryModel::item_array_t& items, - LLPointer<LLInventoryCallback> cb) + LLInventoryModel::item_array_t& items, + LLPointer<LLInventoryCallback> cb) { for (S32 i=0; i<items.count(); i++) { @@ -1401,7 +1444,7 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid, const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid); const std::string cat_name = cat ? cat->getName() : "CAT NOT FOUND"; #ifndef LL_RELEASE_FOR_DOWNLOAD - llinfos << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << LL_ENDL; #endif } } @@ -1409,7 +1452,7 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid, void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) { LLViewerInventoryCategory *pcat = gInventory.getCategory(category); - llinfos << "starting, cat " << (pcat ? pcat->getName() : "[UNKNOWN]") << llendl; + LL_INFOS("Avatar") << self_av_string() << "starting, cat '" << (pcat ? pcat->getName() : "[UNKNOWN]") << "'" << LL_ENDL; const LLUUID cof = getCOF(); @@ -1471,26 +1514,26 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) gInventory.notifyObservers(); // Create links to new COF contents. - llinfos << "creating LLUpdateAppearanceOnDestroy" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "creating LLUpdateAppearanceOnDestroy" << LL_ENDL; LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy(!append); #ifndef LL_RELEASE_FOR_DOWNLOAD - llinfos << "Linking body items" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL; #endif linkAll(cof, body_items, link_waiter); #ifndef LL_RELEASE_FOR_DOWNLOAD - llinfos << "Linking wear items" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Linking wear items" << LL_ENDL; #endif linkAll(cof, wear_items, link_waiter); #ifndef LL_RELEASE_FOR_DOWNLOAD - llinfos << "Linking obj items" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Linking obj items" << LL_ENDL; #endif linkAll(cof, obj_items, link_waiter); #ifndef LL_RELEASE_FOR_DOWNLOAD - llinfos << "Linking gesture items" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Linking gesture items" << LL_ENDL; #endif linkAll(cof, gest_items, link_waiter); @@ -1499,7 +1542,7 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) { createBaseOutfitLink(category, link_waiter); } - llinfos << "waiting for LLUpdateAppearanceOnDestroy" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL; } void LLAppearanceMgr::updatePanelOutfitName(const std::string& name) @@ -1560,8 +1603,6 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo { gAgentWearables.setWearableOutfit(items, wearables, !append); } - -// dec_busy_count(); } static void remove_non_link_items(LLInventoryModel::item_array_t &items) @@ -1656,7 +1697,7 @@ void LLAppearanceMgr::enforceItemRestrictions() ++it) { LLViewerInventoryItem *item = *it; - llinfos << "purging duplicate or excess item " << item->getName() << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "purging duplicate or excess item " << item->getName() << LL_ENDL; gInventory.purgeObject(item->getUUID()); } gInventory.notifyObservers(); @@ -1671,9 +1712,11 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) return; } + LLVOAvatar::ScopedPhaseSetter(gAgentAvatarp,"update_appearance_from_cof"); + BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF); - llinfos << "starting" << llendl; + LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; //checking integrity of the COF in terms of ordering of wearables, //checking and updating links' descriptions of wearables in the COF (before analyzed for "dirty" state) @@ -1765,12 +1808,14 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) } } + selfStartPhase("get_wearables"); + for (LLWearableHoldingPattern::found_list_t::iterator it = holder->getFoundList().begin(); it != holder->getFoundList().end(); ++it) { LLFoundData& found = *it; - lldebugs << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl; + lldebugs << self_av_string() << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl; // Fetch the wearables about to be worn. LLWearableList::instance().getAsset(found.mAssetID, @@ -1842,11 +1887,15 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool { if(!category) return; + selfClearPhases(); + selfStartPhase("wear_inventory_category"); + gAgentWearables.notifyLoadingStarted(); - llinfos << "wearInventoryCategory( " << category->getName() - << " )" << llendl; + LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategory( " << category->getName() + << " )" << LL_ENDL; + selfStartPhase("wear_inventory_category_fetch"); callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal, &LLAppearanceMgr::instance(), category->getUUID(), copy, append)); @@ -1854,7 +1903,9 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append) { - llinfos << "starting" << llendl; + LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; + + selfStopPhase("wear_inventory_category_fetch"); // We now have an outfit ready to be copied to agent inventory. Do // it, and wear that outfit normally. @@ -1937,8 +1988,8 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego // wearables being dirty. if(!category) return; - llinfos << "wearInventoryCategoryOnAvatar( " << category->getName() - << " )" << llendl; + LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName() + << "'" << LL_ENDL; if (gAgentCamera.cameraCustomizeAvatar()) { @@ -1951,8 +2002,7 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego void LLAppearanceMgr::wearOutfitByName(const std::string& name) { - llinfos << "Wearing category " << name << llendl; - //inc_busy_count(); + LL_INFOS("Avatar") << self_av_string() << "Wearing category " << name << LL_ENDL; LLInventoryModel::cat_array_t cat_array; LLInventoryModel::item_array_t item_array; @@ -1992,8 +2042,6 @@ void LLAppearanceMgr::wearOutfitByName(const std::string& name) llwarns << "Couldn't find outfit " <<name<< " in wearOutfitByName()" << llendl; } - - //dec_busy_count(); } bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventoryItem *b) @@ -2274,11 +2322,11 @@ const std::string OTHER_GESTURES_FOLDER = "Other Gestures"; void LLAppearanceMgr::copyLibraryGestures() { - llinfos << "Copying library gestures" << llendl; + LL_INFOS("Avatar") << self_av_string() << "Copying library gestures" << LL_ENDL; // Copy gestures LLUUID lib_gesture_cat_id = - gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE,false,true); + gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_GESTURE,false); if (lib_gesture_cat_id.isNull()) { llwarns << "Unable to copy gestures, source category not found" << llendl; @@ -2330,11 +2378,11 @@ void LLAppearanceMgr::copyLibraryGestures() LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name); if (cat_id.isNull()) { - llwarns << "failed to find gesture folder for " << folder_name << llendl; + llwarns << self_av_string() << "failed to find gesture folder for " << folder_name << llendl; } else { - llinfos << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << LL_ENDL; callAfterCategoryFetch(cat_id, boost::bind(&LLAppearanceMgr::shallowCopyCategory, &LLAppearanceMgr::instance(), @@ -2348,7 +2396,7 @@ void LLAppearanceMgr::autopopulateOutfits() // If this is the very first time the user has logged into viewer2+ (from a legacy viewer, or new account) // then auto-populate outfits from the library into the My Outfits folder. - llinfos << "avatar fully visible" << llendl; + LL_INFOS("Avatar") << self_av_string() << "avatar fully visible" << LL_ENDL; static bool check_populate_my_outfits = true; if (check_populate_my_outfits && @@ -2363,6 +2411,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 @@ -2722,7 +2772,7 @@ void LLAppearanceMgr::dumpCat(const LLUUID& cat_id, const std::string& msg) } void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items, - const std::string& msg) + const std::string& msg) { for (S32 i=0; i<items.count(); i++) { @@ -2733,9 +2783,8 @@ void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items, { asset_id = linked_item->getAssetUUID(); } - llinfos << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << llendl; + LL_DEBUGS("Avatar") << self_av_string() << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << LL_ENDL; } - llinfos << llendl; } LLAppearanceMgr::LLAppearanceMgr(): @@ -2914,7 +2963,6 @@ public: { llwarns << "Nothing fetched in category " << mComplete.front() << llendl; - //dec_busy_count(); gInventory.removeObserver(this); // lets notify observers that loading is finished. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 8946bb6904..1c6f099185 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2012, 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 @@ -42,9 +42,12 @@ #include "llagentcamera.h" #include "llagentlanguage.h" #include "llagentwearables.h" +#include "llfloaterimcontainer.h" #include "llwindow.h" #include "llviewerstats.h" #include "llviewerstatsrecorder.h" +#include "llmarketplacefunctions.h" +#include "llmarketplacenotifications.h" #include "llmd5.h" #include "llmeshrepository.h" #include "llpumpio.h" @@ -57,6 +60,7 @@ #include "llares.h" #include "llcurl.h" #include "llcalc.h" +#include "llconversationlog.h" #include "lltexturestats.h" #include "lltexturestats.h" #include "llviewerwindow.h" @@ -75,6 +79,7 @@ //#include "llfirstuse.h" #include "llrender.h" #include "llteleporthistory.h" +#include "lltoast.h" #include "lllocationhistory.h" #include "llfasttimerview.h" #include "llvector4a.h" @@ -86,10 +91,12 @@ #include "lllogininstance.h" #include "llprogressview.h" #include "llvocache.h" +#include "llvopartgroup.h" #include "llweb.h" #include "llsecondlifeurls.h" #include "llupdaterservice.h" -#include "llcallfloater.h" +#include "llfloatertexturefetchdebugger.h" +#include "llspellcheck.h" // Linden library includes #include "llavatarnamecache.h" @@ -103,15 +110,19 @@ #include "llvfsthread.h" #include "llvolumemgr.h" #include "llxfermanager.h" +#include "llphysicsextensions.h" #include "llnotificationmanager.h" #include "llnotifications.h" #include "llnotificationsutil.h" +#include "llleap.h" +#include "stringize.h" + // Third party library includes #include <boost/bind.hpp> #include <boost/foreach.hpp> - +#include <boost/algorithm/string.hpp> #if LL_WINDOWS @@ -121,7 +132,6 @@ #endif #include "llapr.h" -#include "apr_dso.h" #include <boost/lexical_cast.hpp> #include "llviewerkeyboard.h" @@ -158,6 +168,7 @@ #include "llcontainerview.h" #include "lltooltip.h" +#include "llsdutil.h" #include "llsdserialize.h" #include "llworld.h" @@ -190,6 +201,7 @@ #include "llviewercontrol.h" #include "lleventnotifier.h" #include "llcallbacklist.h" +#include "lldeferredsounds.h" #include "pipeline.h" #include "llgesturemgr.h" #include "llsky.h" @@ -312,7 +324,7 @@ BOOL gLogoutInProgress = FALSE; //////////////////////////////////////////////////////////// // Internal globals... that should be removed. static std::string gArgs; - +const int MAX_MARKER_LENGTH = 1024; const std::string MARKER_FILE_NAME("SecondLife.exec_marker"); const std::string ERROR_MARKER_FILE_NAME("SecondLife.error_marker"); const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker"); @@ -369,6 +381,9 @@ void init_default_trans_args() default_trans_args.insert("CAPITALIZED_APP_NAME"); default_trans_args.insert("SECOND_LIFE_GRID"); default_trans_args.insert("SUPPORT_SITE"); + // This URL shows up in a surprising number of places in various skin + // files. We really only want to have to maintain a single copy of it. + default_trans_args.insert("create_account_url"); } //---------------------------------------------------------------------------- @@ -445,7 +460,18 @@ static void ui_audio_callback(const LLUUID& uuid) { if (gAudiop) { - gAudiop->triggerSound(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); + SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); + gAudiop->triggerSound(soundData); + } +} + +// A callback set in LLAppViewer::init() +static void deferred_ui_audio_callback(const LLUUID& uuid) +{ + if (gAudiop) + { + SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); + LLDeferredSounds::instance().deferSound(soundData); } } @@ -525,6 +551,7 @@ static void settings_to_globals() LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile"); LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); + LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures"); LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor"); LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f; LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor"); @@ -542,7 +569,7 @@ static void settings_to_globals() gAgentPilot.setNumRuns(gSavedSettings.getS32("StatsNumRuns")); gAgentPilot.setQuitAfterRuns(gSavedSettings.getBOOL("StatsQuitAfterRuns")); gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle")); - + gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc"); gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale"); @@ -557,7 +584,6 @@ static void settings_modify() LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4] gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession; gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline"); - gAuditTexture = gSavedSettings.getBOOL("AuditTexture"); } class LLFastTimerLogThread : public LLThread @@ -612,13 +638,14 @@ LLTextureFetch* LLAppViewer::sTextureFetch = NULL; LLAppViewer::LLAppViewer() : mMarkerFile(), - mLogoutMarkerFile(NULL), + mLogoutMarkerFile(), mReportedCrash(false), mNumSessions(0), mPurgeCache(false), mPurgeOnExit(false), mSecondInstance(false), mSavedFinalSnapshot(false), + mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded. mForceGraphicsDetail(false), mQuitRequested(false), mLogoutRequestSent(false), @@ -669,12 +696,15 @@ bool LLAppViewer::init() // initialize SSE options LLVector4a::initClass(); + //initialize particle index pool + LLVOPartGroup::initClass(); + // Need to do this initialization before we do anything else, since anything // that touches files should really go through the lldir API gDirUtilp->initAppDirs("SecondLife"); // set skin search path to default, will be overridden later // this allows simple skinned file lookups to work - gDirUtilp->setSkinFolder("default"); + gDirUtilp->setSkinFolder("default", "en"); initLogging(); @@ -692,7 +722,7 @@ bool LLAppViewer::init() //set the max heap size. initMaxHeapSize() ; - LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")) ; + LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")*1024*1024) ; // write Google Breakpad minidump files to our log directory std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); @@ -713,25 +743,27 @@ bool LLAppViewer::init() mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling")); -#if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::initClass(); -#endif - + // Initialize the non-LLCurl libcurl library. Should be called + // before consumers (LLTextureFetch). + mAppCoreHttp.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(); { // Viewer metrics initialization - static LLCachedControl<bool> metrics_submode(gSavedSettings, - "QAModeMetrics", - false, - "Enables QA features (logging, faster cycling) for metrics collector"); + //static LLCachedControl<bool> metrics_submode(gSavedSettings, + // "QAModeMetrics", + // false, + // "Enables QA features (logging, faster cycling) for metrics collector"); - if (metrics_submode) + if (gSavedSettings.getBOOL("QAModeMetrics")) { app_metrics_qa_mode = true; app_metrics_interval = METRICS_INTERVAL_QA; @@ -753,15 +785,19 @@ bool LLAppViewer::init() LLUI::initClass(settings_map, LLUIImageList::getInstance(), ui_audio_callback, + deferred_ui_audio_callback, &LLUI::sGLScaleFactor); LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ; - // Setup paths and LLTrans after LLUI::initClass has been called. - LLUI::setupPaths(); - LLTransUtil::parseStrings("strings.xml", default_trans_args); - LLTransUtil::parseLanguageStrings("language_settings.xml"); + // NOW LLUI::getLanguage() should work. gDirUtilp must know the language + // for this session ASAP so all the file-loading commands that follow, + // that use findSkinnedFilenames(), will include the localized files. + gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), LLUI::getLanguage()); + + // Setup LLTrans after LLUI::initClass has been called. + initStrings(); - // Setup notifications after LLUI::setupPaths() has been called. + // Setup notifications after LLUI::initClass() has been called. LLNotifications::instance(); LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ; @@ -781,9 +817,6 @@ bool LLAppViewer::init() ////////////////////////////////////////////////////////////////////////////// // *FIX: The following code isn't grouped into functions yet. - // Statistics / debug timer initialization - init_statistics(); - // // Various introspection concerning the libs we're using - particularly // the libs involved in getting to a full login screen. @@ -1009,6 +1042,24 @@ bool LLAppViewer::init() } } +#if LL_WINDOWS + if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion()) + { + if (gGLManager.mIsIntel) + { + LLNotificationsUtil::add("IntelOldDriver"); + } + else if (gGLManager.mIsNVIDIA) + { + LLNotificationsUtil::add("NVIDIAOldDriver"); + } + else if (gGLManager.mIsATI) + { + LLNotificationsUtil::add("AMDOldDriver"); + } + } +#endif + // save the graphics card gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString(); @@ -1033,11 +1084,38 @@ bool LLAppViewer::init() gGLActive = FALSE; + + // Iterate over --leap command-line options. But this is a bit tricky: if + // there's only one, it won't be an array at all. + LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand")); + LL_DEBUGS("InitInfo") << "LeapCommand: " << LeapCommand << LL_ENDL; + if (LeapCommand.isDefined() && ! LeapCommand.isArray()) + { + // If LeapCommand is actually a scalar value, make an array of it. + // Have to do it in two steps because LeapCommand.append(LeapCommand) + // trashes content! :-P + LLSD item(LeapCommand); + LeapCommand.append(item); + } + BOOST_FOREACH(const std::string& leap, llsd::inArray(LeapCommand)) + { + LL_INFOS("InitInfo") << "processing --leap \"" << leap << '"' << LL_ENDL; + // We don't have any better description of this plugin than the + // user-specified command line. Passing "" causes LLLeap to derive a + // description from the command line itself. + // Suppress LLLeap::Error exception: trust LLLeap's own logging. We + // don't consider any one --leap command mission-critical, so if one + // fails, log it, shrug and carry on. + LLLeap::create("", leap, false); // exception=false + } + if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0) { - loadEventHostModule(gSavedSettings.getS32("QAModeEventHostPort")); + LL_WARNS("InitInfo") << "QAModeEventHostPort DEPRECATED: " + << "lleventhost no longer supported as a dynamic library" + << LL_ENDL; } - + LLViewerMedia::initClass(); LL_INFOS("InitInfo") << "Viewer media initialized." << LL_ENDL ; @@ -1118,6 +1196,8 @@ void LLAppViewer::checkMemory() static LLFastTimer::DeclareTimer FTM_MESSAGES("System Messages"); static LLFastTimer::DeclareTimer FTM_SLEEP("Sleep"); +static LLFastTimer::DeclareTimer FTM_YIELD("Yield"); + static LLFastTimer::DeclareTimer FTM_TEXTURE_CACHE("Texture Cache"); static LLFastTimer::DeclareTimer FTM_DECODE("Image Decode"); static LLFastTimer::DeclareTimer FTM_VFS("VFS Thread"); @@ -1131,9 +1211,10 @@ static LLFastTimer::DeclareTimer FTM_SERVICE_CALLBACK("Callback"); static LLFastTimer::DeclareTimer FTM_AGENT_AUTOPILOT("Autopilot"); static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE("Update"); +LLFastTimer::DeclareTimer FTM_FRAME("Frame", true); + bool LLAppViewer::mainLoop() { - LLMemType mt1(LLMemType::MTYPE_MAIN); mMainloopTimeout = new LLWatchdogTimeout(); //------------------------------------------- @@ -1149,7 +1230,7 @@ bool LLAppViewer::mainLoop() LLVoiceChannel::initClass(); LLVoiceClient::getInstance()->init(gServicePump); - LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLCallFloater::sOnCurrentChannelChanged, _1), true); + LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); LLTimer frameTimer,idleTimer; LLTimer debugTime; LLViewerJoystick* joystick(LLViewerJoystick::getInstance()); @@ -1169,7 +1250,8 @@ bool LLAppViewer::mainLoop() // Handle messages while (!LLApp::isExiting()) { - LLFastTimer::nextFrame(); // Should be outside of any timer instances + LLFastTimer _(FTM_FRAME); + LLFastTimer::nextFrame(); //clear call stack records llclearcallstacks; @@ -1214,7 +1296,7 @@ bool LLAppViewer::mainLoop() if(mem_leak_instance) { mem_leak_instance->idle() ; - } + } // canonical per-frame event mainloop.post(newFrame); @@ -1233,7 +1315,6 @@ bool LLAppViewer::mainLoop() && (gHeadlessClient || !gViewerWindow->getShowProgress()) && !gFocusMgr.focusLocked()) { - LLMemType mjk(LLMemType::MTYPE_JOY_KEY); joystick->scanJoystick(); gKeyboard->scanKeyboard(); } @@ -1247,7 +1328,6 @@ bool LLAppViewer::mainLoop() if (gAres != NULL && gAres->isInitialized()) { - LLMemType mt_ip(LLMemType::MTYPE_IDLE_PUMP); pingMainloopTimeout("Main:ServicePump"); LLFastTimer t4(FTM_PUMP); { @@ -1297,12 +1377,12 @@ bool LLAppViewer::mainLoop() // Sleep and run background threads { - LLMemType mt_sleep(LLMemType::MTYPE_SLEEP); LLFastTimer t2(FTM_SLEEP); // yield some time to the os based on command line option if(mYieldTime >= 0) { + LLFastTimer t(FTM_YIELD); ms_sleep(mYieldTime); } @@ -1335,27 +1415,27 @@ bool LLAppViewer::mainLoop() ms_sleep(500); } - static const F64 FRAME_SLOW_THRESHOLD = 0.5; //2 frames per seconds const F64 max_idle_time = llmin(.005*10.0*gFrameTimeSeconds, 0.005); // 5 ms a second idleTimer.reset(); - bool is_slow = (frameTimer.getElapsedTimeF64() > FRAME_SLOW_THRESHOLD) ; S32 total_work_pending = 0; S32 total_io_pending = 0; - while(!is_slow)//do not unpause threads if the frame rates are very low. + while(1) { 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 } { @@ -1381,6 +1461,11 @@ bool LLAppViewer::mainLoop() } } gMeshRepo.update() ; + + if(!LLCurl::getCurlThread()->update(1)) + { + LLCurl::getCurlThread()->pause() ; //nothing in the curl thread. + } if(!total_work_pending) //pause texture fetching threads if nothing to process. { @@ -1394,6 +1479,17 @@ bool LLAppViewer::mainLoop() LLLFSThread::sLocal->pause(); } + //texture fetching debugger + if(LLTextureFetchDebugger::isEnabled()) + { + LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = + LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger"); + if(tex_fetch_debugger_instance) + { + tex_fetch_debugger_instance->idle() ; + } + } + if ((LLStartUp::getStartupState() >= STATE_CLEANUP) && (frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD)) { @@ -1475,6 +1571,9 @@ void LLAppViewer::flushVFSIO() bool LLAppViewer::cleanup() { + //ditch LLVOAvatarSelf instance + gAgentAvatarp = NULL; + // workaround for DEV-35406 crash on shutdown LLEventPumps::instance().reset(); @@ -1496,21 +1595,27 @@ bool LLAppViewer::cleanup() if (! isError()) { std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); - logdir += gDirUtilp->getDirDelimiter(); gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp"); } - // *TODO - generalize this and move DSO wrangling to a helper class -brad - std::set<struct apr_dso_handle_t *>::const_iterator i; - for(i = mPlugins.begin(); i != mPlugins.end(); ++i) { - int (*ll_plugin_stop_func)(void) = NULL; - apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, *i, "ll_plugin_stop"); - ll_plugin_stop_func(); - - rv = apr_dso_unload(*i); - } - mPlugins.clear(); + // Kill off LLLeap objects. We can find them all because LLLeap is derived + // from LLInstanceTracker. But collect instances first: LLInstanceTracker + // specifically forbids adding/deleting instances while iterating. + std::vector<LLLeap*> leaps; + leaps.reserve(LLLeap::instanceCount()); + for (LLLeap::instance_iter li(LLLeap::beginInstances()), lend(LLLeap::endInstances()); + li != lend; ++li) + { + leaps.push_back(&*li); + } + // Okay, now trash them all. We don't have to NULL or erase the entry + // in 'leaps' because the whole vector is going away momentarily. + BOOST_FOREACH(LLLeap* leap, leaps) + { + delete leap; + } + } // destroy 'leaps' //flag all elements as needing to be destroyed immediately // to ensure shutdown order @@ -1533,6 +1638,9 @@ bool LLAppViewer::cleanup() // shut down mesh streamer gMeshRepo.shutdown(); + // shut down Havok + LLPhysicsExtensions::quitSystem(); + // Must clean up texture references before viewer window is destroyed. if(LLHUDManager::instanceExists()) { @@ -1727,6 +1835,13 @@ bool LLAppViewer::cleanup() { llinfos << "Not saving per-account settings; don't know the account name yet." << llendl; } + // Only save per account settings if the previous login succeeded, otherwise + // we might end up with a cleared out settings file in case a previous login + // failed after loading per account settings. + else if (!mSavePerAccountSettings) + { + llinfos << "Not saving per-account settings; last login was not successful." << llendl; + } else { gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE); @@ -1742,11 +1857,13 @@ bool LLAppViewer::cleanup() // save mute list. gMuteList used to also be deleted here too. LLMuteList::getInstance()->cache(gAgent.getID()); + //save call log list + LLConversationLog::instance().cache(); + if (mPurgeOnExit) { llinfos << "Purging all cache files on exit" << llendflush; - std::string mask = gDirUtilp->getDirDelimiter() + "*.*"; - gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask); + gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*"); } removeMarkerFile(); // Any crashes from here on we'll just have to ignore @@ -1776,6 +1893,7 @@ bool LLAppViewer::cleanup() pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread pending += LLVFSThread::updateClass(0); pending += LLLFSThread::updateClass(0); + pending += LLCurl::getCurlThread()->update(1) ; F64 idle_time = idleTimer.getElapsedTimeF64(); if(!pending) { @@ -1787,9 +1905,11 @@ bool LLAppViewer::cleanup() break; } } + LLCurl::getCurlThread()->pause() ; // Delete workers first // shotdown all worker threads before deleting them in case of co-dependencies + mAppCoreHttp.requestStop(); sTextureFetch->shutdown(); sTextureCache->shutdown(); sImageDecodeThread->shutdown(); @@ -1797,8 +1917,20 @@ bool LLAppViewer::cleanup() sTextureFetch->shutDownTextureCacheThread() ; sTextureFetch->shutDownImageDecodeThread() ; + llinfos << "Shutting down message system" << llendflush; + end_messaging_system(); + + // *NOTE:Mani - The following call is not thread safe. + LL_CHECK_MEMORY + LLCurl::cleanupClass(); + LL_CHECK_MEMORY + + // Non-LLCurl libcurl library + mAppCoreHttp.cleanup(); + LLFilePickerThread::cleanupClass(); + //MUST happen AFTER LLCurl::cleanupClass delete sTextureCache; sTextureCache = NULL; delete sTextureFetch; @@ -1824,10 +1956,6 @@ bool LLAppViewer::cleanup() LLMetricPerformanceTesterBasic::cleanClass() ; -#if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::cleanupClass(); -#endif - llinfos << "Cleaning up Media and Textures" << llendflush; //Note: @@ -1867,12 +1995,6 @@ bool LLAppViewer::cleanup() LLViewerAssetStatsFF::cleanup(); - llinfos << "Shutting down message system" << llendflush; - end_messaging_system(); - - // *NOTE:Mani - The following call is not thread safe. - LLCurl::cleanupClass(); - // If we're exiting to launch an URL, do that here so the screen // is at the right resolution before we launch IE. if (!gLaunchFileOnQuit.empty()) @@ -1934,7 +2056,7 @@ bool LLAppViewer::initThreads() static const bool enable_threads = true; #endif - LLImage::initClass(); + LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange")); LLVFSThread::initClass(enable_threads && false); LLLFSThread::initClass(enable_threads && false); @@ -2155,10 +2277,8 @@ bool LLAppViewer::initConfiguration() OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK); return false; } - - LLUI::setupPaths(); // setup paths for LLTrans based on settings files only - LLTransUtil::parseStrings("strings.xml", default_trans_args); - LLTransUtil::parseLanguageStrings("language_settings.xml"); + + initStrings(); // setup paths for LLTrans based on settings files only // - set procedural settings // Note: can't use LL_PATH_PER_SL_ACCOUNT for any of these since we haven't logged in yet gSavedSettings.setString("ClientSettingsFile", @@ -2472,13 +2592,28 @@ bool LLAppViewer::initConfiguration() LLStartUp::setStartSLURL(start_slurl); } - const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent"); - if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) - { - // hack to force the skin to default. - gDirUtilp->setSkinFolder(skinfolder->getValue().asString()); - //gDirUtilp->setSkinFolder("default"); - } + const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent"); + if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) + { + // Examining "Language" may not suffice -- see LLUI::getLanguage() + // logic. Unfortunately LLUI::getLanguage() doesn't yet do us much + // good because we haven't yet called LLUI::initClass(). + gDirUtilp->setSkinFolder(skinfolder->getValue().asString(), + gSavedSettings.getString("Language")); + } + + if (gSavedSettings.getBOOL("SpellCheck")) + { + std::list<std::string> dict_list; + std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary"); + boost::split(dict_list, dict_setting, boost::is_any_of(std::string(","))); + if (!dict_list.empty()) + { + LLSpellChecker::setUseSpellCheck(dict_list.front()); + dict_list.pop_front(); + LLSpellChecker::instance().setSecondaryDictionaries(dict_list); + } + } mYieldTime = gSavedSettings.getS32("YieldTime"); @@ -2561,14 +2696,6 @@ bool LLAppViewer::initConfiguration() } } - // If automatic login from command line with --login switch - // init StartSLURL location. In interactive login, LLPanelLogin - // will take care of it. - if ((clp.hasOption("login") || clp.hasOption("autologin")) && !clp.hasOption("url") && !clp.hasOption("slurl")) - { - LLStartUp::setStartSLURL(LLSLURL(gSavedSettings.getString("LoginLocation"))); - } - if (!gSavedSettings.getBOOL("AllowMultipleViewers")) { // @@ -2616,12 +2743,27 @@ bool LLAppViewer::initConfiguration() } } - // need to do this here - need to have initialized global settings first + // NextLoginLocation is set from the command line option std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" ); if ( !nextLoginLocation.empty() ) { + LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL; LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation)); - }; + } + else if ( ( clp.hasOption("login") || clp.hasOption("autologin")) + && !clp.hasOption("url") + && !clp.hasOption("slurl")) + { + // If automatic login from command line with --login switch + // init StartSLURL location. + std::string start_slurl_setting = gSavedSettings.getString("LoginLocation"); + LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL; + LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting)); + } + else + { + // the login location will be set by the login panel (see LLPanelLogin) + } gLastRunVersion = gSavedSettings.getString("LastRunVersion"); @@ -2630,6 +2772,52 @@ bool LLAppViewer::initConfiguration() return true; // Config was successful. } +// The following logic is replicated in initConfiguration() (to be able to get +// some initial strings before we've finished initializing enough to know the +// current language) and also in init() (to initialize for real). Somehow it +// keeps growing, necessitating a method all its own. +void LLAppViewer::initStrings() +{ + LLTransUtil::parseStrings("strings.xml", default_trans_args); + LLTransUtil::parseLanguageStrings("language_settings.xml"); + + // parseStrings() sets up the LLTrans substitution table. Add this one item. + LLTrans::setDefaultArg("[sourceid]", gSavedSettings.getString("sourceid")); + + // Now that we've set "[sourceid]", have to go back through + // default_trans_args and reinitialize all those other keys because some + // of them, in turn, reference "[sourceid]". + BOOST_FOREACH(std::string key, default_trans_args) + { + std::string brackets(key), nobrackets(key); + // Invalid to inspect key[0] if key is empty(). But then, the entire + // body of this loop is pointless if key is empty(). + if (key.empty()) + continue; + + if (key[0] != '[') + { + // key was passed without brackets. That means that 'nobrackets' + // is correct but 'brackets' is not. + brackets = STRINGIZE('[' << brackets << ']'); + } + else + { + // key was passed with brackets. That means that 'brackets' is + // correct but 'nobrackets' is not. Erase the left bracket. + nobrackets.erase(0, 1); + std::string::size_type length(nobrackets.length()); + if (length && nobrackets[length - 1] == ']') + { + nobrackets.erase(length - 1); + } + } + // Calling LLTrans::getString() is what embeds the other default + // translation strings into this one. + LLTrans::setDefaultArg(brackets, LLTrans::getString(nobrackets)); + } +} + namespace { // *TODO - decide if there's a better place for these functions. // do we need a file llupdaterui.cpp or something? -brad @@ -2824,11 +3012,21 @@ bool LLAppViewer::initWindow() // always start windowed BOOL ignorePixelDepth = gSavedSettings.getBOOL("IgnorePixelDepth"); - gViewerWindow = new LLViewerWindow(gWindowTitle, - VIEWER_WINDOW_CLASSNAME, - gSavedSettings.getS32("WindowX"), gSavedSettings.getS32("WindowY"), - gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"), - gSavedSettings.getBOOL("FullScreen"), ignorePixelDepth); + + LLViewerWindow::Params window_params; + window_params + .title(gWindowTitle) + .name(VIEWER_WINDOW_CLASSNAME) + .x(gSavedSettings.getS32("WindowX")) + .y(gSavedSettings.getS32("WindowY")) + .width(gSavedSettings.getU32("WindowWidth")) + .height(gSavedSettings.getU32("WindowHeight")) + .min_width(gSavedSettings.getU32("MinWindowWidth")) + .min_height(gSavedSettings.getU32("MinWindowHeight")) + .fullscreen(gSavedSettings.getBOOL("FullScreen")) + .ignore_pixel_depth(ignorePixelDepth); + + gViewerWindow = new LLViewerWindow(window_params); LL_INFOS("AppInit") << "gViewerwindow created." << LL_ENDL; @@ -2968,8 +3166,7 @@ void LLAppViewer::cleanupSavedSettings() void LLAppViewer::removeCacheFiles(const std::string& file_mask) { - std::string mask = gDirUtilp->getDirDelimiter() + file_mask; - gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), mask); + gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), file_mask); } void LLAppViewer::writeSystemInfo() @@ -2996,8 +3193,8 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["OSInfo"] = getOSInfo().getOSStringSimple(); // The user is not logged on yet, but record the current grid choice login url - // which may have been the intended grid. This can b - gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridLabel(); + // which may have been the intended grid. + gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridId(); // *FIX:Mani - move this down in llappviewerwin32 #ifdef LL_WINDOWS @@ -3022,8 +3219,8 @@ void LLAppViewer::writeSystemInfo() } // Dump some debugging info - LL_INFOS("SystemInfo") << LLTrans::getString("APP_NAME") - << " version " << LLVersionInfo::getShortVersion() << LL_ENDL; + LL_INFOS("SystemInfo") << "Application: " << LLTrans::getString("APP_NAME") << LL_ENDL; + LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::getChannelAndVersion() << LL_ENDL; // Dump the local time and time zone time_t now; @@ -3038,8 +3235,6 @@ void LLAppViewer::writeSystemInfo() LL_INFOS("SystemInfo") << "OS: " << getOSInfo().getOSStringSimple() << LL_ENDL; LL_INFOS("SystemInfo") << "OS info: " << getOSInfo() << LL_ENDL; - LL_INFOS("SystemInfo") << "Timers: " << LLFastTimer::sClockType << LL_ENDL; - writeDebugInfo(); // Save out debug_info.log early, in case of crash. } @@ -3151,22 +3346,27 @@ void LLAppViewer::handleViewerCrash() //we're already in a crash situation if (gDirUtilp) { - std::string crash_file_name; - if(gLLErrorActivated) crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LLERROR_MARKER_FILE_NAME); - else crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME); - llinfos << "Creating crash marker file " << crash_file_name << llendl; + std::string crash_file_name = ( gLLErrorActivated ) + ? gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LLERROR_MARKER_FILE_NAME) + : gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME); + LL_INFOS("MarkerFile") << "Creating crash marker file " << crash_file_name << LL_ENDL; LLAPRFile crash_file ; crash_file.open(crash_file_name, LL_APR_W); if (crash_file.getFileHandle()) { LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL; + recordMarkerVersion(crash_file); } else { LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_file_name << LL_ENDL; } } + else + { + LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL; + } if (gMessageSystem && gDirUtilp) { @@ -3218,7 +3418,7 @@ bool LLAppViewer::anotherInstanceRunning() // If the file is currently locked, that means another process is already running. std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, MARKER_FILE_NAME); - LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL; + LL_DEBUGS("MarkerFile") << "Checking marker file '"<< marker_file << "' for lock..." << LL_ENDL; //Freeze case checks if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB)) @@ -3244,6 +3444,46 @@ bool LLAppViewer::anotherInstanceRunning() return false; } +// static +void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file) +{ + std::string marker_version(LLVersionInfo::getChannelAndVersion()); + if ( marker_version.length() > MAX_MARKER_LENGTH ) + { + LL_WARNS_ONCE("MarkerFile") << "Version length ("<< marker_version.length()<< ") greater than maximum: marker matching may be incorrect" << LL_ENDL; + } + + // record the viewer version in the marker file + marker_file.write(marker_version.data(), marker_version.length()); +} + +bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const +{ + bool sameVersion = false; + + std::string my_version(LLVersionInfo::getChannelAndVersion()); + char marker_version[MAX_MARKER_LENGTH]; + S32 marker_version_length; + + LLAPRFile marker_file; + marker_file.open(marker_name, LL_APR_RB); + if (marker_file.getFileHandle()) + { + marker_version_length = marker_file.read(marker_version, sizeof(marker_version)); + LL_DEBUGS("MarkerFile") << "Compare markers: "; + std::string marker_string(marker_version, marker_version_length); + LL_CONT << "\n mine '" << my_version << "'" + << "\n marker '" << marker_string << "'" + << LL_ENDL; + if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) ) + { + sameVersion = true; + } + marker_file.close(); + } + return sameVersion; +} + void LLAppViewer::initMarkerFile() { //First, check for the existence of other files. @@ -3266,27 +3506,55 @@ void LLAppViewer::initMarkerFile() if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning()) { - gLastExecEvent = LAST_EXEC_FROZE; - LL_INFOS("MarkerFile") << "Exec marker found: program froze on previous execution" << LL_ENDL; + if ( markerIsSameVersion(mMarkerFileName) ) + { + LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found" << LL_ENDL; + gLastExecEvent = LAST_EXEC_FROZE; + } + else + { + LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL; + } } if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB)) { - gLastExecEvent = LAST_EXEC_LOGOUT_FROZE; - LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; + if (markerIsSameVersion(logout_marker_file)) + { + gLastExecEvent = LAST_EXEC_LOGOUT_FROZE; + LL_INFOS("MarkerFile") << "Logout crashed '"<< logout_marker_file << "', setting LastExecEvent to " << gLastExecEvent << LL_ENDL; + } + else + { + LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "' found, but versions did not match" << LL_ENDL; + } LLAPRFile::remove(logout_marker_file); } if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB)) { - if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; - else gLastExecEvent = LAST_EXEC_LLERROR_CRASH; - LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; + if (markerIsSameVersion(llerror_marker_file)) + { + gLastExecEvent = ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE ) + ? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_LLERROR_CRASH; + LL_INFOS("MarkerFile") << "Last exec LLError '"<< llerror_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; + } + else + { + LL_INFOS("MarkerFile") << "Last exec LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL; + } LLAPRFile::remove(llerror_marker_file); } if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB)) { - if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; - else gLastExecEvent = LAST_EXEC_OTHER_CRASH; - LL_INFOS("MarkerFile") << "Last exec crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; + if (markerIsSameVersion(error_marker_file)) + { + gLastExecEvent = (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) + ? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_OTHER_CRASH; + LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; + } + else + { + LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL; + } LLAPRFile::remove(error_marker_file); } @@ -3302,35 +3570,48 @@ void LLAppViewer::initMarkerFile() if (s == APR_SUCCESS && mMarkerFile.getFileHandle()) { - LL_DEBUGS("MarkerFile") << "Marker file created." << LL_ENDL; + LL_DEBUGS("MarkerFile") << "Marker file '"<< mMarkerFileName << "' created." << LL_ENDL; + if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE)) + { + recordMarkerVersion(mMarkerFile); + LL_DEBUGS("MarkerFile") << "Marker file locked." << LL_ENDL; + } + else + { + LL_INFOS("MarkerFile") << "Marker file cannot be locked." << LL_ENDL; + } } else { - LL_INFOS("MarkerFile") << "Failed to create marker file." << LL_ENDL; - return; - } - if (apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) - { - mMarkerFile.close() ; - LL_INFOS("MarkerFile") << "Marker file cannot be locked." << LL_ENDL; - return; + LL_INFOS("MarkerFile") << "Failed to create marker file '"<< mMarkerFileName << "'." << LL_ENDL; } - - LL_DEBUGS("MarkerFile") << "Marker file locked." << LL_ENDL; } void LLAppViewer::removeMarkerFile(bool leave_logout_marker) { - LL_DEBUGS("MarkerFile") << "removeMarkerFile()" << LL_ENDL; + LL_DEBUGS("MarkerFile") << "removeMarkerFile("<<leave_logout_marker<<")" << LL_ENDL; if (mMarkerFile.getFileHandle()) { - mMarkerFile.close() ; + LL_DEBUGS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"'"<< LL_ENDL; + mMarkerFile.close(); LLAPRFile::remove( mMarkerFileName ); } - if (mLogoutMarkerFile != NULL && !leave_logout_marker) + else { + LL_WARNS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL; + } + if (!leave_logout_marker) + { + if (mLogoutMarkerFile.getFileHandle()) + { + LL_DEBUGS("MarkerFile") << "removeMarkerFile marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL; + mLogoutMarkerFile.close(); + } + else + { + LL_WARNS("MarkerFile") << "removeMarkerFile marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL; + } LLAPRFile::remove( mLogoutMarkerFileName ); - mLogoutMarkerFile = NULL; } } @@ -3473,8 +3754,7 @@ void LLAppViewer::migrateCacheDirectory() { gSavedSettings.setBOOL("MigrateCacheDirectory", FALSE); - std::string delimiter = gDirUtilp->getDirDelimiter(); - std::string old_cache_dir = gDirUtilp->getOSUserAppDir() + delimiter + "cache"; + std::string old_cache_dir = gDirUtilp->add(gDirUtilp->getOSUserAppDir(), "cache"); std::string new_cache_dir = gDirUtilp->getCacheDir(true); if (gDirUtilp->fileExists(old_cache_dir)) @@ -3490,8 +3770,8 @@ void LLAppViewer::migrateCacheDirectory() while (iter.next(file_name)) { if (file_name == "." || file_name == "..") continue; - std::string source_path = old_cache_dir + delimiter + file_name; - std::string dest_path = new_cache_dir + delimiter + file_name; + std::string source_path = gDirUtilp->add(old_cache_dir, file_name); + std::string dest_path = gDirUtilp->add(new_cache_dir, file_name); if (!LLFile::rename(source_path, dest_path)) { file_count++; @@ -3722,7 +4002,7 @@ bool LLAppViewer::initCache() LLDirIterator iter(dir, mask); if (iter.next(found_file)) { - old_vfs_data_file = dir + gDirUtilp->getDirDelimiter() + found_file; + old_vfs_data_file = gDirUtilp->add(dir, found_file); S32 start_pos = found_file.find_last_of('.'); if (start_pos > 0) @@ -3828,8 +4108,7 @@ void LLAppViewer::purgeCache() LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL; LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE); LLVOCache::getInstance()->removeCache(LL_PATH_CACHE); - std::string mask = "*.*"; - gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), mask); + gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*.*"); } std::string LLAppViewer::getSecondLifeTitle() const @@ -4025,7 +4304,6 @@ static LLFastTimer::DeclareTimer FTM_VLMANAGER("VL Manager"); /////////////////////////////////////////////////////// void LLAppViewer::idle() { - LLMemType mt_idle(LLMemType::MTYPE_IDLE); pingMainloopTimeout("Main:Idle"); // Update frame timers @@ -4034,6 +4312,7 @@ void LLAppViewer::idle() LLFrameTimer::updateFrameTime(); LLFrameTimer::updateFrameCount(); LLEventTimer::updateClass(); + LLNotificationsUI::LLToast::updateClass(); LLCriticalDamp::updateInterpolants(); LLMortician::updateClass(); LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify() @@ -4137,7 +4416,6 @@ void LLAppViewer::idle() // of SEND_STATS_PERIOD so that the initial stats report will // be sent immediately. static LLFrameStatsTimer viewer_stats_timer(SEND_STATS_PERIOD); - reset_statistics(); // Update session stats every large chunk of time // *FIX: (???) SAMANTHA @@ -4173,6 +4451,7 @@ void LLAppViewer::idle() // The 5-second interval is nice for this purpose. If the object debug // bit moves or is disabled, please give this a suitable home. LLViewerAssetStatsFF::record_fps_main(gFPSClamped); + LLViewerAssetStatsFF::record_avatar_stats(); } } @@ -4196,7 +4475,7 @@ void LLAppViewer::idle() idle_afk_check(); // Update statistics for this frame - update_statistics(gFrameCount); + update_statistics(); } //////////////////////////////////////// @@ -4220,7 +4499,8 @@ void LLAppViewer::idle() static LLTimer report_interval; // *TODO: Add configuration controls for this - if (report_interval.getElapsedTimeF32() >= app_metrics_interval) + F32 seconds = report_interval.getElapsedTimeF32(); + if (seconds >= app_metrics_interval) { metricsSend(! gDisconnected); report_interval.reset(); @@ -4231,6 +4511,10 @@ void LLAppViewer::idle() { return; } + if (gTeleportDisplay) + { + return; + } gViewerWindow->updateUI(); @@ -4383,6 +4667,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 { @@ -4525,16 +4813,15 @@ void LLAppViewer::sendLogoutRequest() mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME); LLAPRFile outfile ; - outfile.open(mLogoutMarkerFileName, LL_APR_W); - mLogoutMarkerFile = outfile.getFileHandle() ; - if (mLogoutMarkerFile) + mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_W); + if (mLogoutMarkerFile.getFileHandle()) { - llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl; - apr_file_close(mLogoutMarkerFile); + LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << mLogoutMarkerFileName << LL_ENDL; + recordMarkerVersion(outfile); } else { - llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl; + LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL; } } } @@ -4613,7 +4900,6 @@ static LLFastTimer::DeclareTimer FTM_CHECK_REGION_CIRCUIT("Check Region Circuit" void LLAppViewer::idleNetwork() { - LLMemType mt_in(LLMemType::MTYPE_IDLE_NETWORK); pingMainloopTimeout("idleNetwork"); gObjectList.mNumNewObjects = 0; @@ -4924,87 +5210,10 @@ void LLAppViewer::handleLoginComplete() mOnLoginCompleted(); writeDebugInfo(); -} - -// *TODO - generalize this and move DSO wrangling to a helper class -brad -void LLAppViewer::loadEventHostModule(S32 listen_port) -{ - std::string dso_name = -#if LL_WINDOWS - "lleventhost.dll"; -#elif LL_DARWIN - "liblleventhost.dylib"; -#else - "liblleventhost.so"; -#endif - - std::string dso_path = gDirUtilp->findFile(dso_name, - gDirUtilp->getAppRODataDir(), - gDirUtilp->getExecutableDir()); - - if(dso_path == "") - { - llerrs << "QAModeEventHost requested but module \"" << dso_name << "\" not found!" << llendl; - return; - } - - LL_INFOS("eventhost") << "Found lleventhost at '" << dso_path << "'" << LL_ENDL; -#if ! defined(LL_WINDOWS) - { - std::string outfile("/tmp/lleventhost.file.out"); - std::string command("file '" + dso_path + "' > '" + outfile + "' 2>&1"); - int rc = system(command.c_str()); - if (rc != 0) - { - LL_WARNS("eventhost") << command << " ==> " << rc << ':' << LL_ENDL; - } - else - { - LL_INFOS("eventhost") << command << ':' << LL_ENDL; - } - { - std::ifstream reader(outfile.c_str()); - std::string line; - while (std::getline(reader, line)) - { - size_t len = line.length(); - if (len && line[len-1] == '\n') - line.erase(len-1); - LL_INFOS("eventhost") << line << LL_ENDL; - } - } - remove(outfile.c_str()); - } -#endif // LL_WINDOWS - - apr_dso_handle_t * eventhost_dso_handle = NULL; - apr_pool_t * eventhost_dso_memory_pool = NULL; - - //attempt to load the shared library - apr_pool_create(&eventhost_dso_memory_pool, NULL); - apr_status_t rv = apr_dso_load(&eventhost_dso_handle, - dso_path.c_str(), - eventhost_dso_memory_pool); - llassert_always(! ll_apr_warn_status(rv, eventhost_dso_handle)); - llassert_always(eventhost_dso_handle != NULL); - - int (*ll_plugin_start_func)(LLSD const &) = NULL; - rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_start_func, eventhost_dso_handle, "ll_plugin_start"); - - llassert_always(! ll_apr_warn_status(rv, eventhost_dso_handle)); - llassert_always(ll_plugin_start_func != NULL); - - LLSD args; - args["listen_port"] = listen_port; - - int status = ll_plugin_start_func(args); - - if(status != 0) - { - llerrs << "problem loading eventhost plugin, status: " << status << llendl; - } - mPlugins.insert(eventhost_dso_handle); + // we logged in successfully, so save settings on logout + llinfos << "Login successful, per account settings will be saved on log out." << llendl; + mSavePerAccountSettings=true; } void LLAppViewer::launchUpdater() @@ -5022,7 +5231,7 @@ void LLAppViewer::launchUpdater() #endif // *TODO change userserver to be grid on both viewer and sim, since // userserver no longer exists. - query_map["userserver"] = LLGridManager::getInstance()->getGridLabel(); + query_map["userserver"] = LLGridManager::getInstance()->getGridId(); query_map["channel"] = LLVersionInfo::getChannel(); // *TODO constantize this guy // *NOTE: This URL is also used in win_setup/lldownloader.cpp @@ -5104,20 +5313,20 @@ void LLAppViewer::launchUpdater() // we tell the updater where to find the xml containing string // translations which it can use for its own UI std::string xml_strings_file = "strings.xml"; - std::vector<std::string> xui_path_vec = LLUI::getXUIPaths(); + std::vector<std::string> xui_path_vec = + gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_strings_file); std::string xml_search_paths; - std::vector<std::string>::const_iterator iter; + const char* delim = ""; // build comma-delimited list of xml paths to pass to updater - for (iter = xui_path_vec.begin(); iter != xui_path_vec.end(); ) - { - std::string this_skin_dir = gDirUtilp->getDefaultSkinDir() - + gDirUtilp->getDirDelimiter() - + (*iter); - llinfos << "Got a XUI path: " << this_skin_dir << llendl; - xml_search_paths.append(this_skin_dir); - ++iter; - if (iter != xui_path_vec.end()) - xml_search_paths.append(","); // comma-delimit + BOOST_FOREACH(std::string this_skin_path, xui_path_vec) + { + // Although we already have the full set of paths with the filename + // appended, the linux-updater.bin command-line switches require us to + // snip the filename OFF and pass it as a separate switch argument. :-P + llinfos << "Got a XUI path: " << this_skin_path << llendl; + xml_search_paths.append(delim); + xml_search_paths.append(gDirUtilp->getDirName(this_skin_path)); + delim = ","; } // build the overall command-line to run the updater correctly LLAppViewer::sUpdaterInfo->mUpdateExePath = diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 71a7868191..0cc02b14e6 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -31,6 +31,7 @@ #include "llcontrol.h" #include "llsys.h" // for LLOSInfo #include "lltimer.h" +#include "llappcorehttp.h" class LLCommandLineParser; class LLFrameTimer; @@ -41,7 +42,8 @@ class LLTextureFetch; class LLWatchdogTimeout; class LLUpdaterService; -struct apr_dso_handle_t; +extern LLFastTimer::DeclareTimer FTM_FRAME; + class LLAppViewer : public LLApp { @@ -175,6 +177,9 @@ public: // Metrics policy helper statics. static void metricsUpdateRegion(U64 region_handle); static void metricsSend(bool enable_reporting); + + // llcorehttp init/shutdown/config information. + LLAppCoreHttp & getAppCoreHttp() { return mAppCoreHttp; } protected: virtual bool initWindow(); // Initialize the viewer's window. @@ -196,6 +201,7 @@ private: void initMaxHeapSize(); bool initThreads(); // Initialize viewer threads, return false on failure. bool initConfiguration(); // Initialize settings from the command line/config file. + void initStrings(); // Initialize LLTrans machinery void initUpdater(); // Initialize the updater service. bool initCache(); // Initialize local client cache. void checkMemory() ; @@ -211,7 +217,9 @@ private: bool anotherInstanceRunning(); void initMarkerFile(); - + static void recordMarkerVersion(LLAPRFile& marker_file); + bool markerIsSameVersion(const std::string& marker_name) const; + void idle(); void idleShutdown(); // update avatar SLID and display name caches @@ -220,8 +228,6 @@ private: void sendLogoutRequest(); void disconnectViewer(); - - void loadEventHostModule(S32 listen_port); // *FIX: the app viewer class should be some sort of singleton, no? // Perhaps its child class is the singleton and this should be an abstract base. @@ -233,7 +239,7 @@ private: LLAPRFile mMarkerFile; // A file created to indicate the app is running. std::string mLogoutMarkerFileName; - apr_file_t* mLogoutMarkerFile; // A file created to indicate the app is running. + LLAPRFile mLogoutMarkerFile; // A file created to indicate the app is running. LLOSInfo mSysOSInfo; @@ -251,6 +257,7 @@ private: bool mPurgeOnExit; bool mSavedFinalSnapshot; + bool mSavePerAccountSettings; // only save per account settings if login succeeded bool mForceGraphicsDetail; @@ -270,12 +277,13 @@ private: LLAllocator mAlloc; - std::set<struct apr_dso_handle_t*> mPlugins; - LLFrameTimer mMemCheckTimer; boost::scoped_ptr<LLUpdaterService> mUpdater; + // llcorehttp library init/shutdown helper + LLAppCoreHttp mAppCoreHttp; + //--------------------------------------------- //*NOTE: Mani - legacy updater stuff // Still useable? diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 48d02dfeaa..8695652168 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -31,7 +31,6 @@ #include "llcommandlineparser.h" #include "lldiriterator.h" -#include "llmemtype.h" #include "llurldispatcher.h" // SLURL from other app instance #include "llviewernetwork.h" #include "llviewercontrol.h" @@ -71,8 +70,6 @@ static void exceptionTerminateHandler() int main( int argc, char **argv ) { - LLMemType mt1(LLMemType::MTYPE_STARTUP); - #if LL_SOLARIS && defined(__sparc) asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC #endif @@ -365,7 +362,7 @@ void LLAppViewerLinux::handleCrashReporting(bool reportFreeze) const char * cmdargv[] = {cmd.c_str(), "-user", - (char*)LLGridManager::getInstance()->getGridLabel().c_str(), + (char*)LLGridManager::getInstance()->getGridId().c_str(), "-name", LLAppViewer::instance()->getSecondLifeTitle().c_str(), NULL}; diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index c2916717bd..4d340cafa9 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -33,8 +33,6 @@ #include "llappviewermacosx.h" #include "llcommandlineparser.h" -#include "llmemtype.h" - #include "llviewernetwork.h" #include "llviewercontrol.h" #include "llmd5.h" @@ -67,8 +65,6 @@ namespace int main( int argc, char **argv ) { - LLMemType mt1(LLMemType::MTYPE_STARTUP); - #if LL_SOLARIS && defined(__sparc) asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC #endif diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 647ace7ee3..8326be433e 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -26,11 +26,15 @@ #include "llviewerprecompiledheaders.h" +#ifdef INCLUDE_VLD +#include "vld.h" +#endif + #include "llappviewerwin32.h" -#include "llmemtype.h" -#include "llwindowwin32.cpp" // *FIX: for setting gIconResource. +#include "llwindowwin32.h" // *FIX: for setting gIconResource. +#include "llgl.h" #include "res/resource.h" // *FIX: for setting gIconResource. #include <fcntl.h> //_O_APPEND @@ -42,6 +46,11 @@ #include "llviewercontrol.h" #include "lldxhardware.h" +#include "nvapi/nvapi.h" +#include "nvapi/NvApiDriverSettings.h" + +#include <stdlib.h> + #include "llweb.h" #include "llsecondlifeurls.h" @@ -56,6 +65,7 @@ #include "llwindebug.h" #endif + // *FIX:Mani - This hack is to fix a linker issue with libndofdev.lib // The lib was compiled under VS2005 - in VS2003 we need to remap assert #ifdef LL_DEBUG @@ -71,6 +81,20 @@ extern "C" { const std::string LLAppViewerWin32::sWindowClass = "Second Life"; +/* + This function is used to print to the command line a text message + describing the nvapi error and quits +*/ +void nvapi_error(NvAPI_Status status) +{ + NvAPI_ShortString szDesc = {0}; + NvAPI_GetErrorMessage(status, szDesc); + llwarns << szDesc << llendl; + + //should always trigger when asserts are enabled + llassert(status == NVAPI_OK); +} + // Create app mutex creates a unique global windows object. // If the object can be created it returns true, otherwise // it returns false. The false result can be used to determine @@ -92,6 +116,79 @@ bool create_app_mutex() return result; } +void ll_nvapi_init(NvDRSSessionHandle hSession) +{ + // (2) load all the system settings into the session + NvAPI_Status status = NvAPI_DRS_LoadSettings(hSession); + if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } + + NvAPI_UnicodeString profile_name; + std::string app_name = LLTrans::getString("APP_NAME"); + llutf16string w_app_name = utf8str_to_utf16str(app_name); + wsprintf(profile_name, L"%s", w_app_name.c_str()); + status = NvAPI_DRS_SetCurrentGlobalProfile(hSession, profile_name); + if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } + + // (3) Obtain the current profile. + NvDRSProfileHandle hProfile = 0; + status = NvAPI_DRS_GetCurrentGlobalProfile(hSession, &hProfile); + if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } + + // load settings for querying + status = NvAPI_DRS_LoadSettings(hSession); + if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } + + //get the preferred power management mode for Second Life + NVDRS_SETTING drsSetting = {0}; + drsSetting.version = NVDRS_SETTING_VER; + status = NvAPI_DRS_GetSetting(hSession, hProfile, PREFERRED_PSTATE_ID, &drsSetting); + if (status == NVAPI_SETTING_NOT_FOUND) + { //only override if the user hasn't specifically set this setting + // (4) Specify that we want the VSYNC disabled setting + // first we fill the NVDRS_SETTING struct, then we call the function + drsSetting.version = NVDRS_SETTING_VER; + drsSetting.settingId = PREFERRED_PSTATE_ID; + drsSetting.settingType = NVDRS_DWORD_TYPE; + drsSetting.u32CurrentValue = PREFERRED_PSTATE_PREFER_MAX; + status = NvAPI_DRS_SetSetting(hSession, hProfile, &drsSetting); + if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } + } + else if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } + + + + // (5) Now we apply (or save) our changes to the system + status = NvAPI_DRS_SaveSettings(hSession); + if (status != NVAPI_OK) + { + nvapi_error(status); + } +} + //#define DEBUGGING_SEH_FILTER 1 #if DEBUGGING_SEH_FILTER # define WINMAIN DebuggingWinMain @@ -104,7 +201,13 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, LPSTR lpCmdLine, int nCmdShow) { - LLMemType mt1(LLMemType::MTYPE_STARTUP); +#ifdef INCLUDE_VLD + // only works for debug builds (hard coded into vld.h) + #ifdef _DEBUG + // start with Visual Leak Detector turned off + VLDGlobalDisable(); + #endif // _DEBUG +#endif // INCLUDE_VLD const S32 MAX_HEAPS = 255; DWORD heap_enable_lfh_error[MAX_HEAPS]; @@ -112,11 +215,15 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, #if WINDOWS_CRT_MEM_CHECKS && !INCLUDE_VLD _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); // dump memory leaks on exit -#elif 1 +#elif 0 // Experimental - enable the low fragmentation heap // This results in a 2-3x improvement in opening a new Inventory window (which uses a large numebr of allocations) // Note: This won't work when running from the debugger unless the _NO_DEBUG_HEAP environment variable is set to 1 + // Enable to get mem debugging within visual studio. +#if LL_DEBUG + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); +#else _CrtSetDbgFlag(0); // default, just making explicit ULONG ulEnableLFH = 2; @@ -131,6 +238,7 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, heap_enable_lfh_error[i] = GetLastError(); } #endif +#endif // *FIX: global gIconResource = MAKEINTRESOURCE(IDI_LL_ICON); @@ -150,6 +258,27 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, return -1; } + NvAPI_Status status; + + // Initialize NVAPI + status = NvAPI_Initialize(); + NvDRSSessionHandle hSession = 0; + + if (status == NVAPI_OK) + { + // Create the session handle to access driver settings + status = NvAPI_DRS_CreateSession(&hSession); + if (status != NVAPI_OK) + { + nvapi_error(status); + } + else + { + //override driver setting as needed + ll_nvapi_init(hSession); + } + } + // Have to wait until after logging is initialized to display LFH info if (num_heaps > 0) { @@ -217,6 +346,15 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, LLAppViewer::sUpdaterInfo = NULL ; } + + + // (NVAPI) (6) We clean up. This is analogous to doing a free() + if (hSession) + { + NvAPI_DRS_DestroySession(hSession); + hSession = 0; + } + return 0; } diff --git a/indra/newview/llassetuploadqueue.cpp b/indra/newview/llassetuploadqueue.cpp index 7e50098a17..f943759bb8 100644 --- a/indra/newview/llassetuploadqueue.cpp +++ b/indra/newview/llassetuploadqueue.cpp @@ -123,7 +123,9 @@ public: for(LLSD::array_const_iterator line = compile_errors.beginArray(); line < compile_errors.endArray(); line++) { - mSupplier->log(line->asString()); + std::string str = line->asString(); + str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); + mSupplier->log(str); llinfos << content["errors"] << llendl; } } diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 65bfc990d1..7b2c536f5a 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -919,7 +919,7 @@ public: bool uploadConfirmationCallback( const LLSD& notification, const LLSD& response, - boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder) + LLPointer<LLNewAgentInventoryVariablePriceResponder> responder) { S32 option; std::string confirmation_url; @@ -949,7 +949,7 @@ public: void confirmUpload( const std::string& confirmation_url, - boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder) + LLPointer<LLNewAgentInventoryVariablePriceResponder> responder) { if ( getFilename().empty() ) { @@ -1124,7 +1124,7 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog( // and cause sadness. mImpl->confirmUpload( confirmation_url, - boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this)); + LLPointer<LLNewAgentInventoryVariablePriceResponder>(this)); } else { @@ -1157,7 +1157,7 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog( mImpl, _1, _2, - boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this))); + LLPointer<LLNewAgentInventoryVariablePriceResponder>(this))); } } diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp index c9543988a6..ea0b8f00a4 100644 --- a/indra/newview/llattachmentsmgr.cpp +++ b/indra/newview/llattachmentsmgr.cpp @@ -62,6 +62,12 @@ void LLAttachmentsMgr::onIdle(void *) void LLAttachmentsMgr::onIdle() { + // Make sure we got a region before trying anything else + if( !gAgent.getRegion() ) + { + return; + } + S32 obj_count = mPendingAttachments.size(); if (obj_count == 0) { diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp new file mode 100644 index 0000000000..1d72397cbc --- /dev/null +++ b/indra/newview/llautoreplace.cpp @@ -0,0 +1,802 @@ +/** + * @file llautoreplace.cpp + * @brief Auto Replace Manager + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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; either + * version 2.1 of the License, or (at your option) any later version. + * + * 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 + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llautoreplace.h" +#include "llsdserialize.h" +#include "llboost.h" +#include "llcontrol.h" +#include "llviewercontrol.h" +#include "llnotificationsutil.h" + +const char* LLAutoReplace::SETTINGS_FILE_NAME = "autoreplace.xml"; + +void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text) +{ + // make sure these returned values are cleared in case there is no replacement + replacement_start = 0; + replacement_length = 0; + replacement_string.clear(); + + static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace"); + if (perform_autoreplace) + { + S32 word_end = cursor_pos - 1; + + bool at_space = (input_text[word_end] == ' '); + bool have_word = (LLWStringUtil::isPartOfWord(input_text[word_end])); + + if (at_space || have_word) + { + if (at_space && word_end > 0) + { + // find out if this space immediately follows a word + word_end--; + have_word = (LLWStringUtil::isPartOfWord(input_text[word_end])); + } + if (have_word) + { + // word_end points to the end of a word, now find the start of the word + std::string word; + S32 word_start = word_end; + for (S32 back_one = word_start - 1; + back_one >= 0 && LLWStringUtil::isPartOfWord(input_text[back_one]); + back_one-- + ) + { + word_start--; // walk word_start back to the beginning of the word + } + LL_DEBUGS("AutoReplace") << "word_start: " << word_start << " word_end: " << word_end << LL_ENDL; + std::string str_text = std::string(input_text.begin(), input_text.end()); + std::string last_word = str_text.substr(word_start, word_end - word_start + 1); + std::string replacement_word(mSettings.replaceWord(last_word)); + + if (replacement_word != last_word) + { + // The last word is one for which we have a replacement + if (at_space) + { + // return the replacement string + replacement_start = word_start; + replacement_length = last_word.length(); + replacement_string = utf8str_to_wstring(replacement_word); + LLWString old_string = utf8str_to_wstring(last_word); + S32 size_change = replacement_string.size() - old_string.size(); + cursor_pos += size_change; + } + } + } + } + } +} + +std::string LLAutoReplace::getUserSettingsFileName() +{ + std::string path=gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""); + + if (!path.empty()) + { + path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, SETTINGS_FILE_NAME); + } + return path; +} + +std::string LLAutoReplace::getAppSettingsFileName() +{ + std::string path=gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""); + + if (!path.empty()) + { + path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, SETTINGS_FILE_NAME); + } + else + { + LL_ERRS("AutoReplace") << "Failed to get app settings directory name" << LL_ENDL; + } + return path; +} + +LLAutoReplaceSettings LLAutoReplace::getSettings() +{ + return mSettings; +} + +void LLAutoReplace::setSettings(const LLAutoReplaceSettings& newSettings) +{ + mSettings.set(newSettings); + /// Make the newSettings active and write them to user storage + saveToUserSettings(); +} + +LLAutoReplace::LLAutoReplace() +{ +} + +void LLAutoReplace::initSingleton() +{ + loadFromSettings(); +} + +void LLAutoReplace::loadFromSettings() +{ + std::string filename=getUserSettingsFileName(); + if (filename.empty()) + { + LL_INFOS("AutoReplace") << "no valid user settings directory." << LL_ENDL; + } + if(gDirUtilp->fileExists(filename)) + { + LLSD userSettings; + llifstream file; + file.open(filename.c_str()); + if (file.is_open()) + { + LLSDSerialize::fromXML(userSettings, file); + } + file.close(); + if ( mSettings.setFromLLSD(userSettings) ) + { + LL_INFOS("AutoReplace") << "settings loaded from '" << filename << "'" << LL_ENDL; + } + else + { + LL_WARNS("AutoReplace") << "invalid settings found in '" << filename << "'" << LL_ENDL; + } + } + else // no user settings found, try application settings + { + std::string defaultName = getAppSettingsFileName(); + LL_INFOS("AutoReplace") << " user settings file '" << filename << "' not found"<< LL_ENDL; + + bool gotSettings = false; + if(gDirUtilp->fileExists(defaultName)) + { + LLSD appDefault; + llifstream file; + file.open(defaultName.c_str()); + if (file.is_open()) + { + LLSDSerialize::fromXMLDocument(appDefault, file); + } + file.close(); + + if ( mSettings.setFromLLSD(appDefault) ) + { + LL_INFOS("AutoReplace") << "settings loaded from '" << defaultName.c_str() << "'" << LL_ENDL; + gotSettings = true; + } + else + { + LL_WARNS("AutoReplace") << "invalid settings found in '" << defaultName.c_str() << "'" << LL_ENDL; + } + } + + if ( ! gotSettings ) + { + if (mSettings.setFromLLSD(mSettings.getExampleLLSD())) + { + LL_WARNS("AutoReplace") << "no settings found; loaded example." << LL_ENDL; + } + else + { + LL_WARNS("AutoReplace") << "no settings found and example invalid!" << LL_ENDL; + } + } + } +} + +void LLAutoReplace::saveToUserSettings() +{ + std::string filename=getUserSettingsFileName(); + llofstream file; + file.open(filename.c_str()); + LLSDSerialize::toPrettyXML(mSettings.asLLSD(), file); + file.close(); + LL_INFOS("AutoReplace") << "settings saved to '" << filename << "'" << LL_ENDL; +} + +// ================================================================ +// LLAutoReplaceSettings +// ================================================================ + +const std::string LLAutoReplaceSettings::AUTOREPLACE_LIST_NAME = "name"; ///< key for looking up list names +const std::string LLAutoReplaceSettings::AUTOREPLACE_LIST_REPLACEMENTS = "replacements"; ///< key for looking up replacement map + +LLAutoReplaceSettings::LLAutoReplaceSettings() +{ +} + +LLAutoReplaceSettings::LLAutoReplaceSettings(const LLAutoReplaceSettings& settings) +{ + // copy all values through fundamental type intermediates for thread safety + mLists = LLSD::emptyArray(); + + for ( LLSD::array_const_iterator list = settings.mLists.beginArray(), listEnd = settings.mLists.endArray(); + list != listEnd; + list++ + ) + { + if ( (*list).isMap() ) // can fail due to LLSD-30: ignore it + { + LLSD listMap = LLSD::emptyMap(); + std::string listName = (*list)[AUTOREPLACE_LIST_NAME]; + listMap[AUTOREPLACE_LIST_NAME] = listName; + listMap[AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap(); + + for ( LLSD::map_const_iterator + entry = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].beginMap(), + entriesEnd = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].endMap(); + entry != entriesEnd; + entry++ + ) + { + std::string keyword = entry->first; + std::string replacement = entry->second.asString(); + listMap[AUTOREPLACE_LIST_REPLACEMENTS].insert(keyword, LLSD(replacement)); + } + + mLists.append(listMap); + } + } +} + +void LLAutoReplaceSettings::set(const LLAutoReplaceSettings& newSettings) +{ + mLists = newSettings.mLists; +} + +bool LLAutoReplaceSettings::setFromLLSD(const LLSD& settingsFromLLSD) +{ + bool settingsValid = true; + + if ( settingsFromLLSD.isArray() ) + { + for ( LLSD::array_const_iterator + list = settingsFromLLSD.beginArray(), + listEnd = settingsFromLLSD.endArray(); + settingsValid && list != listEnd; + list++ + ) + { + if ( (*list).isDefined() ) // can be undef due to LLSD-30: ignore it + { + settingsValid = listIsValid(*list); + } + } + } + else + { + settingsValid = false; + LL_WARNS("AutoReplace") << "settings are not an array" << LL_ENDL; + } + + if ( settingsValid ) + { + mLists = settingsFromLLSD; + } + else + { + LL_WARNS("AutoReplace") << "invalid settings discarded; using hard coded example" << LL_ENDL; + } + + return settingsValid; +} + +bool LLAutoReplaceSettings::listNameMatches( const LLSD& list, const std::string name ) +{ + return list.isMap() + && list.has(AUTOREPLACE_LIST_NAME) + && list[AUTOREPLACE_LIST_NAME].asString() == name; +} + +const LLSD* LLAutoReplaceSettings::getListEntries(std::string listName) +{ + const LLSD* returnedEntries = NULL; + for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray(); + returnedEntries == NULL && list != endList; + list++ + ) + { + const LLSD& thisList = *list; + if ( listNameMatches(thisList, listName) ) + { + returnedEntries = &thisList[AUTOREPLACE_LIST_REPLACEMENTS]; + } + } + return returnedEntries; +} + +std::string LLAutoReplaceSettings::replacementFor(std::string keyword, std::string listName) +{ + std::string replacement; + bool foundList = false; + for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray(); + ! foundList && list != endList; + list++ + ) + { + const LLSD& thisList = *list; + if ( listNameMatches(thisList, listName) ) + { + foundList = true; // whether there is a replacement or not, we're done + if ( thisList.isMap() + && thisList.has(AUTOREPLACE_LIST_REPLACEMENTS) + && thisList[AUTOREPLACE_LIST_REPLACEMENTS].has(keyword) + ) + { + replacement = thisList[AUTOREPLACE_LIST_REPLACEMENTS][keyword].asString(); + LL_DEBUGS("AutoReplace")<<"'"<<keyword<<"' -> '"<<replacement<<"'"<<LL_ENDL; + } + } + if (!foundList) + { + LL_WARNS("AutoReplace")<<"failed to find list '"<<listName<<"'"<<LL_ENDL; + } + } + if (replacement.empty()) + { + LL_WARNS("AutoReplace")<<"failed to find '"<<keyword<<"'"<<LL_ENDL; + } + return replacement; +} + +LLSD LLAutoReplaceSettings::getListNames() +{ + LL_DEBUGS("AutoReplace")<<"====="<<LL_ENDL; + LLSD toReturn = LLSD::emptyArray(); + S32 counter=0; + for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray(); + list != endList; + list++ + ) + { + const LLSD& thisList = *list; + if ( thisList.isMap() ) + { + if ( thisList.has(AUTOREPLACE_LIST_NAME) ) + { + std::string name = thisList[AUTOREPLACE_LIST_NAME].asString(); + LL_DEBUGS("AutoReplace")<<counter<<" '"<<name<<"'"<<LL_ENDL; + toReturn.append(LLSD(name)); + } + else + { + LL_ERRS("AutoReplace") <<counter<<" ! MISSING "<<AUTOREPLACE_LIST_NAME<< LL_ENDL; + } + } + else + { + LL_WARNS("AutoReplace")<<counter<<" ! not a map: "<<LLSD::typeString(thisList.type())<< LL_ENDL; + } + counter++; + } + LL_DEBUGS("AutoReplace")<<"^^^^^^"<<LL_ENDL; + return toReturn; +} + +bool LLAutoReplaceSettings::listIsValid(const LLSD& list) +{ + bool listValid = true; + if ( ! list.isMap() ) + { + listValid = false; + LL_WARNS("AutoReplace") << "list is not a map" << LL_ENDL; + } + else if ( ! list.has(AUTOREPLACE_LIST_NAME) + || ! list[AUTOREPLACE_LIST_NAME].isString() + || list[AUTOREPLACE_LIST_NAME].asString().empty() + ) + { + listValid = false; + LL_WARNS("AutoReplace") + << "list found without " << AUTOREPLACE_LIST_NAME + << " (or it is empty)" + << LL_ENDL; + } + else if ( ! list.has(AUTOREPLACE_LIST_REPLACEMENTS) || ! list[AUTOREPLACE_LIST_REPLACEMENTS].isMap() ) + { + listValid = false; + LL_WARNS("AutoReplace") << "list '" << list[AUTOREPLACE_LIST_NAME].asString() << "' without " << AUTOREPLACE_LIST_REPLACEMENTS << LL_ENDL; + } + else + { + for ( LLSD::map_const_iterator + entry = list[AUTOREPLACE_LIST_REPLACEMENTS].beginMap(), + entriesEnd = list[AUTOREPLACE_LIST_REPLACEMENTS].endMap(); + listValid && entry != entriesEnd; + entry++ + ) + { + if ( ! entry->second.isString() ) + { + listValid = false; + LL_WARNS("AutoReplace") + << "non-string replacement value found in list '" + << list[AUTOREPLACE_LIST_NAME].asString() << "'" + << LL_ENDL; + } + } + } + + return listValid; +} + +const LLSD* LLAutoReplaceSettings::exportList(std::string listName) +{ + const LLSD* exportedList = NULL; + for ( LLSD::array_const_iterator list = mLists.beginArray(), listEnd = mLists.endArray(); + exportedList == NULL && list != listEnd; + list++ + ) + { + if ( listNameMatches(*list, listName) ) + { + const LLSD& namedList = (*list); + exportedList = &namedList; + } + } + return exportedList; +} + +bool LLAutoReplaceSettings::listNameIsUnique(const LLSD& newList) +{ + bool nameIsUnique = true; + // this must always be called with a valid list, so it is safe to assume it has a name + std::string newListName = newList[AUTOREPLACE_LIST_NAME].asString(); + for ( LLSD::array_const_iterator list = mLists.beginArray(), listEnd = mLists.endArray(); + nameIsUnique && list != listEnd; + list++ + ) + { + if ( listNameMatches(*list, newListName) ) + { + LL_WARNS("AutoReplace")<<"duplicate list name '"<<newListName<<"'"<<LL_ENDL; + nameIsUnique = false; + } + } + return nameIsUnique; +} + +/* static */ +void LLAutoReplaceSettings::createEmptyList(LLSD& emptyList) +{ + emptyList = LLSD::emptyMap(); + emptyList[AUTOREPLACE_LIST_NAME] = "Empty"; + emptyList[AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap(); +} + +/* static */ +void LLAutoReplaceSettings::setListName(LLSD& list, const std::string& newName) +{ + list[AUTOREPLACE_LIST_NAME] = newName; +} + +/* static */ +std::string LLAutoReplaceSettings::getListName(LLSD& list) +{ + std::string name; + if ( list.isMap() && list.has(AUTOREPLACE_LIST_NAME) && list[AUTOREPLACE_LIST_NAME].isString() ) + { + name = list[AUTOREPLACE_LIST_NAME].asString(); + } + return name; +} + +LLAutoReplaceSettings::AddListResult LLAutoReplaceSettings::addList(const LLSD& newList) +{ + AddListResult result; + if ( listIsValid( newList ) ) + { + if ( listNameIsUnique( newList ) ) + { + mLists.append(newList); + result = AddListOk; + } + else + { + LL_WARNS("AutoReplace") << "attempt to add duplicate name" << LL_ENDL; + result = AddListDuplicateName; + } + } + else + { + LL_WARNS("AutoReplace") << "attempt to add invalid list" << LL_ENDL; + result = AddListInvalidList; + } + return result; +} + +LLAutoReplaceSettings::AddListResult LLAutoReplaceSettings::replaceList(const LLSD& newList) +{ + AddListResult result = AddListInvalidList; + if ( listIsValid( newList ) ) + { + std::string listName = newList[AUTOREPLACE_LIST_NAME].asString(); + bool listFound = false; + S32 search_index; + LLSD targetList; + // The following is working around the fact that LLSD arrays containing maps also seem to have undefined entries... see LLSD-30 + for ( search_index = 0, targetList = mLists[0]; + !listFound && search_index < mLists.size(); + search_index += 1, targetList = mLists[search_index] + ) + { + if ( targetList.isMap() ) + { + if ( listNameMatches( targetList, listName) ) + { + LL_DEBUGS("AutoReplace")<<"list to replace found at "<<search_index<<LL_ENDL; + mLists.erase(search_index); + mLists.insert(search_index, newList); + listFound = true; + result = AddListOk; + } + } + } + + if ( ! listFound ) + { + LL_WARNS("AutoReplace") << "attempt to replace unconfigured list" << LL_ENDL; + } + } + else + { + LL_WARNS("AutoReplace") << "attempt to add invalid list" << LL_ENDL; + } + return result; +} + +bool LLAutoReplaceSettings::removeReplacementList(std::string listName) +{ + bool found = false; + for( S32 index = 0; !found && mLists[index].isDefined(); index++ ) + { + if( listNameMatches(mLists.get(index), listName) ) + { + LL_DEBUGS("AutoReplace")<<"list '"<<listName<<"'"<<LL_ENDL; + mLists.erase(index); + found = true; + } + } + return found; +} + +/// Move the named list up in the priority order +bool LLAutoReplaceSettings::increaseListPriority(std::string listName) +{ + LL_DEBUGS("AutoReplace")<<listName<<LL_ENDL; + bool found = false; + S32 search_index, previous_index; + LLSD targetList; + // The following is working around the fact that LLSD arrays containing maps also seem to have undefined entries... see LLSD-30 + previous_index = -1; + for ( search_index = 0, targetList = mLists[0]; + !found && search_index < mLists.size(); + search_index += 1, targetList = mLists[search_index] + ) + { + if ( targetList.isMap() ) + { + if ( listNameMatches( targetList, listName) ) + { + LL_DEBUGS("AutoReplace")<<"found at "<<search_index<<", previous is "<<previous_index<<LL_ENDL; + found = true; + if (previous_index >= 0) + { + LL_DEBUGS("AutoReplace") << "erase "<<search_index<<LL_ENDL; + mLists.erase(search_index); + LL_DEBUGS("AutoReplace") << "insert at "<<previous_index<<LL_ENDL; + mLists.insert(previous_index, targetList); + } + else + { + LL_WARNS("AutoReplace") << "attempted to move top list up" << LL_ENDL; + } + } + else + { + previous_index = search_index; + } + } + else + { + LL_DEBUGS("AutoReplace") << search_index<<" is "<<LLSD::typeString(targetList.type())<<LL_ENDL; + } + } + return found; +} + +/// Move the named list down in the priority order +bool LLAutoReplaceSettings::decreaseListPriority(std::string listName) +{ + LL_DEBUGS("AutoReplace")<<listName<<LL_ENDL; + S32 found_index = -1; + S32 search_index; + for ( search_index = 0; + found_index == -1 && search_index < mLists.size(); + search_index++ + ) + { + if ( listNameMatches( mLists[search_index], listName) ) + { + LL_DEBUGS("AutoReplace")<<"found at index "<<search_index<<LL_ENDL; + found_index = search_index; + } + } + if (found_index != -1) + { + S32 next_index; + for ( next_index = found_index+1; + next_index < mLists.size() && ! mLists[next_index].isMap(); + next_index++ + ) + { + // skipping over any undefined slots (see LLSD-30) + LL_WARNS("AutoReplace")<<next_index<<" ! not a map: "<<LLSD::typeString(mLists[next_index].type())<< LL_ENDL; + } + if ( next_index < mLists.size() ) + { + LLSD next_list = mLists[next_index]; + LL_DEBUGS("AutoReplace") << "erase "<<next_index<<LL_ENDL; + mLists.erase(next_index); + LL_DEBUGS("AutoReplace") << "insert at "<<found_index<<LL_ENDL; + mLists.insert(found_index, next_list); + } + else + { + LL_WARNS("AutoReplace") << "attempted to move bottom list down" << LL_ENDL; + } + } + else + { + LL_WARNS("AutoReplace") << "not found" << LL_ENDL; + } + return (found_index != -1); +} + + +std::string LLAutoReplaceSettings::replaceWord(const std::string currentWord) +{ + std::string returnedWord = currentWord; // in case no replacement is found + static LLCachedControl<bool> autoreplace_enabled(gSavedSettings, "AutoReplace"); + if ( autoreplace_enabled ) + { + LL_DEBUGS("AutoReplace")<<"checking '"<<currentWord<<"'"<< LL_ENDL; + //loop through lists in order + bool found = false; + for( LLSD::array_const_iterator list = mLists.beginArray(), endLists = mLists.endArray(); + ! found && list != endLists; + list++ + ) + { + const LLSD& checkList = *list; + const LLSD& replacements = checkList[AUTOREPLACE_LIST_REPLACEMENTS]; + + if ( replacements.has(currentWord) ) + { + found = true; + LL_DEBUGS("AutoReplace") + << " found in list '" << checkList[AUTOREPLACE_LIST_NAME].asString() + << " => '" << replacements[currentWord].asString() << "'" + << LL_ENDL; + returnedWord = replacements[currentWord].asString(); + } + } + } + return returnedWord; +} + +bool LLAutoReplaceSettings::addEntryToList(LLWString keyword, LLWString replacement, std::string listName) +{ + bool added = false; + + if ( ! keyword.empty() && ! replacement.empty() ) + { + bool isOneWord = true; + for (S32 character = 0; isOneWord && character < keyword.size(); character++ ) + { + if ( ! LLWStringUtil::isPartOfWord(keyword[character]) ) + { + LL_WARNS("AutoReplace") << "keyword '" << wstring_to_utf8str(keyword) << "' not a single word (len "<<keyword.size()<<" '"<<character<<"')" << LL_ENDL; + isOneWord = false; + } + } + + if ( isOneWord ) + { + bool listFound = false; + for( LLSD::array_iterator list = mLists.beginArray(), endLists = mLists.endArray(); + ! listFound && list != endLists; + list++ + ) + { + if ( listNameMatches(*list, listName) ) + { + listFound = true; + (*list)[AUTOREPLACE_LIST_REPLACEMENTS][wstring_to_utf8str(keyword)]=wstring_to_utf8str(replacement); + } + } + if (listFound) + { + added = true; + } + else + { + LL_WARNS("AutoReplace") << "list '" << listName << "' not found" << LL_ENDL; + } + } + } + + return added; +} + +bool LLAutoReplaceSettings::removeEntryFromList(std::string keyword, std::string listName) +{ + bool found = false; + for( LLSD::array_iterator list = mLists.beginArray(), endLists = mLists.endArray(); + ! found && list != endLists; + list++ + ) + { + if ( listNameMatches(*list, listName) ) + { + found = true; + (*list)[AUTOREPLACE_LIST_REPLACEMENTS].erase(keyword); + } + } + if (!found) + { + LL_WARNS("AutoReplace") << "list '" << listName << "' not found" << LL_ENDL; + } + return found; +} + +LLSD LLAutoReplaceSettings::getExampleLLSD() +{ + LL_DEBUGS("AutoReplace")<<LL_ENDL; + LLSD example = LLSD::emptyArray(); + + example[0] = LLSD::emptyMap(); + example[0][AUTOREPLACE_LIST_NAME] = "Example List 1"; + example[0][AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap(); + example[0][AUTOREPLACE_LIST_REPLACEMENTS]["keyword1"] = "replacement string 1"; + example[0][AUTOREPLACE_LIST_REPLACEMENTS]["keyword2"] = "replacement string 2"; + + example[1] = LLSD::emptyMap(); + example[1][AUTOREPLACE_LIST_NAME] = "Example List 2"; + example[1][AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap(); + example[1][AUTOREPLACE_LIST_REPLACEMENTS]["mistake1"] = "correction 1"; + example[1][AUTOREPLACE_LIST_REPLACEMENTS]["mistake2"] = "correction 2"; + + return example; +} + +const LLSD& LLAutoReplaceSettings::asLLSD() +{ + return mLists; +} + +LLAutoReplaceSettings::~LLAutoReplaceSettings() +{ +} diff --git a/indra/newview/llautoreplace.h b/indra/newview/llautoreplace.h new file mode 100644 index 0000000000..9eecc2d981 --- /dev/null +++ b/indra/newview/llautoreplace.h @@ -0,0 +1,227 @@ +/** + * @file llautoreplace.h + * @brief Auto Replace Manager + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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; either + * version 2.1 of the License, or (at your option) any later version. + * + * 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 + */ +#ifndef LLAUTOREPLACE_H +#define LLAUTOREPLACE_H + +#include "lllineeditor.h" + +class LLAutoReplace; + +/** The configuration data for the LLAutoReplace object + * + * This is a separate class so that the LLFloaterAutoReplaceSettings + * can have a copy of the configuration to manipulate before committing + * the changes back to the LLAutoReplace singleton that provides the + * autoreplace callback. + */ +class LLAutoReplaceSettings +{ + public: + LLAutoReplaceSettings(); + ~LLAutoReplaceSettings(); + + /// Constructor for creating a tempory copy of the current settings + LLAutoReplaceSettings(const LLAutoReplaceSettings& settings); + + /// Replace the current settings with new ones and save them to the user settings file + void set(const LLAutoReplaceSettings& newSettings); + + /// Load the current settings read from an LLSD file + bool setFromLLSD(const LLSD& settingsFromLLSD); + ///< @returns whether or not the settingsFromLLSD were valid + + // ================================================================ + ///@{ @name List Operations + // ================================================================ + + /// @returns the configured list names as an LLSD Array of strings + LLSD getListNames(); + + /// Status values returned from the addList method + typedef enum + { + AddListOk, + AddListDuplicateName, + AddListInvalidList, + } AddListResult; + + /// Inserts a new list at the end of the priority order + AddListResult addList(const LLSD& newList); + + /// Inserts a list in place of an existing list of the same name + AddListResult replaceList(const LLSD& newList); + + /// Removes the named list, @returns false if not found + bool removeReplacementList(std::string listName); + + /// Move the named list up in the priority order + bool increaseListPriority(std::string listName); + ///< @returns false if the list is not found + + /// Move the named list down in the priority order + bool decreaseListPriority(std::string listName); + ///< @returns false if the list is not found + + /// Get a copy of just one list (for saving to an export file) + const LLSD* exportList(std::string listName); + /// @returns an LLSD map + + /// Checks for required elements, and that each has the correct type. + bool listIsValid(const LLSD& listSettings); + + /// Checks for required elements, and that each has the correct type. + bool listNameIs(const LLSD& listSettings); + + /// Checks to see if a new lists name conflicts with one in the settings + bool listNameIsUnique(const LLSD& newList); + /// @note must be called with LLSD that has passed listIsValid + + /// Initializes emptyList to an empty list named 'Empty' + static void createEmptyList(LLSD& emptyList); + + /// Resets the name of a list to a new value + static void setListName(LLSD& list, const std::string& newName); + + /// Gets the name of a list + static std::string getListName(LLSD& list); + + ///@} + // ================================================================ + ///@{ @name Replacement Entry Operations + // ================================================================ + + /// Get the replacements specified by a given list + const LLSD* getListEntries(std::string listName); + ///< @returns an LLSD Map of keyword -> replacement test pairs + + /// Get the replacement for the keyword from the specified list + std::string replacementFor(std::string keyword, std::string listName); + + /// Adds a keywword/replacement pair to the named list + bool addEntryToList(LLWString keyword, LLWString replacement, std::string listName); + + /// Removes the keywword and its replacement from the named list + bool removeEntryFromList(std::string keyword, std::string listName); + + /** + * Look for currentWord in the lists in order, returning any substitution found + * If no configured substitution is found, returns currentWord + */ + std::string replaceWord(const std::string currentWord /**< word to search for */ ); + + /// Provides a hard-coded example of settings + LLSD getExampleLLSD(); + + /// Get the actual settings as LLSD + const LLSD& asLLSD(); + ///< @note for use only in AutoReplace::saveToUserSettings + + private: + /// Efficiently and safely compare list names + bool listNameMatches( const LLSD& list, const std::string name ); + + /// The actual llsd data structure + LLSD mLists; + + static const std::string AUTOREPLACE_LIST_NAME; ///< key for looking up list names + static const std::string AUTOREPLACE_LIST_REPLACEMENTS; ///< key for looking up replacement map + + /**< + * LLSD structure of the lists + * - The configuration is an array (mLists), + * - Each entry in the array is a replacement list + * - Each replacement list is a map with three keys: + * @verbatim + * "name" String the name of the list + * "replacements" Map keyword -> replacement pairs + * + * <llsd> + * <array> + * <map> + * <key>name</key> <string>List 1</string> + * <key>data</key> + * <map> + * <key>keyword1</key> <string>replacement1</string> + * <key>keyword2</key> <string>replacement2</string> + * </map> + * </map> + * <map> + * <key>name</key> <string>List 2</string> + * <key>data</key> + * <map> + * <key>keyword1</key> <string>replacement1</string> + * <key>keyword2</key> <string>replacement2</string> + * </map> + * </map> + * </array> + * </llsd> + * @endverbatim + */ +}; + +/** Provides a facility to auto-replace text dynamically as it is entered. + * + * When the end of a word is detected (defined as any punctuation character, + * or any whitespace except newline or return), the preceding word is used + * as a lookup key in an ordered list of maps. If a match is found in any + * map, the replacement start index and length are returned along with the + * new replacement string. + * + * See the autoreplaceCallback method for how to add autoreplace functionality + * to a text entry tool. + */ +class LLAutoReplace : public LLSingleton<LLAutoReplace> +{ +public: + /// Callback that provides the hook for use in text entry methods + void autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text); + + /// Get a copy of the current settings + LLAutoReplaceSettings getSettings(); + + /// Commit new settings after making changes + void setSettings(const LLAutoReplaceSettings& settings); + +private: + friend class LLSingleton<LLAutoReplace>; + LLAutoReplace(); + /*virtual*/ void initSingleton(); + + LLAutoReplaceSettings mSettings; ///< configuration information + + /// Read settings from persistent storage + void loadFromSettings(); + + /// Make the newSettings active and write them to user storage + void saveToUserSettings(); + + /// Compute the user settings file name + std::string getUserSettingsFileName(); + + /// Compute the (read-ony) application settings file name + std::string getAppSettingsFileName(); + + /// basename for the settings files + static const char* SETTINGS_FILE_NAME; +}; + +#endif /* LLAUTOREPLACE_H */ diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 10fd6b739e..b513a52ff7 100755 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -42,7 +42,9 @@ #include "llappviewer.h" // for gLastVersionChannel #include "llcachename.h" #include "llcallingcard.h" // for LLAvatarTracker +#include "llconversationlog.h" #include "llfloateravatarpicker.h" // for LLFloaterAvatarPicker +#include "llfloaterconversationpreview.h" #include "llfloatergroupinvite.h" #include "llfloatergroups.h" #include "llfloaterreg.h" @@ -55,6 +57,7 @@ #include "llinventorybridge.h" #include "llinventorymodel.h" // for gInventory.findCategoryUUIDForType #include "llinventorypanel.h" +#include "llfloaterimcontainer.h" #include "llimview.h" // for gIMMgr #include "llmutelist.h" #include "llnotificationsutil.h" // for LLNotificationsUtil @@ -66,7 +69,6 @@ #include "llviewerobjectlist.h" #include "llviewermessage.h" // for handle_lure #include "llviewerregion.h" -#include "llimfloater.h" #include "lltrans.h" #include "llcallingcard.h" #include "llslurl.h" // IDEVO @@ -93,7 +95,7 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin LLRecentPeople::instance().add(id); } -void on_avatar_name_friendship(const LLUUID& id, const LLAvatarName av_name) +static void on_avatar_name_friendship(const LLUUID& id, const LLAvatarName av_name) { LLAvatarActions::requestFriendshipDialog(id, av_name.getCompleteName()); } @@ -134,7 +136,7 @@ void LLAvatarActions::removeFriendsDialog(const uuid_vec_t& ids) LLAvatarName av_name; if(LLAvatarNameCache::get(agent_id, &av_name)) { - args["NAME"] = av_name.mDisplayName; + args["NAME"] = av_name.getDisplayName(); } msgType = "RemoveFromFriends"; @@ -179,11 +181,11 @@ void LLAvatarActions::offerTeleport(const uuid_vec_t& ids) static void on_avatar_name_cache_start_im(const LLUUID& agent_id, const LLAvatarName& av_name) { - std::string name = av_name.getCompleteName(); + std::string name = av_name.getDisplayName(); LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id); if (session_id != LLUUID::null) { - LLIMFloater::show(session_id); + LLFloaterIMContainer::getInstance()->showConversation(session_id); } make_ui_sound("UISndStartIM"); } @@ -191,11 +193,10 @@ static void on_avatar_name_cache_start_im(const LLUUID& agent_id, // static void LLAvatarActions::startIM(const LLUUID& id) { - if (id.isNull()) + if (id.isNull() || gAgent.getID() == id) return; - LLAvatarNameCache::get(id, - boost::bind(&on_avatar_name_cache_start_im, _1, _2)); + LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_cache_start_im, _1, _2)); } // static @@ -214,7 +215,7 @@ void LLAvatarActions::endIM(const LLUUID& id) static void on_avatar_name_cache_start_call(const LLUUID& agent_id, const LLAvatarName& av_name) { - std::string name = av_name.getCompleteName(); + std::string name = av_name.getDisplayName(); LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id, true); if (session_id != LLUUID::null) { @@ -230,12 +231,11 @@ void LLAvatarActions::startCall(const LLUUID& id) { return; } - LLAvatarNameCache::get(id, - boost::bind(&on_avatar_name_cache_start_call, _1, _2)); + LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_cache_start_call, _1, _2)); } // static -void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids) +void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids, const LLUUID& floater_id) { if (ids.size() == 0) { @@ -252,7 +252,7 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids) // create the new ad hoc voice session const std::string title = LLTrans::getString("conference-title"); LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, - ids[0], id_array, true); + ids[0], id_array, true, floater_id); if (session_id == LLUUID::null) { return; @@ -285,7 +285,7 @@ bool LLAvatarActions::canCall() } // static -void LLAvatarActions::startConference(const uuid_vec_t& ids) +void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& floater_id) { // *HACK: Copy into dynamic array LLDynamicArray<LLUUID> id_array; @@ -294,35 +294,32 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids) id_array.push_back(*it); } const std::string title = LLTrans::getString("conference-title"); - LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array); - if (session_id != LLUUID::null) + LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array, false, floater_id); + + if (session_id == LLUUID::null) { - LLIMFloater::show(session_id); + return; } + + LLFloaterIMContainer::getInstance()->showConversation(session_id); + make_ui_sound("UISndStartIM"); } +static const char* get_profile_floater_name(const LLUUID& avatar_id) +{ + // Use different floater XML for our profile to be able to save its rect. + return avatar_id == gAgentID ? "my_profile" : "profile"; +} + static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name) { - std::string username = av_name.mUsername; - if (username.empty()) - { - username = LLCacheName::buildUsername(av_name.mDisplayName); - } - - llinfos << "opening web profile for " << username << llendl; - std::string url = getProfileURL(username); + std::string url = getProfileURL(av_name.getAccountName()); // PROFILES: open in webkit window - const bool show_chrome = false; - static LLCachedControl<LLRect> profile_rect(gSavedSettings, "WebProfileRect"); LLFloaterWebContent::Params p; - p.url(url). - id(agent_id.asString()). - show_chrome(show_chrome). - window_class("profile"). - preferred_media_size(profile_rect); - LLFloaterReg::showInstance("profile", p); + p.url(url).id(agent_id.asString()); + LLFloaterReg::showInstance(get_profile_floater_name(agent_id), p); } // static @@ -339,14 +336,15 @@ bool LLAvatarActions::profileVisible(const LLUUID& id) { LLSD sd; sd["id"] = id; - LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*> (LLFloaterReg::findInstance("profile", sd)); + LLFloater* browser = getProfileFloater(id); return browser && browser->isShown(); } //static LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& id) { - LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*> (LLFloaterReg::findInstance("profile", LLSD().with("id", id))); + LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*> + (LLFloaterReg::findInstance(get_profile_floater_name(id), LLSD().with("id", id))); return browser; } @@ -355,7 +353,7 @@ void LLAvatarActions::hideProfile(const LLUUID& id) { LLSD sd; sd["id"] = id; - LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*> (LLFloaterReg::findInstance("profile", sd)); + LLFloater* browser = getProfileFloater(id); if (browser) { browser->closeFloater(); @@ -372,19 +370,19 @@ void LLAvatarActions::showOnMap(const LLUUID& id) return; } - gFloaterWorldMap->trackAvatar(id, av_name.mDisplayName); + gFloaterWorldMap->trackAvatar(id, av_name.getDisplayName()); LLFloaterReg::showInstance("world_map"); } // static void LLAvatarActions::pay(const LLUUID& id) { - LLNotification::Params params("BusyModePay"); + LLNotification::Params params("DoNotDisturbModePay"); params.functor.function(boost::bind(&LLAvatarActions::handlePay, _1, _2, id)); - if (gAgent.getBusy()) + if (gAgent.isDoNotDisturb()) { - // warn users of being in busy mode during a transaction + // warn users of being in do not disturb mode during a transaction LLNotifications::instance().add(params); } else @@ -446,6 +444,7 @@ void LLAvatarActions::share(const LLUUID& id) { LLSD key; LLFloaterSidePanelContainer::showPanel("inventory", key); + LLFloaterReg::showInstance("im_container"); LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL,id); @@ -527,23 +526,6 @@ namespace action_give_inventory return acceptable; } - static void build_residents_string(const std::vector<LLAvatarName> avatar_names, std::string& residents_string) - { - llassert(avatar_names.size() > 0); - - const std::string& separator = LLTrans::getString("words_separator"); - for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; ) - { - LLAvatarName av_name = *it; - residents_string.append(av_name.mDisplayName); - if (++it == avatar_names.end()) - { - break; - } - residents_string.append(separator); - } - } - static void build_items_string(const std::set<LLUUID>& inventory_selected_uuids , std::string& items_string) { llassert(inventory_selected_uuids.size() > 0); @@ -592,7 +574,7 @@ namespace action_give_inventory } S32 count = LLShareInfo::instance().mAvatarNames.size(); - bool shared = false; + bool shared = count && !inventory_selected_uuids.empty(); // iterate through avatars for(S32 i = 0; i < count; ++i) @@ -614,8 +596,10 @@ namespace action_give_inventory LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); if (inv_cat) { - LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id); - shared = true; + if (!LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id, "ItemsShared")) + { + shared = false; + } break; } LLViewerInventoryItem* inv_item = gInventory.getItem(*it); @@ -630,8 +614,10 @@ namespace action_give_inventory } else { - LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id); - shared = true; + if (!LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id)) + { + shared = false; + } } } if (noncopy_items.beginArray() != noncopy_items.endArray()) @@ -641,8 +627,10 @@ namespace action_give_inventory LLSD payload; payload["agent_id"] = avatar_uuid; payload["items"] = noncopy_items; + payload["success_notification"] = "ItemsShared"; LLNotificationsUtil::add("CannotCopyWarning", substitutions, payload, &LLGiveInventory::handleCopyProtectedItem); + shared = false; break; } } @@ -673,54 +661,127 @@ namespace action_give_inventory } std::string residents; - build_residents_string(avatar_names, residents); + LLAvatarActions::buildResidentsString(avatar_names, residents); 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); } } +// static +void LLAvatarActions::buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string) +{ + llassert(avatar_names.size() > 0); + + std::sort(avatar_names.begin(), avatar_names.end()); + const std::string& separator = LLTrans::getString("words_separator"); + for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; ) + { + residents_string.append((*it).getDisplayName()); + if (++it == avatar_names.end()) + { + break; + } + residents_string.append(separator); + } +} +// static +void LLAvatarActions::buildResidentsString(const uuid_vec_t& avatar_uuids, std::string& residents_string) +{ + std::vector<LLAvatarName> avatar_names; + uuid_vec_t::const_iterator it = avatar_uuids.begin(); + for (; it != avatar_uuids.end(); ++it) + { + LLAvatarName av_name; + if (LLAvatarNameCache::get(*it, &av_name)) + { + avatar_names.push_back(av_name); + } + } + + // We should check whether the vector is not empty to pass the assertion + // that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString. + if (!avatar_names.empty()) + { + LLAvatarActions::buildResidentsString(avatar_names, residents_string); + } +} //static std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs() { - std::set<LLUUID> inventory_selected_uuids; + std::set<LLFolderViewItem*> inventory_selected; LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel(); if (active_panel) { - inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); + inventory_selected= active_panel->getRootFolder()->getSelectionList(); } - if (inventory_selected_uuids.empty()) + if (inventory_selected.empty()) { LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); if (sidepanel_inventory) { - inventory_selected_uuids = sidepanel_inventory->getInboxOrOutboxSelectionList(); + inventory_selected= sidepanel_inventory->getInboxSelectionList(); } } + std::set<LLUUID> inventory_selected_uuids; + for (std::set<LLFolderViewItem*>::iterator it = inventory_selected.begin(), end_it = inventory_selected.end(); + it != end_it; + ++it) + { + inventory_selected_uuids.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID()); + } return inventory_selected_uuids; } //static -void LLAvatarActions::shareWithAvatars() +void LLAvatarActions::shareWithAvatars(LLView * panel) { using namespace action_give_inventory; + LLFloater* root_floater = gFloaterView->getParentFloater(panel); LLFloaterAvatarPicker* picker = - LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE); + LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE, FALSE, root_floater->getName()); + if (!picker) + { + return; + } + picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable)); picker->openFriendsTab(); + + if (root_floater) + { + root_floater->addDependentFloater(picker); + } LLNotificationsUtil::add("ShareNotification"); } @@ -739,15 +800,15 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL // check selection in the panel LLFolderView* root_folder = inv_panel->getRootFolder(); - const std::set<LLUUID> inventory_selected_uuids = root_folder->getSelectionList(); - if (inventory_selected_uuids.empty()) return false; // nothing selected + const std::set<LLFolderViewItem*> inventory_selected = root_folder->getSelectionList(); + if (inventory_selected.empty()) return false; // nothing selected bool can_share = true; - std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); - const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end(); + std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin(); + const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end(); for (; it != it_end; ++it) { - LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); + LLViewerInventoryCategory* inv_cat = gInventory.getCategory(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID()); // any category can be offered. if (inv_cat) { @@ -755,9 +816,9 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL } // check if inventory item can be given - LLFolderViewItem* item = root_folder->getItemByID(*it); + LLFolderViewItem* item = *it; if (!item) return false; - LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getListener()); + LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getViewModelItem()); if (bridge && bridge->canShare()) { continue; @@ -790,6 +851,26 @@ void LLAvatarActions::toggleBlock(const LLUUID& id) } // static +void LLAvatarActions::toggleMuteVoice(const LLUUID& id) +{ + std::string name; + gCacheName->getFullName(id, name); // needed for mute + + LLMuteList* mute_list = LLMuteList::getInstance(); + bool is_muted = mute_list->isMuted(id, LLMute::flagVoiceChat); + + LLMute mute(id, name, LLMute::AGENT); + if (!is_muted) + { + mute_list->add(mute, LLMute::flagVoiceChat); + } + else + { + mute_list->remove(mute, LLMute::flagVoiceChat); + } +} + +// static bool LLAvatarActions::canOfferTeleport(const LLUUID& id) { // First use LLAvatarTracker::isBuddy() @@ -835,6 +916,33 @@ void LLAvatarActions::inviteToGroup(const LLUUID& id) } } +// static +void LLAvatarActions::viewChatHistory(const LLUUID& id) +{ + const std::vector<LLConversation>& conversations = LLConversationLog::instance().getConversations(); + std::vector<LLConversation>::const_iterator iter = conversations.begin(); + + for (; iter != conversations.end(); ++iter) + { + if (iter->getParticipantID() == id) + { + LLFloaterReg::showInstance("preview_conversation", iter->getSessionID(), true); + return; + } + } + + if (LLLogChat::isTranscriptExist(id)) + { + LLAvatarName avatar_name; + LLSD extended_id(id); + + LLAvatarNameCache::get(id, &avatar_name); + extended_id[LL_FCP_COMPLETE_NAME] = avatar_name.getCompleteName(); + extended_id[LL_FCP_ACCOUNT_NAME] = avatar_name.getAccountName(); + LLFloaterReg::showInstance("preview_conversation", extended_id, true); + } +} + //== private methods ======================================================================================== // static @@ -877,7 +985,7 @@ bool LLAvatarActions::handlePay(const LLSD& notification, const LLSD& response, S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (option == 0) { - gAgent.clearBusy(); + gAgent.setDoNotDisturb(false); } LLFloaterPayUtil::payDirectly(&give_money, avatar_id, /*is_group=*/false); @@ -985,7 +1093,6 @@ void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::stri LLSD payload; payload["from_id"] = target_id; - payload["SUPPRESS_TOAST"] = true; LLNotificationsUtil::add("FriendshipOffered", args, payload); } @@ -1004,6 +1111,12 @@ bool LLAvatarActions::isBlocked(const LLUUID& id) } // static +bool LLAvatarActions::isVoiceMuted(const LLUUID& id) +{ + return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat); +} + +// static bool LLAvatarActions::canBlock(const LLUUID& id) { std::string full_name; diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 748b7cb3d1..6e1198cd09 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -34,8 +34,10 @@ #include <string> #include <vector> +class LLAvatarName; class LLInventoryPanel; class LLFloater; +class LLView; /** * Friend-related actions (add, remove, offer teleport, etc) @@ -81,14 +83,14 @@ public: static void startCall(const LLUUID& id); /** - * Start an ad-hoc conference voice call with multiple users + * Start an ad-hoc conference voice call with multiple users in a specific IM floater. */ - static void startAdhocCall(const uuid_vec_t& ids); + static void startAdhocCall(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null); /** - * Start conference chat with the given avatars. + * Start conference chat with the given avatars in a specific IM floater. */ - static void startConference(const uuid_vec_t& ids); + static void startConference(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null); /** * Show avatar profile. @@ -116,7 +118,7 @@ public: /** * Share items with the picked avatars. */ - static void shareWithAvatars(); + static void shareWithAvatars(LLView * panel); /** * Block/unblock the avatar. @@ -124,6 +126,11 @@ public: static void toggleBlock(const LLUUID& id); /** + * Block/unblock the avatar voice. + */ + static void toggleMuteVoice(const LLUUID& id); + + /** * Return true if avatar with "id" is a friend */ static bool isFriend(const LLUUID& id); @@ -134,6 +141,11 @@ public: static bool isBlocked(const LLUUID& id); /** + * @return true if the avatar voice is blocked + */ + static bool isVoiceMuted(const LLUUID& id); + + /** * @return true if you can block the avatar */ static bool canBlock(const LLUUID& id); @@ -198,6 +210,27 @@ public: */ static bool canShareSelectedItems(LLInventoryPanel* inv_panel = NULL); + /** + * Builds a string of residents' display names separated by "words_separator" string. + * + * @param avatar_names - a vector of given avatar names from which resulting string is built + * @param residents_string - the resulting string + */ + static void buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string); + + /** + * Builds a string of residents' display names separated by "words_separator" string. + * + * @param avatar_uuids - a vector of given avatar uuids from which resulting string is built + * @param residents_string - the resulting string + */ + static void buildResidentsString(const uuid_vec_t& avatar_uuids, std::string& residents_string); + + /** + * Opens the chat history for avatar + */ + static void viewChatHistory(const LLUUID& id); + static std::set<LLUUID> getInventorySelectedUUIDs(); private: diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 42e7decec1..714bde6f37 100644..100755 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -28,6 +28,8 @@ #include "llavatariconctrl.h" +#include <boost/signals2.hpp> + // viewer includes #include "llagent.h" #include "llavatarconstants.h" @@ -36,7 +38,7 @@ #include "llmenugl.h" #include "lluictrlfactory.h" #include "llagentdata.h" -#include "llimfloater.h" +#include "llfloaterimsession.h" // library includes #include "llavatarnamecache.h" @@ -75,6 +77,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); @@ -145,9 +150,13 @@ LLAvatarIconCtrl::Params::Params() LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p) -: LLIconCtrl(p), + : LLIconCtrl(p), + LLAvatarPropertiesObserver(), + mAvatarId(), + mFullName(), mDrawTooltip(p.draw_tooltip), - mDefaultIconName(p.default_icon_name) + mDefaultIconName(p.default_icon_name), + mAvatarNameCacheConnection() { mPriority = LLViewerFetchedTexture::BOOST_ICON; @@ -200,6 +209,11 @@ LLAvatarIconCtrl::~LLAvatarIconCtrl() LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId, this); // Name callbacks will be automatically disconnected since LLUICtrl is trackable } + + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } } //virtual @@ -242,9 +256,19 @@ void LLAvatarIconCtrl::setValue(const LLSD& value) LLIconCtrl::setValue(value); } - LLAvatarNameCache::get(mAvatarId, - boost::bind(&LLAvatarIconCtrl::onAvatarNameCache, - this, _1, _2)); + fetchAvatarName(); +} + +void LLAvatarIconCtrl::fetchAvatarName() +{ + if (mAvatarId.notNull()) + { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLAvatarIconCtrl::onAvatarNameCache, this, _1, _2)); + } } bool LLAvatarIconCtrl::updateFromCache() @@ -289,11 +313,13 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type) void LLAvatarIconCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) { + mAvatarNameCacheConnection.disconnect(); + if (agent_id == mAvatarId) { // Most avatar icon controls are next to a UI element that shows // a display name, so only show username. - mFullName = av_name.mUsername; + mFullName = av_name.getUserName(); if (mDrawTooltip) { diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h index 7f568fc5b8..4929efb7d0 100644 --- a/indra/newview/llavatariconctrl.h +++ b/indra/newview/llavatariconctrl.h @@ -27,7 +27,9 @@ #ifndef LL_LLAVATARICONCTRL_H #define LL_LLAVATARICONCTRL_H -#include "lliconctrl.h" +#include <boost/signals2.hpp> + +#include "../llui/lliconctrl.h" #include "llavatarpropertiesprocessor.h" #include "llviewermenu.h" @@ -86,20 +88,24 @@ public: // LLAvatarPropertiesProcessor observer trigger virtual void processProperties(void* data, EAvatarProcessorType type); - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); - const LLUUID& getAvatarId() const { return mAvatarId; } const std::string& getFullName() const { return mFullName; } void setDrawTooltip(bool value) { mDrawTooltip = value;} protected: - LLUUID mAvatarId; - std::string mFullName; - bool mDrawTooltip; - std::string mDefaultIconName; + LLUUID mAvatarId; + std::string mFullName; + bool mDrawTooltip; + std::string mDefaultIconName; bool updateFromCache(); + +private: + void fetchAvatarName(); + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + + boost::signals2::connection mAvatarNameCacheConnection; }; #endif // LL_LLAVATARICONCTRL_H diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 771419f60a..9f02f301a1 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -46,6 +46,7 @@ #include "lluuid.h" #include "llvoiceclient.h" #include "llviewercontrol.h" // for gSavedSettings +#include "lltooldraganddrop.h" static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list"); @@ -278,7 +279,7 @@ void LLAvatarList::refresh() LLAvatarName av_name; have_names &= LLAvatarNameCache::get(buddy_id, &av_name); - if (!have_filter || findInsensitive(av_name.mDisplayName, mNameFilter)) + if (!have_filter || findInsensitive(av_name.getDisplayName(), mNameFilter)) { if (nadded >= ADD_LIMIT) { @@ -296,8 +297,9 @@ void LLAvatarList::refresh() } else { + std::string display_name = av_name.getDisplayName(); addNewItem(buddy_id, - av_name.mDisplayName.empty() ? waiting_str : av_name.mDisplayName, + display_name.empty() ? waiting_str : display_name, LLAvatarTracker::instance().isBuddyOnline(buddy_id)); } @@ -325,7 +327,7 @@ void LLAvatarList::refresh() const LLUUID& buddy_id = it->asUUID(); LLAvatarName av_name; have_names &= LLAvatarNameCache::get(buddy_id, &av_name); - if (!findInsensitive(av_name.mDisplayName, mNameFilter)) + if (!findInsensitive(av_name.getDisplayName(), mNameFilter)) { removeItemByUUID(buddy_id); modified = true; @@ -398,7 +400,7 @@ bool LLAvatarList::filterHasMatches() // If name has not been loaded yet we consider it as a match. // When the name will be loaded the filter will be applied again(in refresh()). - if (have_name && !findInsensitive(av_name.mDisplayName, mNameFilter)) + if (have_name && !findInsensitive(av_name.getDisplayName(), mNameFilter)) { continue; } @@ -461,6 +463,57 @@ BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask) return handled; } +BOOL LLAvatarList::handleMouseDown(S32 x, S32 y, MASK mask) +{ + gFocusMgr.setMouseCapture(this); + + S32 screen_x; + S32 screen_y; + localPointToScreen(x, y, &screen_x, &screen_y); + LLToolDragAndDrop::getInstance()->setDragStart(screen_x, screen_y); + + return LLFlatListViewEx::handleMouseDown(x, y, mask); +} + +BOOL LLAvatarList::handleMouseUp( S32 x, S32 y, MASK mask ) +{ + if(hasMouseCapture()) + { + gFocusMgr.setMouseCapture(NULL); + } + + return LLFlatListViewEx::handleMouseUp(x, y, mask); +} + +BOOL LLAvatarList::handleHover(S32 x, S32 y, MASK mask) +{ + bool handled = hasMouseCapture(); + if(handled) + { + S32 screen_x; + S32 screen_y; + localPointToScreen(x, y, &screen_x, &screen_y); + + if(LLToolDragAndDrop::getInstance()->isOverThreshold(screen_x, screen_y)) + { + // First, create the global drag and drop object + std::vector<EDragAndDropType> types; + uuid_vec_t cargo_ids; + getSelectedUUIDs(cargo_ids); + types.resize(cargo_ids.size(), DAD_PERSON); + LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_PEOPLE; + LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src); + } + } + + if(!handled) + { + handled = LLFlatListViewEx::handleHover(x, y, mask); + } + + return handled; +} + bool LLAvatarList::isAvalineItemSelected() { std::vector<LLPanel*> selected_items; diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index 4814a88a79..3542577ae3 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -84,6 +84,9 @@ public: bool getIconsVisible() const { return mShowIcons; } const std::string getIconParamName() const{return mIconParamName;} virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); // Return true if filter has at least one match. bool filterHasMatches(); diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 30eecfe323..3e6c817dd6 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -27,6 +27,8 @@ #include "llviewerprecompiledheaders.h" +#include <boost/signals2.hpp> + #include "llavataractions.h" #include "llavatarlistitem.h" @@ -38,6 +40,7 @@ #include "llavatarnamecache.h" #include "llavatariconctrl.h" #include "lloutputmonitorctrl.h" +#include "lltooldraganddrop.h" bool LLAvatarListItem::sStaticInitialized = false; S32 LLAvatarListItem::sLeftPadding = 0; @@ -58,7 +61,8 @@ LLAvatarListItem::Params::Params() LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/) -: LLPanel(), + : LLPanel(), + LLFriendObserver(), mAvatarIcon(NULL), mAvatarName(NULL), mLastInteractionTime(NULL), @@ -73,7 +77,8 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/) mShowInfoBtn(true), mShowProfileBtn(true), mShowPermissions(false), - mHovered(false) + mHovered(false), + mAvatarNameCacheConnection() { if (not_from_ui_factory) { @@ -86,7 +91,14 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/) LLAvatarListItem::~LLAvatarListItem() { if (mAvatarId.notNull()) + { LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarId, this); + } + + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } } BOOL LLAvatarListItem::postBuild() @@ -129,6 +141,29 @@ BOOL LLAvatarListItem::postBuild() return TRUE; } +void LLAvatarListItem::handleVisibilityChange ( BOOL new_visibility ) +{ + //Adjust positions of icons (info button etc) when + //speaking indicator visibility was changed/toggled while panel was closed (not visible) + if(new_visibility && mSpeakingIndicator->getIndicatorToggled()) + { + updateChildren(); + mSpeakingIndicator->setIndicatorToggled(false); + } +} + +void LLAvatarListItem::fetchAvatarName() +{ + if (mAvatarId.notNull()) + { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2)); + } +} + S32 LLAvatarListItem::notifyParent(const LLSD& info) { if (info.has("visibility_changed")) @@ -259,8 +294,7 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id, const LLUUID& session_id, b mAvatarIcon->setValue(id); // Set avatar name. - LLAvatarNameCache::get(id, - boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2)); + fetchAvatarName(); } } @@ -358,8 +392,7 @@ std::string LLAvatarListItem::getAvatarToolTip() const void LLAvatarListItem::updateAvatarName() { - LLAvatarNameCache::get(getAvatarId(), - boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2)); + fetchAvatarName(); } //== PRIVATE SECITON ========================================================== @@ -371,8 +404,10 @@ void LLAvatarListItem::setNameInternal(const std::string& name, const std::strin void LLAvatarListItem::onAvatarNameCache(const LLAvatarName& av_name) { - setAvatarName(av_name.mDisplayName); - setAvatarToolTip(av_name.mUsername); + mAvatarNameCacheConnection.disconnect(); + + setAvatarName(av_name.getDisplayName()); + setAvatarToolTip(av_name.getUserName()); //requesting the list to resort notifyParent(LLSD().with("sort", LLSD())); diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index c95ac39696..7ef35a746e 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -27,6 +27,8 @@ #ifndef LL_LLAVATARLISTITEM_H #define LL_LLAVATARLISTITEM_H +#include <boost/signals2.hpp> + #include "llpanel.h" #include "lloutputmonitorctrl.h" #include "llbutton.h" @@ -82,6 +84,7 @@ public: /** * Processes notification from speaker indicator to update children when indicator's visibility is changed. */ + virtual void handleVisibilityChange ( BOOL new_visibility ); virtual S32 notifyParent(const LLSD& info); virtual void onMouseLeave(S32 x, S32 y, MASK mask); virtual void onMouseEnter(S32 x, S32 y, MASK mask); @@ -214,6 +217,9 @@ private: /// true when the mouse pointer is hovering over this item bool mHovered; + + void fetchAvatarName(); + boost::signals2::connection mAvatarNameCacheConnection; static bool sStaticInitialized; // this variable is introduced to improve code readability static S32 sLeftPadding; // padding to first left visible child (icon or name) diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index b1cd83a1fb..706bc42ea0 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -33,6 +33,7 @@ #include "llagentpicksinfo.h" #include "lldateutil.h" #include "llviewergenericmessage.h" +#include "llstartup.h" // Linden library includes #include "llavatarconstants.h" // AVATAR_TRANSACTED, etc. @@ -113,6 +114,14 @@ void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EA void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id) { + // this is the startup state when send_complete_agent_movement() message is sent. + // Before this, the AvatarPropertiesRequest message + // won't work so don't bother trying + if (LLStartUp::getStartupState() <= STATE_AGENT_SEND) + { + return; + } + if (isPendingRequest(avatar_id, APT_PROPERTIES)) { // waiting for a response, don't re-request diff --git a/indra/newview/llblockedlistitem.cpp b/indra/newview/llblockedlistitem.cpp new file mode 100644 index 0000000000..d9afd2b629 --- /dev/null +++ b/indra/newview/llblockedlistitem.cpp @@ -0,0 +1,114 @@ +/** + * @file llviewerobjectlistitem.cpp + * @brief viewer object list item implementation + * + * Class LLPanelInventoryListItemBase displays inventory item as an element + * of LLInventoryItemsList. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "llblockedlistitem.h" + +// llui +#include "lliconctrl.h" +#include "lltextbox.h" +#include "lltextutil.h" + +// newview +#include "llavatariconctrl.h" +#include "llgroupiconctrl.h" +#include "llinventoryicon.h" +#include "llviewerobject.h" + +LLBlockedListItem::LLBlockedListItem(const LLMute* item) +: LLPanel(), + mItemID(item->mID), + mItemName(item->mName), + mMuteType(item->mType) +{ + buildFromFile("panel_blocked_list_item.xml"); +} + +BOOL LLBlockedListItem::postBuild() +{ + mTitleCtrl = getChild<LLTextBox>("item_name"); + mTitleCtrl->setValue(mItemName); + + switch (mMuteType) + { + case LLMute::AGENT: + case LLMute::EXTERNAL: + { + LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon"); + avatar_icon->setVisible(TRUE); + avatar_icon->setValue(mItemID); + } + break; + case LLMute::GROUP: + { + LLGroupIconCtrl* group_icon = getChild<LLGroupIconCtrl>("group_icon"); + group_icon->setVisible(TRUE); + group_icon->setValue(mItemID); + } + break; + case LLMute::OBJECT: + case LLMute::BY_NAME: + getChild<LLUICtrl>("object_icon")->setVisible(TRUE); + break; + + default: + break; + } + + return TRUE; +} + +void LLBlockedListItem::onMouseEnter(S32 x, S32 y, MASK mask) +{ + getChildView("hovered_icon")->setVisible(true); + LLPanel::onMouseEnter(x, y, mask); +} + +void LLBlockedListItem::onMouseLeave(S32 x, S32 y, MASK mask) +{ + getChildView("hovered_icon")->setVisible(false); + LLPanel::onMouseLeave(x, y, mask); +} + +void LLBlockedListItem::setValue(const LLSD& value) +{ + if (!value.isMap() || !value.has("selected")) + { + return; + } + + getChildView("selected_icon")->setVisible(value["selected"]); +} + +void LLBlockedListItem::highlightName(const std::string& highlited_text) +{ + LLStyle::Params params; + LLTextUtil::textboxSetHighlightedVal(mTitleCtrl, params, mItemName, highlited_text); +} diff --git a/indra/newview/llblockedlistitem.h b/indra/newview/llblockedlistitem.h new file mode 100644 index 0000000000..05409e8a3b --- /dev/null +++ b/indra/newview/llblockedlistitem.h @@ -0,0 +1,73 @@ +/** + * @file llviewerobjectlistitem.h + * @brief viewer object list item header file + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 LLVIEWEROBJECTLISTITEM_H_ +#define LLVIEWEROBJECTLISTITEM_H_ + +#include "llmutelist.h" +#include "llpanel.h" +#include "llstyle.h" +#include "lltextbox.h" +#include "lliconctrl.h" + +/** + * This class represents items of LLBlockList, which represents + * contents of LLMuteList. LLMuteList "consists" of LLMute items. + * Each LLMute represents either blocked avatar or object and + * stores info about mute type (avatar or object) + * + * Each item consists if object/avatar icon and object/avatar name + * + * To create a blocked list item just need to pass LLMute pointer + * and appropriate block list item will be created depending on + * LLMute type (LLMute::EType) and other LLMute's info + */ +class LLBlockedListItem : public LLPanel +{ +public: + + LLBlockedListItem(const LLMute* item); + virtual BOOL postBuild(); + + void onMouseEnter(S32 x, S32 y, MASK mask); + void onMouseLeave(S32 x, S32 y, MASK mask); + + virtual void setValue(const LLSD& value); + + void highlightName(const std::string& highlited_text); + const std::string& getName() const { return mItemName; } + const LLMute::EType& getType() const { return mMuteType; } + const LLUUID& getUUID() const { return mItemID; } + +private: + + LLTextBox* mTitleCtrl; + const LLUUID mItemID; + std::string mItemName; + LLMute::EType mMuteType; + +}; + +#endif /* LLVIEWEROBJECTLISTITEM_H_ */ diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp new file mode 100644 index 0000000000..066cb71677 --- /dev/null +++ b/indra/newview/llblocklist.cpp @@ -0,0 +1,284 @@ +/** + * @file llblocklist.cpp + * @brief List of the blocked avatars and objects. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "llblocklist.h" + +#include "llavataractions.h" +#include "llblockedlistitem.h" +#include "llfloatersidepanelcontainer.h" +#include "llviewermenu.h" + +static LLDefaultChildRegistry::Register<LLBlockList> r("block_list"); + +static const LLBlockListNameComparator NAME_COMPARATOR; +static const LLBlockListNameTypeComparator NAME_TYPE_COMPARATOR; + +LLBlockList::LLBlockList(const Params& p) +: LLFlatListViewEx(p), + mSelectedItem(NULL), + mDirty(true) +{ + + LLMuteList::getInstance()->addObserver(this); + + // Set up context menu. + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + + registrar.add ("Block.Action", boost::bind(&LLBlockList::onCustomAction, this, _2)); + enable_registrar.add("Block.Enable", boost::bind(&LLBlockList::isActionEnabled, this, _2)); + + LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>( + "menu_people_blocked_gear.xml", + gMenuHolder, + LLViewerMenuHolderGL::child_registry_t::instance()); + if(context_menu) + { + mContextMenu = context_menu->getHandle(); + } +} + +LLBlockList::~LLBlockList() +{ + if (mContextMenu.get()) + { + mContextMenu.get()->die(); + } + + LLMuteList::getInstance()->removeObserver(this); +} + +BOOL LLBlockList::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask); + + LLToggleableMenu* context_menu = mContextMenu.get(); + if (context_menu && size()) + { + context_menu->buildDrawLabels(); + context_menu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(this, context_menu, x, y); + } + + return handled; +} + +void LLBlockList::setNameFilter(const std::string& filter) +{ + std::string filter_upper = filter; + LLStringUtil::toUpper(filter_upper); + if (mNameFilter != filter_upper) + { + mNameFilter = filter_upper; + setDirty(); + } +} + +void LLBlockList::sortByName() +{ + setComparator(&NAME_COMPARATOR); + sort(); +} + +void LLBlockList::sortByType() +{ + setComparator(&NAME_TYPE_COMPARATOR); + sort(); +} + +void LLBlockList::draw() +{ + if (mDirty) + { + refresh(); + } + + LLFlatListView::draw(); +} + +void LLBlockList::addNewItem(const LLMute* mute) +{ + LLBlockedListItem* item = new LLBlockedListItem(mute); + if (!mNameFilter.empty()) + { + item->highlightName(mNameFilter); + } + addItem(item, item->getUUID(), ADD_BOTTOM); +} + +void LLBlockList::refresh() +{ + bool have_filter = !mNameFilter.empty(); + + // save selection to restore it after list rebuilt + LLUUID selected = getSelectedUUID(); + + // calling refresh may be initiated by removing currently selected item + // so select next item and save the selection to restore it after list rebuilt + if (!selectNextItemPair(false, true)) + { + selectNextItemPair(true, true); + } + LLUUID next_selected = getSelectedUUID(); + + clear(); + + std::vector<LLMute> mutes = LLMuteList::instance().getMutes(); + std::vector<LLMute>::const_iterator mute_it = mutes.begin(); + + for (; mute_it != mutes.end(); ++mute_it) + { + if (have_filter && !findInsensitive(mute_it->mName, mNameFilter)) + continue; + + addNewItem(&*mute_it); + } + + if (getItemPair(selected)) + { + // restore previously selected item + selectItemPair(getItemPair(selected), true); + } + else if (getItemPair(next_selected)) + { + // previously selected item was removed, so select next item + selectItemPair(getItemPair(next_selected), true); + } + + // Sort the list. + sort(); + + setDirty(false); +} + +bool LLBlockList::findInsensitive(std::string haystack, const std::string& needle_upper) +{ + LLStringUtil::toUpper(haystack); + return haystack.find(needle_upper) != std::string::npos; +} + +LLBlockedListItem* LLBlockList::getBlockedItem() const +{ + LLPanel* panel = LLFlatListView::getSelectedItem(); + LLBlockedListItem* item = dynamic_cast<LLBlockedListItem*>(panel); + return item; +} + +bool LLBlockList::isActionEnabled(const LLSD& userdata) +{ + bool action_enabled = true; + + const std::string command_name = userdata.asString(); + + if ("profile_item" == command_name) + { + LLBlockedListItem* item = getBlockedItem(); + action_enabled = item && (LLMute::AGENT == item->getType()); + } + + if ("unblock_item" == command_name) + { + action_enabled = getSelectedItem() != NULL; + } + + return action_enabled; +} + +void LLBlockList::onCustomAction(const LLSD& userdata) +{ + if (!isActionEnabled(userdata)) + { + return; + } + + LLBlockedListItem* item = getBlockedItem(); + const std::string command_name = userdata.asString(); + + if ("unblock_item" == command_name) + { + LLMute mute(item->getUUID(), item->getName()); + LLMuteList::getInstance()->remove(mute); + } + else if ("profile_item" == command_name) + { + switch(item->getType()) + { + + case LLMute::AGENT: + LLAvatarActions::showProfile(item->getUUID()); + break; + + default: + break; + } + } +} + +bool LLBlockListItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const +{ + const LLBlockedListItem* blocked_item1 = dynamic_cast<const LLBlockedListItem*>(item1); + const LLBlockedListItem* blocked_item2 = dynamic_cast<const LLBlockedListItem*>(item2); + + if (!blocked_item1 || !blocked_item2) + { + llerror("blocked_item1 and blocked_item2 cannot be null", 0); + return true; + } + + return doCompare(blocked_item1, blocked_item2); +} + +bool LLBlockListNameComparator::doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const +{ + std::string name1 = blocked_item1->getName(); + std::string name2 = blocked_item2->getName(); + + LLStringUtil::toUpper(name1); + LLStringUtil::toUpper(name2); + + return name1 < name2; +} + +bool LLBlockListNameTypeComparator::doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const +{ + LLMute::EType type1 = blocked_item1->getType(); + LLMute::EType type2 = blocked_item2->getType(); + + // if mute type is LLMute::BY_NAME or LLMute::OBJECT it means that this mute is an object + bool both_mutes_are_objects = (LLMute::OBJECT == type1 || LLMute::BY_NAME == type1) && (LLMute::OBJECT == type2 || LLMute::BY_NAME == type2); + + // mute types may be different, but since both LLMute::BY_NAME and LLMute::OBJECT types represent objects + // it's needed to perform additional checking of both_mutes_are_objects variable + if (type1 != type2 && !both_mutes_are_objects) + { + // objects in block list go first, so return true if mute type is not an avatar + return LLMute::AGENT != type1; + } + + return NAME_COMPARATOR.compare(blocked_item1, blocked_item2); +} diff --git a/indra/newview/llblocklist.h b/indra/newview/llblocklist.h new file mode 100644 index 0000000000..1a215710f4 --- /dev/null +++ b/indra/newview/llblocklist.h @@ -0,0 +1,138 @@ +/** + * @file llblocklist.h + * @brief List of the blocked avatars and objects. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 LLBLOCKLIST_H_ +#define LLBLOCKLIST_H_ + +#include "llflatlistview.h" +#include "lllistcontextmenu.h" +#include "llmutelist.h" +#include "lltoggleablemenu.h" + +class LLBlockedListItem; +class LLMute; + +/** + * List of blocked avatars and objects. + * This list represents contents of the LLMuteList. + * Each change in LLMuteList leads to rebuilding this list, so + * it's always in actual state. + */ +class LLBlockList: public LLFlatListViewEx, public LLMuteListObserver +{ + LOG_CLASS(LLBlockList); +public: + struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params> + { + Params(){}; + }; + + LLBlockList(const Params& p); + virtual ~LLBlockList(); + + virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + LLToggleableMenu* getContextMenu() const { return mContextMenu.get(); } + LLBlockedListItem* getBlockedItem() const; + + virtual void onChange() { refresh(); } + virtual void draw(); + + void setNameFilter(const std::string& filter); + void sortByName(); + void sortByType(); + void refresh(); + +private: + + void addNewItem(const LLMute* mute); + void setDirty(bool dirty = true) { mDirty = dirty; } + bool findInsensitive(std::string haystack, const std::string& needle_upper); + + bool isActionEnabled(const LLSD& userdata); + void onCustomAction (const LLSD& userdata); + + + LLHandle<LLToggleableMenu> mContextMenu; + + LLBlockedListItem* mSelectedItem; + std::string mNameFilter; + bool mDirty; + +}; + + +/* + * Abstract comparator for blocked items + */ +class LLBlockListItemComparator : public LLFlatListView::ItemComparator +{ + LOG_CLASS(LLBlockListItemComparator); + +public: + LLBlockListItemComparator() {}; + virtual ~LLBlockListItemComparator() {}; + + virtual bool compare(const LLPanel* item1, const LLPanel* item2) const; + +protected: + + virtual bool doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const = 0; +}; + + +/* + * Compares items by name + */ +class LLBlockListNameComparator : public LLBlockListItemComparator +{ + LOG_CLASS(LLBlockListNameComparator); + +public: + LLBlockListNameComparator() {}; + virtual ~LLBlockListNameComparator() {}; + +protected: + + virtual bool doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const; +}; + +/* + * Compares items by type and then by name within type + * Objects come first then avatars + */ +class LLBlockListNameTypeComparator : public LLBlockListItemComparator +{ + LOG_CLASS(LLBlockListNameTypeComparator); + +public: + LLBlockListNameTypeComparator() {}; + virtual ~LLBlockListNameTypeComparator() {}; + +protected: + + virtual bool doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const; +}; + +#endif /* LLBLOCKLIST_H_ */ diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp index 6e77d1e336..19747757db 100644 --- a/indra/newview/llbrowsernotification.cpp +++ b/indra/newview/llbrowsernotification.cpp @@ -35,11 +35,13 @@ using namespace LLNotificationsUI; -bool LLBrowserNotification::processNotification(const LLSD& notify) +LLBrowserNotification::LLBrowserNotification() + : LLSystemNotificationHandler("Browser", "browser") { - LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - if (!notification) return false; +} +bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification) +{ LLUUID media_id = notification->getPayload()["media_id"].asUUID(); LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id); if (media_instance) diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp deleted file mode 100644 index e3217668c5..0000000000 --- a/indra/newview/llcallfloater.cpp +++ /dev/null @@ -1,820 +0,0 @@ -/** - * @file llcallfloater.cpp - * @author Mike Antipov - * @brief Voice Control Panel in a Voice Chats (P2P, Group, Nearby...). - * - * $LicenseInfo:firstyear=2009&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 "llcallfloater.h" - -#include "llnotificationsutil.h" -#include "lltrans.h" - -#include "llagent.h" -#include "llagentdata.h" // for gAgentID -#include "llavatarnamecache.h" -#include "llavatariconctrl.h" -#include "llavatarlist.h" -#include "lldraghandle.h" -#include "llimfloater.h" -#include "llimview.h" -#include "llfloaterreg.h" -#include "llparticipantlist.h" -#include "llspeakers.h" -#include "lltextutil.h" -#include "lltransientfloatermgr.h" -#include "llviewercontrol.h" -#include "llviewerdisplayname.h" -#include "llviewerwindow.h" -#include "llvoicechannel.h" -#include "llviewerparcelmgr.h" -#include "llfirstuse.h" - -static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids); -void reshape_floater(LLCallFloater* floater, S32 delta_height); - -class LLNonAvatarCaller : public LLAvatarListItem -{ -public: - LLNonAvatarCaller() : LLAvatarListItem(false) - { - - } - BOOL postBuild() - { - BOOL rv = LLAvatarListItem::postBuild(); - - if (rv) - { - setOnline(true); - showLastInteractionTime(false); - setShowProfileBtn(false); - setShowInfoBtn(false); - mAvatarIcon->setValue("Avaline_Icon"); - mAvatarIcon->setToolTip(std::string("")); - } - return rv; - } - - void setName(const std::string& name) - { - const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name); - LLAvatarListItem::setAvatarName(formatted_phone); - LLAvatarListItem::setAvatarToolTip(formatted_phone); - } - - void setSpeakerId(const LLUUID& id) { mSpeakingIndicator->setSpeakerId(id); } -}; - - -static void* create_non_avatar_caller(void*) -{ - return new LLNonAvatarCaller; -} - -LLVoiceChannel* LLCallFloater::sCurrentVoiceChannel = NULL; - -LLCallFloater::LLCallFloater(const LLSD& key) -: LLTransientDockableFloater(NULL, false, key) -, mSpeakerManager(NULL) -, mParticipants(NULL) -, mAvatarList(NULL) -, mNonAvatarCaller(NULL) -, mVoiceType(VC_LOCAL_CHAT) -, mAgentPanel(NULL) -, mSpeakingIndicator(NULL) -, mIsModeratorMutedVoice(false) -, mInitParticipantsVoiceState(false) -{ - static LLUICachedControl<S32> voice_left_remove_delay ("VoiceParticipantLeftRemoveDelay", 10); - mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), voice_left_remove_delay); - - mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL); - LLVoiceClient::instance().addObserver(this); - LLTransientFloaterMgr::getInstance()->addControlView(this); - - // update the agent's name if display name setting change - LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLCallFloater::updateAgentModeratorState, this)); - LLViewerDisplayName::addNameChangedCallback(boost::bind(&LLCallFloater::updateAgentModeratorState, this)); - -} - -LLCallFloater::~LLCallFloater() -{ - resetVoiceRemoveTimers(); - delete mSpeakerDelayRemover; - - delete mParticipants; - mParticipants = NULL; - - mAvatarListRefreshConnection.disconnect(); - mVoiceChannelStateChangeConnection.disconnect(); - - if(LLVoiceClient::instanceExists()) - { - LLVoiceClient::getInstance()->removeObserver(this); - } - LLTransientFloaterMgr::getInstance()->removeControlView(this); -} - -// virtual -BOOL LLCallFloater::postBuild() -{ - mAvatarList = getChild<LLAvatarList>("speakers_list"); - mAvatarListRefreshConnection = mAvatarList->setRefreshCompleteCallback(boost::bind(&LLCallFloater::onAvatarListRefreshed, this)); - - childSetAction("leave_call_btn", boost::bind(&LLCallFloater::leaveCall, this)); - - mNonAvatarCaller = findChild<LLNonAvatarCaller>("non_avatar_caller"); - mNonAvatarCaller->setVisible(FALSE); - - initAgentData(); - - connectToChannel(LLVoiceChannel::getCurrentVoiceChannel()); - - updateTransparency(TT_ACTIVE); // force using active floater transparency (STORM-730) - - updateSession(); - return TRUE; -} - -// virtual -void LLCallFloater::onOpen(const LLSD& /*key*/) -{ - LLFirstUse::speak(false); -} - -// virtual -void LLCallFloater::draw() -{ - // we have to refresh participants to display ones not in voice as disabled. - // It should be done only when she joins or leaves voice chat. - // But seems that LLVoiceClientParticipantObserver is not enough to satisfy this requirement. - // *TODO: mantipov: remove from draw() - - // NOTE: it looks like calling onChange() here is not necessary, - // but sometime it is not called properly from the observable object. - // Seems this is a problem somewhere in Voice Client (LLVoiceClient::participantAddedEvent) -// onChange(); - - bool is_moderator_muted = LLVoiceClient::getInstance()->getIsModeratorMuted(gAgentID); - - if (mIsModeratorMutedVoice != is_moderator_muted) - { - setModeratorMutedVoice(is_moderator_muted); - } - - // Need to resort the participant list if it's in sort by recent speaker order. - if (mParticipants) - mParticipants->updateRecentSpeakersOrder(); - - LLFloater::draw(); -} - -// virtual -void LLCallFloater::setFocus( BOOL b ) -{ - LLFloater::setFocus(b); - - // Force using active floater transparency (STORM-730). - // We have to override setFocus() for LLCallFloater because selecting an item - // of the voice morphing combobox causes the floater to lose focus and thus become transparent. - updateTransparency(TT_ACTIVE); -} - -// virtual -void LLCallFloater::onParticipantsChanged() -{ - if (NULL == mParticipants) return; - updateParticipantsVoiceState(); - - // Add newly joined participants. - uuid_vec_t speakers_uuids; - get_voice_participants_uuids(speakers_uuids); - for (uuid_vec_t::const_iterator it = speakers_uuids.begin(); it != speakers_uuids.end(); it++) - { - mParticipants->addAvatarIDExceptAgent(*it); - } -} - -////////////////////////////////////////////////////////////////////////// -/// PRIVATE SECTION -////////////////////////////////////////////////////////////////////////// - -void LLCallFloater::leaveCall() -{ - LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel(); - if (voice_channel) - { - gIMMgr->endCall(voice_channel->getSessionID()); - } -} - -void LLCallFloater::updateSession() -{ - LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel(); - if (voice_channel) - { - LL_DEBUGS("Voice") << "Current voice channel: " << voice_channel->getSessionID() << LL_ENDL; - - if (mSpeakerManager && voice_channel->getSessionID() == mSpeakerManager->getSessionID()) - { - LL_DEBUGS("Voice") << "Speaker manager is already set for session: " << voice_channel->getSessionID() << LL_ENDL; - return; - } - else - { - mSpeakerManager = NULL; - } - } - - const LLUUID& session_id = voice_channel ? voice_channel->getSessionID() : LLUUID::null; - - LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id); - if (im_session) - { - mSpeakerManager = LLIMModel::getInstance()->getSpeakerManager(session_id); - switch (im_session->mType) - { - case IM_NOTHING_SPECIAL: - case IM_SESSION_P2P_INVITE: - mVoiceType = VC_PEER_TO_PEER; - - if (!im_session->mOtherParticipantIsAvatar) - { - mVoiceType = VC_PEER_TO_PEER_AVALINE; - } - break; - case IM_SESSION_CONFERENCE_START: - case IM_SESSION_GROUP_START: - case IM_SESSION_INVITE: - if (gAgent.isInGroup(session_id)) - { - mVoiceType = VC_GROUP_CHAT; - } - else - { - mVoiceType = VC_AD_HOC_CHAT; - } - break; - default: - llwarning("Failed to determine voice call IM type", 0); - mVoiceType = VC_GROUP_CHAT; - break; - } - } - - if (NULL == mSpeakerManager) - { - // By default show nearby chat participants - mSpeakerManager = LLLocalSpeakerMgr::getInstance(); - LL_DEBUGS("Voice") << "Set DEFAULT speaker manager" << LL_ENDL; - mVoiceType = VC_LOCAL_CHAT; - } - - updateTitle(); - - // Hide "Leave Call" button for nearby chat - bool is_local_chat = mVoiceType == VC_LOCAL_CHAT; - getChildView("leave_call_btn_panel")->setVisible( !is_local_chat); - - refreshParticipantList(); - updateAgentModeratorState(); - - // Show floater for voice calls & only in CONNECTED to voice channel state - if (!is_local_chat && - voice_channel && - LLVoiceChannel::STATE_CONNECTED == voice_channel->getState()) - { - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); - bool show_me = !(im_floater && im_floater->getVisible()); - if (show_me) - { - setVisible(true); - } - } -} - -void LLCallFloater::refreshParticipantList() -{ - bool non_avatar_caller = VC_PEER_TO_PEER_AVALINE == mVoiceType; - - if (non_avatar_caller) - { - LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSpeakerManager->getSessionID()); - mNonAvatarCaller->setSpeakerId(session->mOtherParticipantID); - mNonAvatarCaller->setName(session->mName); - } - - mNonAvatarCaller->setVisible(non_avatar_caller); - mAvatarList->setVisible(!non_avatar_caller); - - if (!non_avatar_caller) - { - mParticipants = new LLParticipantList(mSpeakerManager, mAvatarList, true, mVoiceType != VC_GROUP_CHAT && mVoiceType != VC_AD_HOC_CHAT, false); - mParticipants->setValidateSpeakerCallback(boost::bind(&LLCallFloater::validateSpeaker, this, _1)); - const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder"); - mParticipants->setSortOrder(LLParticipantList::EParticipantSortOrder(speaker_sort_order)); - - if (LLLocalSpeakerMgr::getInstance() == mSpeakerManager) - { - mAvatarList->setNoItemsCommentText(getString("no_one_near")); - } - - // we have to made delayed initialization of voice state of participant list. - // it will be performed after first LLAvatarList refreshing in the onAvatarListRefreshed(). - mInitParticipantsVoiceState = true; - } -} - -void LLCallFloater::onAvatarListRefreshed() -{ - if (mInitParticipantsVoiceState) - { - initParticipantsVoiceState(); - mInitParticipantsVoiceState = false; - } - else - { - updateParticipantsVoiceState(); - } -} - -// static -void LLCallFloater::sOnCurrentChannelChanged(const LLUUID& /*session_id*/) -{ - LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel(); - - // *NOTE: if signal was sent for voice channel with LLVoiceChannel::STATE_NO_CHANNEL_INFO - // it sill be sent for the same channel again (when state is changed). - // So, lets ignore this call. - if (channel == sCurrentVoiceChannel) return; - - LLCallFloater* call_floater = LLFloaterReg::getTypedInstance<LLCallFloater>("voice_controls"); - - call_floater->connectToChannel(channel); -} - -void LLCallFloater::onAvatarNameCache(const LLUUID& agent_id, - const LLAvatarName& av_name) -{ - LLStringUtil::format_map_t args; - args["[NAME]"] = av_name.getCompleteName(); - std::string title = getString("title_peer_2_peer", args); - setTitle(title); -} - -void LLCallFloater::updateTitle() -{ - LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel(); - if (mVoiceType == VC_PEER_TO_PEER) - { - LLUUID session_id = voice_channel->getSessionID(); - LLIMModel::LLIMSession* im_session = - LLIMModel::getInstance()->findIMSession(session_id); - if (im_session) - { - LLAvatarNameCache::get(im_session->mOtherParticipantID, - boost::bind(&LLCallFloater::onAvatarNameCache, - this, _1, _2)); - return; - } - } - std::string title; - switch (mVoiceType) - { - case VC_LOCAL_CHAT: - title = getString("title_nearby"); - break; - case VC_PEER_TO_PEER: - case VC_PEER_TO_PEER_AVALINE: - { - title = voice_channel->getSessionName(); - - if (VC_PEER_TO_PEER_AVALINE == mVoiceType) - { - title = LLTextUtil::formatPhoneNumber(title); - } - - LLStringUtil::format_map_t args; - args["[NAME]"] = title; - title = getString("title_peer_2_peer", args); - } - break; - case VC_AD_HOC_CHAT: - title = getString("title_adhoc"); - break; - case VC_GROUP_CHAT: - { - LLStringUtil::format_map_t args; - args["[GROUP]"] = voice_channel->getSessionName(); - title = getString("title_group", args); - } - break; - } - - setTitle(title); -} - -void LLCallFloater::initAgentData() -{ - mAgentPanel = getChild<LLPanel> ("my_panel"); - - if ( mAgentPanel ) - { - mAgentPanel->getChild<LLUICtrl>("user_icon")->setValue(gAgentID); - - // Just use display name, because it's you - LLAvatarName av_name; - LLAvatarNameCache::get( gAgentID, &av_name ); - mAgentPanel->getChild<LLUICtrl>("user_text")->setValue(av_name.mDisplayName); - - mSpeakingIndicator = mAgentPanel->getChild<LLOutputMonitorCtrl>("speaking_indicator"); - mSpeakingIndicator->setSpeakerId(gAgentID); - } -} - -void LLCallFloater::setModeratorMutedVoice(bool moderator_muted) -{ - mIsModeratorMutedVoice = moderator_muted; - - if (moderator_muted) - { - LLNotificationsUtil::add("VoiceIsMutedByModerator"); - } - mSpeakingIndicator->setIsMuted(moderator_muted); -} - -void LLCallFloater::onModeratorNameCache(const LLAvatarName& av_name) -{ - std::string name; - name = av_name.mDisplayName; - - if(mSpeakerManager && gAgent.isInGroup(mSpeakerManager->getSessionID())) - { - // This method can be called when LLVoiceChannel.mState == STATE_NO_CHANNEL_INFO - // in this case there are not any speakers yet. - if (mSpeakerManager->findSpeaker(gAgentID)) - { - // Agent is Moderator - if (mSpeakerManager->findSpeaker(gAgentID)->mIsModerator) - - { - const std::string moderator_indicator(LLTrans::getString("IM_moderator_label")); - name += " " + moderator_indicator; - } - } - } - mAgentPanel->getChild<LLUICtrl>("user_text")->setValue(name); -} - -void LLCallFloater::updateAgentModeratorState() -{ - LLAvatarNameCache::get(gAgentID, boost::bind(&LLCallFloater::onModeratorNameCache, this, _2)); -} - -static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids) -{ - // Get a list of participants from VoiceClient - std::set<LLUUID> participants; - LLVoiceClient::getInstance()->getParticipantList(participants); - - for (std::set<LLUUID>::const_iterator iter = participants.begin(); - iter != participants.end(); ++iter) - { - speakers_uuids.push_back(*iter); - } - -} - -void LLCallFloater::initParticipantsVoiceState() -{ - // Set initial status for each participant in the list. - std::vector<LLPanel*> items; - mAvatarList->getItems(items); - std::vector<LLPanel*>::const_iterator - it = items.begin(), - it_end = items.end(); - - - uuid_vec_t speakers_uuids; - get_voice_participants_uuids(speakers_uuids); - - for(; it != it_end; ++it) - { - LLAvatarListItem *item = dynamic_cast<LLAvatarListItem*>(*it); - - if (!item) continue; - - LLUUID speaker_id = item->getAvatarId(); - - uuid_vec_t::const_iterator speaker_iter = std::find(speakers_uuids.begin(), speakers_uuids.end(), speaker_id); - - // If an avatarID assigned to a panel is found in a speakers list - // obtained from VoiceClient we assign the JOINED status to the owner - // of this avatarID. - if (speaker_iter != speakers_uuids.end()) - { - setState(item, STATE_JOINED); - } - else - { - LLPointer<LLSpeaker> speakerp = mSpeakerManager->findSpeaker(speaker_id); - // If someone has already left the call before, we create his - // avatar row panel with HAS_LEFT status and remove it after - // the timeout, otherwise we create a panel with INVITED status - if (speakerp.notNull() && speakerp.get()->mHasLeftCurrentCall) - { - setState(item, STATE_LEFT); - } - else - { - setState(item, STATE_INVITED); - } - } - } -} - -void LLCallFloater::updateParticipantsVoiceState() -{ - uuid_vec_t speakers_list; - - // Get a list of participants from VoiceClient - uuid_vec_t speakers_uuids; - get_voice_participants_uuids(speakers_uuids); - - // Updating the status for each participant already in list. - std::vector<LLPanel*> items; - mAvatarList->getItems(items); - std::vector<LLPanel*>::const_iterator - it = items.begin(), - it_end = items.end(); - - for(; it != it_end; ++it) - { - LLAvatarListItem *item = dynamic_cast<LLAvatarListItem*>(*it); - if (!item) continue; - - const LLUUID participant_id = item->getAvatarId(); - bool found = false; - - uuid_vec_t::iterator speakers_iter = std::find(speakers_uuids.begin(), speakers_uuids.end(), participant_id); - - LL_DEBUGS("Voice") << "processing speaker: " << item->getAvatarName() << ", " << item->getAvatarId() << LL_ENDL; - - // If an avatarID assigned to a panel is found in a speakers list - // obtained from VoiceClient we assign the JOINED status to the owner - // of this avatarID. - if (speakers_iter != speakers_uuids.end()) - { - setState(item, STATE_JOINED); - - LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(participant_id); - if (speaker.isNull()) - continue; - speaker->mHasLeftCurrentCall = FALSE; - - speakers_uuids.erase(speakers_iter); - found = true; - } - - if (!found) - { - updateNotInVoiceParticipantState(item); - } - } -} - -void LLCallFloater::updateNotInVoiceParticipantState(LLAvatarListItem* item) -{ - LLUUID participant_id = item->getAvatarId(); - ESpeakerState current_state = getState(participant_id); - - switch (current_state) - { - case STATE_JOINED: - // If an avatarID is not found in a speakers list from VoiceClient and - // a panel with this ID has a JOINED status this means that this person - // HAS LEFT the call. - setState(item, STATE_LEFT); - - { - LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(participant_id); - if (speaker.notNull()) - { - speaker->mHasLeftCurrentCall = TRUE; - } - } - break; - case STATE_LEFT: - // nothing to do. These states should not be changed. - break; - case STATE_INVITED: - // If avatar was invited into group chat and went offline it is still exists in mSpeakerStateMap - // If it goes online it will be rendered as JOINED via LAvatarListItem. - // Lets update its visual representation. See EXT-6660 - case STATE_UNKNOWN: - // If an avatarID is not found in a speakers list from VoiceClient and - // a panel with this ID has an UNKNOWN status this means that this person - // HAS ENTERED session but it is not in voice chat yet. So, set INVITED status - setState(item, STATE_INVITED); - break; - default: - // for possible new future states. - llwarns << "Unsupported (" << getState(participant_id) << ") state for: " << item->getAvatarName() << llendl; - break; - } -} - -void LLCallFloater::setState(LLAvatarListItem* item, ESpeakerState state) -{ - // *HACK: mantipov: sometimes such situation is possible while switching to voice channel: -/* - - voice channel is switched to the one user is joining - - participant list is initialized with voice states: agent is in voice - - than such log messages were found (with agent UUID) - - LLVivoxProtocolParser::process_impl: parsing: <Response requestId="22" action="Session.MediaDisconnect.1"><ReturnCode>0</ReturnCode><Results><StatusCode>0</StatusCode><StatusString /></Results><InputXml><Request requestId="22" action="Session.MediaDisconnect.1"><SessionGroupHandle>9</SessionGroupHandle><SessionHandle>12</SessionHandle><Media>Audio</Media></Request></InputXml></Response> - - LLVoiceClient::sessionState::removeParticipant: participant "sip:x2pwNkMbpR_mK4rtB_awASA==@bhr.vivox.com" (da9c0d90-c6e9-47f9-8ae2-bb41fdac0048) removed. - - and than while updating participants voice states agent is marked as HAS LEFT - - next updating of LLVoiceClient state makes agent JOINED - So, lets skip HAS LEFT state for agent's avatar -*/ - if (STATE_LEFT == state && item->getAvatarId() == gAgentID) return; - - setState(item->getAvatarId(), state); - - switch (state) - { - case STATE_INVITED: - item->setState(LLAvatarListItem::IS_VOICE_INVITED); - break; - case STATE_JOINED: - removeVoiceRemoveTimer(item->getAvatarId()); - item->setState(LLAvatarListItem::IS_VOICE_JOINED); - break; - case STATE_LEFT: - { - setVoiceRemoveTimer(item->getAvatarId()); - item->setState(LLAvatarListItem::IS_VOICE_LEFT); - } - break; - default: - llwarns << "Unrecognized avatar panel state (" << state << ")" << llendl; - break; - } -} - -void LLCallFloater::setVoiceRemoveTimer(const LLUUID& voice_speaker_id) -{ - mSpeakerDelayRemover->setActionTimer(voice_speaker_id); -} - -bool LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id) -{ - uuid_vec_t& speaker_uuids = mAvatarList->getIDs(); - uuid_vec_t::iterator pos = std::find(speaker_uuids.begin(), speaker_uuids.end(), voice_speaker_id); - if(pos != speaker_uuids.end()) - { - speaker_uuids.erase(pos); - mAvatarList->setDirty(); - } - - return false; -} - - -void LLCallFloater::resetVoiceRemoveTimers() -{ - mSpeakerDelayRemover->removeAllTimers(); -} - -void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id) -{ - mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id); -} - -bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id) -{ - bool is_valid = true; - switch (mVoiceType) - { - case VC_LOCAL_CHAT: - { - // A nearby chat speaker is considered valid it it's known to LLVoiceClient (i.e. has enabled voice). - uuid_vec_t speakers; - get_voice_participants_uuids(speakers); - is_valid = std::find(speakers.begin(), speakers.end(), speaker_id) != speakers.end(); - } - break; - case VC_GROUP_CHAT: - // if participant had left this call before do not allow add her again. See EXT-4216. - // but if she Join she will be added into the list from the LLCallFloater::onChange() - is_valid = STATE_LEFT != getState(speaker_id); - break; - default: - // do nothing. required for Linux build - break; - } - - return is_valid; -} - -void LLCallFloater::connectToChannel(LLVoiceChannel* channel) -{ - mVoiceChannelStateChangeConnection.disconnect(); - - sCurrentVoiceChannel = channel; - - mVoiceChannelStateChangeConnection = sCurrentVoiceChannel->setStateChangedCallback(boost::bind(&LLCallFloater::onVoiceChannelStateChanged, this, _1, _2)); - - updateState(channel->getState()); -} - -void LLCallFloater::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state) -{ - // check is voice operational and if it doesn't work hide VCP (EXT-4397) - if(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking()) - { - updateState(new_state); - } - else - { - closeFloater(); - } -} - -void LLCallFloater::updateState(const LLVoiceChannel::EState& new_state) -{ - LL_DEBUGS("Voice") << "Updating state: " << new_state << ", session name: " << sCurrentVoiceChannel->getSessionName() << LL_ENDL; - if (LLVoiceChannel::STATE_CONNECTED == new_state) - { - updateSession(); - } - else - { - reset(new_state); - } -} - -void LLCallFloater::reset(const LLVoiceChannel::EState& new_state) -{ - // lets forget states from the previous session - // for timers... - resetVoiceRemoveTimers(); - - // ...and for speaker state - mSpeakerStateMap.clear(); - - delete mParticipants; - mParticipants = NULL; - mAvatarList->clear(); - - // These ifs were added instead of simply showing "loading" to make VCP work correctly in parcels - // with disabled voice (EXT-4648 and EXT-4649) - if (!LLViewerParcelMgr::getInstance()->allowAgentVoice() && LLVoiceChannel::STATE_HUNG_UP == new_state) - { - // hides "Leave Call" when call is ended in parcel with disabled voice- hiding usually happens in - // updateSession() which won't be called here because connect to nearby voice never happens - getChildView("leave_call_btn_panel")->setVisible( false); - // setting title to nearby chat an "no one near..." text- because in region with disabled - // voice we won't have chance to really connect to nearby, so VCP is changed here manually - setTitle(getString("title_nearby")); - mAvatarList->setNoItemsCommentText(getString("no_one_near")); - } - // "loading" is shown only when state is "ringing" to avoid showing it in nearby chat vcp - // of parcels with disabled voice all the time- "no_one_near" is now shown there (EXT-4648) - else if (new_state == LLVoiceChannel::STATE_RINGING) - { - // update floater to show Loading while waiting for data. - mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData")); - } - - mAvatarList->setVisible(TRUE); - mNonAvatarCaller->setVisible(FALSE); - - mSpeakerManager = NULL; -} - -//EOF diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h deleted file mode 100644 index 00a3f76e56..0000000000 --- a/indra/newview/llcallfloater.h +++ /dev/null @@ -1,273 +0,0 @@ -/** - * @file llcallfloater.h - * @author Mike Antipov - * @brief Voice Control Panel in a Voice Chats (P2P, Group, Nearby...). - * - * $LicenseInfo:firstyear=2009&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_LLCALLFLOATER_H -#define LL_LLCALLFLOATER_H - -#include "lltransientdockablefloater.h" -#include "llvoicechannel.h" -#include "llvoiceclient.h" - -class LLAvatarList; -class LLAvatarListItem; -class LLAvatarName; -class LLNonAvatarCaller; -class LLOutputMonitorCtrl; -class LLParticipantList; -class LLSpeakerMgr; -class LLSpeakersDelayActionsStorage; - -/** - * The Voice Control Panel is an ambient window summoned by clicking the flyout chevron - * on the Speak button. It can be torn-off and freely positioned onscreen. - * - * When the Resident is engaged in Voice Chat, the Voice Control Panel provides control - * over the audible volume of each of the other participants, the Resident's own Voice - * Morphing settings (if she has subscribed to enable the feature), and Voice Recording. - * - * When the Resident is engaged in any chat except Nearby Chat, the Voice Control Panel - * also provides a 'Leave Call' button to allow the Resident to leave that voice channel. - */ -class LLCallFloater : public LLTransientDockableFloater, LLVoiceClientParticipantObserver -{ -public: - - LOG_CLASS(LLCallFloater); - - LLCallFloater(const LLSD& key); - ~LLCallFloater(); - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void draw(); - /*virtual*/ void setFocus( BOOL b ); - - /** - * Is called by LLVoiceClient::notifyParticipantObservers when voice participant list is changed. - * - * Refreshes list to display participants not in voice as disabled. - */ - /*virtual*/ void onParticipantsChanged(); - - static void sOnCurrentChannelChanged(const LLUUID& session_id); - -private: - typedef enum e_voice_controls_type - { - VC_LOCAL_CHAT, - VC_GROUP_CHAT, - VC_AD_HOC_CHAT, - VC_PEER_TO_PEER, - VC_PEER_TO_PEER_AVALINE - }EVoiceControls; - - typedef enum e_speaker_state - { - STATE_UNKNOWN, - STATE_INVITED, - STATE_JOINED, - STATE_LEFT, - } ESpeakerState; - - typedef std::map<LLUUID, ESpeakerState> speaker_state_map_t; - - void leaveCall(); - - /** - * Updates mSpeakerManager and list according to current Voice Channel - * - * It compares mSpeakerManager & current Voice Channel session IDs. - * If they are different gets Speaker manager related to current channel and updates channel participant list. - */ - void updateSession(); - - /** - * Refreshes participant list according to current Voice Channel - */ - void refreshParticipantList(); - - /** - * Handles event on avatar list is refreshed after it was marked dirty. - * - * It sets initial participants voice states (once after the first refreshing) - * and updates voice states each time anybody is joined/left voice chat in session. - */ - void onAvatarListRefreshed(); - - /** - * Updates window title with an avatar name - */ - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); - - void updateTitle(); - void initAgentData(); - void setModeratorMutedVoice(bool moderator_muted); - void updateAgentModeratorState(); - void onModeratorNameCache(const LLAvatarName& av_name); - - /** - * Sets initial participants voice states in avatar list (Invited, Joined, Has Left). - * - * @see refreshParticipantList() - * @see onAvatarListRefreshed() - * @see mInitParticipantsVoiceState - */ - void initParticipantsVoiceState(); - - /** - * Updates participants voice states in avatar list (Invited, Joined, Has Left). - * - * @see onAvatarListRefreshed() - * @see onChanged() - */ - void updateParticipantsVoiceState(); - - /** - * Updates voice state of participant not in current voice channel depend on its current state. - */ - void updateNotInVoiceParticipantState(LLAvatarListItem* item); - void setState(LLAvatarListItem* item, ESpeakerState state); - void setState(const LLUUID& speaker_id, ESpeakerState state) - { - lldebugs << "Storing state: " << speaker_id << ", " << state << llendl; - mSpeakerStateMap[speaker_id] = state; - } - - ESpeakerState getState(const LLUUID& speaker_id) - { - lldebugs << "Getting state: " << speaker_id << ", " << mSpeakerStateMap[speaker_id] << llendl; - - return mSpeakerStateMap[speaker_id]; - } - - /** - * Instantiates new LLAvatarListItemRemoveTimer and adds it into the map if it is not already created. - * - * @param voice_speaker_id LLUUID of Avatar List item to be removed from the list when timer expires. - */ - void setVoiceRemoveTimer(const LLUUID& voice_speaker_id); - - /** - * Removes specified by UUID Avatar List item. - * - * @param voice_speaker_id LLUUID of Avatar List item to be removed from the list. - */ - bool removeVoiceLeftParticipant(const LLUUID& voice_speaker_id); - - /** - * Deletes all timers from the list to prevent started timers from ticking after destruction - * and after switching on another voice channel. - */ - void resetVoiceRemoveTimers(); - - /** - * Removes specified by UUID timer from the map. - * - * @param voice_speaker_id LLUUID of Avatar List item whose timer should be removed from the map. - */ - void removeVoiceRemoveTimer(const LLUUID& voice_speaker_id); - - /** - * Called by LLParticipantList before adding a speaker to the participant list. - * - * If false is returned, the speaker will not be added to the list. - * - * @param speaker_id Speaker to validate. - * @return true if this is a valid speaker, false otherwise. - */ - bool validateSpeaker(const LLUUID& speaker_id); - - /** - * Connects to passed channel to be updated according to channel's voice states. - */ - void connectToChannel(LLVoiceChannel* channel); - - /** - * Callback to process changing of voice channel's states. - */ - void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state); - - /** - * Updates floater according to passed channel's voice state. - */ - void updateState(const LLVoiceChannel::EState& new_state); - - /** - * Resets floater to be ready to show voice participants. - * - * Clears all data from the latest voice session. - */ - void reset(const LLVoiceChannel::EState& new_state); - -private: - speaker_state_map_t mSpeakerStateMap; - LLSpeakerMgr* mSpeakerManager; - LLParticipantList* mParticipants; - LLAvatarList* mAvatarList; - LLNonAvatarCaller* mNonAvatarCaller; - EVoiceControls mVoiceType; - LLPanel* mAgentPanel; - LLOutputMonitorCtrl* mSpeakingIndicator; - bool mIsModeratorMutedVoice; - - /** - * Flag indicated that participants voice states should be initialized. - * - * It is used due to Avatar List has delayed refreshing after it content is changed. - * Real initializing is performed when Avatar List is first time refreshed. - * - * @see onAvatarListRefreshed() - * @see initParticipantsVoiceState() - */ - bool mInitParticipantsVoiceState; - - boost::signals2::connection mAvatarListRefreshConnection; - - - /** - * time out speakers when they are not part of current session - */ - LLSpeakersDelayActionsStorage* mSpeakerDelayRemover; - - /** - * Stores reference to current voice channel. - * - * Is used to ignore voice channel changed callback for the same channel. - * - * @see sOnCurrentChannelChanged() - */ - static LLVoiceChannel* sCurrentVoiceChannel; - - /* virtual */ - LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; } - - boost::signals2::connection mVoiceChannelStateChangeConnection; -}; - - -#endif //LL_LLCALLFLOATER_H - diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 0d55c4429a..30306b230f 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -54,6 +54,7 @@ #include "llresmgr.h" #include "llslurl.h" #include "llimview.h" +#include "lltrans.h" #include "llviewercontrol.h" #include "llviewernetwork.h" #include "llviewerobjectlist.h" @@ -703,9 +704,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) if(chat_notify) { // Look up the name of this agent for the notification - LLAvatarNameCache::get(agent_id, - boost::bind(&on_avatar_name_cache_notify, - _1, _2, online, payload)); + LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload)); } mModifyMask |= LLFriendObserver::ONLINE; @@ -722,13 +721,14 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id, // Popup a notify box with online status of this agent // Use display name only because this user is your friend LLSD args; - args["NAME"] = av_name.mDisplayName; + args["NAME"] = av_name.getDisplayName(); + args["STATUS"] = online ? LLTrans::getString("OnlineStatus") : LLTrans::getString("OfflineStatus"); LLNotificationPtr notification; if (online) { notification = - LLNotificationsUtil::add("FriendOnline", + LLNotificationsUtil::add("FriendOnlineOffline", args, payload.with("respond_on_mousedown", TRUE), boost::bind(&LLAvatarActions::startIM, agent_id)); @@ -736,7 +736,7 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id, else { notification = - LLNotificationsUtil::add("FriendOffline", args, payload); + LLNotificationsUtil::add("FriendOnlineOffline", args, payload); } // If there's an open IM session with this agent, send a notification there too. @@ -867,7 +867,7 @@ bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship { LLAvatarName av_name; LLAvatarNameCache::get( buddy_id, &av_name); - buddy_map_t::value_type value(av_name.mDisplayName, buddy_id); + buddy_map_t::value_type value(av_name.getDisplayName(), buddy_id); if(buddy->isOnline() && buddy->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)) { mMappable.insert(value); @@ -890,7 +890,7 @@ bool LLCollectAllBuddies::operator()(const LLUUID& buddy_id, LLRelationship* bud { LLAvatarName av_name; LLAvatarNameCache::get(buddy_id, &av_name); - mFullName = av_name.mDisplayName; + mFullName = av_name.getDisplayName(); buddy_map_t::value_type value(mFullName, buddy_id); if(buddy->isOnline()) { diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index 987651fc80..43757d0174 100644 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -29,7 +29,8 @@ #include "llchannelmanager.h" #include "llappviewer.h" -#include "llnotificationstorage.h" +#include "lldonotdisturbnotificationstorage.h" +#include "llpersistentnotificationstorage.h" #include "llviewercontrol.h" #include "llviewerwindow.h" #include "llrootview.h" @@ -138,6 +139,9 @@ void LLChannelManager::onLoginCompleted() } LLPersistentNotificationStorage::getInstance()->loadNotifications(); + + LLDoNotDisturbNotificationStorage::getInstance()->initialize(); + LLDoNotDisturbNotificationStorage::getInstance()->loadNotifications(); } //-------------------------------------------------------------------------- diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index d6095cce07..7d0331757b 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -669,47 +669,3 @@ void LLChatBar::onCommitGesture(LLUICtrl* ctrl) mGestureCombo->setFocus(FALSE); } } - - -/* Cruft - global gChatHandler declared below has been commented out, - so this class is never used. See similar code in llnearbychatbar.cpp -class LLChatHandler : public LLCommandHandler -{ -public: - // not allowed from outside the app - LLChatHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { } - - // Your code here - bool handle(const LLSD& tokens, const LLSD& query_map, - LLMediaCtrl* web) - { - bool retval = false; - // Need at least 2 tokens to have a valid message. - if (tokens.size() < 2) - { - retval = false; - } - else - { - S32 channel = tokens[0].asInteger(); - // VWR-19499 Restrict function to chat channels greater than 0. - if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG)) - { - retval = true; - // Say mesg on channel - std::string mesg = tokens[1].asString(); - send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel); - } - else - { - retval = false; - // Tell us this is an unsupported SLurl. - } - } - return retval; - } -}; - -// Creating the object registers with the dispatcher. -//LLChatHandler gChatHandler; -cruft */ diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 42de47e777..53926c1fef 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -28,6 +28,8 @@ #include "llchathistory.h" +#include <boost/signals2.hpp> + #include "llavatarnamecache.h" #include "llinstantmessage.h" @@ -56,7 +58,7 @@ #include "llworld.h" #include "lluiconstants.h" #include "llstring.h" - +#include "llurlaction.h" #include "llviewercontrol.h" static LLDefaultChildRegistry::Register<LLChatHistory> r("chat_history"); @@ -110,7 +112,10 @@ public: mFrom(), mSessionID(), mMinUserNameWidth(0), - mUserNameFont(NULL) + mUserNameFont(NULL), + mUserNameTextBox(NULL), + mTimeBoxTextBox(NULL), + mAvatarNameCacheConnection() {} static LLChatHistoryHeader* createInstance(const std::string& file_name) @@ -124,6 +129,11 @@ public: { // Detach the info button so that it doesn't get destroyed (EXT-8463). hideInfoCtrl(); + + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } } BOOL handleMouseUp(S32 x, S32 y, MASK mask) @@ -143,8 +153,20 @@ public: { LLMuteList::getInstance()->add(LLMute(getAvatarId(), mFrom, LLMute::OBJECT)); - LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with("blocked_to_select", getAvatarId())); + LLFloaterSidePanelContainer::showPanel("people", "panel_people", + LLSD().with("people_panel_tab_name", "blocked_panel").with("blocked_to_select", getAvatarId())); + } + else if (level == "map") + { + std::string url = "secondlife://" + mObjectData["slurl"].asString(); + LLUrlAction::showLocationOnMap(url); + } + else if (level == "teleport") + { + std::string url = "secondlife://" + mObjectData["slurl"].asString(); + LLUrlAction::teleportToLocation(url); } + } void onAvatarIconContextMenuItemClicked(const LLSD& userdata) @@ -187,6 +209,9 @@ public: setMouseEnterCallback(boost::bind(&LLChatHistoryHeader::showInfoCtrl, this)); setMouseLeaveCallback(boost::bind(&LLChatHistoryHeader::hideInfoCtrl, this)); + mUserNameTextBox = getChild<LLTextBox>("user_name"); + mTimeBoxTextBox = getChild<LLTextBox>("time_box"); + return LLPanel::postBuild(); } @@ -282,8 +307,7 @@ public: // Start with blank so sample data from XUI XML doesn't // flash on the screen user_name->setValue( LLSD() ); - LLAvatarNameCache::get(mAvatarID, - boost::bind(&LLChatHistoryHeader::onAvatarNameCache, this, _1, _2)); + fetchAvatarName(); } else if (chat.mChatStyle == CHAT_STYLE_HISTORY || mSourceType == CHAT_SOURCE_AGENT) @@ -377,8 +401,8 @@ public: /*virtual*/ void draw() { - LLTextBox* user_name = getChild<LLTextBox>("user_name"); - LLTextBox* time_box = getChild<LLTextBox>("time_box"); + LLTextBox* user_name = mUserNameTextBox; //getChild<LLTextBox>("user_name"); + LLTextBox* time_box = mTimeBoxTextBox; //getChild<LLTextBox>("time_box"); LLRect user_name_rect = user_name->getRect(); S32 user_name_width = user_name_rect.getWidth(); @@ -415,31 +439,6 @@ public: } } - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) - { - mFrom = av_name.mDisplayName; - - LLTextBox* user_name = getChild<LLTextBox>("user_name"); - user_name->setValue( LLSD(av_name.mDisplayName ) ); - user_name->setToolTip( av_name.mUsername ); - - if (gSavedSettings.getBOOL("NameTagShowUsernames") && - LLAvatarNameCache::useDisplayNames() && - !av_name.mIsDisplayNameDefault) - { - LLStyle::Params style_params_name; - LLColor4 userNameColor = LLUIColorTable::instance().getColor("EmphasisColor"); - style_params_name.color(userNameColor); - style_params_name.font.name("SansSerifSmall"); - style_params_name.font.style("NORMAL"); - style_params_name.readonly_color(userNameColor); - user_name->appendText(" - " + av_name.mUsername, FALSE, style_params_name); - } - setToolTip( av_name.mUsername ); - // name might have changed, update width - updateMinUserNameWidth(); - } - protected: static const S32 PADDING = 20; @@ -495,7 +494,7 @@ protected: void showInfoCtrl() { - if (mAvatarID.isNull() || mFrom.empty() || SYSTEM_FROM == mFrom) return; + if (mAvatarID.isNull() || mFrom.empty() || CHAT_SOURCE_SYSTEM == mSourceType) return; if (!sInfoCtrl) { @@ -554,6 +553,46 @@ private: user_name->reshape(user_rect.getWidth() + delta_pos_x, user_rect.getHeight()); } + void fetchAvatarName() + { + if (mAvatarID.notNull()) + { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID, + boost::bind(&LLChatHistoryHeader::onAvatarNameCache, this, _1, _2)); + } + } + + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) + { + mAvatarNameCacheConnection.disconnect(); + + mFrom = av_name.getDisplayName(); + + LLTextBox* user_name = getChild<LLTextBox>("user_name"); + user_name->setValue( LLSD(av_name.getDisplayName() ) ); + user_name->setToolTip( av_name.getUserName() ); + + if (gSavedSettings.getBOOL("NameTagShowUsernames") && + av_name.useDisplayNames() && + !av_name.isDisplayNameDefault()) + { + LLStyle::Params style_params_name; + LLColor4 userNameColor = LLUIColorTable::instance().getColor("EmphasisColor"); + style_params_name.color(userNameColor); + style_params_name.font.name("SansSerifSmall"); + style_params_name.font.style("NORMAL"); + style_params_name.readonly_color(userNameColor); + user_name->appendText(" - " + av_name.getUserName(), FALSE, style_params_name); + } + setToolTip( av_name.getUserName() ); + // name might have changed, update width + updateMinUserNameWidth(); + } + protected: LLHandle<LLView> mPopupMenuHandleAvatar; LLHandle<LLView> mPopupMenuHandleObject; @@ -568,6 +607,11 @@ protected: S32 mMinUserNameWidth; const LLFontGL* mUserNameFont; + LLTextBox* mUserNameTextBox; + LLTextBox* mTimeBoxTextBox; + +private: + boost::signals2::connection mAvatarNameCacheConnection; }; LLUICtrl* LLChatHistoryHeader::sInfoCtrl = NULL; @@ -584,7 +628,8 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p) mBottomSeparatorPad(p.bottom_separator_pad), mTopHeaderPad(p.top_header_pad), mBottomHeaderPad(p.bottom_header_pad), - mIsLastMessageFromLog(false) + mIsLastMessageFromLog(false), + mNotifyAboutUnreadMsg(p.notify_unread_msg) { LLTextEditor::Params editor_params(p); editor_params.rect = getLocalRect(); @@ -594,6 +639,14 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p) mEditor = LLUICtrlFactory::create<LLTextEditor>(editor_params, this); } +LLSD LLChatHistory::getValue() const +{ + LLSD* text=new LLSD(); + text->assign(mEditor->getText()); + return *text; + +} + LLChatHistory::~LLChatHistory() { this->clear(); @@ -621,7 +674,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; @@ -690,9 +742,13 @@ void LLChatHistory::clear() mLastFromID = LLUUID::null; } +static LLFastTimer::DeclareTimer FTM_APPEND_MESSAGE("Append Chat Message"); + void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LLStyle::Params& input_append_params) { + LLFastTimer _(FTM_APPEND_MESSAGE); bool use_plain_text_chat_history = args["use_plain_text_chat_history"].asBoolean(); + bool square_brackets = false; // square brackets necessary for a system messages llassert(mEditor); if (!mEditor) @@ -700,9 +756,10 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL return; } + bool from_me = chat.mFromID == gAgent.getID(); mEditor->setPlainText(use_plain_text_chat_history); - if (!mEditor->scrolledToEnd() && chat.mFromID != gAgent.getID() && !chat.mFromName.empty()) + if (mNotifyAboutUnreadMsg && !mEditor->scrolledToEnd() && !from_me && !chat.mFromName.empty()) { mUnreadChatSources.insert(chat.mFromName); mMoreChatPanel->setVisible(TRUE); @@ -732,16 +789,23 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL } LLColor4 txt_color = LLUIColorTable::instance().getColor("White"); + LLColor4 name_color(txt_color); + LLViewerChat::getChatColor(chat,txt_color); LLFontGL* fontp = LLViewerChat::getChatFont(); std::string font_name = LLFontGL::nameFromFont(fontp); std::string font_size = LLFontGL::sizeFromFont(fontp); - LLStyle::Params style_params; - style_params.color(txt_color); - style_params.readonly_color(txt_color); - style_params.font.name(font_name); - style_params.font.size(font_size); - style_params.font.style(input_append_params.font.style); + + LLStyle::Params body_message_params; + body_message_params.color(txt_color); + body_message_params.readonly_color(txt_color); + body_message_params.font.name(font_name); + body_message_params.font.size(font_size); + body_message_params.font.style(input_append_params.font.style); + + LLStyle::Params name_params(body_message_params); + name_params.color(name_color); + name_params.readonly_color(name_color); std::string prefix = chat.mText.substr(0, 4); @@ -764,29 +828,60 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL if (irc_me || chat.mChatStyle == CHAT_STYLE_IRC) { delimiter = LLStringUtil::null; - style_params.font.style = "ITALIC"; + body_message_params.font.style = "ITALIC"; + } + + if(chat.mChatType == CHAT_TYPE_WHISPER) + { + body_message_params.font.style = "ITALIC"; + } + else if(chat.mChatType == CHAT_TYPE_SHOUT) + { + body_message_params.font.style = "BOLD"; } bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY; // We graying out chat history by graying out messages that contains full date in a time string if (message_from_log) { - style_params.color(LLColor4::grey); - style_params.readonly_color(LLColor4::grey); + txt_color = LLColor4::grey; + body_message_params.color(txt_color); + body_message_params.readonly_color(txt_color); + name_params.color(txt_color); + name_params.readonly_color(txt_color); } + bool prependNewLineState = mEditor->getText().size() != 0; + + // compact mode: show a timestamp and name if (use_plain_text_chat_history) { - LLStyle::Params timestamp_style(style_params); + square_brackets = chat.mFromName == SYSTEM_FROM; + + LLStyle::Params timestamp_style(body_message_params); + + // out of the timestamp + if (args["show_time"].asBoolean()) + { if (!message_from_log) { LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor"); timestamp_style.color(timestamp_color); timestamp_style.readonly_color(timestamp_color); } - mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getText().size() != 0, timestamp_style); + mEditor->appendText("[" + chat.mTimeStr + "] ", prependNewLineState, timestamp_style); + prependNewLineState = false; + } + + // out the opening square bracket (if need) + if (square_brackets) + { + mEditor->appendText("[", prependNewLineState, body_message_params); + prependNewLineState = false; + } - if (utf8str_trim(chat.mFromName).size() != 0) + // names showing + if (args["show_names_for_p2p_conv"].asBoolean() && utf8str_trim(chat.mFromName).size() != 0) { // Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text. if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull()) @@ -796,32 +891,47 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL // set the link for the object name to be the objectim SLapp // (don't let object names with hyperlinks override our objectim Url) - LLStyle::Params link_params(style_params); + LLStyle::Params link_params(body_message_params); LLColor4 link_color = LLUIColorTable::instance().getColor("HTMLLinkColor"); link_params.color = link_color; link_params.readonly_color = link_color; link_params.is_link = true; link_params.link_href = url; - mEditor->appendText(chat.mFromName + delimiter, - false, link_params); + mEditor->appendText(chat.mFromName + delimiter, prependNewLineState, link_params); + prependNewLineState = false; } else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log) { - LLStyle::Params link_params(style_params); + LLStyle::Params link_params(body_message_params); link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID)); + if (from_me) + { std::string localized_name; + bool is_localized = LLTrans::findString(localized_name, "AgentNameSubst"); + mEditor->appendText((is_localized? localized_name:"(You)") + delimiter, + prependNewLineState, link_params); + prependNewLineState = false; + } + else + { // Add link to avatar's inspector and delimiter to message. - mEditor->appendText(std::string(link_params.link_href) + delimiter, false, link_params); + mEditor->appendText(std::string(link_params.link_href) + delimiter, + prependNewLineState, link_params); + prependNewLineState = false; + } } else { - mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter, false, style_params); + mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter, + prependNewLineState, body_message_params); + prependNewLineState = false; } } } - else + else // showing timestamp and name in the expanded mode { + prependNewLineState = false; LLView* view = NULL; LLInlineViewSegment::Params p; p.force_newline = true; @@ -842,8 +952,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL } else { - view = getHeader(chat, style_params, args); - if (mEditor->getText().size() == 0) + view = getHeader(chat, name_params, args); + if (mEditor->getLength() == 0) p.top_pad = 0; else p.top_pad = mTopHeaderPad; @@ -871,41 +981,16 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL mIsLastMessageFromLog = message_from_log; } + // body of the message processing + + // notify processing if (chat.mNotifId.notNull()) { LLNotificationPtr notification = LLNotificationsUtil::find(chat.mNotifId); if (notification != NULL) { LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel( - notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history); - //we can't set follows in xml since it broke toasts behavior - notify_box->setFollowsLeft(); - notify_box->setFollowsRight(); - notify_box->setFollowsTop(); - - ctrl_list_t ctrls = notify_box->getControlPanel()->getCtrlList(); - S32 offset = 0; - // Children were added by addChild() which uses push_front to insert them into list, - // so to get buttons in correct order reverse iterator is used (EXT-5906) - for (ctrl_list_t::reverse_iterator it = ctrls.rbegin(); it != ctrls.rend(); it++) - { - LLButton * button = dynamic_cast<LLButton*> (*it); - if (button != NULL) - { - button->setOrigin( offset, - button->getRect().mBottom); - button->setLeftHPad(2 * HPAD); - button->setRightHPad(2 * HPAD); - // set zero width before perform autoResize() - button->setRect(LLRect(button->getRect().mLeft, - button->getRect().mTop, button->getRect().mLeft, - button->getRect().mBottom)); - button->setAutoResize(true); - button->autoResize(); - offset += HPAD + button->getRect().getWidth(); - button->setFollowsNone(); - } - } + notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history, mEditor); //Prepare the rect for the view LLRect target_rect = mEditor->getDocumentView()->getRect(); @@ -922,6 +1007,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL mEditor->appendWidget(params, "\n", false); } } + + // usual messages showing else { std::string message = irc_me ? chat.mText.substr(3) : chat.mText; @@ -929,7 +1016,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL //MESSAGE TEXT PROCESSING //*HACK getting rid of redundant sender names in system notifications sent using sender name (see EXT-5010) - if (use_plain_text_chat_history && gAgentID != chat.mFromID && chat.mFromID.notNull()) + if (use_plain_text_chat_history && !from_me && chat.mFromID.notNull()) { std::string slurl_about = SLURL_APP_AGENT + chat.mFromID.asString() + SLURL_ABOUT; if (message.length() > slurl_about.length() && @@ -944,13 +1031,19 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL message = chat.mFromName + message; } - mEditor->appendText(message, FALSE, style_params); + if (square_brackets) + { + message += "]"; + } + + mEditor->appendText(message, prependNewLineState, body_message_params); + prependNewLineState = false; } mEditor->blockUndo(); // automatically scroll to end when receiving chat from myself - if (chat.mFromID == gAgentID) + if (from_me) { mEditor->setCursorAndScrollToEnd(); } diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h index 28344e6a10..bb6d4fb59c 100644 --- a/indra/newview/llchathistory.h +++ b/indra/newview/llchathistory.h @@ -60,6 +60,8 @@ class LLChatHistory : public LLUICtrl Optional<LLTextBox::Params> more_chat_text; + Optional<bool> notify_unread_msg; + Params() : message_header("message_header"), message_separator("message_separator"), @@ -71,7 +73,8 @@ class LLChatHistory : public LLUICtrl bottom_separator_pad("bottom_separator_pad"), top_header_pad("top_header_pad"), bottom_header_pad("bottom_header_pad"), - more_chat_text("more_chat_text") + more_chat_text("more_chat_text"), + notify_unread_msg("notify_unread_msg", true) {} }; @@ -100,7 +103,7 @@ class LLChatHistory : public LLUICtrl public: ~LLChatHistory(); - + LLSD getValue() const; void initFromParams(const Params&); /** @@ -122,6 +125,7 @@ class LLChatHistory : public LLUICtrl LLUUID mLastFromID; LLDate mLastMessageTime; bool mIsLastMessageFromLog; + bool mNotifyAboutUnreadMsg; //std::string mLastMessageTimeStr; std::string mMessageHeaderFilename; diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 9a84280f25..a1a9463d43 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -35,7 +35,7 @@ #include "llfloaterreg.h" #include "lllocalcliprect.h" #include "lltrans.h" -#include "llnearbychatbar.h" +#include "llfloaterimnearbychat.h" #include "llviewercontrol.h" #include "llagentdata.h" @@ -81,23 +81,30 @@ public: LLObjectHandler gObjectHandler; //******************************************************************************************************************* -//LLNearbyChatToastPanel +//LLFloaterIMNearbyChatToastPanel //******************************************************************************************************************* -LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance() +LLFloaterIMNearbyChatToastPanel* LLFloaterIMNearbyChatToastPanel::createInstance() { - LLNearbyChatToastPanel* item = new LLNearbyChatToastPanel(); + LLFloaterIMNearbyChatToastPanel* item = new LLFloaterIMNearbyChatToastPanel(); item->buildFromFile("panel_chat_item.xml"); item->setFollows(FOLLOWS_NONE); return item; } -void LLNearbyChatToastPanel::reshape (S32 width, S32 height, BOOL called_from_parent ) +void LLFloaterIMNearbyChatToastPanel::reshape (S32 width, S32 height, BOOL called_from_parent ) { LLPanel::reshape(width, height,called_from_parent); - LLUICtrl* msg_text = getChild<LLUICtrl>("msg_text", false); - LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false); + // reshape() may be called from LLView::initFromParams() before the children are created. + // We call findChild() instead of getChild() here to avoid creating dummy controls. + LLUICtrl* msg_text = findChild<LLUICtrl>("msg_text", false); + LLUICtrl* icon = findChild<LLUICtrl>("avatar_icon", false); + + if (!msg_text || !icon) + { + return; + } LLRect msg_text_rect = msg_text->getRect(); LLRect avatar_rect = icon->getRect(); @@ -114,12 +121,12 @@ void LLNearbyChatToastPanel::reshape (S32 width, S32 height, BOOL called_from_p msg_text->setRect(msg_text_rect); } -BOOL LLNearbyChatToastPanel::postBuild() +BOOL LLFloaterIMNearbyChatToastPanel::postBuild() { return LLPanel::postBuild(); } -void LLNearbyChatToastPanel::addMessage(LLSD& notification) +void LLFloaterIMNearbyChatToastPanel::addMessage(LLSD& notification) { std::string messageText = notification["message"].asString(); // UTF-8 line of text @@ -171,7 +178,7 @@ void LLNearbyChatToastPanel::addMessage(LLSD& notification) } -void LLNearbyChatToastPanel::init(LLSD& notification) +void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification) { std::string messageText = notification["message"].asString(); // UTF-8 line of text std::string fromName = notification["from"].asString(); // agent or object name @@ -266,7 +273,7 @@ void LLNearbyChatToastPanel::init(LLSD& notification) mIsDirty = true;//will set Avatar Icon in draw } -void LLNearbyChatToastPanel::snapToMessageHeight () +void LLFloaterIMNearbyChatToastPanel::snapToMessageHeight () { LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false); S32 new_height = llmax (text_box->getTextPixelHeight() + 2*text_box->getVPad() + 2*msg_height_pad, 25); @@ -281,22 +288,22 @@ void LLNearbyChatToastPanel::snapToMessageHeight () } -void LLNearbyChatToastPanel::onMouseLeave (S32 x, S32 y, MASK mask) +void LLFloaterIMNearbyChatToastPanel::onMouseLeave (S32 x, S32 y, MASK mask) { } -void LLNearbyChatToastPanel::onMouseEnter (S32 x, S32 y, MASK mask) +void LLFloaterIMNearbyChatToastPanel::onMouseEnter (S32 x, S32 y, MASK mask) { if(mSourceType != CHAT_SOURCE_AGENT) return; } -BOOL LLNearbyChatToastPanel::handleMouseDown (S32 x, S32 y, MASK mask) +BOOL LLFloaterIMNearbyChatToastPanel::handleMouseDown (S32 x, S32 y, MASK mask) { return LLPanel::handleMouseDown(x,y,mask); } -BOOL LLNearbyChatToastPanel::handleMouseUp (S32 x, S32 y, MASK mask) +BOOL LLFloaterIMNearbyChatToastPanel::handleMouseUp (S32 x, S32 y, MASK mask) { /* fix for request EXT-4780 @@ -316,16 +323,16 @@ BOOL LLNearbyChatToastPanel::handleMouseUp (S32 x, S32 y, MASK mask) return TRUE; else { - LLNearbyChatBar::getInstance()->showHistory(); + (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->showHistory(); return FALSE; } } - LLNearbyChatBar::getInstance()->showHistory(); + (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->showHistory(); return LLPanel::handleMouseUp(x,y,mask); } -void LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e) +void LLFloaterIMNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e) { LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false); if(icon) @@ -333,7 +340,7 @@ void LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e) } -bool LLNearbyChatToastPanel::canAddText () +bool LLFloaterIMNearbyChatToastPanel::canAddText () { LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text"); if(!msg_text) @@ -341,7 +348,7 @@ bool LLNearbyChatToastPanel::canAddText () return msg_text->getLineCount()<10; } -BOOL LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask) +BOOL LLFloaterIMNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask) { LLUICtrl* avatar_icon = getChild<LLUICtrl>("avatar_icon", false); @@ -353,8 +360,10 @@ BOOL LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask) return TRUE; return LLPanel::handleRightMouseDown(x,y,mask); } -void LLNearbyChatToastPanel::draw() +void LLFloaterIMNearbyChatToastPanel::draw() { + LLPanel::draw(); + if(mIsDirty) { LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon", false); @@ -372,7 +381,6 @@ void LLNearbyChatToastPanel::draw() } mIsDirty = false; } - LLToastPanelBase::draw(); } diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h index 1d700dcede..54b6499d52 100644 --- a/indra/newview/llchatitemscontainerctrl.h +++ b/indra/newview/llchatitemscontainerctrl.h @@ -40,18 +40,18 @@ typedef enum e_show_item_header CHATITEMHEADER_SHOW_BOTH } EShowItemHeader; -class LLNearbyChatToastPanel: public LLToastPanelBase +class LLFloaterIMNearbyChatToastPanel : public LLPanel { protected: - LLNearbyChatToastPanel() + LLFloaterIMNearbyChatToastPanel() : mIsDirty(false), mSourceType(CHAT_SOURCE_OBJECT) {}; public: - ~LLNearbyChatToastPanel(){} + ~LLFloaterIMNearbyChatToastPanel(){} - static LLNearbyChatToastPanel* createInstance(); + static LLFloaterIMNearbyChatToastPanel* createInstance(); const LLUUID& getFromID() const { return mFromID;} const std::string& getFromName() const { return mFromName; } diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index a076374903..3dbb43c657 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -27,35 +27,17 @@ #include "llviewerprecompiledheaders.h" // must be first include #include "llchiclet.h" -#include "llagent.h" -#include "llavataractions.h" #include "llchicletbar.h" -#include "lleventtimer.h" -#include "llgroupactions.h" -#include "lliconctrl.h" -#include "llimfloater.h" -#include "llimview.h" +#include "llfloaterimsession.h" +#include "llfloaterimcontainer.h" #include "llfloaterreg.h" #include "lllocalcliprect.h" -#include "llmenugl.h" -#include "llnotifications.h" -#include "llnotificationsutil.h" -#include "lloutputmonitorctrl.h" #include "llscriptfloater.h" -#include "llspeakers.h" -#include "lltextbox.h" -#include "llvoiceclient.h" -#include "llgroupmgr.h" -#include "llnotificationmanager.h" -#include "lltransientfloatermgr.h" +#include "llsingleton.h" #include "llsyswellwindow.h" static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel"); -static LLDefaultChildRegistry::Register<LLIMWellChiclet> t2_0("chiclet_im_well"); static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification"); -static LLDefaultChildRegistry::Register<LLIMP2PChiclet> t3("chiclet_im_p2p"); -static LLDefaultChildRegistry::Register<LLIMGroupChiclet> t4("chiclet_im_group"); -static LLDefaultChildRegistry::Register<LLAdHocChiclet> t5("chiclet_im_adhoc"); static LLDefaultChildRegistry::Register<LLScriptChiclet> t6("chiclet_script"); static LLDefaultChildRegistry::Register<LLInvOfferChiclet> t7("chiclet_offer"); @@ -66,65 +48,10 @@ boost::signals2::signal<LLChiclet* (const LLUUID&), ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -/** - * Updates the Well's 'Lit' state to flash it when "new messages" are come. - * - * It gets callback which will be called 2*N times with passed period. See EXT-3147 - */ -class LLSysWellChiclet::FlashToLitTimer : public LLEventTimer -{ -public: - typedef boost::function<void()> callback_t; - - /** - * Constructor. - * - * @param count - how many times callback should be called (twice to not change original state) - * @param period - how frequently callback should be called - * @param cb - callback to be called each tick - */ - FlashToLitTimer(S32 count, F32 period, callback_t cb) - : LLEventTimer(period) - , mCallback(cb) - , mFlashCount(2 * count) - , mCurrentFlashCount(0) - { - mEventTimer.stop(); - } - - BOOL tick() - { - mCallback(); - - if (++mCurrentFlashCount == mFlashCount) mEventTimer.stop(); - return FALSE; - } - - void flash() - { - mCurrentFlashCount = 0; - mEventTimer.start(); - } - - void stopFlashing() - { - mEventTimer.stop(); - } - -private: - callback_t mCallback; - - /** - * How many times Well will blink. - */ - S32 mFlashCount; - S32 mCurrentFlashCount; -}; - LLSysWellChiclet::Params::Params() -: button("button") -, unread_notifications("unread_notifications") -, max_displayed_count("max_displayed_count", 99) + : button("button") + , unread_notifications("unread_notifications") + , max_displayed_count("max_displayed_count", 99) { button.name = "button"; button.tab_stop = FALSE; @@ -132,30 +59,24 @@ LLSysWellChiclet::Params::Params() } LLSysWellChiclet::LLSysWellChiclet(const Params& p) -: LLChiclet(p) -, mButton(NULL) -, mCounter(0) -, mMaxDisplayedCount(p.max_displayed_count) -, mIsNewMessagesState(false) -, mFlashToLitTimer(NULL) -, mContextMenu(NULL) + : LLChiclet(p) + , mButton(NULL) + , mCounter(0) + , mMaxDisplayedCount(p.max_displayed_count) + , mIsNewMessagesState(false) + , mFlashToLitTimer(NULL) + , mContextMenu(NULL) { LLButton::Params button_params = p.button; mButton = LLUICtrlFactory::create<LLButton>(button_params); addChild(mButton); - // use settings from settings.xml to be able change them via Debug settings. See EXT-5973. - // Due to Timer is implemented as derived class from EventTimer it is impossible to change period - // in runtime. So, both settings are made as required restart. - static S32 flash_to_lit_count = gSavedSettings.getS32("WellIconFlashCount"); - static F32 flash_period = gSavedSettings.getF32("WellIconFlashPeriod"); - - mFlashToLitTimer = new FlashToLitTimer(flash_to_lit_count, flash_period, boost::bind(&LLSysWellChiclet::changeLitState, this)); + mFlashToLitTimer = new LLFlashTimer(boost::bind(&LLSysWellChiclet::changeLitState, this, _1)); } LLSysWellChiclet::~LLSysWellChiclet() { - delete mFlashToLitTimer; + mFlashToLitTimer->unset(); } void LLSysWellChiclet::setCounter(S32 counter) @@ -190,7 +111,7 @@ void LLSysWellChiclet::setToggleState(BOOL toggled) { mButton->setToggleState(toggled); } -void LLSysWellChiclet::changeLitState() +void LLSysWellChiclet::changeLitState(bool blink) { setNewMessagesState(!mIsNewMessagesState); } @@ -235,117 +156,18 @@ BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) } /************************************************************************/ -/* LLIMWellChiclet implementation */ -/************************************************************************/ -LLIMWellChiclet::LLIMWellChiclet(const Params& p) -: LLSysWellChiclet(p) -{ - LLIMModel::instance().addNewMsgCallback(boost::bind(&LLIMWellChiclet::messageCountChanged, this, _1)); - LLIMModel::instance().addNoUnreadMsgsCallback(boost::bind(&LLIMWellChiclet::messageCountChanged, this, _1)); - - LLIMMgr::getInstance()->addSessionObserver(this); - - LLIMWellWindow::getInstance()->setSysWellChiclet(this); -} - -LLIMWellChiclet::~LLIMWellChiclet() -{ - LLIMMgr::getInstance()->removeSessionObserver(this); -} - -void LLIMWellChiclet::onMenuItemClicked(const LLSD& user_data) -{ - std::string action = user_data.asString(); - if("close all" == action) - { - LLIMWellWindow::getInstance()->closeAll(); - } -} - -bool LLIMWellChiclet::enableMenuItem(const LLSD& user_data) -{ - std::string item = user_data.asString(); - if (item == "can close all") - { - return !LLIMWellWindow::getInstance()->isWindowEmpty(); - } - return true; -} - -void LLIMWellChiclet::createMenu() -{ - if(mContextMenu) - { - llwarns << "Menu already exists" << llendl; - return; - } - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - registrar.add("IMWellChicletMenu.Action", - boost::bind(&LLIMWellChiclet::onMenuItemClicked, this, _2)); - - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - enable_registrar.add("IMWellChicletMenu.EnableItem", - boost::bind(&LLIMWellChiclet::enableMenuItem, this, _2)); - - mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu> - ("menu_im_well_button.xml", - LLMenuGL::sMenuContainer, - LLViewerMenuHolderGL::child_registry_t::instance()); -} - -void LLIMWellChiclet::messageCountChanged(const LLSD& session_data) -{ - const LLUUID& session_id = session_data["session_id"]; - const S32 counter = LLChicletBar::getInstance()->getTotalUnreadIMCount(); - const bool im_not_visible = !LLFloaterReg::instanceVisible("im_container") - && !LLFloaterReg::instanceVisible("impanel", session_id); - - setNewMessagesState(counter > mCounter && im_not_visible); - - // we have to flash to 'Lit' state each time new unread message is coming. - if (counter > mCounter && im_not_visible) - { - mFlashToLitTimer->flash(); - } - else if (counter == 0) - { - // if notification is resolved while well is flashing it can leave in the 'Lit' state - // when flashing finishes itself. Let break flashing here. - mFlashToLitTimer->stopFlashing(); - } - - setCounter(counter); -} - -/************************************************************************/ /* LLNotificationChiclet implementation */ /************************************************************************/ LLNotificationChiclet::LLNotificationChiclet(const Params& p) -: LLSysWellChiclet(p) -, mUreadSystemNotifications(0) +: LLSysWellChiclet(p), + mUreadSystemNotifications(0) { - // connect counter handlers to the signals - connectCounterUpdatersToSignal("notify"); - connectCounterUpdatersToSignal("groupnotify"); - connectCounterUpdatersToSignal("offer"); - + mNotificationChannel.reset(new ChicletNotificationChannel(this)); // ensure that notification well window exists, to synchronously // handle toast add/delete events. LLNotificationWellWindow::getInstance()->setSysWellChiclet(this); } -void LLNotificationChiclet::connectCounterUpdatersToSignal(const std::string& notification_type) -{ - LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance(); - LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type); - if(n_handler) - { - n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::incUreadSystemNotifications, this)); - n_handler->setDelNotification(boost::bind(&LLNotificationChiclet::decUreadSystemNotifications, this)); - } -} - void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data) { std::string action = user_data.asString(); @@ -394,6 +216,23 @@ void LLNotificationChiclet::setCounter(S32 counter) updateWidget(getCounter() == 0); } + +bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification ) +{ + if (notification->getName() == "ScriptDialog") + { + return false; + } + + if( !(notification->canLogToIM() && notification->hasFormElements()) + && (!notification->getPayload().has("give_inventory_notification") + || notification->getPayload()["give_inventory_notification"])) + { + return true; + } + return false; +} + ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -409,12 +248,6 @@ LLChiclet::LLChiclet(const Params& p) , mSessionId(LLUUID::null) , mShowCounter(p.show_counter) { - -} - -LLChiclet::~LLChiclet() -{ - } boost::signals2::connection LLChiclet::setLeftButtonClickCallback( @@ -449,7 +282,9 @@ LLSD LLChiclet::getValue() const void LLChiclet::setValue(const LLSD& value) { if(value.isUUID()) + { setSessionId(value.asUUID()); + } } ////////////////////////////////////////////////////////////////////////// @@ -461,12 +296,9 @@ LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p) , mShowSpeaker(false) , mDefaultWidth(p.rect().getWidth()) , mNewMessagesIcon(NULL) -, mSpeakerCtrl(NULL) -, mCounterCtrl(NULL) , mChicletButton(NULL) , mPopupMenu(NULL) { - enableCounterControl(p.enable_counter); } /* virtual*/ @@ -477,16 +309,6 @@ BOOL LLIMChiclet::postBuild() mChicletButton->setDoubleClickCallback(boost::bind(&LLIMChiclet::onMouseDown, this)); return TRUE; } -void LLIMChiclet::setShowSpeaker(bool show) -{ - bool needs_resize = getShowSpeaker() != show; - if(needs_resize) - { - mShowSpeaker = show; - } - - toggleSpeakerControl(); -} void LLIMChiclet::enableCounterControl(bool enable) { @@ -497,87 +319,13 @@ void LLIMChiclet::enableCounterControl(bool enable) } } -void LLIMChiclet::setShowCounter(bool show) -{ - if(!mCounterEnabled) - { - return; - } - - bool needs_resize = getShowCounter() != show; - if(needs_resize) - { - LLChiclet::setShowCounter(show); - toggleCounterControl(); - } -} - -void LLIMChiclet::initSpeakerControl() -{ - // virtual -} - void LLIMChiclet::setRequiredWidth() { - bool show_speaker = getShowSpeaker(); - bool show_counter = getShowCounter(); S32 required_width = mDefaultWidth; - - if (show_counter) - { - required_width += mCounterCtrl->getRect().getWidth(); - } - if (show_speaker) - { - required_width += mSpeakerCtrl->getRect().getWidth(); - } - reshape(required_width, getRect().getHeight()); - onChicletSizeChanged(); } -void LLIMChiclet::toggleSpeakerControl() -{ - if(getShowSpeaker()) - { - // move speaker to the right of chiclet icon - LLRect speaker_rc = mSpeakerCtrl->getRect(); - speaker_rc.setLeftTopAndSize(mDefaultWidth, speaker_rc.mTop, speaker_rc.getWidth(), speaker_rc.getHeight()); - mSpeakerCtrl->setRect(speaker_rc); - - if(getShowCounter()) - { - // move speaker to the right of counter - mSpeakerCtrl->translate(mCounterCtrl->getRect().getWidth(), 0); - } - - initSpeakerControl(); - } - - setRequiredWidth(); - mSpeakerCtrl->setSpeakerId(LLUUID::null); - mSpeakerCtrl->setVisible(getShowSpeaker()); -} - -void LLIMChiclet::setCounter(S32 counter) -{ - if (mCounterCtrl->getCounter() == counter) - { - return; - } - - mCounterCtrl->setCounter(counter); - setShowCounter(counter); - setShowNewMessagesIcon(counter); -} - -void LLIMChiclet::toggleCounterControl() -{ - setRequiredWidth(); - mCounterCtrl->setVisible(getShowCounter()); -} - void LLIMChiclet::setShowNewMessagesIcon(bool show) { if(mNewMessagesIcon) @@ -594,8 +342,7 @@ bool LLIMChiclet::getShowNewMessagesIcon() void LLIMChiclet::onMouseDown() { - LLIMFloater::toggle(getSessionId()); - setCounter(0); + LLFloaterIMSession::toggle(getSessionId()); } void LLIMChiclet::setToggleState(bool toggle) @@ -603,52 +350,6 @@ void LLIMChiclet::setToggleState(bool toggle) mChicletButton->setToggleState(toggle); } -void LLIMChiclet::draw() -{ - LLUICtrl::draw(); -} - -// static -LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id) -{ - EType type = TYPE_UNKNOWN; - - if(session_id.isNull()) - return type; - - EInstantMessage im_type = LLIMModel::getInstance()->getType(session_id); - if (IM_COUNT == im_type) - { - llassert_always(0 && "IM session not found"); // should never happen - return type; - } - - switch(im_type) - { - case IM_NOTHING_SPECIAL: - case IM_SESSION_P2P_INVITE: - type = TYPE_IM; - break; - case IM_SESSION_GROUP_START: - case IM_SESSION_INVITE: - if (gAgent.isInGroup(session_id)) - { - type = TYPE_GROUP; - } - else - { - type = TYPE_AD_HOC; - } - break; - case IM_SESSION_CONFERENCE_START: - type = TYPE_AD_HOC; - default: - break; - } - - return type; -} - BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) { if(!mPopupMenu) @@ -684,382 +385,6 @@ bool LLIMChiclet::canCreateMenu() ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -LLIMP2PChiclet::Params::Params() -: avatar_icon("avatar_icon") -, chiclet_button("chiclet_button") -, unread_notifications("unread_notifications") -, speaker("speaker") -, new_message_icon("new_message_icon") -, show_speaker("show_speaker") -{ -} - -LLIMP2PChiclet::LLIMP2PChiclet(const Params& p) -: LLIMChiclet(p) -, mChicletIconCtrl(NULL) -{ - LLButton::Params button_params = p.chiclet_button; - mChicletButton = LLUICtrlFactory::create<LLButton>(button_params); - addChild(mChicletButton); - - LLIconCtrl::Params new_msg_params = p.new_message_icon; - mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params); - addChild(mNewMessagesIcon); - - LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon; - mChicletIconCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params); - addChild(mChicletIconCtrl); - - LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; - mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params); - addChild(mCounterCtrl); - - setCounter(getCounter()); - setShowCounter(getShowCounter()); - - LLChicletSpeakerCtrl::Params speaker_params = p.speaker; - mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params); - addChild(mSpeakerCtrl); - - sendChildToFront(mNewMessagesIcon); - setShowSpeaker(p.show_speaker); -} - -void LLIMP2PChiclet::initSpeakerControl() -{ - mSpeakerCtrl->setSpeakerId(getOtherParticipantId()); -} - -void LLIMP2PChiclet::setOtherParticipantId(const LLUUID& other_participant_id) -{ - LLIMChiclet::setOtherParticipantId(other_participant_id); - mChicletIconCtrl->setValue(getOtherParticipantId()); -} - -void LLIMP2PChiclet::updateMenuItems() -{ - if(!mPopupMenu) - return; - if(getSessionId().isNull()) - return; - - LLIMFloater* open_im_floater = LLIMFloater::findInstance(getSessionId()); - bool open_window_exists = open_im_floater && open_im_floater->getVisible(); - mPopupMenu->getChild<LLUICtrl>("Send IM")->setEnabled(!open_window_exists); - - bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId()); - mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend); -} - -void LLIMP2PChiclet::createPopupMenu() -{ - if(!canCreateMenu()) - return; - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - registrar.add("IMChicletMenu.Action", boost::bind(&LLIMP2PChiclet::onMenuItemClicked, this, _2)); - - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> - ("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -} - -void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data) -{ - std::string level = user_data.asString(); - LLUUID other_participant_id = getOtherParticipantId(); - - if("profile" == level) - { - LLAvatarActions::showProfile(other_participant_id); - } - else if("im" == level) - { - LLAvatarActions::startIM(other_participant_id); - } - else if("add" == level) - { - LLAvatarActions::requestFriendshipDialog(other_participant_id); - } - else if("end" == level) - { - LLAvatarActions::endIM(other_participant_id); - } -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -LLAdHocChiclet::Params::Params() -: avatar_icon("avatar_icon") -, chiclet_button("chiclet_button") -, unread_notifications("unread_notifications") -, speaker("speaker") -, new_message_icon("new_message_icon") -, show_speaker("show_speaker") -, avatar_icon_color("avatar_icon_color", LLColor4::green) -{ -} - -LLAdHocChiclet::LLAdHocChiclet(const Params& p) -: LLIMChiclet(p) -, mChicletIconCtrl(NULL) -{ - LLButton::Params button_params = p.chiclet_button; - mChicletButton = LLUICtrlFactory::create<LLButton>(button_params); - addChild(mChicletButton); - - LLIconCtrl::Params new_msg_params = p.new_message_icon; - mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params); - addChild(mNewMessagesIcon); - - LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon; - mChicletIconCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params); - //Make the avatar modified - mChicletIconCtrl->setColor(p.avatar_icon_color); - addChild(mChicletIconCtrl); - - LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; - mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params); - addChild(mCounterCtrl); - - setCounter(getCounter()); - setShowCounter(getShowCounter()); - - LLChicletSpeakerCtrl::Params speaker_params = p.speaker; - mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params); - addChild(mSpeakerCtrl); - - sendChildToFront(mNewMessagesIcon); - setShowSpeaker(p.show_speaker); -} - -void LLAdHocChiclet::setSessionId(const LLUUID& session_id) -{ - LLChiclet::setSessionId(session_id); - LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id); - mChicletIconCtrl->setValue(im_session->mOtherParticipantID); -} - -void LLAdHocChiclet::draw() -{ - switchToCurrentSpeaker(); - LLIMChiclet::draw(); -} - -void LLAdHocChiclet::initSpeakerControl() -{ - switchToCurrentSpeaker(); -} - -void LLAdHocChiclet::switchToCurrentSpeaker() -{ - LLUUID speaker_id; - LLSpeakerMgr::speaker_list_t speaker_list; - - LLIMModel::getInstance()->findIMSession(getSessionId())->mSpeakers->getSpeakerList(&speaker_list, FALSE); - for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i) - { - LLPointer<LLSpeaker> s = *i; - if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING) - { - speaker_id = s->mID; - break; - } - } - - mSpeakerCtrl->setSpeakerId(speaker_id); -} - -void LLAdHocChiclet::createPopupMenu() -{ - if(!canCreateMenu()) - return; - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - registrar.add("IMChicletMenu.Action", boost::bind(&LLAdHocChiclet::onMenuItemClicked, this, _2)); - - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> - ("menu_imchiclet_adhoc.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -} - -void LLAdHocChiclet::onMenuItemClicked(const LLSD& user_data) -{ - std::string level = user_data.asString(); - LLUUID group_id = getSessionId(); - - if("end" == level) - { - LLGroupActions::endIM(group_id); - } -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -LLIMGroupChiclet::Params::Params() -: group_icon("group_icon") -, chiclet_button("chiclet_button") -, unread_notifications("unread_notifications") -, speaker("speaker") -, new_message_icon("new_message_icon") -, show_speaker("show_speaker") -{ -} - -LLIMGroupChiclet::LLIMGroupChiclet(const Params& p) -: LLIMChiclet(p) -, LLGroupMgrObserver(LLUUID::null) -, mChicletIconCtrl(NULL) -{ - LLButton::Params button_params = p.chiclet_button; - mChicletButton = LLUICtrlFactory::create<LLButton>(button_params); - addChild(mChicletButton); - - LLIconCtrl::Params new_msg_params = p.new_message_icon; - mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params); - addChild(mNewMessagesIcon); - - LLChicletGroupIconCtrl::Params avatar_params = p.group_icon; - mChicletIconCtrl = LLUICtrlFactory::create<LLChicletGroupIconCtrl>(avatar_params); - addChild(mChicletIconCtrl); - - LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; - mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params); - addChild(mCounterCtrl); - - setCounter(getCounter()); - setShowCounter(getShowCounter()); - - LLChicletSpeakerCtrl::Params speaker_params = p.speaker; - mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params); - addChild(mSpeakerCtrl); - - sendChildToFront(mNewMessagesIcon); - setShowSpeaker(p.show_speaker); -} - -LLIMGroupChiclet::~LLIMGroupChiclet() -{ - LLGroupMgr::getInstance()->removeObserver(this); -} - -void LLIMGroupChiclet::draw() -{ - if(getShowSpeaker()) - { - switchToCurrentSpeaker(); - } - LLIMChiclet::draw(); -} - -void LLIMGroupChiclet::initSpeakerControl() -{ - switchToCurrentSpeaker(); -} - -void LLIMGroupChiclet::switchToCurrentSpeaker() -{ - LLUUID speaker_id; - LLSpeakerMgr::speaker_list_t speaker_list; - - LLIMModel::getInstance()->findIMSession(getSessionId())->mSpeakers->getSpeakerList(&speaker_list, FALSE); - for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i) - { - LLPointer<LLSpeaker> s = *i; - if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING) - { - speaker_id = s->mID; - break; - } - } - - mSpeakerCtrl->setSpeakerId(speaker_id); -} - -void LLIMGroupChiclet::setSessionId(const LLUUID& session_id) -{ - LLChiclet::setSessionId(session_id); - - LLGroupMgr* grp_mgr = LLGroupMgr::getInstance(); - LLGroupMgrGroupData* group_data = grp_mgr->getGroupData(session_id); - if (group_data && group_data->mInsigniaID.notNull()) - { - mChicletIconCtrl->setValue(group_data->mInsigniaID); - } - else - { - if(getSessionId() != mID) - { - grp_mgr->removeObserver(this); - mID = getSessionId(); - grp_mgr->addObserver(this); - } - grp_mgr->sendGroupPropertiesRequest(session_id); - } -} - -void LLIMGroupChiclet::changed(LLGroupChange gc) -{ - if (GC_PROPERTIES == gc) - { - LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(getSessionId()); - if (group_data) - { - mChicletIconCtrl->setValue(group_data->mInsigniaID); - } - } -} - -void LLIMGroupChiclet::updateMenuItems() -{ - if(!mPopupMenu) - return; - if(getSessionId().isNull()) - return; - - LLIMFloater* open_im_floater = LLIMFloater::findInstance(getSessionId()); - bool open_window_exists = open_im_floater && open_im_floater->getVisible(); - mPopupMenu->getChild<LLUICtrl>("Chat")->setEnabled(!open_window_exists); -} - -void LLIMGroupChiclet::createPopupMenu() -{ - if(!canCreateMenu()) - return; - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - registrar.add("IMChicletMenu.Action", boost::bind(&LLIMGroupChiclet::onMenuItemClicked, this, _2)); - - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> - ("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -} - -void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data) -{ - std::string level = user_data.asString(); - LLUUID group_id = getSessionId(); - - if("group chat" == level) - { - LLGroupActions::startIM(group_id); - } - else if("info" == level) - { - LLGroupActions::show(group_id); - } - else if("end" == level) - { - LLGroupActions::endIM(group_id); - } -} - - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - LLChicletPanel::Params::Params() : chiclet_padding("chiclet_padding") , scrolling_offset("scrolling_offset") @@ -1100,33 +425,19 @@ LLChicletPanel::~LLChicletPanel() } } -void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){ - +void LLChicletPanel::onMessageCountChanged(const LLSD& data) +{ LLUUID session_id = data["session_id"].asUUID(); S32 unread = data["participant_unread"].asInteger(); - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id); if (im_floater && im_floater->getVisible() && im_floater->hasFocus()) { unread = 0; } - - std::list<LLChiclet*> chiclets = LLIMChiclet::sFindChicletsSignal(session_id); - std::list<LLChiclet *>::iterator iter; - for (iter = chiclets.begin(); iter != chiclets.end(); iter++) { - LLChiclet* chiclet = *iter; - if (chiclet != NULL) - { - chiclet->setCounter(unread); - } - else - { - llwarns << "Unable to set counter for chiclet " << session_id << llendl; - } - } } -void object_chiclet_callback(const LLSD& data) +void LLChicletPanel::objectChicletCallback(const LLSD& data) { LLUUID notification_id = data["notification_id"]; bool new_message = data["new_message"]; @@ -1138,10 +449,6 @@ void object_chiclet_callback(const LLSD& data) LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*iter); if (chiclet != NULL) { - if(data.has("unread")) - { - chiclet->setCounter(data["unread"]); - } chiclet->setShowNewMessagesIcon(new_message); } } @@ -1150,10 +457,10 @@ void object_chiclet_callback(const LLSD& data) BOOL LLChicletPanel::postBuild() { LLPanel::postBuild(); - LLIMModel::instance().addNewMsgCallback(boost::bind(im_chiclet_callback, this, _1)); - LLIMModel::instance().addNoUnreadMsgsCallback(boost::bind(im_chiclet_callback, this, _1)); - LLScriptFloaterManager::getInstance()->addNewObjectCallback(boost::bind(object_chiclet_callback, _1)); - LLScriptFloaterManager::getInstance()->addToggleObjectFloaterCallback(boost::bind(object_chiclet_callback, _1)); + LLIMModel::instance().addNewMsgCallback(boost::bind(&LLChicletPanel::onMessageCountChanged, this, _1)); + LLIMModel::instance().addNoUnreadMsgsCallback(boost::bind(&LLChicletPanel::onMessageCountChanged, this, _1)); + LLScriptFloaterManager::getInstance()->addNewObjectCallback(boost::bind(&LLChicletPanel::objectChicletCallback, this, _1)); + LLScriptFloaterManager::getInstance()->addToggleObjectFloaterCallback(boost::bind(&LLChicletPanel::objectChicletCallback, this, _1)); LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLChicletPanel::findChiclet<LLChiclet>, this, _1)); LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLChicletPanel::onCurrentVoiceChannelChanged, this, _1)); @@ -1183,28 +490,13 @@ void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id) LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it); if(chiclet) { - chiclet->setShowSpeaker(true); if (gSavedSettings.getBOOL("OpenIMOnVoice")) { - LLIMFloater::show(chiclet->getSessionId()); + LLFloaterIMContainer::getInstance()->showConversation(session_id); } } } - if(!s_previous_active_voice_session_id.isNull() && s_previous_active_voice_session_id != session_id) - { - chiclets = LLIMChiclet::sFindChicletsSignal(s_previous_active_voice_session_id); - - for(std::list<LLChiclet *>::iterator it = chiclets.begin(); it != chiclets.end(); ++it) - { - LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it); - if(chiclet) - { - chiclet->setShowSpeaker(false); - } - } - } - s_previous_active_voice_session_id = session_id; } @@ -1677,7 +969,7 @@ bool LLChicletPanel::isAnyIMFloaterDoked() for (chiclet_list_t::iterator it = mChicletList.begin(); it != mChicletList.end(); it++) { - LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>( + LLFloaterIMSession* im_floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>( "impanel", (*it)->getSessionId()); if (im_floater != NULL && im_floater->getVisible() && !im_floater->isMinimized() && im_floater->isDocked()) @@ -1690,89 +982,17 @@ bool LLChicletPanel::isAnyIMFloaterDoked() return res; } -S32 LLChicletPanel::getTotalUnreadIMCount() -{ - S32 count = 0; - chiclet_list_t::const_iterator it = mChicletList.begin(); - for( ; mChicletList.end() != it; ++it) - { - LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it); - if(chiclet) - { - count += chiclet->getCounter(); - } - } - return count; -} - ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// LLChicletNotificationCounterCtrl::Params::Params() -: max_displayed_count("max_displayed_count", 99) -{ -} - -LLChicletNotificationCounterCtrl::LLChicletNotificationCounterCtrl(const Params& p) - : LLTextBox(p) - , mCounter(0) - , mInitialWidth(0) - , mMaxDisplayedCount(p.max_displayed_count) + : max_displayed_count("max_displayed_count", 99) { - mInitialWidth = getRect().getWidth(); -} - -void LLChicletNotificationCounterCtrl::setCounter(S32 counter) -{ - mCounter = counter; - - // note same code in LLSysWellChiclet::setCounter(S32 counter) - std::string s_count; - if(counter != 0) - { - static std::string more_messages_exist("+"); - std::string more_messages(counter > mMaxDisplayedCount ? more_messages_exist : ""); - s_count = llformat("%d%s" - , llmin(counter, mMaxDisplayedCount) - , more_messages.c_str() - ); - } - - if(mCounter != 0) - { - setText(s_count); - } - else - { - setText(std::string("")); - } -} - -LLRect LLChicletNotificationCounterCtrl::getRequiredRect() -{ - LLRect rc; - S32 text_width = getTextPixelWidth(); - - rc.mRight = rc.mLeft + llmax(text_width, mInitialWidth); - - return rc; -} - -void LLChicletNotificationCounterCtrl::setValue(const LLSD& value) -{ - if(value.isInteger()) - setCounter(value.asInteger()); -} - -LLSD LLChicletNotificationCounterCtrl::getValue() const -{ - return LLSD(getCounter()); } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// - LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p) : LLAvatarIconCtrl(p) { @@ -1782,29 +1002,6 @@ LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p) ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -LLChicletGroupIconCtrl::LLChicletGroupIconCtrl(const Params& p) -: LLIconCtrl(p) -, mDefaultIcon(p.default_icon) -{ - setValue(LLUUID::null); -} - -void LLChicletGroupIconCtrl::setValue(const LLSD& value ) -{ - if(value.asUUID().isNull()) - { - LLIconCtrl::setValue(mDefaultIcon); - } - else - { - LLIconCtrl::setValue(value); - } -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - LLChicletInvOfferIconCtrl::LLChicletInvOfferIconCtrl(const Params& p) : LLChicletAvatarIconCtrl(p) , mDefaultIcon(p.default_icon) @@ -1827,15 +1024,6 @@ void LLChicletInvOfferIconCtrl::setValue(const LLSD& value ) ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p) - : LLOutputMonitorCtrl(p) -{ -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - LLScriptChiclet::Params::Params() : icon("icon") , chiclet_button("chiclet_button") @@ -1871,11 +1059,6 @@ void LLScriptChiclet::setSessionId(const LLUUID& session_id) setToolTip(LLScriptFloaterManager::getObjectName(session_id)); } -void LLScriptChiclet::setCounter(S32 counter) -{ - setShowNewMessagesIcon( counter > 0 ); -} - void LLScriptChiclet::onMouseDown() { LLScriptFloaterManager::getInstance()->toggleScriptFloater(getSessionId()); @@ -1954,11 +1137,6 @@ void LLInvOfferChiclet::setSessionId(const LLUUID& session_id) } } -void LLInvOfferChiclet::setCounter(S32 counter) -{ - setShowNewMessagesIcon( counter > 0 ); -} - void LLInvOfferChiclet::onMouseDown() { LLScriptFloaterManager::instance().toggleScriptFloater(getSessionId()); diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 1f1069dcb4..efaf03384a 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -29,14 +29,11 @@ #include "llavatariconctrl.h" #include "llbutton.h" -#include "llpanel.h" +#include "llnotifications.h" #include "lltextbox.h" -#include "lloutputmonitorctrl.h" -#include "llgroupmgr.h" -#include "llimview.h" class LLMenuGL; -class LLIMFloater; +class LLFloaterIMSession; /** * Class for displaying amount of messages/notifications(unread). @@ -48,11 +45,11 @@ public: struct Params : public LLInitParam::Block<Params, LLTextBox::Params> { /** - * Contains maximum displayed count of unread messages. Default value is 9. - * - * If count is less than "max_unread_count" will be displayed as is. - * Otherwise 9+ will be shown (for default value). - */ + * Contains maximum displayed count of unread messages. Default value is 9. + * + * If count is less than "max_unread_count" will be displayed as is. + * Otherwise 9+ will be shown (for default value). + */ Optional<S32> max_displayed_count; Params(); @@ -120,35 +117,6 @@ protected: }; /** - * Class for displaying group's icon in Group chiclet. - */ -class LLChicletGroupIconCtrl : public LLIconCtrl -{ -public: - - struct Params : public LLInitParam::Block<Params, LLIconCtrl::Params> - { - Optional<std::string> default_icon; - - Params() - : default_icon("default_icon", "Generic_Group") - {} - }; - - /** - * Sets icon, if value is LLUUID::null - default icon will be set. - */ - virtual void setValue(const LLSD& value ); - -protected: - - LLChicletGroupIconCtrl(const Params& p); - friend class LLUICtrlFactory; - - std::string mDefaultIcon; -}; - -/** * Class for displaying icon in inventory offer chiclet. */ class LLChicletInvOfferIconCtrl : public LLChicletAvatarIconCtrl @@ -182,23 +150,6 @@ private: }; /** - * Class for displaying of speaker's voice indicator - */ -class LLChicletSpeakerCtrl : public LLOutputMonitorCtrl -{ -public: - - struct Params : public LLInitParam::Block<Params, LLOutputMonitorCtrl::Params> - { - Params(){}; - }; -protected: - - LLChicletSpeakerCtrl(const Params&p); - friend class LLUICtrlFactory; -}; - -/** * Base class for all chiclets. */ class LLChiclet : public LLUICtrl @@ -213,7 +164,7 @@ public: Params(); }; - /*virtual*/ ~LLChiclet(); + virtual ~LLChiclet() {} /** * Associates chat session id with chiclet. @@ -226,26 +177,11 @@ public: virtual const LLUUID& getSessionId() const { return mSessionId; } /** - * Sets number of unread notifications. - */ - virtual void setCounter(S32 counter) = 0; - - /** - * Returns number of unread notifications. - */ - virtual S32 getCounter() = 0; - - /** * Sets show counter state. */ virtual void setShowCounter(bool show) { mShowCounter = show; } /** - * Returns show counter state. - */ - virtual bool getShowCounter() {return mShowCounter;}; - - /** * Connects chiclet clicked event with callback. */ /*virtual*/ boost::signals2::connection setLeftButtonClickCallback( @@ -322,6 +258,7 @@ public: * It is used for default setting up of chicklet:click handler, etc. */ BOOL postBuild(); + /** * Sets IM session name. This name will be displayed in chiclet tooltip. */ @@ -334,52 +271,11 @@ public: virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; } /** - * Gets id of person/group user is chatting with. + * Enables/disables the counter control for a chiclet. */ - virtual LLUUID getOtherParticipantId() { return mOtherParticipantId; } - - /** - * Init Speaker Control with speaker's ID - */ - virtual void initSpeakerControl(); - - /** - * set status (Shows/Hide) for voice control. - */ - virtual void setShowSpeaker(bool show); - - /** - * Returns voice chat status control visibility. - */ - virtual bool getShowSpeaker() {return mShowSpeaker;}; - - /** - * Shows/Hides for voice control for a chiclet. - */ - virtual void toggleSpeakerControl(); - - /** - * Sets number of unread messages. Will update chiclet's width if number text - * exceeds size of counter and notify it's parent about size change. - */ - virtual void setCounter(S32); - - /** - * Enables/disables the counter control for a chiclet. - */ virtual void enableCounterControl(bool enable); /** - * Sets show counter state. - */ - virtual void setShowCounter(bool show); - - /** - * Shows/Hides for counter control for a chiclet. - */ - virtual void toggleCounterControl(); - - /** * Sets required width for a chiclet according to visible controls. */ virtual void setRequiredWidth(); @@ -394,21 +290,6 @@ public: */ virtual bool getShowNewMessagesIcon(); - virtual void draw(); - - /** - * Determine whether given ID refers to a group or an IM chat session. - * - * This is used when we need to chose what IM chiclet (P2P/group) - * class to instantiate. - * - * @param session_id session ID. - * @return TYPE_GROUP in case of group chat session, - * TYPE_IM in case of P2P session, - * TYPE_UNKNOWN otherwise. - */ - static EType getIMSessionType(const LLUUID& session_id); - /** * The action taken on mouse down event. * @@ -450,8 +331,6 @@ protected: S32 mDefaultWidth; LLIconCtrl* mNewMessagesIcon; - LLChicletNotificationCounterCtrl* mCounterCtrl; - LLChicletSpeakerCtrl* mSpeakerCtrl; LLButton* mChicletButton; /** the id of another participant, either an avatar id or a group id*/ @@ -479,137 +358,6 @@ public: sFindChicletsSignal; }; -/** - * Implements P2P chiclet. - */ -class LLIMP2PChiclet : public LLIMChiclet -{ -public: - struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params> - { - Optional<LLButton::Params> chiclet_button; - - Optional<LLChicletAvatarIconCtrl::Params> avatar_icon; - - Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications; - - Optional<LLChicletSpeakerCtrl::Params> speaker; - - Optional<LLIconCtrl::Params> new_message_icon; - - Optional<bool> show_speaker; - - Params(); - }; - - /* virtual */ void setOtherParticipantId(const LLUUID& other_participant_id); - - /** - * Init Speaker Control with speaker's ID - */ - /*virtual*/ void initSpeakerControl(); - - /** - * Returns number of unread messages. - */ - /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } - -protected: - LLIMP2PChiclet(const Params& p); - friend class LLUICtrlFactory; - - /** - * Creates chiclet popup menu. Will create P2P or Group IM Chat menu - * based on other participant's id. - */ - virtual void createPopupMenu(); - - /** - * Processes clicks on chiclet popup menu. - */ - virtual void onMenuItemClicked(const LLSD& user_data); - - /** - * Enables/disables menus based on relationship with other participant. - * Enables/disables "show session" menu item depending on visible IM floater existence. - */ - virtual void updateMenuItems(); - -private: - - LLChicletAvatarIconCtrl* mChicletIconCtrl; -}; - -/** - * Implements AD-HOC chiclet. - */ -class LLAdHocChiclet : public LLIMChiclet -{ -public: - struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params> - { - Optional<LLButton::Params> chiclet_button; - - Optional<LLChicletAvatarIconCtrl::Params> avatar_icon; - - Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications; - - Optional<LLChicletSpeakerCtrl::Params> speaker; - - Optional<LLIconCtrl::Params> new_message_icon; - - Optional<bool> show_speaker; - - Optional<LLColor4> avatar_icon_color; - - Params(); - }; - - /** - * Sets session id. - * Session ID for group chat is actually Group ID. - */ - /*virtual*/ void setSessionId(const LLUUID& session_id); - - /** - * Keep Speaker Control with actual speaker's ID - */ - /*virtual*/ void draw(); - - /** - * Init Speaker Control with speaker's ID - */ - /*virtual*/ void initSpeakerControl(); - - /** - * Returns number of unread messages. - */ - /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } - -protected: - LLAdHocChiclet(const Params& p); - friend class LLUICtrlFactory; - - /** - * Creates chiclet popup menu. Will create AdHoc Chat menu - * based on other participant's id. - */ - virtual void createPopupMenu(); - - /** - * Processes clicks on chiclet popup menu. - */ - virtual void onMenuItemClicked(const LLSD& user_data); - - /** - * Finds a current speaker and resets the SpeakerControl with speaker's ID - */ - /*virtual*/ void switchToCurrentSpeaker(); - -private: - - LLChicletAvatarIconCtrl* mChicletIconCtrl; -}; /** * Chiclet for script floaters. @@ -631,10 +379,6 @@ public: /*virtual*/ void setSessionId(const LLUUID& session_id); - /*virtual*/ void setCounter(S32 counter); - - /*virtual*/ S32 getCounter() { return 0; } - /** * Toggle script floater */ @@ -680,10 +424,6 @@ public: /*virtual*/ void setSessionId(const LLUUID& session_id); - /*virtual*/ void setCounter(S32 counter); - - /*virtual*/ S32 getCounter() { return 0; } - /** * Toggle script floater */ @@ -708,96 +448,13 @@ private: }; /** - * Implements Group chat chiclet. - */ -class LLIMGroupChiclet : public LLIMChiclet, public LLGroupMgrObserver -{ -public: - - struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params> - { - Optional<LLButton::Params> chiclet_button; - - Optional<LLChicletGroupIconCtrl::Params> group_icon; - - Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications; - - Optional<LLChicletSpeakerCtrl::Params> speaker; - - Optional<LLIconCtrl::Params> new_message_icon; - - Optional<bool> show_speaker; - - Params(); - }; - - /** - * Sets session id. - * Session ID for group chat is actually Group ID. - */ - /*virtual*/ void setSessionId(const LLUUID& session_id); - - /** - * Keep Speaker Control with actual speaker's ID - */ - /*virtual*/ void draw(); - - /** - * Callback for LLGroupMgrObserver, we get this when group data is available or changed. - * Sets group icon. - */ - /*virtual*/ void changed(LLGroupChange gc); - - /** - * Init Speaker Control with speaker's ID - */ - /*virtual*/ void initSpeakerControl(); - - /** - * Returns number of unread messages. - */ - /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } - - ~LLIMGroupChiclet(); - -protected: - LLIMGroupChiclet(const Params& p); - friend class LLUICtrlFactory; - - /** - * Finds a current speaker and resets the SpeakerControl with speaker's ID - */ - /*virtual*/ void switchToCurrentSpeaker(); - - /** - * Creates chiclet popup menu. Will create P2P or Group IM Chat menu - * based on other participant's id. - */ - virtual void createPopupMenu(); - - /** - * Processes clicks on chiclet popup menu. - */ - virtual void onMenuItemClicked(const LLSD& user_data); - - /** - * Enables/disables "show session" menu item depending on visible IM floater existence. - */ - virtual void updateMenuItems(); - -private: - - LLChicletGroupIconCtrl* mChicletIconCtrl; -}; - -/** * Implements notification chiclet. Used to display total amount of unread messages * across all IM sessions, total amount of system notifications. See EXT-3147 for details */ class LLSysWellChiclet : public LLChiclet { public: - + struct Params : public LLInitParam::Block<Params, LLChiclet::Params> { Optional<LLButton::Params> button; @@ -843,7 +500,7 @@ protected: * There is an assumption that it will be called 2*N times to do not change its start state. * @see FlashToLitTimer */ - void changeLitState(); + void changeLitState(bool blink); /** * Displays menu. @@ -859,86 +516,58 @@ protected: S32 mMaxDisplayedCount; bool mIsNewMessagesState; - FlashToLitTimer* mFlashToLitTimer; + LLFlashTimer* mFlashToLitTimer; LLContextMenu* mContextMenu; }; -/** - * Class represented a chiclet for IM Well Icon. - * - * It displays a count of unread messages from other participants in all IM sessions. - */ -class LLIMWellChiclet : public LLSysWellChiclet, LLIMSessionObserver -{ - friend class LLUICtrlFactory; -public: - virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {} - virtual void sessionRemoved(const LLUUID& session_id) { messageCountChanged(LLSD()); } - virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {} - - ~LLIMWellChiclet(); -protected: - LLIMWellChiclet(const Params& p); - - /** - * Processes clicks on chiclet popup menu. - */ - virtual void onMenuItemClicked(const LLSD& user_data); - - /** - * Enables chiclet menu items. - */ - bool enableMenuItem(const LLSD& user_data); - - /** - * Creates menu. - */ - /*virtual*/ void createMenu(); - - /** - * Handles changes in a session (message was added, messages were read, etc.) - * - * It get total count of unread messages from a LLIMMgr in all opened sessions and display it. - * - * @param[in] session_data contains session related data, is not used now - * ["session_id"] - id of an appropriate session - * ["participant_unread"] - count of unread messages from "real" participants. - * - * @see LLIMMgr::getNumberOfUnreadParticipantMessages() - */ - void messageCountChanged(const LLSD& session_data); -}; - class LLNotificationChiclet : public LLSysWellChiclet { + LOG_CLASS(LLNotificationChiclet); + friend class LLUICtrlFactory; public: struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{}; - + protected: + struct ChicletNotificationChannel : public LLNotificationChannel + { + ChicletNotificationChannel(LLNotificationChiclet* chiclet) + : LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString())) + , mChiclet(chiclet) + { + // connect counter handlers to the signals + connectToChannel("Group Notifications"); + connectToChannel("Offer"); + connectToChannel("Notifications"); + } + + static bool filterNotification(LLNotificationPtr notify); + // connect counter updaters to the corresponding signals + /*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); } + /*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); } + + LLNotificationChiclet* const mChiclet; + }; + + boost::scoped_ptr<ChicletNotificationChannel> mNotificationChannel; + LLNotificationChiclet(const Params& p); - + /** * Processes clicks on chiclet menu. */ void onMenuItemClicked(const LLSD& user_data); - + /** * Enables chiclet menu items. */ bool enableMenuItem(const LLSD& user_data); - + /** * Creates menu. */ /*virtual*/ void createMenu(); - // connect counter updaters to the corresponding signals - void connectCounterUpdatersToSignal(const std::string& notification_type); - - // methods for updating a number of unread System notifications - void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications); } - void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications); } /*virtual*/ void setCounter(S32 counter); S32 mUreadSystemNotifications; }; @@ -1044,9 +673,7 @@ public: S32 getMinWidth() const { return mMinWidth; } - S32 getTotalUnreadIMCount(); - - S32 notifyParent(const LLSD& info); + /*virtual*/ S32 notifyParent(const LLSD& info); /** * Toggle chiclet by session id ON and toggle OFF all other chiclets. @@ -1158,6 +785,10 @@ protected: */ void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param); + void onMessageCountChanged(const LLSD& data); + + void objectChicletCallback(const LLSD& data); + typedef std::vector<LLChiclet*> chiclet_list_t; /** diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp index a17e1d13f5..a51c844775 100644 --- a/indra/newview/llchicletbar.cpp +++ b/indra/newview/llchicletbar.cpp @@ -25,44 +25,17 @@ */ #include "llviewerprecompiledheaders.h" // must be first include - #include "llchicletbar.h" -// library includes -#include "llfloaterreg.h" -#include "lllayoutstack.h" - -// newview includes #include "llchiclet.h" -#include "llimfloater.h" // for LLIMFloater +#include "lllayoutstack.h" +#include "llpaneltopinfobar.h" #include "llsyswellwindow.h" 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; @@ -78,109 +51,19 @@ LLChicletBar::LLChicletBar(const LLSD&) : mChicletPanel(NULL), mToolbarStack(NULL) { - // Firstly add our self to IMSession observers, so we catch session events - // before chiclets do that. - LLIMMgr::getInstance()->addSessionObserver(this); - buildFromFile("panel_chiclet_bar.xml"); } -LLChicletBar::~LLChicletBar() -{ - if (!LLSingleton<LLIMMgr>::destroyed()) - { - LLIMMgr::getInstance()->removeSessionObserver(this); - } -} - -LLIMChiclet* LLChicletBar::createIMChiclet(const LLUUID& session_id) -{ - LLIMChiclet::EType im_chiclet_type = LLIMChiclet::getIMSessionType(session_id); - - switch (im_chiclet_type) - { - case LLIMChiclet::TYPE_IM: - return getChicletPanel()->createChiclet<LLIMP2PChiclet>(session_id); - case LLIMChiclet::TYPE_GROUP: - return getChicletPanel()->createChiclet<LLIMGroupChiclet>(session_id); - case LLIMChiclet::TYPE_AD_HOC: - return getChicletPanel()->createChiclet<LLAdHocChiclet>(session_id); - case LLIMChiclet::TYPE_UNKNOWN: - break; - } - - return NULL; -} - -//virtual -void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) -{ - if (!getChicletPanel()) return; - - LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id); - if (!session) return; - - // no need to spawn chiclets for participants in P2P calls called through Avaline - if (session->isP2P() && session->isOtherParticipantAvaline()) return; - - if (getChicletPanel()->findChiclet<LLChiclet>(session_id)) return; - - LLIMChiclet* chiclet = createIMChiclet(session_id); - if(chiclet) - { - chiclet->setIMSessionName(name); - chiclet->setOtherParticipantId(other_participant_id); - - LLIMFloater::onIMChicletCreated(session_id); - - } - else - { - llwarns << "Could not create chiclet" << llendl; - } -} - -//virtual -void LLChicletBar::sessionRemoved(const LLUUID& session_id) -{ - if(getChicletPanel()) - { - // IM floater should be closed when session removed and associated chiclet closed - LLIMFloater* iMfloater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); - if (iMfloater != NULL) - { - iMfloater->closeFloater(); - } - - getChicletPanel()->removeChiclet(session_id); - } -} - -void LLChicletBar::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) -{ - //this is only needed in case of outgoing ad-hoc/group chat sessions - LLChicletPanel* chiclet_panel = getChicletPanel(); - if (chiclet_panel) - { - //it should be ad-hoc im chiclet or group im chiclet - LLChiclet* chiclet = chiclet_panel->findChiclet<LLChiclet>(old_session_id); - if (chiclet) chiclet->setSessionId(new_session_id); - } -} - -S32 LLChicletBar::getTotalUnreadIMCount() -{ - return getChicletPanel()->getTotalUnreadIMCount(); -} - BOOL LLChicletBar::postBuild() { mToolbarStack = getChild<LLLayoutStack>("toolbar_stack"); mChicletPanel = getChild<LLChicletPanel>("chiclet_list"); - showWellButton("im_well", !LLIMWellWindow::getInstance()->isWindowEmpty()); showWellButton("notification_well", !LLNotificationWellWindow::getInstance()->isWindowEmpty()); + LLPanelTopInfoBar::instance().setResizeCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this)); + LLPanelTopInfoBar::instance().setVisibleCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this)); + return TRUE; } @@ -230,15 +113,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 @@ -338,3 +214,33 @@ S32 LLChicletBar::getChicletPanelShrinkHeadroom() const llassert(shrink_headroom >= 0); // the panel cannot get narrower than the minimum return shrink_headroom; } + +void LLChicletBar::fitWithTopInfoBar() +{ + LLPanelTopInfoBar& top_info_bar = LLPanelTopInfoBar::instance(); + + LLRect rect = getRect(); + S32 width = rect.getWidth(); + + if (top_info_bar.getVisible()) + { + S32 delta = top_info_bar.calcScreenRect().mRight - calcScreenRect().mLeft; + if (delta < 0 && rect.mLeft < llabs(delta)) + delta = -rect.mLeft; + rect.setLeftTopAndSize(rect.mLeft + delta, rect.mTop, rect.getWidth(), rect.getHeight()); + width = rect.getWidth() - delta; + } + else + { + LLView* parent = getParent(); + if (parent) + { + LLRect parent_rect = parent->getRect(); + rect.setLeftTopAndSize(0, rect.mTop, rect.getWidth(), rect.getHeight()); + width = parent_rect.getWidth(); + } + } + + setRect(rect); + LLPanel::reshape(width, rect.getHeight(), false); +} diff --git a/indra/newview/llchicletbar.h b/indra/newview/llchicletbar.h index 224dfbb647..956c82cb77 100644 --- a/indra/newview/llchicletbar.h +++ b/indra/newview/llchicletbar.h @@ -28,7 +28,6 @@ #define LL_LLCHICLETBAR_H #include "llpanel.h" -#include "llimview.h" class LLChicletPanel; class LLIMChiclet; @@ -38,30 +37,17 @@ class LLLayoutStack; class LLChicletBar : public LLSingleton<LLChicletBar> , public LLPanel - , public LLIMSessionObserver { LOG_CLASS(LLChicletBar); friend class LLSingleton<LLChicletBar>; public: - ~LLChicletBar(); BOOL postBuild(); LLChicletPanel* getChicletPanel() { return mChicletPanel; } - // LLIMSessionObserver observe triggers - virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id); - virtual void sessionRemoved(const LLUUID& session_id); - void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id); - - S32 getTotalUnreadIMCount(); - /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent); - /** - * Creates IM Chiclet based on session type (IM chat or Group chat) - */ - LLIMChiclet* createIMChiclet(const LLUUID& session_id); /** * Shows/hides panel with specified well button (IM or Notification) @@ -89,6 +75,12 @@ private: */ S32 getChicletPanelShrinkHeadroom() const; + /** + * function adjusts Chiclet bar width to prevent overlapping with Mini-Location bar + * EXP-1463 + */ + void fitWithTopInfoBar(); + protected: LLChicletBar(const LLSD& key = LLSD()); diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 54598f90c8..e9c7a3fa03 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -328,6 +328,19 @@ BOOL LLCOFWearables::postBuild() return LLPanel::postBuild(); } +void LLCOFWearables::setAttachmentsTitle() +{ + if (mAttachmentsTab) + { + U32 free_slots = MAX_AGENT_ATTACHMENTS - mAttachments->size(); + + LLStringUtil::format_map_t args_attachments; + args_attachments["[COUNT]"] = llformat ("%d", free_slots); + std::string attachments_title = LLTrans::getString("Attachments remain", args_attachments); + mAttachmentsTab->setTitle(attachments_title); + } +} + void LLCOFWearables::onSelectionChange(LLFlatListView* selected_list) { if (!selected_list) return; @@ -490,6 +503,7 @@ void LLCOFWearables::populateAttachmentsAndBodypartsLists(const LLInventoryModel { mAttachments->sort(); mAttachments->notify(REARRANGE); //notifying the parent about the list's size change (cause items were added with rearrange=false) + setAttachmentsTitle(); } else { diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h index 1f8d6d0c94..9957d6a64e 100644 --- a/indra/newview/llcofwearables.h +++ b/indra/newview/llcofwearables.h @@ -91,6 +91,8 @@ public: */ void selectClothing(LLWearableType::EType clothing_type); + void setAttachmentsTitle(); + protected: void populateAttachmentsAndBodypartsLists(const LLInventoryModel::item_array_t& cof_items); 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/llcommunicationchannel.cpp b/indra/newview/llcommunicationchannel.cpp new file mode 100644 index 0000000000..0821510645 --- /dev/null +++ b/indra/newview/llcommunicationchannel.cpp @@ -0,0 +1,113 @@ +/** +* @file llcommunicationchannel.cpp +* @brief Implementation of llcommunicationchannel +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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" // must be first include + +#include "llcommunicationchannel.h" + +#include <string> +#include <map> + +#include "llagent.h" +#include "lldate.h" +#include "llnotifications.h" + + +LLCommunicationChannel::LLCommunicationChannel(const std::string& pName, const std::string& pParentName) + : LLNotificationChannel(pName, pParentName, filterByDoNotDisturbStatus) + , mHistory() +{ +} + +LLCommunicationChannel::~LLCommunicationChannel() +{ +} + +bool LLCommunicationChannel::filterByDoNotDisturbStatus(LLNotificationPtr) +{ + return !gAgent.isDoNotDisturb(); +} + +S32 LLCommunicationChannel::getHistorySize() const +{ + return mHistory.size(); +} + +LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::beginHistory() const +{ + return mHistory.begin(); +} + +LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::endHistory() const +{ + return mHistory.end(); +} + +LLCommunicationChannel::history_list_t::iterator LLCommunicationChannel::beginHistory() +{ + return mHistory.begin(); +} + +LLCommunicationChannel::history_list_t::iterator LLCommunicationChannel::endHistory() +{ + return mHistory.end(); +} + +void LLCommunicationChannel::clearHistory() +{ + mHistory.clear(); +} + +void LLCommunicationChannel::removeItemFromHistory(LLNotificationPtr p) +{ + //Find the notification and removes it from mHistory + for(history_list_t::iterator it = beginHistory(); it != endHistory(); ++it) + { + if(it->second == p) + { + mHistory.erase(it); + break; + } + } +} + +void LLCommunicationChannel::onDelete(LLNotificationPtr p) +{ + removeItemFromHistory(p); +} + +void LLCommunicationChannel::onFilterFail(LLNotificationPtr pNotificationPtr) +{ + std::string notificationType = pNotificationPtr->getType(); + if ((notificationType == "groupnotify") + || (notificationType == "offer") + || (notificationType == "notifytoast") + && !pNotificationPtr->isCancelled()) + { + mHistory.insert(std::make_pair<LLDate, LLNotificationPtr>(pNotificationPtr->getDate(), pNotificationPtr)); + } +} diff --git a/indra/newview/llcommunicationchannel.h b/indra/newview/llcommunicationchannel.h new file mode 100644 index 0000000000..0d8f7f4387 --- /dev/null +++ b/indra/newview/llcommunicationchannel.h @@ -0,0 +1,66 @@ +/** +* @file llcommunicationchannel.h +* @brief Header file for llcommunicationchannel +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLCOMMUNICATIONCHANNEL_H +#define LL_LLCOMMUNICATIONCHANNEL_H + +#include <string> +#include <map> + +#include "lldate.h" +#include "llerror.h" +#include "llnotifications.h" + +class LLCommunicationChannel : public LLNotificationChannel +{ + LOG_CLASS(LLCommunicationChannel); +public: + LLCommunicationChannel(const std::string& pName, const std::string& pParentName); + virtual ~LLCommunicationChannel(); + + static bool filterByDoNotDisturbStatus(LLNotificationPtr); + + typedef std::multimap<LLDate, LLNotificationPtr> history_list_t; + S32 getHistorySize() const; + history_list_t::const_iterator beginHistory() const; + history_list_t::const_iterator endHistory() const; + history_list_t::iterator beginHistory(); + history_list_t::iterator endHistory(); + + void clearHistory(); + void removeItemFromHistory(LLNotificationPtr p); + +protected: + virtual void onDelete(LLNotificationPtr p); + virtual void onFilterFail(LLNotificationPtr pNotificationPtr); + +private: + + history_list_t mHistory; +}; + +#endif // LL_LLCOMMUNICATIONCHANNEL_H + diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index a42677845e..4f5f9e22b6 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -100,6 +100,7 @@ BOOL LLFloaterScriptQueue::postBuild() { childSetAction("close",onCloseBtn,this); getChildView("close")->setEnabled(FALSE); + setVisible(true); return TRUE; } @@ -158,7 +159,6 @@ void LLFloaterScriptQueue::addObject(const LLUUID& id) BOOL LLFloaterScriptQueue::start() { - //llinfos << "LLFloaterCompileQueue::start()" << llendl; std::string buffer; LLSelectMgr *mgr = LLSelectMgr::getInstance(); @@ -178,7 +178,7 @@ BOOL LLFloaterScriptQueue::start() args["[COUNT]"] = llformat ("%d", mObjectIDs.count()); buffer = getString ("Starting", args); - getChild<LLScrollListCtrl>("queue output")->setCommentText(buffer); + getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM); return nextObject(); } @@ -211,7 +211,7 @@ BOOL LLFloaterScriptQueue::nextObject() if(isDone() && !mDone) { mDone = true; - getChild<LLScrollListCtrl>("queue output")->setCommentText(getString("Done")); + getChild<LLScrollListCtrl>("queue output")->addSimpleElement(getString("Done"), ADD_BOTTOM); getChildView("close")->setEnabled(TRUE); } return successful_start; @@ -277,7 +277,7 @@ public: return; } - queue->getChild<LLScrollListCtrl>("queue output")->setCommentText(message); + queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(message, ADD_BOTTOM); } private: @@ -464,7 +464,7 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id, } if(queue && (buffer.size() > 0)) { - queue->getChild<LLScrollListCtrl>("queue output")->setCommentText(buffer); + queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM); } delete data; } @@ -637,7 +637,7 @@ void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj, LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); std::string buffer; buffer = getString("Resetting") + (": ") + item->getName(); - getChild<LLScrollListCtrl>("queue output")->setCommentText(buffer); + getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM); LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_ScriptReset); msg->nextBlockFast(_PREHASH_AgentData); @@ -690,7 +690,7 @@ void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj, LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); std::string buffer; buffer = getString("Running") + (": ") + item->getName(); - list->setCommentText(buffer); + list->addSimpleElement(buffer, ADD_BOTTOM); LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_SetScriptRunning); @@ -745,7 +745,7 @@ void LLFloaterNotRunQueue::handleInventory(LLViewerObject* viewer_obj, LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); std::string buffer; buffer = getString("NotRunning") + (": ") +item->getName(); - list->setCommentText(buffer); + list->addSimpleElement(buffer, ADD_BOTTOM); LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_SetScriptRunning); diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp new file mode 100644 index 0000000000..dd20ca15ae --- /dev/null +++ b/indra/newview/llconversationlog.cpp @@ -0,0 +1,612 @@ +/** + * @file llconversationlog.h + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "llagent.h" +#include "llavatarnamecache.h" +#include "llconversationlog.h" +#include "lldiriterator.h" +#include "llnotificationsutil.h" +#include "lltrans.h" + +#include <boost/foreach.hpp> +#include "boost/lexical_cast.hpp" + +const int CONVERSATION_LIFETIME = 30; // lifetime of LLConversation is 30 days by spec + +struct ConversationParams +{ + ConversationParams(time_t time) + : mTime(time), + mTimestamp(LLConversation::createTimestamp(time)) + {} + + time_t mTime; + std::string mTimestamp; + SessionType mConversationType; + std::string mConversationName; + std::string mHistoryFileName; + LLUUID mSessionID; + LLUUID mParticipantID; + bool mHasOfflineIMs; +}; + +/************************************************************************/ +/* LLConversation implementation */ +/************************************************************************/ + +LLConversation::LLConversation(const ConversationParams& params) +: mTime(params.mTime), + mTimestamp(params.mTimestamp), + mConversationType(params.mConversationType), + mConversationName(params.mConversationName), + mHistoryFileName(params.mHistoryFileName), + mSessionID(params.mSessionID), + mParticipantID(params.mParticipantID), + mHasOfflineIMs(params.mHasOfflineIMs) +{ + setListenIMFloaterOpened(); +} + +LLConversation::LLConversation(const LLIMModel::LLIMSession& session) +: mTime(time_corrected()), + mTimestamp(createTimestamp(mTime)), + mConversationType(session.mSessionType), + mConversationName(session.mName), + mHistoryFileName(session.mHistoryFileName), + mSessionID(session.isOutgoingAdHoc() ? session.generateOutgouigAdHocHash() : session.mSessionID), + mParticipantID(session.mOtherParticipantID), + mHasOfflineIMs(session.mHasOfflineMessage) +{ + setListenIMFloaterOpened(); +} + +LLConversation::LLConversation(const LLConversation& conversation) +{ + mTime = conversation.getTime(); + mTimestamp = conversation.getTimestamp(); + mConversationType = conversation.getConversationType(); + mConversationName = conversation.getConversationName(); + mHistoryFileName = conversation.getHistoryFileName(); + mSessionID = conversation.getSessionID(); + mParticipantID = conversation.getParticipantID(); + mHasOfflineIMs = conversation.hasOfflineMessages(); + + setListenIMFloaterOpened(); +} + +LLConversation::~LLConversation() +{ + mIMFloaterShowedConnection.disconnect(); +} + +void LLConversation::updateTimestamp() +{ + mTime = time_corrected(); + mTimestamp = createTimestamp(mTime); +} + +void LLConversation::onIMFloaterShown(const LLUUID& session_id) +{ + if (mSessionID == session_id) + { + mHasOfflineIMs = false; + } +} + +// static +const std::string LLConversation::createTimestamp(const time_t& utc_time) +{ + std::string timeStr; + LLSD substitution; + substitution["datetime"] = (S32) utc_time; + + timeStr = "["+LLTrans::getString ("TimeMonth")+"]/[" + +LLTrans::getString ("TimeDay")+"]/[" + +LLTrans::getString ("TimeYear")+"] [" + +LLTrans::getString ("TimeHour")+"]:[" + +LLTrans::getString ("TimeMin")+"]"; + + + LLStringUtil::format (timeStr, substitution); + return timeStr; +} + +bool LLConversation::isOlderThan(U32 days) const +{ + time_t now = time_corrected(); + U32 age = (U32)((now - mTime) / SEC_PER_DAY); // age of conversation in days + + return age > days; +} + +void LLConversation::setListenIMFloaterOpened() +{ + LLFloaterIMSession* floater = LLFloaterIMSession::findInstance(mSessionID); + + bool offline_ims_visible = LLFloaterIMSession::isVisible(floater) && floater->hasFocus(); + + // we don't need to listen for im floater with this conversation is opened + // if floater is already opened or this conversation doesn't have unread offline messages + if (mHasOfflineIMs && !offline_ims_visible) + { + mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1)); + } + else + { + mHasOfflineIMs = false; + } +} + +/************************************************************************/ +/* LLConversationLogFriendObserver implementation */ +/************************************************************************/ + +// Note : An LLSingleton like LLConversationLog cannot be an LLFriendObserver +// at the same time. +// This is because avatar observers are deleted by the observed object which +// conflicts with the way LLSingleton are deleted. + +class LLConversationLogFriendObserver : public LLFriendObserver +{ +public: + LLConversationLogFriendObserver() {} + virtual ~LLConversationLogFriendObserver() {} + virtual void changed(U32 mask); +}; + +void LLConversationLogFriendObserver::changed(U32 mask) +{ + if (mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE)) + { + LLConversationLog::instance().notifyObservers(); + } +} + +/************************************************************************/ +/* LLConversationLog implementation */ +/************************************************************************/ + +LLConversationLog::LLConversationLog() : + mAvatarNameCacheConnection(), + mLoggingEnabled(false) +{ + LLControlVariable * keep_log_ctrlp = gSavedPerAccountSettings.getControl("KeepConversationLogTranscripts").get(); + S32 log_mode = keep_log_ctrlp->getValue(); + keep_log_ctrlp->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2)); + if (log_mode > 0) + { + loadFromFile(getFileName()); + + enableLogging(log_mode); + } +} + +void LLConversationLog::enableLogging(S32 log_mode) +{ + mLoggingEnabled = log_mode > 0; + if (log_mode > 0) + { + mConversations.clear(); + loadFromFile(getFileName()); + LLIMMgr::instance().addSessionObserver(this); + mNewMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1)); + + mFriendObserver = new LLConversationLogFriendObserver; + LLAvatarTracker::instance().addObserver(mFriendObserver); + } + else + { + saveToFile(getFileName()); + + LLIMMgr::instance().removeSessionObserver(this); + mNewMessageSignalConnection.disconnect(); + LLAvatarTracker::instance().removeObserver(mFriendObserver); + } + + notifyObservers(); +} + +void LLConversationLog::logConversation(const LLUUID& session_id, BOOL has_offline_msg) +{ + const LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); + LLConversation* conversation = findConversation(session); + + if (session && session->mOtherParticipantID != gAgentID) + { + if (conversation) + { + if(has_offline_msg) + { + updateOfflineIMs(session, has_offline_msg); + } + updateConversationTimestamp(conversation); + } + else + { + createConversation(session); + } + } +} + +void LLConversationLog::createConversation(const LLIMModel::LLIMSession* session) +{ + if (session) + { + LLConversation conversation(*session); + mConversations.push_back(conversation); + + if (LLIMModel::LLIMSession::P2P_SESSION == session->mSessionType) + { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(session->mOtherParticipantID, boost::bind(&LLConversationLog::onAvatarNameCache, this, _1, _2, session)); + } + + notifyObservers(); + } +} + +void LLConversationLog::updateConversationName(const LLIMModel::LLIMSession* session, const std::string& name) +{ + if (!session) + { + return; + } + + LLConversation* conversation = findConversation(session); + if (conversation) + { + conversation->setConversationName(name); + notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_NAME); + } +} + +void LLConversationLog::updateOfflineIMs(const LLIMModel::LLIMSession* session, BOOL new_messages) +{ + if (!session) + { + return; + } + + LLConversation* conversation = findConversation(session); + if (conversation) + { + conversation->setOfflineMessages(new_messages); + notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_OfflineIMs); + } +} + +void LLConversationLog::updateConversationTimestamp(LLConversation* conversation) +{ + if (conversation) + { + conversation->updateTimestamp(); + notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_TIME); + } +} + +LLConversation* LLConversationLog::findConversation(const LLIMModel::LLIMSession* session) +{ + if (session) + { + const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID; + + conversations_vec_t::iterator conv_it = mConversations.begin(); + for(; conv_it != mConversations.end(); ++conv_it) + { + if (conv_it->getSessionID() == session_id) + { + return &*conv_it; + } + } + } + + return NULL; +} + +void LLConversationLog::removeConversation(const LLConversation& conversation) +{ + conversations_vec_t::iterator conv_it = mConversations.begin(); + for(; conv_it != mConversations.end(); ++conv_it) + { + if (conv_it->getSessionID() == conversation.getSessionID() && conv_it->getTime() == conversation.getTime()) + { + mConversations.erase(conv_it); + notifyObservers(); + cache(); + return; + } + } +} + +const LLConversation* LLConversationLog::getConversation(const LLUUID& session_id) +{ + conversations_vec_t::const_iterator conv_it = mConversations.begin(); + for(; conv_it != mConversations.end(); ++conv_it) + { + if (conv_it->getSessionID() == session_id) + { + return &*conv_it; + } + } + + return NULL; +} + +void LLConversationLog::addObserver(LLConversationLogObserver* observer) +{ + mObservers.insert(observer); +} + +void LLConversationLog::removeObserver(LLConversationLogObserver* observer) +{ + mObservers.erase(observer); +} + +void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg) +{ + logConversation(session_id, has_offline_msg); +} + +void LLConversationLog::cache() +{ + if (gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0) + { + saveToFile(getFileName()); + } +} + +void LLConversationLog::getListOfBackupLogs(std::vector<std::string>& list_of_backup_logs) +{ + // get Users log directory + std::string dirname = gDirUtilp->getPerAccountChatLogsDir(); + + // add final OS dependent delimiter + dirname += gDirUtilp->getDirDelimiter(); + + // create search pattern + std::string pattern = "conversation.log.backup*"; + + LLDirIterator iter(dirname, pattern); + std::string filename; + while (iter.next(filename)) + { + list_of_backup_logs.push_back(gDirUtilp->add(dirname, filename)); + } +} + +void LLConversationLog::deleteBackupLogs() +{ + std::vector<std::string> backup_logs; + getListOfBackupLogs(backup_logs); + + BOOST_FOREACH(const std::string& fullpath, backup_logs) + { + LLFile::remove(fullpath); + } +} + +bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory) +{ + + std::string backupFileName; + unsigned backupFileCount = 0; + + //Does the file exist in the current path, if it does lets move it + if(LLFile::isfile(originDirectory)) + { + //The target directory contains that file already, so lets store it + if(LLFile::isfile(targetDirectory)) + { + backupFileName = targetDirectory + ".backup"; + + //If needed store backup file as .backup1 etc. + while(LLFile::isfile(backupFileName)) + { + ++backupFileCount; + backupFileName = targetDirectory + ".backup" + boost::lexical_cast<std::string>(backupFileCount); + } + + //Rename the file to its backup name so it is not overwritten + LLFile::rename(targetDirectory, backupFileName); + } + + //Move the file from the current path to target path + if(LLFile::rename(originDirectory, targetDirectory) != 0) + { + return false; + } + } + + return true; +} + +std::string LLConversationLog::getFileName() +{ + std::string filename = "conversation"; + return gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename) + ".log"; +} + +bool LLConversationLog::saveToFile(const std::string& filename) +{ + if (!filename.size()) + { + llwarns << "Call log list filename is empty!" << llendl; + return false; + } + + LLFILE* fp = LLFile::fopen(filename, "wb"); + if (!fp) + { + llwarns << "Couldn't open call log list" << filename << llendl; + return false; + } + + std::string participant_id; + std::string conversation_id; + + conversations_vec_t::const_iterator conv_it = mConversations.begin(); + for (; conv_it != mConversations.end(); ++conv_it) + { + conv_it->getSessionID().toString(conversation_id); + conv_it->getParticipantID().toString(participant_id); + + // examples of two file entries + // [1343221177] 0 1 0 John Doe| 7e4ec5be-783f-49f5-71dz-16c58c64c145 4ec62a74-c246-0d25-2af6-846beac2aa55 john.doe| + // [1343222639] 2 0 0 Ad-hoc Conference| c3g67c89-c479-4c97-b21d-32869bcfe8rc 68f1c33e-4135-3e3e-a897-8c9b23115c09 Ad-hoc Conference hash597394a0-9982-766d-27b8-c75560213b9a| + + fprintf(fp, "[%lld] %d %d %d %s| %s %s %s|\n", + (S64)conv_it->getTime(), + (S32)conv_it->getConversationType(), + (S32)0, + (S32)conv_it->hasOfflineMessages(), + conv_it->getConversationName().c_str(), + participant_id.c_str(), + conversation_id.c_str(), + conv_it->getHistoryFileName().c_str()); + } + fclose(fp); + return true; +} +bool LLConversationLog::loadFromFile(const std::string& filename) +{ + if(!filename.size()) + { + llwarns << "Call log list filename is empty!" << llendl; + return false; + } + + LLFILE* fp = LLFile::fopen(filename, "rb"); + if (!fp) + { + llwarns << "Couldn't open call log list" << filename << llendl; + return false; + } + + char buffer[MAX_STRING]; + char conv_name_buffer[MAX_STRING]; + char part_id_buffer[MAX_STRING]; + char conv_id_buffer[MAX_STRING]; + char history_file_name[MAX_STRING]; + S32 has_offline_ims; + S32 stype; + S64 time; + // before CHUI-348 it was a flag of conversation voice state + int prereserved_unused; + + while (!feof(fp) && fgets(buffer, MAX_STRING, fp)) + { + conv_name_buffer[0] = '\0'; + part_id_buffer[0] = '\0'; + conv_id_buffer[0] = '\0'; + + sscanf(buffer, "[%lld] %d %d %d %[^|]| %s %s %[^|]|", + &time, + &stype, + &prereserved_unused, + &has_offline_ims, + conv_name_buffer, + part_id_buffer, + conv_id_buffer, + history_file_name); + + ConversationParams params((time_t)time); + params.mConversationType = (SessionType)stype; + params.mHasOfflineIMs = has_offline_ims; + params.mConversationName = std::string(conv_name_buffer); + params.mParticipantID = LLUUID(part_id_buffer); + params.mSessionID = LLUUID(conv_id_buffer); + params.mHistoryFileName = std::string(history_file_name); + + LLConversation conversation(params); + + // CHUI-325 + // The conversation log should be capped to the last 30 days. Conversations with the last utterance + // being over 30 days old should be purged from the conversation log text file on login. + if (conversation.isOlderThan(CONVERSATION_LIFETIME)) + { + continue; + } + + mConversations.push_back(conversation); + } + fclose(fp); + + LLFile::remove(filename); + cache(); + + notifyObservers(); + return true; +} + +void LLConversationLog::notifyObservers() +{ + std::set<LLConversationLogObserver*>::const_iterator iter = mObservers.begin(); + for (; iter != mObservers.end(); ++iter) + { + (*iter)->changed(); + } +} + +void LLConversationLog::notifyParticularConversationObservers(const LLUUID& session_id, U32 mask) +{ + std::set<LLConversationLogObserver*>::const_iterator iter = mObservers.begin(); + for (; iter != mObservers.end(); ++iter) + { + (*iter)->changed(session_id, mask); + } +} + +void LLConversationLog::onNewMessageReceived(const LLSD& data) +{ + const LLUUID session_id = data["session_id"].asUUID(); + logConversation(session_id, false); +} + +void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, const LLIMModel::LLIMSession* session) +{ + mAvatarNameCacheConnection.disconnect(); + updateConversationName(session, av_name.getCompleteName()); +} + +void LLConversationLog::onClearLog() +{ + LLNotificationsUtil::add("PreferenceChatClearLog", LLSD(), LLSD(), boost::bind(&LLConversationLog::onClearLogResponse, this, _1, _2)); +} + +void LLConversationLog::onClearLogResponse(const LLSD& notification, const LLSD& response) +{ + if (0 == LLNotificationsUtil::getSelectedOption(notification, response)) + { + mConversations.clear(); + notifyObservers(); + cache(); + deleteBackupLogs(); + } +} diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h new file mode 100644 index 0000000000..265b1f0ef0 --- /dev/null +++ b/indra/newview/llconversationlog.h @@ -0,0 +1,216 @@ +/** + * @file llconversationlog.h + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 LLCONVERSATIONLOG_H_ +#define LLCONVERSATIONLOG_H_ + +#include "llcallingcard.h" +#include "llfloaterimsession.h" +#include "llimview.h" + +class LLConversationLogObserver; +struct ConversationParams; + +typedef LLIMModel::LLIMSession::SType SessionType; + +/* + * This class represents a particular session(conversation) of any type(im/voice/p2p/group/...) by storing some of session's data. + * Each LLConversation object has a corresponding visual representation in a form of LLConversationLogListItem. + */ +class LLConversation +{ +public: + + LLConversation(const ConversationParams& params); + LLConversation(const LLIMModel::LLIMSession& session); + LLConversation(const LLConversation& conversation); + + ~LLConversation(); + + const SessionType& getConversationType() const { return mConversationType; } + const std::string& getConversationName() const { return mConversationName; } + const std::string& getHistoryFileName() const { return mHistoryFileName; } + const LLUUID& getSessionID() const { return mSessionID; } + const LLUUID& getParticipantID() const { return mParticipantID; } + const std::string& getTimestamp() const { return mTimestamp; } + const time_t& getTime() const { return mTime; } + bool hasOfflineMessages() const { return mHasOfflineIMs; } + + void setConversationName(std::string conv_name) { mConversationName = conv_name; } + void setOfflineMessages(bool new_messages) { mHasOfflineIMs = new_messages; } + bool isOlderThan(U32 days) const; + + /* + * updates last interaction time + */ + void updateTimestamp(); + + /* + * Resets flag of unread offline message to false when im floater with this conversation is opened. + */ + void onIMFloaterShown(const LLUUID& session_id); + + /* + * returns string representation(in form of: mm/dd/yyyy hh:mm) of time when conversation was started + */ + static const std::string createTimestamp(const time_t& utc_time); + +private: + + /* + * If conversation has unread offline messages sets callback for opening LLFloaterIMSession + * with this conversation. + */ + void setListenIMFloaterOpened(); + + boost::signals2::connection mIMFloaterShowedConnection; + + time_t mTime; // last interaction time + SessionType mConversationType; + std::string mConversationName; + std::string mHistoryFileName; + LLUUID mSessionID; + LLUUID mParticipantID; + bool mHasOfflineIMs; + std::string mTimestamp; // last interaction time in form of: mm/dd/yyyy hh:mm +}; + +/** + * LLConversationLog stores all agent's conversations. + * This class is responsible for creating and storing LLConversation objects when im or voice session starts. + * Also this class saves/retrieves conversations to/from file. + * + * Also please note that it may be several conversations with the same sessionID stored in the conversation log. + * To distinguish two conversations with the same sessionID it's also needed to compare their creation date. + */ + +class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObserver +{ + friend class LLSingleton<LLConversationLog>; +public: + + void removeConversation(const LLConversation& conversation); + + /** + * Returns first conversation with matched session_id + */ + const LLConversation* getConversation(const LLUUID& session_id); + const std::vector<LLConversation>& getConversations() { return mConversations; } + + void addObserver(LLConversationLogObserver* observer); + void removeObserver(LLConversationLogObserver* observer); + + // LLIMSessionObserver triggers + virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg); + virtual void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}; // Stub + virtual void sessionRemoved(const LLUUID& session_id){} // Stub + virtual void sessionVoiceOrIMStarted(const LLUUID& session_id){}; // Stub + virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id){}; // Stub + + void notifyObservers(); + + void onNewMessageReceived(const LLSD& data); + + /** + * public method which is called on viewer exit to save conversation log + */ + void cache(); + bool moveLog(const std::string &originDirectory, const std::string &targetDirectory); + void getListOfBackupLogs(std::vector<std::string>& list_of_backup_logs); + void deleteBackupLogs(); + + void onClearLog(); + void onClearLogResponse(const LLSD& notification, const LLSD& response); + + bool getIsLoggingEnabled() { return mLoggingEnabled; } + bool isLogEmpty() { return mConversations.empty(); } + + /** + * constructs file name in which conversations log will be saved + * file name is conversation.log + */ + std::string getFileName(); + +private: + + LLConversationLog(); + virtual ~LLConversationLog() + { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + } + + void enableLogging(S32 log_mode); + + /** + * adds conversation to the conversation list and notifies observers + */ + void logConversation(const LLUUID& session_id, BOOL has_offline_msg); + + void notifyParticularConversationObservers(const LLUUID& session_id, U32 mask); + + bool saveToFile(const std::string& filename); + bool loadFromFile(const std::string& filename); + + void onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, const LLIMModel::LLIMSession* session); + + void createConversation(const LLIMModel::LLIMSession* session); + void updateConversationTimestamp(LLConversation* conversation); + void updateConversationName(const LLIMModel::LLIMSession* session, const std::string& name); + void updateOfflineIMs(const LLIMModel::LLIMSession* session, BOOL new_messages); + + LLConversation* findConversation(const LLIMModel::LLIMSession* session); + + typedef std::vector<LLConversation> conversations_vec_t; + std::vector<LLConversation> mConversations; + std::set<LLConversationLogObserver*> mObservers; + + LLFriendObserver* mFriendObserver; // Observer of the LLAvatarTracker instance + + boost::signals2::connection mNewMessageSignalConnection; + boost::signals2::connection mAvatarNameCacheConnection; + + bool mLoggingEnabled; +}; + +class LLConversationLogObserver +{ +public: + + enum EConversationChange + { + CHANGED_TIME = 1, // last interaction time changed + CHANGED_NAME = 2, // conversation name changed + CHANGED_OfflineIMs = 3 + }; + + virtual ~LLConversationLogObserver(){} + virtual void changed() = 0; + virtual void changed(const LLUUID& session_id, U32 mask){}; +}; + +#endif /* LLCONVERSATIONLOG_H_ */ diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp new file mode 100644 index 0000000000..b202cfc9d3 --- /dev/null +++ b/indra/newview/llconversationloglist.cpp @@ -0,0 +1,533 @@ +/** + * @file llconversationloglist.cpp + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "llavataractions.h" +#include "llagent.h" +#include "llfloaterreg.h" +#include "llfloaterconversationpreview.h" +#include "llgroupactions.h" +#include "llconversationloglist.h" +#include "llconversationloglistitem.h" +#include "llviewermenu.h" +#include "lltrans.h" + +static LLDefaultChildRegistry::Register<LLConversationLogList> r("conversation_log_list"); + +static LLConversationLogListNameComparator NAME_COMPARATOR; +static LLConversationLogListDateComparator DATE_COMPARATOR; + +LLConversationLogList::LLConversationLogList(const Params& p) +: LLFlatListViewEx(p), + mIsDirty(true) +{ + LLConversationLog::instance().addObserver(this); + + // Set up context menu. + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar check_registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + + registrar.add ("Calllog.Action", boost::bind(&LLConversationLogList::onCustomAction, this, _2)); + check_registrar.add ("Calllog.Check", boost::bind(&LLConversationLogList::isActionChecked,this, _2)); + enable_registrar.add("Calllog.Enable", boost::bind(&LLConversationLogList::isActionEnabled,this, _2)); + + LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>( + "menu_conversation_log_gear.xml", + gMenuHolder, + LLViewerMenuHolderGL::child_registry_t::instance()); + if(context_menu) + { + mContextMenu = context_menu->getHandle(); + } + + mIsFriendsOnTop = gSavedSettings.getBOOL("SortFriendsFirst"); +} + +LLConversationLogList::~LLConversationLogList() +{ + if (mContextMenu.get()) + { + mContextMenu.get()->die(); + } + + LLConversationLog::instance().removeObserver(this); +} + +void LLConversationLogList::draw() +{ + if (mIsDirty) + { + refresh(); + } + LLFlatListViewEx::draw(); +} + +BOOL LLConversationLogList::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask); + + LLToggleableMenu* context_menu = mContextMenu.get(); + { + context_menu->buildDrawLabels(); + if (context_menu && size()) + context_menu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(this, context_menu, x, y); + } + + return handled; +} + +void LLConversationLogList::setNameFilter(const std::string& filter) +{ + std::string filter_upper = filter; + LLStringUtil::toUpper(filter_upper); + if (mNameFilter != filter_upper) + { + mNameFilter = filter_upper; + setDirty(); + } +} + +bool LLConversationLogList::findInsensitive(std::string haystack, const std::string& needle_upper) +{ + LLStringUtil::toUpper(haystack); + return haystack.find(needle_upper) != std::string::npos; +} + +void LLConversationLogList::sortByName() +{ + setComparator(&NAME_COMPARATOR); + sort(); +} + +void LLConversationLogList::sortByDate() +{ + setComparator(&DATE_COMPARATOR); + sort(); +} + +void LLConversationLogList::toggleSortFriendsOnTop() +{ + mIsFriendsOnTop = !mIsFriendsOnTop; + gSavedSettings.setBOOL("SortFriendsFirst", mIsFriendsOnTop); + sort(); +} + +void LLConversationLogList::changed() +{ + refresh(); +} + +void LLConversationLogList::changed(const LLUUID& session_id, U32 mask) +{ + LLConversationLogListItem* item = getConversationLogListItem(session_id); + + if (!item) + { + return; + } + + if (mask & LLConversationLogObserver::CHANGED_TIME) + { + item->updateTimestamp(); + + // if list is sorted by date and a date of some item has changed, + // than the whole list should be rebuilt + if (E_SORT_BY_DATE == getSortOrder()) + { + mIsDirty = true; + } + } + else if (mask & LLConversationLogObserver::CHANGED_NAME) + { + item->updateName(); + // if list is sorted by name and a name of some item has changed, + // than the whole list should be rebuilt + if (E_SORT_BY_DATE == getSortOrder()) + { + mIsDirty = true; + } + } + else if (mask & LLConversationLogObserver::CHANGED_OfflineIMs) + { + item->updateOfflineIMs(); + } +} + +void LLConversationLogList::addNewItem(const LLConversation* conversation) +{ + LLConversationLogListItem* item = new LLConversationLogListItem(&*conversation); + if (!mNameFilter.empty()) + { + item->highlightNameDate(mNameFilter); + } + addItem(item, conversation->getSessionID(), ADD_TOP); +} + +void LLConversationLogList::refresh() +{ + rebuildList(); + sort(); + + mIsDirty = false; +} + +void LLConversationLogList::rebuildList() +{ + const LLConversation * selected_conversationp = getSelectedConversation(); + + clear(); + + bool have_filter = !mNameFilter.empty(); + LLConversationLog &log_instance = LLConversationLog::instance(); + + const std::vector<LLConversation>& conversations = log_instance.getConversations(); + std::vector<LLConversation>::const_iterator iter = conversations.begin(); + + for (; iter != conversations.end(); ++iter) + { + bool not_found = have_filter && !findInsensitive(iter->getConversationName(), mNameFilter) && !findInsensitive(iter->getTimestamp(), mNameFilter); + if (not_found) + continue; + + addNewItem(&*iter); + } + + // try to restore selection of item + if (NULL != selected_conversationp) + { + selectItemByUUID(selected_conversationp->getSessionID()); + } + + bool logging_enabled = log_instance.getIsLoggingEnabled(); + bool log_empty = log_instance.isLogEmpty(); + if (!logging_enabled && log_empty) + { + setNoItemsCommentText(LLTrans::getString("logging_calls_disabled_log_empty")); + } + else if (!logging_enabled && !log_empty) + { + setNoItemsCommentText(LLTrans::getString("logging_calls_disabled_log_not_empty")); + } + else if (logging_enabled && log_empty) + { + setNoItemsCommentText(LLTrans::getString("logging_calls_enabled_log_empty")); + } + else if (logging_enabled && !log_empty) + { + setNoItemsCommentText(""); + } +} + +void LLConversationLogList::onCustomAction(const LLSD& userdata) +{ + const LLConversation * selected_conversationp = getSelectedConversation(); + + if (NULL == selected_conversationp) + { + return; + } + + const std::string command_name = userdata.asString(); + const LLUUID& selected_conversation_participant_id = selected_conversationp->getParticipantID(); + const LLUUID& selected_conversation_session_id = selected_conversationp->getSessionID(); + LLIMModel::LLIMSession::SType stype = getSelectedSessionType(); + + if ("im" == command_name) + { + switch (stype) + { + case LLIMModel::LLIMSession::P2P_SESSION: + LLAvatarActions::startIM(selected_conversation_participant_id); + break; + + case LLIMModel::LLIMSession::GROUP_SESSION: + LLGroupActions::startIM(selected_conversation_session_id); + break; + + default: + break; + } + } + else if ("call" == command_name) + { + switch (stype) + { + case LLIMModel::LLIMSession::P2P_SESSION: + LLAvatarActions::startCall(selected_conversation_participant_id); + break; + + case LLIMModel::LLIMSession::GROUP_SESSION: + LLGroupActions::startCall(selected_conversation_session_id); + break; + + default: + break; + } + } + else if ("view_profile" == command_name) + { + switch (stype) + { + case LLIMModel::LLIMSession::P2P_SESSION: + LLAvatarActions::showProfile(selected_conversation_participant_id); + break; + + case LLIMModel::LLIMSession::GROUP_SESSION: + LLGroupActions::show(selected_conversation_session_id); + break; + + default: + break; + } + } + else if ("chat_history" == command_name) + { + LLFloaterReg::showInstance("preview_conversation", selected_conversation_session_id, true); + } + else if ("offer_teleport" == command_name) + { + LLAvatarActions::offerTeleport(selected_conversation_participant_id); + } + else if("add_friend" == command_name) + { + if (!LLAvatarActions::isFriend(selected_conversation_participant_id)) + { + LLAvatarActions::requestFriendshipDialog(selected_conversation_participant_id); + } + } + else if("remove_friend" == command_name) + { + if (LLAvatarActions::isFriend(selected_conversation_participant_id)) + { + LLAvatarActions::removeFriendDialog(selected_conversation_participant_id); + } + } + else if ("invite_to_group" == command_name) + { + LLAvatarActions::inviteToGroup(selected_conversation_participant_id); + } + else if ("show_on_map" == command_name) + { + LLAvatarActions::showOnMap(selected_conversation_participant_id); + } + else if ("share" == command_name) + { + LLAvatarActions::share(selected_conversation_participant_id); + } + else if ("pay" == command_name) + { + LLAvatarActions::pay(selected_conversation_participant_id); + } + else if ("block" == command_name) + { + LLAvatarActions::toggleBlock(selected_conversation_participant_id); + } +} + +bool LLConversationLogList::isActionEnabled(const LLSD& userdata) +{ + const LLConversation * selected_conversationp = getSelectedConversation(); + + if (NULL == selected_conversationp || numSelected() > 1) + { + return false; + } + + const std::string command_name = userdata.asString(); + + LLIMModel::LLIMSession::SType stype = getSelectedSessionType(); + const LLUUID& selected_id = selected_conversationp->getParticipantID(); + + bool is_p2p = LLIMModel::LLIMSession::P2P_SESSION == stype; + bool is_group = LLIMModel::LLIMSession::GROUP_SESSION == stype; + + if ("can_im" == command_name || "can_view_profile" == command_name) + { + return is_p2p || is_group; + } + else if ("can_view_chat_history" == command_name) + { + return true; + } + else if ("can_call" == command_name) + { + return (is_p2p || is_group) && LLAvatarActions::canCall(); + } + else if ("add_rem_friend" == command_name || + "can_invite_to_group" == command_name || + "can_share" == command_name || + "can_block" == command_name || + "can_pay" == command_name) + { + return is_p2p; + } + else if("can_offer_teleport" == command_name) + { + return is_p2p && LLAvatarActions::canOfferTeleport(selected_id); + } + else if ("can_show_on_map") + { + return is_p2p && ((LLAvatarTracker::instance().isBuddyOnline(selected_id) && is_agent_mappable(selected_id)) || gAgent.isGodlike()); + } + + return false; +} + +bool LLConversationLogList::isActionChecked(const LLSD& userdata) +{ + const LLConversation * selected_conversationp = getSelectedConversation(); + + if (NULL == selected_conversationp) + { + return false; + } + + const std::string command_name = userdata.asString(); + + const LLUUID& selected_id = selected_conversationp->getParticipantID(); + bool is_p2p = LLIMModel::LLIMSession::P2P_SESSION == getSelectedSessionType(); + + if ("is_blocked" == command_name) + { + return is_p2p && LLAvatarActions::isBlocked(selected_id); + } + else if ("is_friend" == command_name) + { + return is_p2p && LLAvatarActions::isFriend(selected_id); + } + else if ("is_not_friend" == command_name) + { + return is_p2p && !LLAvatarActions::isFriend(selected_id); + } + + return false; +} + +LLIMModel::LLIMSession::SType LLConversationLogList::getSelectedSessionType() +{ + const LLConversationLogListItem* item = getSelectedConversationPanel(); + + if (item) + { + return item->getConversation()->getConversationType(); + } + + return LLIMModel::LLIMSession::NONE_SESSION; +} + +const LLConversationLogListItem* LLConversationLogList::getSelectedConversationPanel() +{ + LLPanel* panel = LLFlatListViewEx::getSelectedItem(); + LLConversationLogListItem* conv_panel = dynamic_cast<LLConversationLogListItem*>(panel); + + return conv_panel; +} + +const LLConversation* LLConversationLogList::getSelectedConversation() +{ + const LLConversationLogListItem* panel = getSelectedConversationPanel(); + + if (panel) + { + return panel->getConversation(); + } + + return NULL; +} + +LLConversationLogListItem* LLConversationLogList::getConversationLogListItem(const LLUUID& session_id) +{ + std::vector<LLPanel*> panels; + LLFlatListViewEx::getItems(panels); + std::vector<LLPanel*>::iterator iter = panels.begin(); + + for (; iter != panels.end(); ++iter) + { + LLConversationLogListItem* item = dynamic_cast<LLConversationLogListItem*>(*iter); + if (item && session_id == item->getConversation()->getSessionID()) + { + return item; + } + } + + return NULL; +} + +LLConversationLogList::ESortOrder LLConversationLogList::getSortOrder() +{ + return static_cast<ESortOrder>(gSavedSettings.getU32("CallLogSortOrder")); +} + +bool LLConversationLogListItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const +{ + const LLConversationLogListItem* conversation_item1 = dynamic_cast<const LLConversationLogListItem*>(item1); + const LLConversationLogListItem* conversation_item2 = dynamic_cast<const LLConversationLogListItem*>(item2); + + if (!conversation_item1 || !conversation_item2) + { + llerror("conversation_item1 and conversation_item2 cannot be null", 0); + return true; + } + + return doCompare(conversation_item1, conversation_item2); +} + +bool LLConversationLogListNameComparator::doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const +{ + std::string name1 = conversation1->getConversation()->getConversationName(); + std::string name2 = conversation2->getConversation()->getConversationName(); + const LLUUID& id1 = conversation1->getConversation()->getParticipantID(); + const LLUUID& id2 = conversation2->getConversation()->getParticipantID(); + + LLStringUtil::toUpper(name1); + LLStringUtil::toUpper(name2); + + bool friends_first = gSavedSettings.getBOOL("SortFriendsFirst"); + if (friends_first && (LLAvatarActions::isFriend(id1) ^ LLAvatarActions::isFriend(id2))) + { + return LLAvatarActions::isFriend(id1); + } + + return name1 < name2; +} + +bool LLConversationLogListDateComparator::doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const +{ + time_t date1 = conversation1->getConversation()->getTime(); + time_t date2 = conversation2->getConversation()->getTime(); + const LLUUID& id1 = conversation1->getConversation()->getParticipantID(); + const LLUUID& id2 = conversation2->getConversation()->getParticipantID(); + + bool friends_first = gSavedSettings.getBOOL("SortFriendsFirst"); + if (friends_first && (LLAvatarActions::isFriend(id1) ^ LLAvatarActions::isFriend(id2))) + { + return LLAvatarActions::isFriend(id1); + } + + return date1 > date2; +} diff --git a/indra/newview/llconversationloglist.h b/indra/newview/llconversationloglist.h new file mode 100644 index 0000000000..62ec57e09e --- /dev/null +++ b/indra/newview/llconversationloglist.h @@ -0,0 +1,153 @@ +/** + * @file llconversationloglist.h + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 LLCONVERSATIONLOGLIST_H_ +#define LLCONVERSATIONLOGLIST_H_ + +#include "llconversationlog.h" +#include "llflatlistview.h" +#include "lltoggleablemenu.h" + +class LLConversationLogListItem; + +/** + * List of all agent's conversations. I.e. history of conversations. + * This list represents contents of the LLConversationLog. + * Each change in LLConversationLog leads to rebuilding this list, so + * it's always in actual state. + */ + +class LLConversationLogList: public LLFlatListViewEx, public LLConversationLogObserver +{ + LOG_CLASS(LLConversationLogList); +public: + + typedef enum e_sort_oder{ + E_SORT_BY_NAME = 0, + E_SORT_BY_DATE = 1, + } ESortOrder; + + struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params> + { + Params(){}; + }; + + LLConversationLogList(const Params& p); + virtual ~LLConversationLogList(); + + virtual void draw(); + + virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + + LLToggleableMenu* getContextMenu() const { return mContextMenu.get(); } + + void addNewItem(const LLConversation* conversation); + void setNameFilter(const std::string& filter); + void sortByName(); + void sortByDate(); + void toggleSortFriendsOnTop(); + bool getSortFriendsOnTop() const { return mIsFriendsOnTop; } + + /** + * Changes from LLConversationLogObserver + */ + virtual void changed(); + virtual void changed(const LLUUID& session_id, U32 mask); + +private: + + void setDirty(bool dirty = true) { mIsDirty = dirty; } + void refresh(); + + /** + * Clears list and re-adds items from LLConverstationLog + * If filter is not empty re-adds items which match the filter + */ + void rebuildList(); + + bool findInsensitive(std::string haystack, const std::string& needle_upper); + + void onCustomAction (const LLSD& userdata); + bool isActionEnabled(const LLSD& userdata); + bool isActionChecked(const LLSD& userdata); + + LLIMModel::LLIMSession::SType getSelectedSessionType(); + const LLConversationLogListItem* getSelectedConversationPanel(); + const LLConversation* getSelectedConversation(); + LLConversationLogListItem* getConversationLogListItem(const LLUUID& session_id); + + ESortOrder getSortOrder(); + + LLHandle<LLToggleableMenu> mContextMenu; + bool mIsDirty; + bool mIsFriendsOnTop; + std::string mNameFilter; +}; + +/** + * Abstract comparator for ConversationLogList items + */ +class LLConversationLogListItemComparator : public LLFlatListView::ItemComparator +{ + LOG_CLASS(LLConversationLogListItemComparator); + +public: + LLConversationLogListItemComparator() {}; + virtual ~LLConversationLogListItemComparator() {}; + + virtual bool compare(const LLPanel* item1, const LLPanel* item2) const; + +protected: + + virtual bool doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const = 0; +}; + +class LLConversationLogListNameComparator : public LLConversationLogListItemComparator +{ + LOG_CLASS(LLConversationLogListNameComparator); + +public: + LLConversationLogListNameComparator() {}; + virtual ~LLConversationLogListNameComparator() {}; + +protected: + + virtual bool doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const; +}; + +class LLConversationLogListDateComparator : public LLConversationLogListItemComparator +{ + LOG_CLASS(LLConversationLogListDateComparator); + +public: + LLConversationLogListDateComparator() {}; + virtual ~LLConversationLogListDateComparator() {}; + +protected: + + virtual bool doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const; +}; + +#endif /* LLCONVERSATIONLOGLIST_H_ */ diff --git a/indra/newview/llconversationloglistitem.cpp b/indra/newview/llconversationloglistitem.cpp new file mode 100644 index 0000000000..4e984d603b --- /dev/null +++ b/indra/newview/llconversationloglistitem.cpp @@ -0,0 +1,184 @@ +/** + * @file llconversationloglistitem.cpp + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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" + +// llui +#include "lliconctrl.h" +#include "lltextbox.h" +#include "lltextutil.h" + +// newview +#include "llavataractions.h" +#include "llavatariconctrl.h" +#include "llconversationlog.h" +#include "llconversationloglistitem.h" +#include "llgroupactions.h" +#include "llgroupiconctrl.h" +#include "llinventoryicon.h" + +LLConversationLogListItem::LLConversationLogListItem(const LLConversation* conversation) +: LLPanel(), + mConversation(conversation), + mConversationName(NULL), + mConversationDate(NULL) +{ + buildFromFile("panel_conversation_log_list_item.xml"); + + LLFloaterIMSession* floater = LLFloaterIMSession::findInstance(mConversation->getSessionID()); + + bool ims_are_read = LLFloaterIMSession::isVisible(floater) && floater->hasFocus(); + + if (mConversation->hasOfflineMessages() && !ims_are_read) + { + mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback(boost::bind(&LLConversationLogListItem::onIMFloaterShown, this, _1)); + } +} + +LLConversationLogListItem::~LLConversationLogListItem() +{ + mIMFloaterShowedConnection.disconnect(); +} + +BOOL LLConversationLogListItem::postBuild() +{ + initIcons(); + + // set conversation name + mConversationName = getChild<LLTextBox>("conversation_name"); + mConversationName->setValue(mConversation->getConversationName()); + + // set conversation date and time + mConversationDate = getChild<LLTextBox>("date_time"); + mConversationDate->setValue(mConversation->getTimestamp()); + + getChild<LLButton>("delete_btn")->setClickedCallback(boost::bind(&LLConversationLogListItem::onRemoveBtnClicked, this)); + setDoubleClickCallback(boost::bind(&LLConversationLogListItem::onDoubleClick, this)); + + return TRUE; +} + +void LLConversationLogListItem::initIcons() +{ + switch (mConversation->getConversationType()) + { + case LLIMModel::LLIMSession::P2P_SESSION: + case LLIMModel::LLIMSession::ADHOC_SESSION: + { + LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon"); + avatar_icon->setVisible(TRUE); + avatar_icon->setValue(mConversation->getParticipantID()); + break; + } + case LLIMModel::LLIMSession::GROUP_SESSION: + { + LLGroupIconCtrl* group_icon = getChild<LLGroupIconCtrl>("group_icon"); + group_icon->setVisible(TRUE); + group_icon->setValue(mConversation->getSessionID()); + break; + } + default: + break; + } + + if (mConversation->hasOfflineMessages()) + { + getChild<LLIconCtrl>("unread_ims_icon")->setVisible(TRUE); + } +} + +void LLConversationLogListItem::updateTimestamp() +{ + mConversationDate->setValue(mConversation->getTimestamp()); +} + +void LLConversationLogListItem::updateName() +{ + mConversationName->setValue(mConversation->getConversationName()); +} + +void LLConversationLogListItem::updateOfflineIMs() +{ + getChild<LLIconCtrl>("unread_ims_icon")->setVisible(mConversation->hasOfflineMessages()); +} + +void LLConversationLogListItem::onMouseEnter(S32 x, S32 y, MASK mask) +{ + getChildView("hovered_icon")->setVisible(true); + LLPanel::onMouseEnter(x, y, mask); +} + +void LLConversationLogListItem::onMouseLeave(S32 x, S32 y, MASK mask) +{ + getChildView("hovered_icon")->setVisible(false); + LLPanel::onMouseLeave(x, y, mask); +} + +void LLConversationLogListItem::setValue(const LLSD& value) +{ + if (!value.isMap() || !value.has("selected")) + { + return; + } + + getChildView("selected_icon")->setVisible(value["selected"]); +} + +void LLConversationLogListItem::onIMFloaterShown(const LLUUID& session_id) +{ + if (mConversation->getSessionID() == session_id) + { + getChild<LLIconCtrl>("unread_ims_icon")->setVisible(FALSE); + } +} + +void LLConversationLogListItem::onRemoveBtnClicked() +{ + LLConversationLog::instance().removeConversation(*mConversation); +} + +void LLConversationLogListItem::highlightNameDate(const std::string& highlited_text) +{ + LLStyle::Params params; + LLTextUtil::textboxSetHighlightedVal(mConversationName, params, mConversation->getConversationName(), highlited_text); + LLTextUtil::textboxSetHighlightedVal(mConversationDate, params, mConversation->getTimestamp(), highlited_text); +} + +void LLConversationLogListItem::onDoubleClick() +{ + switch (mConversation->getConversationType()) + { + case LLIMModel::LLIMSession::P2P_SESSION: + LLAvatarActions::startIM(mConversation->getParticipantID()); + break; + + case LLIMModel::LLIMSession::GROUP_SESSION: + LLGroupActions::startIM(mConversation->getSessionID()); + break; + + default: + break; + } +} diff --git a/indra/newview/llconversationloglistitem.h b/indra/newview/llconversationloglistitem.h new file mode 100644 index 0000000000..ee28456bbb --- /dev/null +++ b/indra/newview/llconversationloglistitem.h @@ -0,0 +1,86 @@ +/** + * @file llconversationloglistitem.h + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 LLCONVERSATIONLOGLISTITEM_H_ +#define LLCONVERSATIONLOGLISTITEM_H_ + +#include "llfloaterimsession.h" +#include "llpanel.h" + +class LLTextBox; +class LLConversation; + +/** + * This class is a visual representation of LLConversation, each of which is LLConversationLog entry. + * LLConversationLogList consists of these LLConversationLogListItems. + * LLConversationLogListItem consists of: + * conversaion_type_icon + * conversaion_name + * conversaion_date + * Also LLConversationLogListItem holds pointer to its LLConversationLog. + */ + +class LLConversationLogListItem : public LLPanel +{ +public: + LLConversationLogListItem(const LLConversation* conversation); + virtual ~LLConversationLogListItem(); + + void onMouseEnter(S32 x, S32 y, MASK mask); + void onMouseLeave(S32 x, S32 y, MASK mask); + + virtual void setValue(const LLSD& value); + + virtual BOOL postBuild(); + + void onIMFloaterShown(const LLUUID& session_id); + void onRemoveBtnClicked(); + + const LLConversation* getConversation() const { return mConversation; } + + void highlightNameDate(const std::string& highlited_text); + + void onDoubleClick(); + + /** + * updates string value of last interaction time from conversation + */ + void updateTimestamp(); + void updateName(); + void updateOfflineIMs(); + +private: + + void initIcons(); + + const LLConversation* mConversation; + + LLTextBox* mConversationName; + LLTextBox* mConversationDate; + + boost::signals2::connection mIMFloaterShowedConnection; +}; + +#endif /* LLCONVERSATIONLOGITEM_H_ */ diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp new file mode 100644 index 0000000000..009fce0a92 --- /dev/null +++ b/indra/newview/llconversationmodel.cpp @@ -0,0 +1,700 @@ +/** + * @file llconversationmodel.cpp + * @brief Implementation of conversations list + * + * $LicenseInfo:firstyear=2009&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 "llagent.h" +#include "llavatarnamecache.h" +#include "llavataractions.h" +#include "llevents.h" +#include "llfloaterimsession.h" +#include "llsdutil.h" +#include "llconversationmodel.h" +#include "llimview.h" //For LLIMModel +#include "lltrans.h" + +#include <boost/foreach.hpp> + +// +// Conversation items : common behaviors +// + +LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) : + LLFolderViewModelItemCommon(root_view_model), + mName(display_name), + mUUID(uuid), + mNeedsRefresh(true), + mConvType(CONV_UNKNOWN), + mLastActiveTime(0.0), + mDisplayModeratorOptions(false), + mAvatarNameCacheConnection() +{ +} + +LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) : + LLFolderViewModelItemCommon(root_view_model), + mName(""), + mUUID(uuid), + mNeedsRefresh(true), + mConvType(CONV_UNKNOWN), + mLastActiveTime(0.0), + mDisplayModeratorOptions(false), + mAvatarNameCacheConnection() +{ +} + +LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_model) : + LLFolderViewModelItemCommon(root_view_model), + mName(""), + mUUID(), + mNeedsRefresh(true), + mConvType(CONV_UNKNOWN), + mLastActiveTime(0.0), + mDisplayModeratorOptions(false), + mAvatarNameCacheConnection() +{ +} + +LLConversationItem::~LLConversationItem() +{ + // Disconnect any previous avatar name cache connection to ensure + // that the callback method is not called after destruction + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } +} + +void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant) +{ + LLUUID session_id = (session ? session->getUUID() : LLUUID()); + LLUUID participant_id = (participant ? participant->getUUID() : LLUUID()); + LLSD event(LLSDMap("type", event_type)("session_uuid", session_id)("participant_uuid", participant_id)); + LLEventPumps::instance().obtain("ConversationsEvents").post(event); +} + +// Virtual action callbacks +void LLConversationItem::performAction(LLInventoryModel* model, std::string action) +{ +} + +void LLConversationItem::openItem( void ) +{ +} + +void LLConversationItem::closeItem( void ) +{ +} + +void LLConversationItem::previewItem( void ) +{ +} + +void LLConversationItem::showProperties(void) +{ +} + +void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32 flags) +{ + if (flags & ITEM_IN_MULTI_SELECTION) + { + items.push_back(std::string("im")); + items.push_back(std::string("offer_teleport")); + items.push_back(std::string("voice_call")); + items.push_back(std::string("remove_friends")); + } + else + { + items.push_back(std::string("view_profile")); + items.push_back(std::string("im")); + items.push_back(std::string("offer_teleport")); + items.push_back(std::string("voice_call")); + items.push_back(std::string("chat_history")); + items.push_back(std::string("separator_chat_history")); + items.push_back(std::string("add_friend")); + items.push_back(std::string("remove_friend")); + items.push_back(std::string("invite_to_group")); + items.push_back(std::string("separator_invite_to_group")); + items.push_back(std::string("map")); + items.push_back(std::string("share")); + items.push_back(std::string("pay")); + items.push_back(std::string("block_unblock")); + items.push_back(std::string("MuteText")); + + if ((getType() != CONV_SESSION_1_ON_1) && mDisplayModeratorOptions) + { + items.push_back(std::string("Moderator Options Separator")); + items.push_back(std::string("Moderator Options")); + items.push_back(std::string("AllowTextChat")); + items.push_back(std::string("moderate_voice_separator")); + items.push_back(std::string("ModerateVoiceMuteSelected")); + items.push_back(std::string("ModerateVoiceUnMuteSelected")); + items.push_back(std::string("ModerateVoiceMute")); + items.push_back(std::string("ModerateVoiceUnmute")); + } + } +} + +// method does subscription to changes in avatar name cache for current session/participant conversation item. +void LLConversationItem::fetchAvatarName(bool isParticipant /*= true*/) +{ + LLUUID item_id = getUUID(); + + // item should not be null for participants + if (isParticipant) + { + llassert(item_id.notNull()); + } + + // disconnect any previous avatar name cache connection + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + + // exclude nearby chat item + if (item_id.notNull()) + { + // for P2P session item, override it as item of called agent + if (CONV_SESSION_1_ON_1 == getType()) + { + item_id = LLIMModel::getInstance()->getOtherParticipantID(item_id); + } + + // subscribe on avatar name cache changes for participant and session items + mAvatarNameCacheConnection = LLAvatarNameCache::get(item_id, boost::bind(&LLConversationItem::onAvatarNameCache, this, _2)); + } +} + +// +// LLConversationItemSession +// + +LLConversationItemSession::LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) : + LLConversationItem(display_name,uuid,root_view_model), + mIsLoaded(false) +{ + mConvType = CONV_SESSION_UNKNOWN; +} + +LLConversationItemSession::LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) : + LLConversationItem(uuid,root_view_model) +{ + mConvType = CONV_SESSION_UNKNOWN; +} + +bool LLConversationItemSession::hasChildren() const +{ + return getChildrenCount() > 0; +} + +void LLConversationItemSession::addParticipant(LLConversationItemParticipant* participant) +{ + addChild(participant); + mIsLoaded = true; + mNeedsRefresh = true; + updateName(participant); + postEvent("add_participant", this, participant); +} + +void LLConversationItemSession::updateName(LLConversationItemParticipant* participant) +{ + EConversationType conversation_type = getType(); + // We modify the session name only in the case of an ad-hoc session or P2P session, exit otherwise (nothing to do) + if ((conversation_type != CONV_SESSION_AD_HOC) && (conversation_type != CONV_SESSION_1_ON_1)) + { + return; + } + + // Avoid changing the default name if no participant present yet + if (mChildren.size() == 0) + { + return; + } + + uuid_vec_t temp_uuids; // uuids vector for building the added participants' names string + if (conversation_type == CONV_SESSION_AD_HOC || conversation_type == CONV_SESSION_1_ON_1) + { + // Build a string containing the participants UUIDs (minus own agent) and check if ready for display (we don't want "(waiting)" in there) + // Note: we don't bind ourselves to the LLAvatarNameCache event as updateParticipantName() is called by + // onAvatarNameCache() which is itself attached to the same event. + + // In the case of a P2P conversation, we need to grab the name of the other participant in the session instance itself + // as we do not create participants for such a session. + + LLFolderViewModelItem * itemp; + BOOST_FOREACH(itemp, mChildren) + { + LLConversationItem* current_participant = dynamic_cast<LLConversationItem*>(itemp); + // Add the avatar uuid to the list (except if it's the own agent uuid) + if (current_participant->getUUID() != gAgentID) + { + LLAvatarName av_name; + if (LLAvatarNameCache::get(current_participant->getUUID(), &av_name)) + { + temp_uuids.push_back(current_participant->getUUID()); + + if (conversation_type == CONV_SESSION_1_ON_1) + { + break; + } + } + } + } + } + + if (temp_uuids.size() != 0) + { + std::string new_session_name; + LLAvatarActions::buildResidentsString(temp_uuids, new_session_name); + renameItem(new_session_name); + postEvent("update_session", this, NULL); + } +} + +void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant) +{ + removeChild(participant); + mNeedsRefresh = true; + updateName(participant); + postEvent("remove_participant", this, participant); +} + +void LLConversationItemSession::removeParticipant(const LLUUID& participant_id) +{ + LLConversationItemParticipant* participant = findParticipant(participant_id); + if (participant) + { + removeParticipant(participant); + } +} + +void LLConversationItemSession::clearParticipants() +{ + clearChildren(); + mIsLoaded = false; + mNeedsRefresh = true; +} + +LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id) +{ + // This is *not* a general tree parsing algorithm. It assumes that a session contains only + // items (LLConversationItemParticipant) that have themselve no children. + LLConversationItemParticipant* participant = NULL; + child_list_t::iterator iter; + for (iter = mChildren.begin(); iter != mChildren.end(); iter++) + { + participant = dynamic_cast<LLConversationItemParticipant*>(*iter); + if (participant->hasSameValue(participant_id)) + { + break; + } + } + return (iter == mChildren.end() ? NULL : participant); +} + +void LLConversationItemSession::setParticipantIsMuted(const LLUUID& participant_id, bool is_muted) +{ + LLConversationItemParticipant* participant = findParticipant(participant_id); + if (participant) + { + participant->muteVoice(is_muted); + } +} + +void LLConversationItemSession::setParticipantIsModerator(const LLUUID& participant_id, bool is_moderator) +{ + LLConversationItemParticipant* participant = findParticipant(participant_id); + if (participant) + { + participant->setIsModerator(is_moderator); + } +} + +void LLConversationItemSession::setTimeNow(const LLUUID& participant_id) +{ + mLastActiveTime = LLFrameTimer::getElapsedSeconds(); + mNeedsRefresh = true; + LLConversationItemParticipant* participant = findParticipant(participant_id); + if (participant) + { + participant->setTimeNow(); + } +} + +void LLConversationItemSession::setDistance(const LLUUID& participant_id, F64 dist) +{ + LLConversationItemParticipant* participant = findParticipant(participant_id); + if (participant) + { + participant->setDistance(dist); + mNeedsRefresh = true; + } +} + +void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + lldebugs << "LLConversationItemParticipant::buildContextMenu()" << llendl; + menuentry_vec_t items; + menuentry_vec_t disabled_items; + + if(this->getType() == CONV_SESSION_1_ON_1) + { + items.push_back(std::string("close_conversation")); + items.push_back(std::string("separator_disconnect_from_voice")); + buildParticipantMenuOptions(items, flags); + } + else if(this->getType() == CONV_SESSION_GROUP) + { + items.push_back(std::string("close_conversation")); + addVoiceOptions(items); + items.push_back(std::string("chat_history")); + items.push_back(std::string("separator_chat_history")); + items.push_back(std::string("group_profile")); + items.push_back(std::string("activate_group")); + items.push_back(std::string("leave_group")); + } + else if(this->getType() == CONV_SESSION_AD_HOC) + { + items.push_back(std::string("close_conversation")); + addVoiceOptions(items); + items.push_back(std::string("chat_history")); + } + + hide_context_entries(menu, items, disabled_items); +} + +void LLConversationItemSession::addVoiceOptions(menuentry_vec_t& items) +{ + LLVoiceChannel* voice_channel = LLIMModel::getInstance() ? LLIMModel::getInstance()->getVoiceChannel(this->getUUID()) : NULL; + + if(voice_channel != LLVoiceChannel::getCurrentVoiceChannel()) + { + items.push_back(std::string("open_voice_conversation")); + } + else + { + items.push_back(std::string("disconnect_from_voice")); + } +} + +// The time of activity of a session is the time of the most recent activity, session and participants included +const bool LLConversationItemSession::getTime(F64& time) const +{ + F64 most_recent_time = mLastActiveTime; + bool has_time = (most_recent_time > 0.1); + LLConversationItemParticipant* participant = NULL; + child_list_t::const_iterator iter; + for (iter = mChildren.begin(); iter != mChildren.end(); iter++) + { + participant = dynamic_cast<LLConversationItemParticipant*>(*iter); + F64 participant_time; + if (participant->getTime(participant_time)) + { + has_time = true; + most_recent_time = llmax(most_recent_time,participant_time); + } + } + if (has_time) + { + time = most_recent_time; + } + return has_time; +} + +void LLConversationItemSession::dumpDebugData(bool dump_children) +{ + // Session info + llinfos << "Merov debug : session " << this << ", uuid = " << mUUID << ", name = " << mName << ", is loaded = " << mIsLoaded << llendl; + // Children info + if (dump_children) + { + for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); iter++) + { + LLConversationItemParticipant* participant = dynamic_cast<LLConversationItemParticipant*>(*iter); + if (participant) + { + participant->dumpDebugData(); + } + } + } +} + +// should be invoked only for P2P sessions +void LLConversationItemSession::onAvatarNameCache(const LLAvatarName& av_name) +{ + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + + renameItem(av_name.getDisplayName()); + postEvent("update_session", this, NULL); +} + +// +// LLConversationItemParticipant +// + +LLConversationItemParticipant::LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) : + LLConversationItem(display_name,uuid,root_view_model), + mIsModerator(false), + mDisplayModeratorLabel(false), + mDistToAgent(-1.0) +{ + mDisplayName = display_name; + mConvType = CONV_PARTICIPANT; +} + +LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) : + LLConversationItem(uuid,root_view_model), + mIsModerator(false), + mDisplayModeratorLabel(false), + mDistToAgent(-1.0) +{ + mConvType = CONV_PARTICIPANT; +} + +void LLConversationItemParticipant::updateName() +{ + llassert(getUUID().notNull()); + if (getUUID().notNull()) + { + LLAvatarName av_name; + if (LLAvatarNameCache::get(getUUID(),&av_name)) + { + updateName(av_name); + } + } +} + +void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_name) +{ + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + + updateName(av_name); +} + +void LLConversationItemParticipant::updateName(const LLAvatarName& av_name) +{ + mName = av_name.getUserName(); + mDisplayName = av_name.getDisplayName(); + + if (mDisplayModeratorLabel) + { + mDisplayName += " " + LLTrans::getString("IM_moderator_label"); + } + + renameItem(mDisplayName); + if (mParent != NULL) + { + LLConversationItemSession* parent_session = dynamic_cast<LLConversationItemSession*>(mParent); + if (parent_session != NULL) + { + parent_session->requestSort(); + parent_session->updateName(this); + postEvent("update_participant", parent_session, this); + } + } +} + +void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + menuentry_vec_t items; + menuentry_vec_t disabled_items; + + buildParticipantMenuOptions(items, flags); + + hide_context_entries(menu, items, disabled_items); +} + +LLConversationItemSession* LLConversationItemParticipant::getParentSession() +{ + LLConversationItemSession* parent_session = NULL; + if (hasParent()) + { + parent_session = dynamic_cast<LLConversationItemSession*>(mParent); + } + return parent_session; +} + +void LLConversationItemParticipant::dumpDebugData() +{ + llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", display name = " << mDisplayName << ", muted = " << isVoiceMuted() << ", moderator = " << mIsModerator << llendl; +} + +void LLConversationItemParticipant::setDisplayModeratorRole(bool displayRole) +{ + if (displayRole != mDisplayModeratorLabel) + { + mDisplayModeratorLabel = displayRole; + updateName(); + } +} + +bool LLConversationItemParticipant::isVoiceMuted() +{ + return LLMuteList::getInstance()->isMuted(mUUID, LLMute::flagVoiceChat); +} + +void LLConversationItemParticipant::muteVoice(bool mute_voice) +{ + std::string name; + gCacheName->getFullName(mUUID, name); + LLMuteList * mute_listp = LLMuteList::getInstance(); + bool voice_already_muted = mute_listp->isMuted(mUUID, name); + + LLMute mute(mUUID, name, LLMute::AGENT); + if (voice_already_muted && !mute_voice) + { + mute_listp->remove(mute); + } + else if (!voice_already_muted && mute_voice) + { + mute_listp->add(mute); + } +} + +// +// LLConversationSort +// + +// Comparison operator: returns "true" is a comes before b, "false" otherwise +bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const +{ + LLConversationItem::EConversationType type_a = a->getType(); + LLConversationItem::EConversationType type_b = b->getType(); + + if ((type_a == LLConversationItem::CONV_PARTICIPANT) && (type_b == LLConversationItem::CONV_PARTICIPANT)) + { + // If both items are participants + U32 sort_order = getSortOrderParticipants(); + if (sort_order == LLConversationFilter::SO_DATE) + { + F64 time_a = 0.0; + F64 time_b = 0.0; + bool has_time_a = a->getTime(time_a); + bool has_time_b = b->getTime(time_b); + if (has_time_a && has_time_b) + { + // Most recent comes first + return (time_a > time_b); + } + else if (has_time_a || has_time_b) + { + // If we have only one time available, the element with time must come first + return has_time_a; + } + // If no time available, we'll default to sort by name at the end of this method + } + else if (sort_order == LLConversationFilter::SO_DISTANCE) + { + F64 dist_a = 0.0; + F64 dist_b = 0.0; + bool has_dist_a = a->getDistanceToAgent(dist_a); + bool has_dist_b = b->getDistanceToAgent(dist_b); + if (has_dist_a && has_dist_b) + { + // Closest comes first + return (dist_a < dist_b); + } + else if (has_dist_a || has_dist_b) + { + // If we have only one distance available, the element with it must come first + return has_dist_a; + } + // If no distance available, we'll default to sort by name at the end of this method + } + } + else if ((type_a > LLConversationItem::CONV_PARTICIPANT) && (type_b > LLConversationItem::CONV_PARTICIPANT)) + { + // If both are sessions + U32 sort_order = getSortOrderSessions(); + + if (sort_order == LLConversationFilter::SO_DATE) + { + // Sort by time + F64 time_a = 0.0; + F64 time_b = 0.0; + bool has_time_a = a->getTime(time_a); + bool has_time_b = b->getTime(time_b); + if (has_time_a && has_time_b) + { + // Most recent comes first + return (time_a > time_b); + } + else if (has_time_a || has_time_b) + { + // If we have only one time available, the element with time must come first + return has_time_a; + } + // If no time available, we'll default to sort by name at the end of this method + } + else + { + if ((type_a == LLConversationItem::CONV_SESSION_NEARBY) || (type_b == LLConversationItem::CONV_SESSION_NEARBY)) + { + // If one is the nearby session, put nearby session *always* last + return (type_b == LLConversationItem::CONV_SESSION_NEARBY); + } + else if (sort_order == LLConversationFilter::SO_SESSION_TYPE) + { + if (type_a != type_b) + { + // Lowest types come first. See LLConversationItem definition of types + return (type_a < type_b); + } + // If types are identical, we'll default to sort by name at the end of this method + } + } + } + else + { + // If one item is a participant and the other a session, the session comes before the participant + // so we simply compare the type + // Notes: as a consequence, CONV_UNKNOWN (which should never get created...) always come first + return (type_a > type_b); + } + // By default, in all other possible cases (including sort order type LLConversationFilter::SO_NAME of course), + // we sort by name + S32 compare = LLStringUtil::compareDict(a->getName(), b->getName()); + return (compare < 0); +} + +// +// LLConversationViewModel +// + +void LLConversationViewModel::sort(LLFolderViewFolder* folder) +{ + base_t::sort(folder); +} + +// EOF diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h new file mode 100755 index 0000000000..8766585049 --- /dev/null +++ b/indra/newview/llconversationmodel.h @@ -0,0 +1,314 @@ +/** + * @file llconversationmodel.h + * @brief Implementation of conversations list + * + * $LicenseInfo:firstyear=2009&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_LLCONVERSATIONMODEL_H +#define LL_LLCONVERSATIONMODEL_H + +#include <boost/signals2.hpp> + +#include "llavatarname.h" +#include "../llui/llfolderviewitem.h" +#include "../llui/llfolderviewmodel.h" +#include "llviewerfoldertype.h" + +// Implementation of conversations list + +class LLConversationItem; +class LLConversationItemSession; +class LLConversationItemParticipant; + +typedef std::map<LLUUID, LLConversationItem*> conversations_items_map; +typedef std::map<LLUUID, LLFolderViewItem*> conversations_widgets_map; + +typedef std::vector<std::string> menuentry_vec_t; + +// Conversation items: we hold a list of those and create an LLFolderViewItem widget for each +// that we tuck into the mConversationsListPanel. +class LLConversationItem : public LLFolderViewModelItemCommon +{ +public: + enum EConversationType + { + CONV_UNKNOWN = 0, + CONV_PARTICIPANT = 1, + CONV_SESSION_NEARBY = 2, // The order counts here as it is used to sort sessions by type + CONV_SESSION_1_ON_1 = 3, + CONV_SESSION_AD_HOC = 4, + CONV_SESSION_GROUP = 5, + CONV_SESSION_UNKNOWN = 6 + }; + + LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model); + LLConversationItem(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model); + LLConversationItem(LLFolderViewModelInterface& root_view_model); + virtual ~LLConversationItem(); + + // Stub those things we won't really be using in this conversation context + virtual const std::string& getName() const { return mName; } + virtual const std::string& getDisplayName() const { return mName; } + virtual const std::string& getSearchableName() const { return mName; } + virtual const LLUUID& getUUID() const { return mUUID; } + virtual time_t getCreationDate() const { return 0; } + virtual LLPointer<LLUIImage> getIcon() const { return NULL; } + virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); } + virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; } + virtual std::string getLabelSuffix() const { return LLStringUtil::null; } + virtual BOOL isItemRenameable() const { return TRUE; } + virtual BOOL renameItem(const std::string& new_name) { mName = new_name; mNeedsRefresh = true; return TRUE; } + virtual BOOL isItemMovable( void ) const { return FALSE; } + virtual BOOL isItemRemovable( void ) const { return FALSE; } + virtual BOOL isItemInTrash( void) const { return FALSE; } + virtual BOOL removeItem() { return FALSE; } + virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) { } + virtual void move( LLFolderViewModelItem* parent_listener ) { } + virtual BOOL isItemCopyable() const { return FALSE; } + virtual BOOL copyToClipboard() const { return FALSE; } + virtual BOOL cutToClipboard() const { return FALSE; } + virtual BOOL isClipboardPasteable() const { return FALSE; } + virtual void pasteFromClipboard() { } + virtual void pasteLinkFromClipboard() { } + virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { } + virtual BOOL isUpToDate() const { return TRUE; } + virtual bool hasChildren() const { return FALSE; } + + virtual bool potentiallyVisible() { return true; } + virtual bool filter( LLFolderViewFilter& filter) { return false; } + virtual bool descendantsPassedFilter(S32 filter_generation = -1) { return true; } + virtual void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) { } + virtual bool passedFilter(S32 filter_generation = -1) { return true; } + + // The action callbacks + virtual void performAction(LLInventoryModel* model, std::string action); + virtual void openItem( void ); + virtual void closeItem( void ); + virtual void previewItem( void ); + virtual void selectItem(void) { } + virtual void showProperties(void); + + // Methods used in sorting (see LLConversationSort::operator()) + EConversationType const getType() const { return mConvType; } + virtual const bool getTime(F64& time) const { time = mLastActiveTime; return (time > 0.1); } + virtual const bool getDistanceToAgent(F64& distance) const { return false; } + + // This method will be called to determine if a drop can be + // performed, and will set drop to TRUE if a drop is + // requested. + // Returns TRUE if a drop is possible/happened, FALSE otherwise. + virtual BOOL dragOrDrop(MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + std::string& tooltip_msg) { return FALSE; } + +// bool hasSameValues(std::string name, const LLUUID& uuid) { return ((name == mName) && (uuid == mUUID)); } + bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); } + + void resetRefresh() { mNeedsRefresh = false; } + bool needsRefresh() { return mNeedsRefresh; } + + void postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant); + + void buildParticipantMenuOptions(menuentry_vec_t& items, U32 flags); + + void fetchAvatarName(bool isParticipant = true); // fetch and update the avatar name + +protected: + virtual void onAvatarNameCache(const LLAvatarName& av_name) {} + + std::string mName; // Name of the session or the participant + LLUUID mUUID; // UUID of the session or the participant + EConversationType mConvType; // Type of conversation item + bool mNeedsRefresh; // Flag signaling to the view that something changed for this item + F64 mLastActiveTime; + bool mDisplayModeratorOptions; + boost::signals2::connection mAvatarNameCacheConnection; +}; + +class LLConversationItemSession : public LLConversationItem +{ +public: + LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model); + LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model); + + /*virtual*/ bool hasChildren() const; + LLPointer<LLUIImage> getIcon() const { return NULL; } + void setSessionID(const LLUUID& session_id) { mUUID = session_id; mNeedsRefresh = true; } + void addParticipant(LLConversationItemParticipant* participant); + void updateName(LLConversationItemParticipant* participant); + void removeParticipant(LLConversationItemParticipant* participant); + void removeParticipant(const LLUUID& participant_id); + void clearParticipants(); + LLConversationItemParticipant* findParticipant(const LLUUID& participant_id); + + void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted); + void setParticipantIsModerator(const LLUUID& participant_id, bool is_moderator); + void setTimeNow(const LLUUID& participant_id); + void setDistance(const LLUUID& participant_id, F64 dist); + + bool isLoaded() { return mIsLoaded; } + + void buildContextMenu(LLMenuGL& menu, U32 flags); + void addVoiceOptions(menuentry_vec_t& items); + virtual const bool getTime(F64& time) const; + + void dumpDebugData(bool dump_children = false); + +private: + /*virtual*/ void onAvatarNameCache(const LLAvatarName& av_name); + + bool mIsLoaded; // true if at least one participant has been added to the session, false otherwise +}; + +class LLConversationItemParticipant : public LLConversationItem +{ +public: + LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model); + LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model); + + virtual const std::string& getDisplayName() const { return mDisplayName; } + + bool isVoiceMuted(); + bool isModerator() const { return mIsModerator; } + void muteVoice(bool mute_voice); + void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; } + void setTimeNow() { mLastActiveTime = LLFrameTimer::getElapsedSeconds(); mNeedsRefresh = true; } + void setDistance(F64 dist) { mDistToAgent = dist; mNeedsRefresh = true; } + + void buildContextMenu(LLMenuGL& menu, U32 flags); + + virtual const bool getDistanceToAgent(F64& dist) const { dist = mDistToAgent; return (dist >= 0.0); } + + void updateName(); // get from the cache (do *not* fetch) and update the avatar name + LLConversationItemSession* getParentSession(); + + void dumpDebugData(); + void setModeratorOptionsVisible(bool visible) { mDisplayModeratorOptions = visible; } + void setDisplayModeratorRole(bool displayRole); + +private: + void onAvatarNameCache(const LLAvatarName& av_name); // callback used by fetchAvatarName + void updateName(const LLAvatarName& av_name); + + bool mIsMuted; // default is false + bool mIsModerator; // default is false + bool mDisplayModeratorLabel; // default is false + std::string mDisplayName; + F64 mDistToAgent; // Distance to the agent. A negative (meaningless) value means the distance has not been set. + boost::signals2::connection mAvatarNameCacheConnection; +}; + +// We don't want to ever filter conversations but we need to declare that class to create a conversation view model. +// We just stubb everything for the moment. +class LLConversationFilter : public LLFolderViewFilter +{ +public: + + enum ESortOrderType + { + SO_NAME = 0, // Sort by name + SO_DATE = 0x1, // Sort by date (most recent) + SO_SESSION_TYPE = 0x2, // Sort by type (valid only for sessions) + SO_DISTANCE = 0x3, // Sort by distance (valid only for participants in nearby chat) + }; + // Default sort order is by type for sessions and by date for participants + static const U32 SO_DEFAULT = (SO_SESSION_TYPE << 16) | (SO_DATE); + + LLConversationFilter() { mEmpty = ""; } + ~LLConversationFilter() {} + + bool check(const LLFolderViewModelItem* item) { return true; } + bool checkFolder(const LLFolderViewModelItem* folder) const { return true; } + void setEmptyLookupMessage(const std::string& message) { } + std::string getEmptyLookupMessage() const { return mEmpty; } + bool showAllResults() const { return true; } + std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const { return std::string::npos; } + std::string::size_type getFilterStringSize() const { return 0; } + + bool isActive() const { return false; } + bool isModified() const { return false; } + void clearModified() { } + const std::string& getName() const { return mEmpty; } + const std::string& getFilterText() { return mEmpty; } + void setModified(EFilterModified behavior = FILTER_RESTART) { } + + void setFilterCount(S32 count) { } + S32 getFilterCount() const { return 0; } + void decrementFilterCount() { } + + bool isDefault() const { return true; } + bool isNotDefault() const { return false; } + void markDefault() { } + void resetDefault() { } + + S32 getCurrentGeneration() const { return 0; } + S32 getFirstSuccessGeneration() const { return 0; } + S32 getFirstRequiredGeneration() const { return 0; } +private: + std::string mEmpty; +}; + +class LLConversationSort +{ +public: + LLConversationSort(U32 order = LLConversationFilter::SO_DEFAULT) : mSortOrder(order) { } + + // 16 LSB bits used for participants, 16 MSB bits for sessions + U32 getSortOrderSessions() const { return ((mSortOrder >> 16) & 0xFFFF); } + U32 getSortOrderParticipants() const { return (mSortOrder & 0xFFFF); } + void setSortOrderSessions(LLConversationFilter::ESortOrderType session) { mSortOrder = ((session & 0xFFFF) << 16) | (mSortOrder & 0xFFFF); } + void setSortOrderParticipants(LLConversationFilter::ESortOrderType participant) { mSortOrder = (mSortOrder & 0xFFFF0000) | (participant & 0xFFFF); } + + bool operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const; + operator U32() const { return mSortOrder; } +private: + // Note: we're treating this value as a sort order bitmask as done in other places in the code (e.g. inventory) + U32 mSortOrder; +}; + +class LLConversationViewModel +: public LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter> +{ +public: + typedef LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter> base_t; + + void sort(LLFolderViewFolder* folder); + bool contentsReady() { return true; } // *TODO : we need to check that participants names are available somewhat + bool startDrag(std::vector<LLFolderViewModelItem*>& items) { return false; } // We do not allow drag of conversation items + +private: +}; + +// Utility function to hide all entries except those in the list +// Can be called multiple times on the same menu (e.g. if multiple items +// are selected). If "append" is false, then only common enabled items +// are set as enabled. + +//(defined in inventorybridge.cpp) +//TODO: Gilbert Linden - Refactor to make this function non-global +void hide_context_entries(LLMenuGL& menu, + const menuentry_vec_t &entries_to_show, + const menuentry_vec_t &disabled_entries); + +#endif // LL_LLCONVERSATIONMODEL_H diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp new file mode 100755 index 0000000000..956abcd586 --- /dev/null +++ b/indra/newview/llconversationview.cpp @@ -0,0 +1,696 @@ +/** + * @file llconversationview.cpp + * @brief Implementation of conversations list widgets and views + * + * $LicenseInfo:firstyear=2009&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 "llconversationview.h" + +#include <boost/bind.hpp> +#include "llagentdata.h" +#include "llconversationmodel.h" +#include "llfloaterimsession.h" +#include "llfloaterimnearbychat.h" +#include "llfloaterimsessiontab.h" +#include "llfloaterimcontainer.h" +#include "llfloaterreg.h" +#include "llgroupiconctrl.h" +#include "lluictrlfactory.h" +#include "lltoolbarview.h" + +// +// Implementation of conversations list session widgets +// +static LLDefaultChildRegistry::Register<LLConversationViewSession> r_conversation_view_session("conversation_view_session"); + +const LLColor4U DEFAULT_WHITE(255, 255, 255); + +class LLNearbyVoiceClientStatusObserver : public LLVoiceClientStatusObserver +{ +public: + + LLNearbyVoiceClientStatusObserver(LLConversationViewSession* conv) + : conversation(conv) + {} + + virtual void onChange(EStatusType status, const std::string &channelURI, bool proximal) + { + conversation->showVoiceIndicator(conversation + && status != STATUS_JOINING + && status != STATUS_LEFT_CHANNEL + && LLVoiceClient::getInstance()->voiceEnabled() + && LLVoiceClient::getInstance()->isVoiceWorking()); + } + +private: + LLConversationViewSession* conversation; +}; + +LLConversationViewSession::Params::Params() : + container() +{} + +LLConversationViewSession::LLConversationViewSession(const LLConversationViewSession::Params& p): + LLFolderViewFolder(p), + mContainer(p.container), + mItemPanel(NULL), + mCallIconLayoutPanel(NULL), + mSessionTitle(NULL), + mSpeakingIndicator(NULL), + mVoiceClientObserver(NULL), + mCollapsedMode(false), + mHasArrow(true), + mIsInActiveVoiceChannel(false), + mFlashStateOn(false), + mFlashStarted(false) +{ + mFlashTimer = new LLFlashTimer(); +} + +LLConversationViewSession::~LLConversationViewSession() +{ + mActiveVoiceChannelConnection.disconnect(); + + if(LLVoiceClient::instanceExists() && mVoiceClientObserver) + { + LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver); + } + + mFlashTimer->unset(); +} + +void LLConversationViewSession::setFlashState(bool flash_state) +{ + if (flash_state && !mFlashStateOn) + { + // flash chat toolbar button if scrolled out of sight (because flashing will not be visible) + if (mContainer->isScrolledOutOfSight(this)) + { + gToolBarView->flashCommand(LLCommandId("chat"), true); + } + } + + mFlashStateOn = flash_state; + mFlashStarted = false; + mFlashTimer->stopFlashing(); +} + +void LLConversationViewSession::startFlashing() +{ + if (mFlashStateOn && !mFlashStarted) + { + mFlashStarted = true; + mFlashTimer->startFlashing(); + } +} + +bool LLConversationViewSession::isHighlightAllowed() +{ + return mFlashStateOn || mIsSelected; +} + +bool LLConversationViewSession::isHighlightActive() +{ + return (mFlashStateOn ? (mFlashTimer->isFlashingInProgress() ? mFlashTimer->isCurrentlyHighlighted() : true) : mIsCurSelection); +} + +BOOL LLConversationViewSession::postBuild() +{ + LLFolderViewItem::postBuild(); + + mItemPanel = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>("panel_conversation_list_item.xml", NULL, LLPanel::child_registry_t::instance()); + addChild(mItemPanel); + + mCallIconLayoutPanel = mItemPanel->getChild<LLPanel>("call_icon_panel"); + mSessionTitle = mItemPanel->getChild<LLTextBox>("conversation_title"); + + mActiveVoiceChannelConnection = LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLConversationViewSession::onCurrentVoiceSessionChanged, this, _1)); + mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator"); + + LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem()); + if (vmi) + { + switch(vmi->getType()) + { + case LLConversationItem::CONV_PARTICIPANT: + case LLConversationItem::CONV_SESSION_1_ON_1: + { + LLIMModel::LLIMSession* session= LLIMModel::instance().findIMSession(vmi->getUUID()); + if (session) + { + LLAvatarIconCtrl* icon = mItemPanel->getChild<LLAvatarIconCtrl>("avatar_icon"); + icon->setVisible(true); + icon->setValue(session->mOtherParticipantID); + mSpeakingIndicator->setSpeakerId(gAgentID, session->mSessionID, true); + mHasArrow = false; + } + break; + } + case LLConversationItem::CONV_SESSION_AD_HOC: + { + LLGroupIconCtrl* icon = mItemPanel->getChild<LLGroupIconCtrl>("group_icon"); + icon->setVisible(true); + mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID(), true); + break; + } + case LLConversationItem::CONV_SESSION_GROUP: + { + LLGroupIconCtrl* icon = mItemPanel->getChild<LLGroupIconCtrl>("group_icon"); + icon->setVisible(true); + icon->setValue(vmi->getUUID()); + mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID(), true); + break; + } + case LLConversationItem::CONV_SESSION_NEARBY: + { + LLIconCtrl* icon = mItemPanel->getChild<LLIconCtrl>("nearby_chat_icon"); + icon->setVisible(true); + mSpeakingIndicator->setSpeakerId(gAgentID, LLUUID::null, true); + mIsInActiveVoiceChannel = true; + if(LLVoiceClient::instanceExists()) + { + LLNearbyVoiceClientStatusObserver* mVoiceClientObserver = new LLNearbyVoiceClientStatusObserver(this); + LLVoiceClient::getInstance()->addObserver(mVoiceClientObserver); + } + break; + } + default: + break; + } + } + + refresh(); + + return TRUE; +} + +void LLConversationViewSession::draw() +{ + getViewModelItem()->update(); + + const LLFolderViewItem::Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>(); + const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE); + + // Indicate that flash can start (moot operation if already started, done or not flashing) + startFlashing(); + + // draw highlight for selected items + drawHighlight(show_context, true, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor); + + // Draw children if root folder, or any other folder that is open. Do not draw children when animating to closed state or you get rendering overlap. + bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this) || isOpen(); + + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + (*fit)->setVisible(draw_children); + } + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + (*iit)->setVisible(draw_children); + } + + // we don't draw the open folder arrow in minimized mode + if (mHasArrow && !mCollapsedMode) + { + // update the rotation angle of open folder arrow + updateLabelRotation(); + drawOpenFolderArrow(default_params, sFgColor); + } + + refresh(); + + LLView::draw(); +} + +BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask ) +{ + //Will try to select a child node and then itself (if a child was not selected) + BOOL result = LLFolderViewFolder::handleMouseDown(x, y, mask); + + //This node (conversation) was selected and a child (participant) was not + if(result && getRoot()) + { + selectConversationItem(); + } + + return result; +} + +BOOL LLConversationViewSession::handleRightMouseDown( S32 x, S32 y, MASK mask ) +{ + BOOL result = LLFolderViewFolder::handleRightMouseDown(x, y, mask); + + if(result) + { + selectConversationItem(); + } + + return result; +} + +void LLConversationViewSession::selectConversationItem() +{ + if(getRoot()->getCurSelectedItem() == this) + { + LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem()); + LLUUID session_id = item? item->getUUID() : LLUUID(); + + LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); + im_container->flashConversationItemWidget(session_id,false); + im_container->selectConversationPair(session_id, false); + im_container->collapseMessagesPane(false); + } +} + +// virtual +S32 LLConversationViewSession::arrange(S32* width, S32* height) +{ + //LLFolderViewFolder::arrange computes value for getIndentation() function below + S32 arranged = LLFolderViewFolder::arrange(width, height); + + S32 h_pad = mHasArrow ? getIndentation() + mArrowSize : getIndentation(); + + LLRect rect(mCollapsedMode ? getLocalRect().mLeft : h_pad, + getLocalRect().mTop, + getLocalRect().mRight, + getLocalRect().mTop - getItemHeight()); + mItemPanel->setShape(rect); + + return arranged; +} + +// virtual +void LLConversationViewSession::toggleOpen() +{ + // conversations should not be opened while in minimized mode + if (!mCollapsedMode) + { + LLFolderViewFolder::toggleOpen(); + + // do item's selection when opened + if (LLFolderViewFolder::isOpen()) + { + getParentFolder()->setSelection(this, true); + } + mContainer->reSelectConversation(); + } +} + +void LLConversationViewSession::toggleCollapsedMode(bool is_collapsed) +{ + mCollapsedMode = is_collapsed; + + // hide the layout stack which contains all item's child widgets + // except for the icon which we display in minimized mode + getChild<LLView>("conversation_item_stack")->setVisible(!mCollapsedMode); + + S32 h_pad = mHasArrow ? getIndentation() + mArrowSize : getIndentation(); + + mItemPanel->translate(mCollapsedMode ? -h_pad : h_pad, 0); +} + +void LLConversationViewSession::setVisibleIfDetached(BOOL visible) +{ + // Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized + // Note: minimized dockable floaters are brought to front hence unminimized when made visible and we don't want that here + LLFolderViewModelItem* item = mViewModelItem; + LLUUID session_uuid = dynamic_cast<LLConversationItem*>(item)->getUUID(); + LLFloater* session_floater = LLFloaterIMSessionTab::getConversation(session_uuid); + + if (session_floater && !session_floater->getHost() && !session_floater->isMinimized()) + { + session_floater->setVisible(visible); + } +} + +LLConversationViewParticipant* LLConversationViewSession::findParticipant(const LLUUID& participant_id) +{ + // This is *not* a general tree parsing algorithm. We search only in the mItems list + // assuming there is no mFolders which makes sense for sessions (sessions don't contain + // sessions). + LLConversationViewParticipant* participant = NULL; + items_t::const_iterator iter; + for (iter = getItemsBegin(); iter != getItemsEnd(); iter++) + { + participant = dynamic_cast<LLConversationViewParticipant*>(*iter); + if (participant->hasSameValue(participant_id)) + { + break; + } + } + return (iter == getItemsEnd() ? NULL : participant); +} + +void LLConversationViewSession::showVoiceIndicator(bool visible) +{ + mCallIconLayoutPanel->setVisible(visible && LLVoiceChannel::getCurrentVoiceChannel()->getSessionID().isNull()); + requestArrange(); +} + +void LLConversationViewSession::refresh() +{ + // Refresh the session view from its model data + LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem()); + vmi->resetRefresh(); + + if (mSessionTitle) + { + mSessionTitle->setText(vmi->getDisplayName()); + } + + // Update all speaking indicators + LLSpeakingIndicatorManager::updateSpeakingIndicators(); + + // we should show indicator for specified voice session only if this is current channel. EXT-5562. + if (!mIsInActiveVoiceChannel) + { + if (mSpeakingIndicator) + { + mSpeakingIndicator->setVisible(false); + } + LLConversationViewParticipant* participant = NULL; + items_t::const_iterator iter; + for (iter = getItemsBegin(); iter != getItemsEnd(); iter++) + { + participant = dynamic_cast<LLConversationViewParticipant*>(*iter); + if (participant) + { + participant->hideSpeakingIndicator(); + } + } + } + requestArrange(); + // Do the regular upstream refresh + LLFolderViewFolder::refresh(); +} + +void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& session_id) +{ + LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem()); + + if (vmi) + { + mIsInActiveVoiceChannel = vmi->getUUID() == session_id; + mCallIconLayoutPanel->setVisible(mIsInActiveVoiceChannel); + } +} + +// +// Implementation of conversations list participant (avatar) widgets +// + +static LLDefaultChildRegistry::Register<LLConversationViewParticipant> r("conversation_view_participant"); +bool LLConversationViewParticipant::sStaticInitialized = false; +S32 LLConversationViewParticipant::sChildrenWidths[LLConversationViewParticipant::ALIC_COUNT]; + +LLConversationViewParticipant::Params::Params() : +container(), +participant_id(), +avatar_icon("avatar_icon"), +info_button("info_button"), +output_monitor("output_monitor") +{} + +LLConversationViewParticipant::LLConversationViewParticipant( const LLConversationViewParticipant::Params& p ): + LLFolderViewItem(p), + mAvatarIcon(NULL), + mInfoBtn(NULL), + mSpeakingIndicator(NULL), + mUUID(p.participant_id) +{ +} + +LLConversationViewParticipant::~LLConversationViewParticipant() +{ + mActiveVoiceChannelConnection.disconnect(); +} + +void LLConversationViewParticipant::initFromParams(const LLConversationViewParticipant::Params& params) +{ + LLAvatarIconCtrl::Params avatar_icon_params(params.avatar_icon()); + applyXUILayout(avatar_icon_params, this); + LLAvatarIconCtrl * avatarIcon = LLUICtrlFactory::create<LLAvatarIconCtrl>(avatar_icon_params); + addChild(avatarIcon); + + LLButton::Params info_button_params(params.info_button()); + applyXUILayout(info_button_params, this); + LLButton * button = LLUICtrlFactory::create<LLButton>(info_button_params); + addChild(button); + + LLOutputMonitorCtrl::Params output_monitor_params(params.output_monitor()); + applyXUILayout(output_monitor_params, this); + LLOutputMonitorCtrl * outputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(output_monitor_params); + addChild(outputMonitor); +} + +BOOL LLConversationViewParticipant::postBuild() +{ + mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon"); + + mInfoBtn = getChild<LLButton>("info_btn"); + mInfoBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onInfoBtnClick, this)); + mInfoBtn->setVisible(false); + + mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator"); + + if (!sStaticInitialized) + { + // Remember children widths including their padding from the next sibling, + // so that we can hide and show them again later. + initChildrenWidths(this); + sStaticInitialized = true; + } + + updateChildren(); + return LLFolderViewItem::postBuild(); +} + +void LLConversationViewParticipant::draw() +{ + static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + static LLUIColor sFgDisabledColor = LLUIColorTable::instance().getColor("MenuItemDisabledColor", DEFAULT_WHITE); + static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE); + static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE); + static LLUIColor sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE); + static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE); + static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE); + + const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE); + + const LLFontGL* font = getLabelFontForStyle(mLabelStyle); + F32 right_x = 0; + + F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad; + F32 text_left = (F32)getLabelXPos(); + + LLColor4 color; + LLLocalSpeakerMgr *speakerMgr = LLLocalSpeakerMgr::getInstance(); + + if (speakerMgr && speakerMgr->isSpeakerToBeRemoved(mUUID)) + { + color = sFgDisabledColor; + } + else + { + color = mIsSelected ? sHighlightFgColor : sFgColor; + } + + drawHighlight(show_context, mIsSelected, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor); + drawLabel(font, text_left, y, color, right_x); + refresh(); + + LLView::draw(); +} + +// virtual +S32 LLConversationViewParticipant::arrange(S32* width, S32* height) +{ + //Need to call arrange first since it computes value used in getIndentation() + S32 arranged = LLFolderViewItem::arrange(width, height); + + //Adjusts the avatar icon based upon the indentation + LLRect avatarRect(getIndentation(), + mAvatarIcon->getRect().mTop, + getIndentation() + mAvatarIcon->getRect().getWidth(), + mAvatarIcon->getRect().mBottom); + mAvatarIcon->setShape(avatarRect); + + //Since dimensions changed, adjust the children (info button, speaker indicator) + updateChildren(); + + return arranged; +} + +void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder) +{ + // Add the item to the folder (conversation) + LLFolderViewItem::addToFolder(folder); + + // Retrieve the folder (conversation) UUID, which is also the speaker session UUID + LLConversationItem* vmi = getParentFolder() ? dynamic_cast<LLConversationItem*>(getParentFolder()->getViewModelItem()) : NULL; + if (vmi) + { + addToSession(vmi->getUUID()); + } +} + +void LLConversationViewParticipant::addToSession(const LLUUID& session_id) +{ + //Allows speaking icon image to be loaded based on mUUID + mAvatarIcon->setValue(mUUID); + + //Allows the speaker indicator to be activated based on the user and conversation + mSpeakingIndicator->setSpeakerId(mUUID, session_id); +} + +void LLConversationViewParticipant::onInfoBtnClick() +{ + LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", mUUID)); +} + +BOOL LLConversationViewParticipant::handleMouseDown( S32 x, S32 y, MASK mask ) +{ + BOOL result = LLFolderViewItem::handleMouseDown(x, y, mask); + + if(result && getRoot()) + { + if(getRoot()->getCurSelectedItem() == this) + { + LLConversationItem* vmi = getParentFolder() ? dynamic_cast<LLConversationItem*>(getParentFolder()->getViewModelItem()) : NULL; + LLUUID session_id = vmi? vmi->getUUID() : LLUUID(); + + LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); + LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id); + im_container->setSelectedSession(session_id); + im_container->flashConversationItemWidget(session_id,false); + im_container->selectFloater(session_floater); + im_container->collapseMessagesPane(false); + } + } + return result; +} + +void LLConversationViewParticipant::onMouseEnter(S32 x, S32 y, MASK mask) +{ + mInfoBtn->setVisible(true); + updateChildren(); + LLFolderViewItem::onMouseEnter(x, y, mask); +} + +void LLConversationViewParticipant::onMouseLeave(S32 x, S32 y, MASK mask) +{ + mInfoBtn->setVisible(false); + updateChildren(); + LLFolderViewItem::onMouseLeave(x, y, mask); +} + +S32 LLConversationViewParticipant::getLabelXPos() +{ + return getIndentation() + mAvatarIcon->getRect().getWidth() + mIconPad; +} + +// static +void LLConversationViewParticipant::initChildrenWidths(LLConversationViewParticipant* self) +{ + //speaking indicator width + padding + S32 speaking_indicator_width = self->getRect().getWidth() - self->mSpeakingIndicator->getRect().mLeft; + + //info btn width + padding + S32 info_btn_width = self->mSpeakingIndicator->getRect().mLeft - self->mInfoBtn->getRect().mLeft; + + S32 index = ALIC_COUNT; + sChildrenWidths[--index] = info_btn_width; + sChildrenWidths[--index] = speaking_indicator_width; + llassert(index == 0); +} + +void LLConversationViewParticipant::updateChildren() +{ + mLabelPaddingRight = DEFAULT_LABEL_PADDING_RIGHT; + LLView* control; + S32 ctrl_width; + LLRect controlRect; + + //Cycles through controls starting from right to left + for (S32 i = 0; i < ALIC_COUNT; ++i) + { + control = getItemChildView((EAvatarListItemChildIndex)i); + + // skip invisible views + if (!control->getVisible()) continue; + + //Get current pos/dimensions + controlRect = control->getRect(); + + ctrl_width = sChildrenWidths[i]; // including space between current & left controls + // accumulate the amount of space taken by the controls + mLabelPaddingRight += ctrl_width; + + //Reposition visible controls in case adjacent controls to the right are hidden. + controlRect.setLeftTopAndSize( + getLocalRect().getWidth() - mLabelPaddingRight, + controlRect.mTop, + controlRect.getWidth(), + controlRect.getHeight()); + + //Sets the new position + control->setShape(controlRect); + } +} + +LLView* LLConversationViewParticipant::getItemChildView(EAvatarListItemChildIndex child_view_index) +{ + LLView* child_view = NULL; + + switch (child_view_index) + { + case ALIC_SPEAKER_INDICATOR: + child_view = mSpeakingIndicator; + break; + case ALIC_INFO_BUTTON: + child_view = mInfoBtn; + break; + default: + LL_WARNS("AvatarItemReshape") << "Unexpected child view index is passed: " << child_view_index << LL_ENDL; + llassert(0); + break; + // leave child_view untouched + } + + return child_view; +} + +void LLConversationViewParticipant::hideSpeakingIndicator() +{ + mSpeakingIndicator->setVisible(false); +} + +// EOF + diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h new file mode 100755 index 0000000000..3eb2e63792 --- /dev/null +++ b/indra/newview/llconversationview.h @@ -0,0 +1,177 @@ +/** + * @file llconversationview.h + * @brief Implementation of conversations list widgets and views + * + * $LicenseInfo:firstyear=2009&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_LLCONVERSATIONVIEW_H +#define LL_LLCONVERSATIONVIEW_H + +#include "../llui/llfolderviewitem.h" + +#include "llavatariconctrl.h" +#include "../llui/llbutton.h" +#include "lloutputmonitorctrl.h" + +class LLTextBox; +class LLFloaterIMContainer; +class LLConversationViewSession; +class LLConversationViewParticipant; + +class LLVoiceClientStatusObserver; + +// Implementation of conversations list session widgets + +class LLConversationViewSession : public LLFolderViewFolder +{ +public: + struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params> + { + Optional<LLFloaterIMContainer*> container; + + Params(); + }; + +protected: + friend class LLUICtrlFactory; + LLConversationViewSession( const Params& p ); + + /*virtual*/ bool isHighlightAllowed(); + /*virtual*/ bool isHighlightActive(); + /*virtual*/ bool isFlashing() { return mFlashStateOn; } + + LLFloaterIMContainer* mContainer; + +public: + virtual ~LLConversationViewSession(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void draw(); + /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + + /*virtual*/ S32 arrange(S32* width, S32* height); + + /*virtual*/ void toggleOpen(); + + /*virtual*/ bool isCollapsed() { return mCollapsedMode; } + + void toggleCollapsedMode(bool is_collapsed); + + void setVisibleIfDetached(BOOL visible); + LLConversationViewParticipant* findParticipant(const LLUUID& participant_id); + + void showVoiceIndicator(bool visible); + + virtual void refresh(); + + /*virtual*/ void setFlashState(bool flash_state); + +private: + + void onCurrentVoiceSessionChanged(const LLUUID& session_id); + void startFlashing(); + void selectConversationItem(); + + LLPanel* mItemPanel; + LLPanel* mCallIconLayoutPanel; + LLTextBox* mSessionTitle; + LLOutputMonitorCtrl* mSpeakingIndicator; + LLFlashTimer* mFlashTimer; + bool mFlashStateOn; + bool mFlashStarted; + + bool mCollapsedMode; + bool mHasArrow; + + bool mIsInActiveVoiceChannel; + + LLVoiceClientStatusObserver* mVoiceClientObserver; + + boost::signals2::connection mActiveVoiceChannelConnection; +}; + +// Implementation of conversations list participant (avatar) widgets + +class LLConversationViewParticipant : public LLFolderViewItem +{ + +public: + + struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params> + { + Optional<LLFloaterIMContainer*> container; + Optional<LLUUID> participant_id; + Optional<LLAvatarIconCtrl::Params> avatar_icon; + Optional<LLButton::Params> info_button; + Optional<LLOutputMonitorCtrl::Params> output_monitor; + + Params(); + }; + + virtual ~LLConversationViewParticipant( void ); + + bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); } + void addToFolder(LLFolderViewFolder* folder); + void addToSession(const LLUUID& session_id); + + void onMouseEnter(S32 x, S32 y, MASK mask); + void onMouseLeave(S32 x, S32 y, MASK mask); + + /*virtual*/ S32 getLabelXPos(); + /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); + void hideSpeakingIndicator(); + +protected: + friend class LLUICtrlFactory; + LLConversationViewParticipant( const Params& p ); + void initFromParams(const Params& params); + BOOL postBuild(); + /*virtual*/ void draw(); + /*virtual*/ S32 arrange(S32* width, S32* height); + + void onInfoBtnClick(); + +private: + + LLAvatarIconCtrl* mAvatarIcon; + LLButton * mInfoBtn; + LLOutputMonitorCtrl* mSpeakingIndicator; + LLUUID mUUID; // UUID of the participant + + typedef enum e_avatar_item_child { + ALIC_SPEAKER_INDICATOR, + ALIC_INFO_BUTTON, + ALIC_COUNT, + } EAvatarListItemChildIndex; + + static bool sStaticInitialized; // this variable is introduced to improve code readability + static S32 sChildrenWidths[ALIC_COUNT]; + static void initChildrenWidths(LLConversationViewParticipant* self); + void updateChildren(); + LLView* getItemChildView(EAvatarListItemChildIndex child_view_index); + + boost::signals2::connection mActiveVoiceChannelConnection; +}; + +#endif // LL_LLCONVERSATIONVIEW_H diff --git a/indra/newview/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp index 347a467a8b..8af2f4ea33 100644 --- a/indra/newview/lldaycyclemanager.cpp +++ b/indra/newview/lldaycyclemanager.cpp @@ -184,7 +184,7 @@ void LLDayCycleManager::loadPresets(const std::string& dir) { std::string file; if (!dir_iter.next(file)) break; // no more files - loadPreset(dir + file); + loadPreset(gDirUtilp->add(dir, file)); } } diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp index ba511a3693..aeecf054b8 100644 --- a/indra/newview/lldebugview.cpp +++ b/indra/newview/lldebugview.cpp @@ -30,7 +30,6 @@ // library includes #include "llfasttimerview.h" -#include "llmemoryview.h" #include "llconsole.h" #include "lltextureview.h" #include "llresmgr.h" @@ -38,7 +37,6 @@ #include "llviewercontrol.h" #include "llviewerwindow.h" #include "llappviewer.h" -#include "llmemoryview.h" #include "llsceneview.h" #include "llviewertexture.h" #include "llfloaterreg.h" @@ -55,9 +53,21 @@ LLDebugView* gDebugView = NULL; static LLDefaultChildRegistry::Register<LLDebugView> r("debug_view"); LLDebugView::LLDebugView(const LLDebugView::Params& p) -: LLView(p) +: LLView(p), + mFastTimerView(NULL), + mMemoryView(NULL), + mDebugConsolep(NULL), + mFloaterSnapRegion(NULL) {} +LLDebugView::~LLDebugView() +{ + // These have already been deleted. Fix the globals appropriately. + gDebugView = NULL; + gTextureView = NULL; + gSceneView = NULL; +} + void LLDebugView::init() { LLRect r; @@ -91,67 +101,27 @@ void LLDebugView::init() r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f), (S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f)); - LLMemoryView::Params mp; - mp.name("memory"); - mp.rect(r); - mp.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT); - mp.visible(false); - mMemoryView = LLUICtrlFactory::create<LLMemoryView>(mp); - addChild(mMemoryView); r.set(150, rect.getHeight() - 50, 820, 100); LLTextureView::Params tvp; tvp.name("gTextureView"); tvp.rect(r); - tvp.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT); + tvp.follows.flags(FOLLOWS_TOP|FOLLOWS_LEFT); tvp.visible(false); gTextureView = LLUICtrlFactory::create<LLTextureView>(tvp); addChild(gTextureView); //gTextureView->reshape(r.getWidth(), r.getHeight(), TRUE); - - - - - if(gAuditTexture) - { - r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureLoadedCounter.size() * 30, 100); - LLTextureSizeView::Params tsv ; - tsv.name("gTextureSizeView"); - tsv.rect(r); - tsv.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT); - tsv.visible(false); - gTextureSizeView = LLUICtrlFactory::create<LLTextureSizeView>(tsv); - addChild(gTextureSizeView); - gTextureSizeView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_SIZE) ; - - r.set(150, rect.getHeight() - 50, 900 + LLViewerTexture::getTotalNumOfCategories() * 30, 100); - LLTextureSizeView::Params tcv ; - tcv.name("gTextureCategoryView"); - tcv.rect(r); - tcv.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT); - tcv.visible(false); - gTextureCategoryView = LLUICtrlFactory::create<LLTextureSizeView>(tcv); - gTextureCategoryView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_CATEGORY); - addChild(gTextureCategoryView); - } -} - - -LLDebugView::~LLDebugView() -{ - // These have already been deleted. Fix the globals appropriately. - gDebugView = NULL; - gTextureView = NULL; - gSceneView = NULL; - gTextureSizeView = NULL; - gTextureCategoryView = NULL; } void LLDebugView::draw() { - LLView* floater_snap_region = getRootView()->getChildView("floater_snap_region"); + if (mFloaterSnapRegion == NULL) + { + mFloaterSnapRegion = getRootView()->getChildView("floater_snap_region"); + } + LLRect debug_rect; - floater_snap_region->localRectToOtherView(floater_snap_region->getLocalRect(), &debug_rect, getParent()); + mFloaterSnapRegion->localRectToOtherView(mFloaterSnapRegion->getLocalRect(), &debug_rect, getParent()); setShape(debug_rect); LLView::draw(); diff --git a/indra/newview/lldebugview.h b/indra/newview/lldebugview.h index 907a42c981..5aec77ad62 100644 --- a/indra/newview/lldebugview.h +++ b/indra/newview/lldebugview.h @@ -51,17 +51,19 @@ public: changeDefault(mouse_opaque, false); } }; + LLDebugView(const Params&); ~LLDebugView(); void init(); void draw(); - + void setStatsVisible(BOOL visible); LLFastTimerView* mFastTimerView; LLMemoryView* mMemoryView; LLConsole* mDebugConsolep; + LLView* mFloaterSnapRegion; }; extern LLDebugView* gDebugView; diff --git a/indra/newview/lldeferredsounds.cpp b/indra/newview/lldeferredsounds.cpp new file mode 100644 index 0000000000..9416e7cd29 --- /dev/null +++ b/indra/newview/lldeferredsounds.cpp @@ -0,0 +1,45 @@ +/** +* @file lldeferredsounds.cpp +* @brief Implementation of lldeferredsounds +* @author Gilbert@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, 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 "lldeferredsounds.h" + +#include "llaudioengine.h" + +void LLDeferredSounds::deferSound(SoundData& sound) +{ + soundVector.push_back(sound); +} +void LLDeferredSounds::playdeferredSounds() +{ + while(soundVector.size()) + { + gAudiop->triggerSound(soundVector.back()); + soundVector.pop_back(); + } +} diff --git a/indra/newview/lldeferredsounds.h b/indra/newview/lldeferredsounds.h new file mode 100644 index 0000000000..bf1eb62957 --- /dev/null +++ b/indra/newview/lldeferredsounds.h @@ -0,0 +1,46 @@ +/** +* @file lldeferredsounds.h +* @brief Header file for lldeferredsounds +* @author Gilbert@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, 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_LLDEFERREDSOUNDS_H +#define LL_LLDEFERREDSOUNDS_H + +#include "llsingleton.h" + +struct SoundData; + +class LLDeferredSounds : public LLSingleton<LLDeferredSounds> +{ +private: + std::vector<SoundData> soundVector; +public: + //Add sounds to be played once progress bar is hidden (such as after teleport or loading screen) + void deferSound(SoundData& sound); + + void playdeferredSounds(); +}; + +#endif // LL_LLDEFERREDSOUNDS_H + diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h index 2188b7edd0..682f9d6476 100644 --- a/indra/newview/lldirpicker.h +++ b/indra/newview/lldirpicker.h @@ -37,8 +37,8 @@ #include <Carbon/Carbon.h> // AssertMacros.h does bad things. +#include "fix_macros.h" #undef verify -#undef check #undef require #include <vector> diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp new file mode 100644 index 0000000000..22f35752bd --- /dev/null +++ b/indra/newview/lldonotdisturbnotificationstorage.cpp @@ -0,0 +1,325 @@ +/** +* @file lldonotdisturbnotificationstorage.cpp +* @brief Implementation of lldonotdisturbnotificationstorage +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "lldonotdisturbnotificationstorage.h" + +#include "llcommunicationchannel.h" +#include "lldir.h" +#include "llerror.h" +#include "llfloaterreg.h" +#include "llnotifications.h" +#include "llnotificationhandler.h" +#include "llnotificationstorage.h" +#include "llscriptfloater.h" +#include "llsd.h" +#include "llsingleton.h" +#include "lluuid.h" + +static const F32 DND_TIMER = 3.0; +const char * LLDoNotDisturbNotificationStorage::toastName = "IMToast"; +const char * LLDoNotDisturbNotificationStorage::offerName = "UserGiveItem"; + +LLDoNotDisturbNotificationStorageTimer::LLDoNotDisturbNotificationStorageTimer() : LLEventTimer(DND_TIMER) +{ + +} + +LLDoNotDisturbNotificationStorageTimer::~LLDoNotDisturbNotificationStorageTimer() +{ + +} + +BOOL LLDoNotDisturbNotificationStorageTimer::tick() +{ + LLDoNotDisturbNotificationStorage * doNotDisturbNotificationStorage = LLDoNotDisturbNotificationStorage::getInstance(); + + if(doNotDisturbNotificationStorage + && doNotDisturbNotificationStorage->getDirty()) + { + doNotDisturbNotificationStorage->saveNotifications(); + } + return FALSE; +} + +LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage() + : LLSingleton<LLDoNotDisturbNotificationStorage>() + , LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml")) + , mDirty(false) +{ + nameToPayloadParameterMap[toastName] = "SESSION_ID"; + nameToPayloadParameterMap[offerName] = "object_id"; +} + +LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage() +{ +} + +void LLDoNotDisturbNotificationStorage::initialize() +{ + getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1)); +} + +bool LLDoNotDisturbNotificationStorage::getDirty() +{ + return mDirty; +} + +void LLDoNotDisturbNotificationStorage::resetDirty() +{ + mDirty = false; +} + +static LLFastTimer::DeclareTimer FTM_SAVE_DND_NOTIFICATIONS("Save DND Notifications"); + +void LLDoNotDisturbNotificationStorage::saveNotifications() +{ + LLFastTimer _(FTM_SAVE_DND_NOTIFICATIONS); + + LLNotificationChannelPtr channelPtr = getCommunicationChannel(); + const LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get()); + llassert(commChannel != NULL); + + LLSD output = LLSD::emptyMap(); + LLSD& data = output["data"]; + data = LLSD::emptyArray(); + + for (LLCommunicationChannel::history_list_t::const_iterator historyIter = commChannel->beginHistory(); + historyIter != commChannel->endHistory(); ++historyIter) + { + LLNotificationPtr notificationPtr = historyIter->second; + + if (!notificationPtr->isRespondedTo() && !notificationPtr->isCancelled() && !notificationPtr->isExpired()) + { + data.append(notificationPtr->asLLSD(true)); + } + } + + writeNotifications(output); + + resetDirty(); +} + +static LLFastTimer::DeclareTimer FTM_LOAD_DND_NOTIFICATIONS("Load DND Notifications"); + +void LLDoNotDisturbNotificationStorage::loadNotifications() +{ + LLFastTimer _(FTM_LOAD_DND_NOTIFICATIONS); + + LLSD input; + if (!readNotifications(input) ||input.isUndefined()) + { + return; + } + + LLSD& data = input["data"]; + if (data.isUndefined()) + { + return; + } + + LLNotifications& instance = LLNotifications::instance(); + bool imToastExists = false; + bool offerExists = false; + + for (LLSD::array_const_iterator notification_it = data.beginArray(); + notification_it != data.endArray(); + ++notification_it) + { + LLSD notification_params = *notification_it; + const LLUUID& notificationID = notification_params["id"]; + std::string notificationName = notification_params["name"]; + LLNotificationPtr notification = instance.find(notificationID); + + if(notificationName == toastName) + { + imToastExists = true; + } + else if(notificationName == offerName) + { + offerExists = true; + } + + //Notification already exists due to persistent storage adding it first into the notification system + if(notification) + { + notification->setDND(true); + instance.update(instance.find(notificationID)); + } + //New notification needs to be added + else + { + notification = (LLNotificationPtr) new LLNotification(notification_params.with("is_dnd", true)); + LLNotificationResponderInterface* responder = createResponder(notification_params["responder_sd"]["responder_type"], notification_params["responder_sd"]); + if (responder == NULL) + { + LL_WARNS("LLDoNotDisturbNotificationStorage") << "cannot create responder for notification of type '" + << notification->getType() << "'" << LL_ENDL; + } + else + { + LLNotificationResponderPtr responderPtr(responder); + notification->setResponseFunctor(responderPtr); + } + + instance.add(notification); + } + + } + + if(imToastExists) + { + LLFloaterReg::showInstance("im_container"); + } + + if(imToastExists || offerExists) + { + make_ui_sound_deferred("UISndNewIncomingIMSession"); + } + + //writes out empty .xml file (since LLCommunicationChannel::mHistory is empty) + saveNotifications(); +} + +void LLDoNotDisturbNotificationStorage::updateNotifications() +{ + + LLNotificationChannelPtr channelPtr = getCommunicationChannel(); + LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get()); + llassert(commChannel != NULL); + + LLNotifications& instance = LLNotifications::instance(); + bool imToastExists = false; + bool offerExists = false; + + for (LLCommunicationChannel::history_list_t::const_iterator it = commChannel->beginHistory(); + it != commChannel->endHistory(); + ++it) + { + LLNotificationPtr notification = it->second; + std::string notificationName = notification->getName(); + + if(notificationName == toastName) + { + imToastExists = true; + } + else if(notificationName == offerName) + { + offerExists = true; + } + + //Notification already exists in notification pipeline (same instance of app running) + if (notification) + { + notification->setDND(true); + instance.update(notification); + } + } + + if(imToastExists) + { + LLFloaterReg::showInstance("im_container"); + } + + if(imToastExists || offerExists) + { + make_ui_sound("UISndNewIncomingIMSession"); + } + + //When exit DND mode, write empty notifications file + if(commChannel->getHistorySize()) + { + commChannel->clearHistory(); + saveNotifications(); + } +} + +LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChannel() const +{ + LLNotificationChannelPtr channelPtr = LLNotifications::getInstance()->getChannel("Communication"); + llassert(channelPtr); + return channelPtr; +} + +void LLDoNotDisturbNotificationStorage::removeNotification(const char * name, const LLUUID& id) +{ + LLNotifications& instance = LLNotifications::instance(); + LLNotificationChannelPtr channelPtr = getCommunicationChannel(); + LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get()); + LLNotificationPtr notification; + LLSD payload; + LLUUID notificationObjectID; + std::string notificationName; + std::string payloadVariable = nameToPayloadParameterMap[name]; + LLCommunicationChannel::history_list_t::iterator it; + std::vector<LLCommunicationChannel::history_list_t::iterator> itemsToRemove; + + //Find notification with the matching session id + for (it = commChannel->beginHistory(); + it != commChannel->endHistory(); + ++it) + { + notification = it->second; + payload = notification->getPayload(); + notificationObjectID = payload[payloadVariable].asUUID(); + notificationName = notification->getName(); + + if((notificationName == name) + && id == notificationObjectID) + { + itemsToRemove.push_back(it); + } + } + + + //Remove the notifications + if(itemsToRemove.size()) + { + while(itemsToRemove.size()) + { + it = itemsToRemove.back(); + notification = it->second; + commChannel->removeItemFromHistory(notification); + instance.cancel(notification); + itemsToRemove.pop_back(); + } + //Trigger saving of notifications to xml once all have been removed + saveNotifications(); + } +} + + +bool LLDoNotDisturbNotificationStorage::onChannelChanged(const LLSD& pPayload) +{ + if (pPayload["sigtype"].asString() != "load") + { + mDirty = true; + } + + return false; +} diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h new file mode 100644 index 0000000000..6e68b0d1be --- /dev/null +++ b/indra/newview/lldonotdisturbnotificationstorage.h @@ -0,0 +1,78 @@ +/** +* @file lldonotdisturbnotificationstorage.h +* @brief Header file for lldonotdisturbnotificationstorage +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLDONOTDISTURBNOTIFICATIONSTORAGE_H +#define LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H + +#include "llerror.h" +#include "lleventtimer.h" +#include "llnotifications.h" +#include "llnotificationstorage.h" +#include "llsingleton.h" + +class LLSD; + +class LLDoNotDisturbNotificationStorageTimer : public LLEventTimer +{ +public: + LLDoNotDisturbNotificationStorageTimer(); + ~LLDoNotDisturbNotificationStorageTimer(); + +public: + BOOL tick(); +}; + +class LLDoNotDisturbNotificationStorage : public LLSingleton<LLDoNotDisturbNotificationStorage>, public LLNotificationStorage +{ + LOG_CLASS(LLDoNotDisturbNotificationStorage); +public: + static const char * toastName; + static const char * offerName; + + LLDoNotDisturbNotificationStorage(); + ~LLDoNotDisturbNotificationStorage(); + + void initialize(); + bool getDirty(); + void resetDirty(); + void saveNotifications(); + void loadNotifications(); + void updateNotifications(); + void removeNotification(const char * name, const LLUUID& id); + +protected: + +private: + bool mDirty; + LLDoNotDisturbNotificationStorageTimer mTimer; + + LLNotificationChannelPtr getCommunicationChannel() const; + bool onChannelChanged(const LLSD& pPayload); + std::map<std::string, std::string> nameToPayloadParameterMap; +}; + +#endif // LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H + diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index debac9dcbf..4b0d3b361d 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -57,6 +57,8 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f; static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound"); +extern bool gShiftFrame; + //////////////////////// // @@ -97,7 +99,6 @@ void LLDrawable::init() mPositionGroup.clear(); mExtents[0].clear(); mExtents[1].clear(); - mQuietCount = 0; mState = 0; mVObjp = NULL; @@ -108,6 +109,8 @@ void LLDrawable::init() mGeneration = -1; mBinRadius = 1.f; + mBinIndex = -1; + mSpatialBridge = NULL; } @@ -251,11 +254,17 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep) return count; } +static LLFastTimer::DeclareTimer FTM_ALLOCATE_FACE("Allocate Face", true); + LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) { - LLMemType mt(LLMemType::MTYPE_DRAWABLE); - LLFace *face = new LLFace(this, mVObjp); + LLFace *face; + { + LLFastTimer t(FTM_ALLOCATE_FACE); + face = new LLFace(this, mVObjp); + } + if (!face) llerrs << "Allocating new Face: " << mFaces.size() << llendl; if (face) @@ -277,10 +286,12 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) { - LLMemType mt(LLMemType::MTYPE_DRAWABLE); - LLFace *face; - face = new LLFace(this, mVObjp); + + { + LLFastTimer t(FTM_ALLOCATE_FACE); + face = new LLFace(this, mVObjp); + } face->setTEOffset(mFaces.size()); face->setTexture(texturep); @@ -403,6 +414,8 @@ void LLDrawable::makeActive() if (!isRoot() && !mParent->isActive()) { mParent->makeActive(); + //NOTE: linked set will now NEVER become static + mParent->setState(LLDrawable::ACTIVE_CHILD); } //all child objects must also be active @@ -422,40 +435,26 @@ void LLDrawable::makeActive() if (mVObjp->getPCode() == LL_PCODE_VOLUME) { - if (mVObjp->isFlexible()) - { - return; - } - } - - if (mVObjp->getPCode() == LL_PCODE_VOLUME) - { gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE); } updatePartition(); } - if (isRoot()) - { - mQuietCount = 0; + llassert(isAvatar() || isRoot() || mParent->isActive()); } - else - { - getParent()->mQuietCount = 0; - } -} void LLDrawable::makeStatic(BOOL warning_enabled) { - if (isState(ACTIVE)) + if (isState(ACTIVE) && + !isState(ACTIVE_CHILD) && + !mVObjp->isAttachment() && + !mVObjp->isFlexible()) { - clearState(ACTIVE); + clearState(ACTIVE | ANIMATED_CHILD); - if (mParent.notNull() && mParent->isActive() && warning_enabled) - { - LL_WARNS_ONCE("Drawable") << "Drawable becomes static with active parent!" << LL_ENDL; - } + //drawable became static with active parent, not acceptable + llassert(mParent.isNull() || !mParent->isActive() || !warning_enabled); LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); @@ -483,8 +482,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled) mSpatialBridge->markDead(); setSpatialBridge(NULL); } + updatePartition(); } - updatePartition(); } // Returns "distance" between target destination and resulting xfrom @@ -525,6 +524,7 @@ F32 LLDrawable::updateXform(BOOL undamped) dist_squared = dist_vec_squared(new_pos, target_pos); LLQuaternion new_rot = nlerp(lerp_amt, old_rot, target_rot); + // FIXME: This can be negative! It is be possible for some rots to 'cancel out' pos or size changes. dist_squared += (1.f - dot(new_rot, target_rot)) * 10.f; LLVector3 new_scale = lerp(old_scale, target_scale, lerp_amt); @@ -538,9 +538,9 @@ F32 LLDrawable::updateXform(BOOL undamped) target_rot = new_rot; target_scale = new_scale; } - else + else if (mVObjp->getAngularVelocity().isExactlyZero()) { - // snap to final position + // snap to final position (only if no target omega is applied) dist_squared = 0.0f; if (getVOVolume() && !isRoot()) { //child prim snapping to some position, needs a rebuild @@ -548,16 +548,41 @@ F32 LLDrawable::updateXform(BOOL undamped) } } } + else + { + // The following fixes MAINT-1742 but breaks vehicles similar to MAINT-2275 + // dist_squared = dist_vec_squared(old_pos, target_pos); + + // The following fixes MAINT-2247 but causes MAINT-2275 + //dist_squared += (1.f - dot(old_rot, target_rot)) * 10.f; + //dist_squared += dist_vec_squared(old_scale, target_scale); + } - if ((mCurrentScale != target_scale) || - (!isRoot() && - (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED || - !mVObjp->getAngularVelocity().isExactlyZero() || - target_pos != mXform.getPosition() || - target_rot != mXform.getRotation()))) - { //child prim moving or scale change requires immediate rebuild + LLVector3 vec = mCurrentScale-target_scale; + + if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED) + { //scale change requires immediate rebuild + mCurrentScale = target_scale; gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); } + else if (!isRoot() && + (!mVObjp->getAngularVelocity().isExactlyZero() || + dist_squared > 0.f)) + { //child prim moving relative to parent, tag as needing to be rendered atomically and rebuild + dist_squared = 1.f; //keep this object on the move list + if (!isState(LLDrawable::ANIMATED_CHILD)) + { + setState(LLDrawable::ANIMATED_CHILD); + gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE); + mVObjp->dirtySpatialGroup(); + } + } + else if (!isRoot() && + ((dist_vec_squared(old_pos, target_pos) > 0.f) + || (1.f - dot(old_rot, target_rot)) > 0.f)) + { //fix for BUG-840, MAINT-2275, MAINT-1742, MAINT-2247 + gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); + } else if (!getVOVolume() && !isAvatar()) { movePartition(); @@ -568,9 +593,7 @@ F32 LLDrawable::updateXform(BOOL undamped) mXform.setRotation(target_rot); mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!) mXform.updateMatrix(); - - mCurrentScale = target_scale; - + if (mSpatialBridge) { gPipeline.markMoved(mSpatialBridge, FALSE); @@ -596,7 +619,11 @@ void LLDrawable::moveUpdatePipeline(BOOL moved) // Update the face centers. for (S32 i = 0; i < getNumFaces(); i++) { - getFace(i)->updateCenterAgent(); + LLFace* face = getFace(i); + if (face) + { + face->updateCenterAgent(); + } } } @@ -623,18 +650,8 @@ BOOL LLDrawable::updateMove() } makeActive(); - - BOOL done; - if (isState(MOVE_UNDAMPED)) - { - done = updateMoveUndamped(); - } - else - { - done = updateMoveDamped(); - } - return done; + return isState(MOVE_UNDAMPED) ? updateMoveUndamped() : updateMoveDamped(); } BOOL LLDrawable::updateMoveUndamped() @@ -651,7 +668,6 @@ BOOL LLDrawable::updateMoveUndamped() } mVObjp->clearChanged(LLXform::MOVED); - return TRUE; } @@ -703,6 +719,11 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) return; } + if (gShiftFrame) + { + return; + } + //switch LOD with the spatial group to avoid artifacts //LLSpatialGroup* sg = getSpatialGroup(); @@ -727,7 +748,8 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) for (S32 i = 0; i < getNumFaces(); i++) { LLFace* facep = getFace(i); - if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA) + if (facep && + (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA)) { LLVector4a box; box.setSub(facep->mExtents[1], facep->mExtents[0]); @@ -756,8 +778,6 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) void LLDrawable::updateTexture() { - LLMemType mt(LLMemType::MTYPE_DRAWABLE); - if (isDead()) { llwarns << "Dead drawable updating texture!" << llendl; @@ -771,18 +791,6 @@ void LLDrawable::updateTexture() if (getVOVolume()) { - /*if (isActive()) - { - if (isRoot()) - { - mQuietCount = 0; - } - else - { - getParent()->mQuietCount = 0; - } - }*/ - gPipeline.markRebuild(this, LLDrawable::REBUILD_MATERIAL, TRUE); } } @@ -811,14 +819,19 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector) mXform.setPosition(mVObjp->getPositionAgent()); } - mXform.setRotation(mVObjp->getRotation()); - mXform.setScale(1,1,1); mXform.updateMatrix(); if (isStatic()) { LLVOVolume* volume = getVOVolume(); - if (!volume) + + bool rebuild = (!volume && + getRenderType() != LLPipeline::RENDER_TYPE_TREE && + getRenderType() != LLPipeline::RENDER_TYPE_TERRAIN && + getRenderType() != LLPipeline::RENDER_TYPE_SKY && + getRenderType() != LLPipeline::RENDER_TYPE_GROUND); + + if (rebuild) { gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE); } @@ -826,13 +839,16 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector) for (S32 i = 0; i < getNumFaces(); i++) { LLFace *facep = getFace(i); - facep->mCenterAgent += LLVector3(shift_vector.getF32ptr()); - facep->mExtents[0].add(shift_vector); - facep->mExtents[1].add(shift_vector); - - if (!volume && facep->hasGeometry()) + if (facep) { - facep->clearVertexBuffer(); + facep->mCenterAgent += LLVector3(shift_vector.getF32ptr()); + facep->mExtents[0].add(shift_vector); + facep->mExtents[1].add(shift_vector); + + if (rebuild && facep->hasGeometry()) + { + facep->clearVertexBuffer(); + } } } @@ -940,8 +956,20 @@ void LLDrawable::updateUVMinMax() { } +LLSpatialGroup* LLDrawable::getSpatialGroup() const +{ + llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1); + return mSpatialGroupp; +} + void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) { + //precondition: mSpatialGroupp MUST be null or DEAD or mSpatialGroupp MUST NOT contain this + llassert(!mSpatialGroupp || mSpatialGroupp->isDead() || !mSpatialGroupp->hasElement(this)); + + //precondition: groupp MUST be null or groupp MUST contain this + llassert(!groupp || groupp->hasElement(this)); + /*if (mSpatialGroupp && (groupp != mSpatialGroupp)) { mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY); @@ -954,10 +982,18 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) for (S32 i = 0; i < getNumFaces(); ++i) { LLFace* facep = getFace(i); - facep->clearVertexBuffer(); + if (facep) + { + facep->clearVertexBuffer(); + } } } + //postcondition: if next group is NULL, previous group must be dead OR NULL OR binIndex must be -1 + //postcondition: if next group is NOT NULL, binIndex must not be -1 + llassert(groupp == NULL ? (mSpatialGroupp == NULL || mSpatialGroupp->isDead()) || getBinIndex() == -1 : + getBinIndex() != -1); + mSpatialGroupp = groupp; } @@ -1077,9 +1113,12 @@ 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); + mBinIndex = -1; + mRenderType = mDrawable->mRenderType; mDrawableType = mDrawable->mRenderType; @@ -1105,6 +1144,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() @@ -1375,6 +1423,11 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) return; } + if (gShiftFrame) + { + return; + } + if (mDrawable->getVObj()) { if (mDrawable->getVObj()->isAttachment()) @@ -1452,6 +1505,10 @@ void LLSpatialBridge::cleanupReferences() LLDrawable::cleanupReferences(); if (mDrawable) { + /* + + DON'T DO THIS -- this should happen through octree destruction + mDrawable->setSpatialGroup(NULL); if (mDrawable->getVObj()) { @@ -1466,7 +1523,7 @@ void LLSpatialBridge::cleanupReferences() drawable->setSpatialGroup(NULL); } } - } + }*/ LLDrawable* drawablep = mDrawable; mDrawable = NULL; @@ -1519,10 +1576,10 @@ BOOL LLDrawable::isAnimating() const return TRUE; } - if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero()) - { + /*if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero()) + { //target omega return TRUE; - } + }*/ return FALSE; } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index e268640a21..4608d16fec 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -38,7 +38,6 @@ #include "llvector4a.h" #include "llquaternion.h" #include "xform.h" -#include "llmemtype.h" #include "lldarray.h" #include "llviewerobject.h" #include "llrect.h" @@ -59,6 +58,7 @@ class LLViewerTexture; const U32 SILHOUETTE_HIGHLIGHT = 0; // All data for new renderer goes into this class. +LL_ALIGN_PREFIX(16) class LLDrawable : public LLRefCount { public: @@ -75,8 +75,17 @@ public: static void initClass(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLDrawable() { init(); } - MEM_TYPE_NEW(LLMemType::MTYPE_DRAWABLE); void markDead(); // Mark this drawable as dead BOOL isDead() const { return isState(DEAD); } @@ -109,6 +118,9 @@ public: F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); } S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; } F32 getBinRadius() const { return mBinRadius; } + S32 getBinIndex() const { return mBinIndex; } + void setBinIndex(S32 index) const { mBinIndex = index; } + void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); } LLXformMatrix* getXform() { return &mXform; } @@ -194,7 +206,7 @@ public: S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators... void setSpatialGroup(LLSpatialGroup *groupp); - LLSpatialGroup *getSpatialGroup() const { return mSpatialGroupp; } + LLSpatialGroup *getSpatialGroup() const; LLSpatialPartition* getSpatialPartition(); // Statics @@ -277,11 +289,13 @@ public: HAS_ALPHA = 0x04000000, RIGGED = 0x08000000, PARTITION_MOVE = 0x10000000, + ANIMATED_CHILD = 0x20000000, + ACTIVE_CHILD = 0x40000000, } EDrawableFlags; private: //aligned members - LLVector4a mExtents[2]; - LLVector4a mPositionGroup; + LL_ALIGN_16(LLVector4a mExtents[2]); + LL_ALIGN_16(LLVector4a mPositionGroup); public: LLXformMatrix mXform; @@ -290,8 +304,6 @@ public: LLPointer<LLDrawable> mParent; F32 mDistanceWRTCamera; - - S32 mQuietCount; static S32 getCurrentFrame() { return sCurVisible; } static S32 getMinVisFrameRange(); @@ -314,6 +326,7 @@ private: mutable U32 mVisible; F32 mRadius; F32 mBinRadius; + mutable S32 mBinIndex; S32 mGeneration; LLVector3 mCurrentScale; @@ -322,7 +335,7 @@ private: static U32 sNumZombieDrawables; static LLDynamicArrayPtr<LLPointer<LLDrawable> > sDeadList; -}; +} LL_ALIGN_POSTFIX(16); inline LLFace* LLDrawable::getFace(const S32 i) const @@ -333,12 +346,14 @@ inline LLFace* LLDrawable::getFace(const S32 i) const if ((U32) i >= mFaces.size()) { - llerrs << "Invalid face index." << llendl; + llwarns << "Invalid face index." << llendl; + return NULL; } if (!mFaces[i]) { - llerrs << "Null face found." << llendl; + llwarns << "Null face found." << llendl; + return NULL; } return mFaces[i]; diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 35f8a85796..94dd927d26 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -116,6 +116,7 @@ LLDrawPool::LLDrawPool(const U32 type) sNumDrawPools++; mId = sNumDrawPools; mVertexShaderLevel = 0; + mSkipRender = false; } LLDrawPool::~LLDrawPool() @@ -253,48 +254,6 @@ void LLFacePool::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures { } -// static -S32 LLFacePool::drawLoop(face_array_t& face_list) -{ - S32 res = 0; - if (!face_list.empty()) - { - for (std::vector<LLFace*>::iterator iter = face_list.begin(); - iter != face_list.end(); iter++) - { - LLFace *facep = *iter; - res += facep->renderIndexed(); - } - } - return res; -} - -// static -S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage) -{ - S32 res = 0; - if (!face_list.empty()) - { - for (std::vector<LLFace*>::iterator iter = face_list.begin(); - iter != face_list.end(); iter++) - { - LLFace *facep = *iter; - gGL.getTexUnit(stage)->bind(facep->getTexture(), TRUE) ; - gGL.getTexUnit(0)->activate(); - res += facep->renderIndexed(); - } - } - return res; -} - -void LLFacePool::drawLoop() -{ - if (!mDrawFace.empty()) - { - drawLoop(mDrawFace); - } -} - void LLFacePool::enqueue(LLFace* facep) { mDrawFace.push_back(facep); @@ -442,7 +401,7 @@ void LLRenderPass::renderTexture(U32 type, U32 mask) void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) { - for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) + for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) { LLDrawInfo* pparams = *i; if (pparams) @@ -460,6 +419,7 @@ void LLRenderPass::applyModelMatrix(LLDrawInfo& params) gGL.loadMatrix(gGLModelView); if (params.mModelMatrix) { + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix); } gPipeline.mMatrixOpCount++; diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index c7acbb42c6..ab9bb9e611 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -77,6 +77,9 @@ public: S32 getId() const { return mId; } U32 getType() const { return mType; } + BOOL getSkipRenderFlag() const { return mSkipRender;} + void setSkipRenderFlag( BOOL flag ) { mSkipRender = flag; } + virtual LLViewerTexture *getDebugTexture(); virtual void beginRenderPass( S32 pass ); virtual void endRenderPass( S32 pass ); @@ -113,6 +116,7 @@ protected: S32 mVertexShaderLevel; S32 mId; U32 mType; // Type of draw pool + BOOL mSkipRender; }; class LLRenderPass : public LLDrawPool @@ -133,7 +137,7 @@ public: PASS_ALPHA, PASS_ALPHA_MASK, PASS_FULLBRIGHT_ALPHA_MASK, - PASS_ALPHA_SHADOW, + PASS_ALPHA_INVISIBLE, NUM_RENDER_TYPES, }; @@ -186,10 +190,6 @@ public: void buildEdges(); - static S32 drawLoop(face_array_t& face_list); - static S32 drawLoopSetTex(face_array_t& face_list, S32 stage); - void drawLoop(); - void addFaceReference(LLFace *facep); void removeFaceReference(LLFace *facep); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index ddb7d3ceeb..313b310e1e 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -337,6 +337,7 @@ void LLDrawPoolAlpha::render(S32 pass) pushBatches(LLRenderPass::PASS_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + pushBatches(LLRenderPass::PASS_ALPHA_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); if(shaders) { @@ -347,7 +348,7 @@ void LLDrawPoolAlpha::render(S32 pass) void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) { - for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) + for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; if (group->mSpatialPartition->mRenderByGroup && @@ -384,7 +385,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) BOOL use_shaders = gPipeline.canUseVertexShaders(); - for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) + for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; llassert(group); @@ -404,6 +405,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) { LLDrawInfo& params = **k; + if ((params.mVertexBuffer->getTypeMask() & mask) != mask) + { //FIXME! + llwarns << "Missing required components, skipping render batch." << llendl; + continue; + } + LLRenderPass::applyModelMatrix(params); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 55b314fbb1..294cecc703 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -261,7 +261,9 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha() sRenderingSkinned = TRUE; gPipeline.bindDeferredShader(*sVertexProgram); - + + sVertexProgram->setMinimumAlpha(0.2f); + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); } @@ -1034,9 +1036,13 @@ void LLDrawPoolAvatar::endDeferredSkinned() gGL.getTexUnit(0)->activate(); } +static LLFastTimer::DeclareTimer FTM_RENDER_AVATARS("renderAvatars"); + void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) { + LLFastTimer t(FTM_RENDER_AVATARS); + if (pass == -1) { for (S32 i = 1; i < getNumPasses(); i++) @@ -1138,6 +1144,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) return; } + llassert(LLPipeline::sImpostorRender || !avatarp->isVisuallyMuted()); + /*if (single_avatar && avatarp->mSpecialRenderMode >= 1) // 1=anim preview, 2=image preview, 3=morph view { gPipeline.enableLightsAvatarEdit(LLColor4(.5f, .5f, .5f, 1.f)); @@ -1191,15 +1199,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) if (pass >= 7 && pass < 9) { - LLGLEnable blend(GL_BLEND); - - gGL.setColorMask(true, true); - gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, - LLRender::BF_ONE_MINUS_SOURCE_ALPHA, - LLRender::BF_ZERO, - LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - - if (pass == 7) { renderRiggedAlpha(avatarp); @@ -1215,20 +1214,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) if (pass == 9) { - LLGLEnable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - gGL.flush(); - - LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0f, -1.0f); - gGL.setSceneBlendType(LLRender::BT_ADD); - - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - gGL.setColorMask(false, true); - renderRiggedGlow(avatarp); - gGL.setColorMask(true, false); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + return; } @@ -1285,7 +1272,10 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face->setGeomIndex(0); face->setIndicesIndex(0); - if (buffer.isNull() || buffer->getTypeMask() != data_mask) + //rigged faces do not batch textures + face->setTextureIndex(255); + + if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable()) { //make a new buffer if (sShaderLevel > 0) { @@ -1319,7 +1309,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); } @@ -1424,7 +1416,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { - if (avatar->isSelf() && !gAgent.needsRenderAvatar() || !gMeshRepo.meshRezEnabled()) + if (avatar->isSelf() && !gAgent.needsRenderAvatar()) { return; } @@ -1553,8 +1545,12 @@ void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar) renderRigged(avatar, RIGGED_DEFERRED_BUMP); } +static LLFastTimer::DeclareTimer FTM_RIGGED_VBO("Rigged VBO"); + void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) { + LLFastTimer t(FTM_RIGGED_VBO); + //update rigged vertex buffers for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type) { @@ -1626,17 +1622,58 @@ void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar) void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar) { - renderRigged(avatar, RIGGED_ALPHA); + if (!mRiggedFace[RIGGED_ALPHA].empty()) + { + LLGLEnable blend(GL_BLEND); + + gGL.setColorMask(true, true); + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, + LLRender::BF_ONE_MINUS_SOURCE_ALPHA, + LLRender::BF_ZERO, + LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + + renderRigged(avatar, RIGGED_ALPHA); + gGL.setColorMask(true, false); + } } void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar) { - renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA); + if (!mRiggedFace[RIGGED_FULLBRIGHT_ALPHA].empty()) + { + LLGLEnable blend(GL_BLEND); + + gGL.setColorMask(true, true); + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, + LLRender::BF_ONE_MINUS_SOURCE_ALPHA, + LLRender::BF_ZERO, + LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + + renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA); + gGL.setColorMask(true, false); + } } void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar) { - renderRigged(avatar, RIGGED_GLOW, true); + if (!mRiggedFace[RIGGED_GLOW].empty()) + { + LLGLEnable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + gGL.flush(); + + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.0f, -1.0f); + gGL.setSceneBlendType(LLRender::BT_ADD); + + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + gGL.setColorMask(false, true); + + renderRigged(avatar, RIGGED_GLOW, true); + + gGL.setColorMask(true, false); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } } diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index b696b90d84..1b0b11298c 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -847,12 +847,12 @@ void LLDrawPoolBump::renderDeferred(S32 pass) LLFastTimer ftm(FTM_RENDER_BUMP); U32 type = LLRenderPass::PASS_BUMP; - LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type); - LLCullResult::drawinfo_list_t::iterator end = gPipeline.endRenderMap(type); + LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); + LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; - for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i) + for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) { LLDrawInfo& params = **i; @@ -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) ; } } @@ -1195,7 +1192,7 @@ static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_MIN_MAX("Min/Max"); static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_RGB2LUM("RGB to Luminance"); static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_RESCALE("Rescale"); static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_GEN_NORMAL("Generate Normal"); -static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_CREATE("Create"); +static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_CREATE("Bump Source Create"); // static void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code ) @@ -1344,8 +1341,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI // immediately assign bump to a global smart pointer in case some local smart pointer // accidentally releases it. LLPointer<LLViewerTexture> bump = LLViewerTextureManager::getLocalTexture( TRUE ); - - + if (!LLPipeline::sRenderDeferred) { LLFastTimer t(FTM_BUMP_SOURCE_CREATE); @@ -1354,6 +1350,10 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI } else { //convert to normal map + + //disable compression on normal maps to prevent errors below + bump->getGLTexture()->setAllowCompression(false); + { LLFastTimer t(FTM_BUMP_SOURCE_CREATE); bump->setExplicitFormat(GL_RGBA8, GL_ALPHA); @@ -1448,10 +1448,10 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI void LLDrawPoolBump::renderBump(U32 type, U32 mask) { - LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type); - LLCullResult::drawinfo_list_t::iterator end = gPipeline.endRenderMap(type); + LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); + LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); - for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i) + for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) { LLDrawInfo& params = **i; diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index b95d8296fa..9bc32fddbd 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -294,6 +294,35 @@ void LLDrawPoolTerrain::renderShadow(S32 pass) //glCullFace(GL_BACK); } + +void LLDrawPoolTerrain::drawLoop() +{ + if (!mDrawFace.empty()) + { + for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); + iter != mDrawFace.end(); iter++) + { + LLFace *facep = *iter; + + LLMatrix4* model_matrix = &(facep->getDrawable()->getRegion()->mRenderMatrix); + + if (model_matrix != gGLLastMatrix) + { + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); + gGLLastMatrix = model_matrix; + gGL.loadMatrix(gGLModelView); + if (model_matrix) + { + gGL.multMatrix((GLfloat*) model_matrix->mMatrix); + } + gPipeline.mMatrixOpCount++; + } + + facep->renderIndexed(); + } + } +} + void LLDrawPoolTerrain::renderFullShader() { // Hack! Get the region that this draw pool is rendering from! @@ -566,7 +595,8 @@ void LLDrawPoolTerrain::renderFull4TU() gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); gGL.translatef(-1.f, 0.f, 0.f); - + gGL.matrixMode(LLRender::MM_MODELVIEW); + // Set alpha texture and do lighting modulation gGL.getTexUnit(3)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_VERT_COLOR); gGL.getTexUnit(3)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); @@ -714,6 +744,7 @@ void LLDrawPoolTerrain::renderFull2TU() gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); gGL.translatef(-1.f, 0.f, 0.f); + gGL.matrixMode(LLRender::MM_MODELVIEW); // Care about alpha only gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); @@ -753,6 +784,7 @@ void LLDrawPoolTerrain::renderFull2TU() gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); gGL.translatef(-2.f, 0.f, 0.f); + gGL.matrixMode(LLRender::MM_MODELVIEW); // Care about alpha only gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 283ed87f1a..2163d087e1 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -83,6 +83,7 @@ protected: void renderFull2TU(); void renderFull4TU(); void renderFullShader(); + void drawLoop(); }; #endif // LL_LLDRAWPOOLSIMPLE_H diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index d198e28c14..fedbd782dc 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -37,6 +37,7 @@ #include "llviewershadermgr.h" #include "llrender.h" #include "llviewercontrol.h" +#include "llviewerregion.h" S32 LLDrawPoolTree::sDiffTex = 0; static LLGLSLShader* shader = NULL; @@ -97,25 +98,33 @@ void LLDrawPoolTree::render(S32 pass) LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1); LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f); - if (gSavedSettings.getBOOL("RenderAnimateTrees")) - { - renderTree(); - } - else + gGL.getTexUnit(sDiffTex)->bind(mTexturep); + + for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); + iter != mDrawFace.end(); iter++) { - gGL.getTexUnit(sDiffTex)->bind(mTexturep); - - for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) + LLFace *face = *iter; + LLVertexBuffer* buff = face->getVertexBuffer(); + + if(buff) { - LLFace *face = *iter; - LLVertexBuffer* buff = face->getVertexBuffer(); - if(buff) + LLMatrix4* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix); + + if (model_matrix != gGLLastMatrix) { - buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); - buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); - gPipeline.addTrianglesDrawn(buff->getNumIndices()); + gGLLastMatrix = model_matrix; + gGL.loadMatrix(gGLModelView); + if (model_matrix) + { + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); + gGL.multMatrix((GLfloat*) model_matrix->mMatrix); + } + gPipeline.mMatrixOpCount++; } + + buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); + buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); + gPipeline.addTrianglesDrawn(buff->getNumIndices()); } } } @@ -187,133 +196,6 @@ void LLDrawPoolTree::endShadowPass(S32 pass) gDeferredTreeShadowProgram.unbind(); } - -void LLDrawPoolTree::renderTree(BOOL selecting) -{ - LLGLState normalize(GL_NORMALIZE, TRUE); - - // Bind the texture for this tree. - gGL.getTexUnit(sDiffTex)->bind(mTexturep.get(), TRUE); - - U32 indices_drawn = 0; - - gGL.matrixMode(LLRender::MM_MODELVIEW); - - for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - LLFace *face = *iter; - LLDrawable *drawablep = face->getDrawable(); - - if (drawablep->isDead() || !face->getVertexBuffer()) - { - continue; - } - - face->getVertexBuffer()->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); - U16* indicesp = (U16*) face->getVertexBuffer()->getIndicesPointer(); - - // Render each of the trees - LLVOTree *treep = (LLVOTree *)drawablep->getVObj().get(); - - LLColor4U color(255,255,255,255); - - if (!selecting || treep->mGLName != 0) - { - if (selecting) - { - S32 name = treep->mGLName; - - color = LLColor4U((U8)(name >> 16), (U8)(name >> 8), (U8)name, 255); - } - - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - //gGL.pushMatrix(); - F32 mat[16]; - for (U32 i = 0; i < 16; i++) - mat[i] = (F32) gGLModelView[i]; - - LLMatrix4 matrix(mat); - - // Translate to tree base HACK - adjustment in Z plants tree underground - const LLVector3 &pos_agent = treep->getPositionAgent(); - //gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); - LLMatrix4 trans_mat; - trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); - trans_mat *= matrix; - - // Rotate to tree position and bend for current trunk/wind - // Note that trunk stiffness controls the amount of bend at the trunk as - // opposed to the crown of the tree - // - const F32 TRUNK_STIFF = 22.f; - - LLQuaternion rot = - LLQuaternion(treep->mTrunkBend.magVec()*TRUNK_STIFF*DEG_TO_RAD, LLVector4(treep->mTrunkBend.mV[VX], treep->mTrunkBend.mV[VY], 0)) * - LLQuaternion(90.f*DEG_TO_RAD, LLVector4(0,0,1)) * - treep->getRotation(); - - LLMatrix4 rot_mat(rot); - rot_mat *= trans_mat; - - F32 radius = treep->getScale().magVec()*0.05f; - LLMatrix4 scale_mat; - scale_mat.mMatrix[0][0] = - scale_mat.mMatrix[1][1] = - scale_mat.mMatrix[2][2] = radius; - - scale_mat *= rot_mat; - - const F32 THRESH_ANGLE_FOR_BILLBOARD = 15.f; - const F32 BLEND_RANGE_FOR_BILLBOARD = 3.f; - - F32 droop = treep->mDroop + 25.f*(1.f - treep->mTrunkBend.magVec()); - - S32 stop_depth = 0; - F32 app_angle = treep->getAppAngle()*LLVOTree::sTreeFactor; - F32 alpha = 1.0; - S32 trunk_LOD = LLVOTree::sMAX_NUM_TREE_LOD_LEVELS; - - for (S32 j = 0; j < 4; j++) - { - - if (app_angle > LLVOTree::sLODAngles[j]) - { - trunk_LOD = j; - break; - } - } - if(trunk_LOD >= LLVOTree::sMAX_NUM_TREE_LOD_LEVELS) - { - continue ; //do not render. - } - - if (app_angle < (THRESH_ANGLE_FOR_BILLBOARD - BLEND_RANGE_FOR_BILLBOARD)) - { - // - // Draw only the billboard - // - // Only the billboard, can use closer to normal alpha func. - stop_depth = -1; - LLFacePool::LLOverrideFaceColor clr(this, color); - indices_drawn += treep->drawBranchPipeline(scale_mat, indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha); - } - else // if (app_angle > (THRESH_ANGLE_FOR_BILLBOARD + BLEND_RANGE_FOR_BILLBOARD)) - { - // - // Draw only the full geometry tree - // - //stop_depth = (app_angle < THRESH_ANGLE_FOR_RECURSION_REDUCTION); - LLFacePool::LLOverrideFaceColor clr(this, color); - indices_drawn += treep->drawBranchPipeline(scale_mat, indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha); - } - - //gGL.popMatrix(); - } - } -} - BOOL LLDrawPoolTree::verify() const { /* BOOL ok = TRUE; diff --git a/indra/newview/lldrawpooltree.h b/indra/newview/lldrawpooltree.h index ddb259bb82..e7e25453cf 100644 --- a/indra/newview/lldrawpooltree.h +++ b/indra/newview/lldrawpooltree.h @@ -68,9 +68,6 @@ public: /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display static S32 sDiffTex; - -private: - void renderTree(BOOL selecting = FALSE); }; #endif // LL_LLDRAWPOOLTREE_H diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index caf15fe1cb..b5faff7968 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -192,14 +192,18 @@ void LLDrawPoolWLSky::renderStars(void) const bool error; LLColor4 star_alpha(LLColor4::black); star_alpha.mV[3] = LLWLParamManager::getInstance()->mCurParams.getFloat("star_brightness", error) / 2.f; - llassert_always(!error); + + // If start_brightness is not set, exit + if( error ) + { + llwarns << "star_brightness missing in mCurParams" << llendl; + return; + } gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex()); gGL.pushMatrix(); gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f); - // gl_FragColor.rgb = gl_Color.rgb; - // gl_FragColor.a = gl_Color.a * star_alpha.a; if (LLGLSLShader::sNoFixedFunction) { gCustomAlphaProgram.bind(); diff --git a/indra/newview/lldriverparam.cpp b/indra/newview/lldriverparam.cpp index 8f47d3c5e5..885cae1737 100644 --- a/indra/newview/lldriverparam.cpp +++ b/indra/newview/lldriverparam.cpp @@ -139,7 +139,7 @@ void LLDriverParamInfo::toStream(std::ostream &out) } else { - llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << gAgentAvatarp << " for driver parameter " << getID() << llendl; + llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << gAgentAvatarp.get() << " for driver parameter " << getID() << llendl; } out << std::endl; } @@ -155,6 +155,7 @@ LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) : mAvatarp(avatarp), mWearablep(NULL) { + mDefaultVec.clear(); } LLDriverParam::LLDriverParam(LLWearable *wearablep) : @@ -162,6 +163,7 @@ LLDriverParam::LLDriverParam(LLWearable *wearablep) : mAvatarp(NULL), mWearablep(wearablep) { + mDefaultVec.clear(); } LLDriverParam::~LLDriverParam() @@ -341,18 +343,19 @@ F32 LLDriverParam::getTotalDistortion() return sum; } -const LLVector3 &LLDriverParam::getAvgDistortion() +const LLVector4a &LLDriverParam::getAvgDistortion() { // It's not actually correct to take the average of averages, but it good enough here. - LLVector3 sum; + LLVector4a sum; + sum.clear(); S32 count = 0; for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ ) { LLDrivenEntry* driven = &(*iter); - sum += driven->mParam->getAvgDistortion(); + sum.add(driven->mParam->getAvgDistortion()); count++; } - sum /= (F32)count; + sum.mul( 1.f/(F32)count); mDefaultVec = sum; return mDefaultVec; @@ -375,21 +378,22 @@ F32 LLDriverParam::getMaxDistortion() } -LLVector3 LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) +LLVector4a LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { - LLVector3 sum; + LLVector4a sum; + sum.clear(); for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ ) { LLDrivenEntry* driven = &(*iter); - sum += driven->mParam->getVertexDistortion( index, poly_mesh ); + sum.add(driven->mParam->getVertexDistortion( index, poly_mesh )); } return sum; } -const LLVector3* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) +const LLVector4a* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { mCurrentDistortionParam = NULL; - const LLVector3* v = NULL; + const LLVector4a* v = NULL; for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ ) { LLDrivenEntry* driven = &(*iter); @@ -404,7 +408,7 @@ const LLVector3* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly return v; }; -const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) +const LLVector4a* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { llassert( mCurrentDistortionParam ); if( !mCurrentDistortionParam ) @@ -432,7 +436,7 @@ const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_ } // We're already in the middle of a param's distortions, so get the next one. - const LLVector3* v = driven->mParam->getNextDistortion( index, poly_mesh ); + const LLVector4a* v = driven->mParam->getNextDistortion( index, poly_mesh ); if( (!v) && (iter != mDriven.end()) ) { // This param is finished, so start the next param. It might not have any diff --git a/indra/newview/lldriverparam.h b/indra/newview/lldriverparam.h index fb1b44458c..216cf003e1 100644 --- a/indra/newview/lldriverparam.h +++ b/indra/newview/lldriverparam.h @@ -75,6 +75,7 @@ protected: //----------------------------------------------------------------------------- +LL_ALIGN_PREFIX(16) class LLDriverParam : public LLViewerVisualParam { friend class LLPhysicsMotion; // physics motion needs to access driven params directly. @@ -83,6 +84,16 @@ public: LLDriverParam(LLWearable *wearablep); ~LLDriverParam(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + // Special: These functions are overridden by child classes LLDriverParamInfo* getInfo() const { return (LLDriverParamInfo*)mInfo; } // This sets mInfo and calls initialization functions @@ -105,24 +116,24 @@ public: // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion(); - /*virtual*/ const LLVector3& getAvgDistortion(); + /*virtual*/ const LLVector4a& getAvgDistortion(); /*virtual*/ F32 getMaxDistortion(); - /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); - /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); - /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); + /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); + /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); + /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); protected: F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight); void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake); - LLVector3 mDefaultVec; // temp holder + LL_ALIGN_16(LLVector4a mDefaultVec); // temp holder typedef std::vector<LLDrivenEntry> entry_list_t; entry_list_t mDriven; LLViewerVisualParam* mCurrentDistortionParam; // Backlink only; don't make this an LLPointer. LLVOAvatar* mAvatarp; LLWearable* mWearablep; -}; +} LL_ALIGN_POSTFIX(16); #endif // LL_LLDRIVERPARAM_H diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 5d6081a35c..fa42b157a7 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -125,8 +125,16 @@ BOOL LLViewerDynamicTexture::render() //----------------------------------------------------------------------------- void LLViewerDynamicTexture::preRender(BOOL clear_depth) { - { - // force rendering to on-screen portion of frame buffer + //only images up to 512x512 are supported + llassert(mFullHeight <= 512); + llassert(mFullWidth <= 512); + + if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI) + { //using offscreen render target, just use the bottom left corner + mOrigin.set(0, 0); + } + else + { // force rendering to on-screen portion of frame buffer LLCoordScreen window_pos; gViewerWindow->getWindow()->getPosition( &window_pos ); mOrigin.set(0, gViewerWindow->getWindowHeightRaw() - mFullHeight); // top left corner @@ -140,9 +148,9 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth) mOrigin.mY += window_pos.mY; mOrigin.mY = llmax(mOrigin.mY, 0) ; } - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); // Set up camera LLViewerCamera* camera = LLViewerCamera::getInstance(); mCamera.setOrigin(*camera); @@ -208,6 +216,13 @@ BOOL LLViewerDynamicTexture::updateAllInstances() return TRUE; } + bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI; + + if (use_fbo) + { + gPipeline.mWaterDis.bindTarget(); + } + LLGLSLShader::bindNoShader(); LLVertexBuffer::unbind(); @@ -241,6 +256,11 @@ BOOL LLViewerDynamicTexture::updateAllInstances() } } + if (use_fbo) + { + gPipeline.mWaterDis.flush(); + } + return ret; } diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index e18090545d..c51e7d1e1a 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -36,6 +36,16 @@ class LLViewerDynamicTexture : public LLViewerTexture { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + enum { LL_VIEWER_DYNAMIC_TEXTURE = LLViewerTexture::DYNAMIC_TEXTURE, @@ -85,7 +95,7 @@ protected: protected: BOOL mClamp; LLCoordGL mOrigin; - LLCamera mCamera; + LL_ALIGN_16(LLCamera mCamera); typedef std::set<LLViewerDynamicTexture*> instance_list_t; static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index 4f4d9a40b4..2c786b7f8b 100644 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -86,7 +86,7 @@ namespace class LLEventPollEventTimer : public LLEventTimer { - typedef boost::intrusive_ptr<LLEventPollResponder> EventPollResponderPtr; + typedef LLPointer<LLEventPollResponder> EventPollResponderPtr; public: LLEventPollEventTimer(F32 period, EventPollResponderPtr responder) diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index 2abfbf37ca..a50184460b 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -55,7 +55,7 @@ public: else { width = mEditor.getDocumentView()->getRect().getWidth() - mEditor.getHPad(); - height = llceil(mStyle->getFont()->getLineHeight()); + height = mStyle->getFont()->getLineHeight(); } return true; } @@ -150,7 +150,7 @@ void LLExpandableTextBox::LLTextBoxEx::showExpandText() std::pair<S32, S32> visible_lines = getVisibleLines(true); S32 last_line = visible_lines.second - 1; - LLStyle::Params expander_style(getDefaultStyleParams()); + LLStyle::Params expander_style(getStyleParams()); expander_style.font.style = "UNDERLINE"; expander_style.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); LLExpanderSegment* expanderp = new LLExpanderSegment(new LLStyle(expander_style), getLineStart(last_line), getLength() + 1, mExpanderLabel, *this); @@ -166,7 +166,7 @@ void LLExpandableTextBox::LLTextBoxEx::hideExpandText() if (mExpanderVisible) { // this will overwrite the expander segment and all text styling with a single style - LLStyleConstSP sp(new LLStyle(getDefaultStyleParams())); + LLStyleConstSP sp(new LLStyle(getStyleParams())); LLNormalTextSegment* segmentp = new LLNormalTextSegment(sp, 0, getLength() + 1, *this); insertSegment(segmentp); 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..28e4b32793 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -44,11 +44,14 @@ #include "llsky.h" #include "llviewercamera.h" #include "llviewertexturelist.h" +#include "llvopartgroup.h" #include "llvosky.h" #include "llvovolume.h" #include "pipeline.h" #include "llviewerregion.h" #include "llviewerwindow.h" +#include "llviewershadermgr.h" + #define LL_MAX_INDICES_COUNT 1000000 @@ -56,7 +59,6 @@ BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE #define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]) - /* For each vertex, given: B - binormal @@ -161,7 +163,10 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) mGeomCount = 0; mGeomIndex = 0; mIndicesCount = 0; - mIndicesIndex = 0; + + //special value to indicate uninitialized position + mIndicesIndex = 0xFFFFFFFF; + mIndexInTex = 0; mTexture = NULL; mTEOffset = -1; @@ -177,12 +182,6 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) mFaceColor = LLColor4(1,0,0,1); - mLastVertexBuffer = mVertexBuffer; - mLastGeomCount = mGeomCount; - mLastGeomIndex = mGeomIndex; - mLastIndicesCount = mIndicesCount; - mLastIndicesIndex = mIndicesIndex; - mImportanceToCamera = 0.f ; mBoundingSphereRadius = 0.0f ; @@ -203,6 +202,12 @@ void LLFace::destroy() mTexture->removeFace(this) ; } + if (isState(LLFace::PARTICLE)) + { + LLVOPartGroup::freeVBSlot(getGeomIndex()/4); + clearState(LLFace::PARTICLE); + } + if (mDrawPoolp) { if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR) @@ -258,8 +263,6 @@ void LLFace::setPool(LLFacePool* pool) void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep) { - LLMemType mt1(LLMemType::MTYPE_DRAWABLE); - if (!new_pool) { llerrs << "Setting pool to null!" << llendl; @@ -313,7 +316,20 @@ void LLFace::setTexture(LLViewerTexture* tex) void LLFace::dirtyTexture() { - gPipeline.markTextured(getDrawable()); + LLDrawable* drawablep = getDrawable(); + + if (mVObjp.notNull() && mVObjp->getVolume() && + mTexture.notNull() && mTexture->getComponents() == 4) + { //dirty texture on an alpha object should be treated as an LoD update + LLVOVolume* vobj = drawablep->getVOVolume(); + if (vobj) + { + vobj->mLODChanged = TRUE; + } + gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE); + } + + gPipeline.markTextured(drawablep); } void LLFace::switchTexture(LLViewerTexture* new_texture) @@ -372,7 +388,6 @@ void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align) mGeomCount = num_vertices; mIndicesCount = num_indices; mVertexBuffer = NULL; - mLastVertexBuffer = NULL; } llassert(verify()); @@ -425,8 +440,6 @@ U16 LLFace::getGeometryAvatar( LLStrider<F32> &vertex_weights, LLStrider<LLVector4> &clothing_weights) { - LLMemType mt1(LLMemType::MTYPE_DRAWABLE); - if (mVertexBuffer.notNull()) { mVertexBuffer->getVertexStrider (vertices, mGeomIndex, mGeomCount); @@ -442,8 +455,6 @@ U16 LLFace::getGeometryAvatar( U16 LLFace::getGeometry(LLStrider<LLVector3> &vertices, LLStrider<LLVector3> &normals, LLStrider<LLVector2> &tex_coords, LLStrider<U16> &indicesp) { - LLMemType mt1(LLMemType::MTYPE_DRAWABLE); - if (mVertexBuffer.notNull()) { mVertexBuffer->getVertexStrider(vertices, mGeomIndex, mGeomCount); @@ -693,6 +704,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) { @@ -710,8 +764,6 @@ bool less_than_max_mag(const LLVector4a& vec) BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, const LLMatrix4& mat_vert_in, const LLMatrix3& mat_normal_in, BOOL global_volume) { - LLMemType mt1(LLMemType::MTYPE_DRAWABLE); - //get bounding box if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED)) { @@ -722,12 +774,6 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, LLMatrix4a mat_normal; mat_normal.loadu(mat_normal_in); - //if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME)) - //{ //vertex buffer no longer valid - // mVertexBuffer = NULL; - // mLastVertexBuffer = NULL; - //} - //VECTORIZE THIS LLVector4a min,max; @@ -989,30 +1035,13 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs void LLFace::updateRebuildFlags() { - if (!mDrawablep->isState(LLDrawable::REBUILD_VOLUME)) - { - BOOL moved = TRUE; - if (mLastVertexBuffer == mVertexBuffer && - !mVertexBuffer->isEmpty()) - { //this face really doesn't need to be regenerated, try real hard not to do so - if (mLastGeomCount == mGeomCount && - mLastGeomIndex == mGeomIndex && - mLastIndicesCount == mIndicesCount && - mLastIndicesIndex == mIndicesIndex) - { //data is in same location in vertex buffer - moved = FALSE; - } - } - mLastMoveTime = gFrameTimeSeconds; - - if (moved) - { - mDrawablep->setState(LLDrawable::REBUILD_VOLUME); - } + if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME)) + { //this rebuild is zero overhead (direct consequence of some change that affects this face) + mLastUpdateTime = gFrameTimeSeconds; } else - { - mLastUpdateTime = gFrameTimeSeconds; + { //this rebuild is overhead (side effect of some change that does not affect this face) + mLastMoveTime = gFrameTimeSeconds; } } @@ -1025,7 +1054,11 @@ bool LLFace::canRenderAsMask() } const LLTextureEntry* te = getTextureEntry(); - + if( !te || !getViewerObject() || !getTexture() ) + { + return false; + } + if ((te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha (te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask getTexture()->getIsAlphaMask()) // texture actually qualifies for masking (lazily recalculated but expensive) @@ -1051,6 +1084,73 @@ bool LLFace::canRenderAsMask() } +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_VOLUME("Volume VB Cache"); + +//static +void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf) +{ + LLFastTimer t(FTM_FACE_GEOM_VOLUME); + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | + LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL; + + if (vf.mWeights) + { + mask |= LLVertexBuffer::MAP_WEIGHT4; + } + + LLVertexBuffer* buff = new LLVertexBuffer(mask, GL_STATIC_DRAW_ARB); + vf.mVertexBuffer = buff; + + buff->allocateBuffer(vf.mNumVertices, 0, true); + + LLStrider<LLVector4a> f_vert; + LLStrider<LLVector3> f_binorm; + LLStrider<LLVector3> f_norm; + LLStrider<LLVector2> f_tc; + + buff->getBinormalStrider(f_binorm); + buff->getVertexStrider(f_vert); + buff->getNormalStrider(f_norm); + buff->getTexCoord0Strider(f_tc); + + for (U32 i = 0; i < vf.mNumVertices; ++i) + { + *f_vert++ = vf.mPositions[i]; + (*f_binorm++).set(vf.mBinormals[i].getF32ptr()); + *f_tc++ = vf.mTexCoords[i]; + (*f_norm++).set(vf.mNormals[i].getF32ptr()); + } + + if (vf.mWeights) + { + LLStrider<LLVector4> f_wght; + buff->getWeight4Strider(f_wght); + for (U32 i = 0; i < vf.mNumVertices; ++i) + { + (*f_wght++).set(vf.mWeights[i].getF32ptr()); + } + } + + buff->flush(); +} + +//helper function for pushing primitives for transform shaders and cleaning up +//uninitialized data on the tail, plus tracking number of expected primitives +void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count) +{ + if (source_count > 0 && dest_count >= source_count) //protect against possible U32 wrapping + { + //push source primitives + buff->drawArrays(LLRender::POINTS, 0, source_count); + U32 tail = dest_count-source_count; + for (U32 i = 0; i < tail; ++i) + { //copy last source primitive into each element in tail + buff->drawArrays(LLRender::POINTS, source_count-1, 1); + } + gPipeline.mTransformFeedbackPrimitives += dest_count; + } +} + static LLFastTimer::DeclareTimer FTM_FACE_GET_GEOM("Face Geom"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_POSITION("Position"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_NORMAL("Normal"); @@ -1060,6 +1160,15 @@ 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,42 +1187,44 @@ 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()) { if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices()) { - llwarns << "Index buffer overflow!" << llendl; - llwarns << "Indices Count: " << mIndicesCount - << " VF Num Indices: " << num_indices - << " Indices Index: " << mIndicesIndex - << " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl; - llwarns << "Last Indices Count: " << mLastIndicesCount - << " Last Indices Index: " << mLastIndicesIndex - << " Face Index: " << f - << " Pool Type: " << mPoolType << llendl; + if (gDebugGL) + { + llwarns << "Index buffer overflow!" << llendl; + llwarns << "Indices Count: " << mIndicesCount + << " VF Num Indices: " << num_indices + << " Indices Index: " << mIndicesIndex + << " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl; + llwarns << " Face Index: " << f + << " Pool Type: " << mPoolType << llendl; + } return FALSE; } if (num_vertices + mGeomIndex > mVertexBuffer->getNumVerts()) { - llwarns << "Vertex buffer overflow!" << llendl; + if (gDebugGL) + { + llwarns << "Vertex buffer overflow!" << llendl; + } return FALSE; } } 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 +1313,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 +1322,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) @@ -1228,17 +1344,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLMatrix4a mat_normal; mat_normal.loadu(mat_norm_in); - //if it's not fullbright and has no normals, bake sunlight based on face normal - //bool bake_sunlight = !getTextureEntry()->getFullbright() && - // !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); - F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0; - + bool do_xform = false; if (rebuild_tcoord) { - LLFastTimer t(FTM_FACE_GEOM_TEXTURE); - bool do_xform; - if (tep) { r = tep->getRotation(); @@ -1267,545 +1376,757 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { do_xform = false; } + } + + static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback"); + +#ifdef GL_TRANSFORM_FEEDBACK_BUFFER + if (use_transform_feedback && + gTransformPositionProgram.mProgramObject && //transform shaders are loaded + mVertexBuffer->useVBOs() && //target buffer is in VRAM + !rebuild_weights && //TODO: add support for weights + !volume.isUnique()) //source volume is NOT flexi + { //use transform feedback to pack vertex buffer + + LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get(); + + if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices) + { + mVObjp->getVolume()->genBinormals(f); + LLFace::cacheFaceInVRAM(vf); + buff = (LLVertexBuffer*) vf.mVertexBuffer.get(); + } + + LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr; + + gGL.pushMatrix(); + gGL.loadMatrix((GLfloat*) mat_vert_in.mMatrix); + + if (rebuild_pos) + { + LLFastTimer t(FTM_FACE_GEOM_POSITION); + gTransformPositionProgram.bind(); + + mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount); + + U8 index = mTextureIndex < 255 ? mTextureIndex : 0; + + S32 val = 0; + U8* vp = (U8*) &val; + vp[0] = index; + vp[1] = 0; + vp[2] = 0; + vp[3] = 0; + + gTransformPositionProgram.uniform1i("texture_index_in", val); + glBeginTransformFeedback(GL_POINTS); + buff->setBuffer(LLVertexBuffer::MAP_VERTEX); + + push_for_transform(buff, vf.mNumVertices, mGeomCount); + + glEndTransformFeedback(); + } + + if (rebuild_color) + { + LLFastTimer t(FTM_FACE_GEOM_COLOR); + gTransformColorProgram.bind(); + + mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount); + + S32 val = *((S32*) color.mV); + + gTransformColorProgram.uniform1i("color_in", val); + glBeginTransformFeedback(GL_POINTS); + buff->setBuffer(LLVertexBuffer::MAP_VERTEX); + push_for_transform(buff, vf.mNumVertices, mGeomCount); + glEndTransformFeedback(); + } + + if (rebuild_emissive) + { + LLFastTimer t(FTM_FACE_GEOM_EMISSIVE); + gTransformColorProgram.bind(); + + mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount); + + U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); + + S32 glow32 = glow | + (glow << 8) | + (glow << 16) | + (glow << 24); + + gTransformColorProgram.uniform1i("color_in", glow32); + glBeginTransformFeedback(GL_POINTS); + buff->setBuffer(LLVertexBuffer::MAP_VERTEX); + push_for_transform(buff, vf.mNumVertices, mGeomCount); + glEndTransformFeedback(); + } + + if (rebuild_normal) + { + LLFastTimer t(FTM_FACE_GEOM_NORMAL); + gTransformNormalProgram.bind(); + + mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount); - //bump setup - LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f ); - LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f); - LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f); + glBeginTransformFeedback(GL_POINTS); + buff->setBuffer(LLVertexBuffer::MAP_NORMAL); + push_for_transform(buff, vf.mNumVertices, mGeomCount); + glEndTransformFeedback(); + } - LLQuaternion bump_quat; - if (mDrawablep->isActive()) + if (rebuild_binormal) { - bump_quat = LLQuaternion(mDrawablep->getRenderMatrix()); + LLFastTimer t(FTM_FACE_GEOM_BINORMAL); + gTransformBinormalProgram.bind(); + + mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount); + + glBeginTransformFeedback(GL_POINTS); + buff->setBuffer(LLVertexBuffer::MAP_BINORMAL); + push_for_transform(buff, vf.mNumVertices, mGeomCount); + glEndTransformFeedback(); } - - if (bump_code) + + if (rebuild_tcoord) { - mVObjp->getVolume()->genBinormals(f); - F32 offset_multiple; - switch( bump_code ) - { - case BE_NO_BUMP: - offset_multiple = 0.f; - break; - case BE_BRIGHTNESS: - case BE_DARKNESS: - if( mTexture.notNull() && mTexture->hasGLTexture()) - { - // Offset by approximately one texel - S32 cur_discard = mTexture->getDiscardLevel(); - S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() ); - max_size <<= cur_discard; - const F32 ARTIFICIAL_OFFSET = 2.f; - offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size; - } - else - { - offset_multiple = 1.f/256; - } - break; + LLFastTimer t(FTM_FACE_GEOM_TEXTURE); + gTransformTexCoordProgram.bind(); + + mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount); + + glBeginTransformFeedback(GL_POINTS); + buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0); + push_for_transform(buff, vf.mNumVertices, mGeomCount); + glEndTransformFeedback(); - default: // Standard bumpmap textures. Assumed to be 256x256 - offset_multiple = 1.f / 256; - break; - } + bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); - F32 s_scale = 1.f; - F32 t_scale = 1.f; - if( tep ) + if (do_bump) { - tep->getScale( &s_scale, &t_scale ); - } - // Use the nudged south when coming from above sun angle, such - // that emboss mapping always shows up on the upward faces of cubes when - // it's noon (since a lot of builders build with the sun forced to noon). - LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir; - LLVector3 moon_ray = gSky.getMoonDirection(); - LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray; - - bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV); - bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV); + mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD1, mGeomIndex, mGeomCount); + glBeginTransformFeedback(GL_POINTS); + buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0); + push_for_transform(buff, vf.mNumVertices, mGeomCount); + glEndTransformFeedback(); + } } - U8 texgen = getTextureEntry()->getTexGen(); - if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT) - { //planar texgen needs binormals - mVObjp->getVolume()->genBinormals(f); + glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0); + + gGL.popMatrix(); + + if (cur_shader) + { + cur_shader->bind(); } + } + else +#endif + { + //if it's not fullbright and has no normals, bake sunlight based on face normal + //bool bake_sunlight = !getTextureEntry()->getFullbright() && + // !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); - U8 tex_mode = 0; - - if (isState(TEXTURE_ANIM)) + if (rebuild_tcoord) { - LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp; - tex_mode = vobj->mTexAnimMode; + LLFastTimer t(FTM_FACE_GEOM_TEXTURE); + + //bump setup + LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f ); + LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f); + LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f); - if (!tex_mode) + LLQuaternion bump_quat; + if (mDrawablep->isActive()) { - clearState(TEXTURE_ANIM); + bump_quat = LLQuaternion(mDrawablep->getRenderMatrix()); } - else + + if (bump_code) { - os = ot = 0.f; - r = 0.f; - cos_ang = 1.f; - sin_ang = 0.f; - ms = mt = 1.f; + mVObjp->getVolume()->genBinormals(f); + F32 offset_multiple; + switch( bump_code ) + { + case BE_NO_BUMP: + offset_multiple = 0.f; + break; + case BE_BRIGHTNESS: + case BE_DARKNESS: + if( mTexture.notNull() && mTexture->hasGLTexture()) + { + // Offset by approximately one texel + S32 cur_discard = mTexture->getDiscardLevel(); + S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() ); + max_size <<= cur_discard; + const F32 ARTIFICIAL_OFFSET = 2.f; + offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size; + } + else + { + offset_multiple = 1.f/256; + } + break; - do_xform = false; + default: // Standard bumpmap textures. Assumed to be 256x256 + offset_multiple = 1.f / 256; + break; + } + + F32 s_scale = 1.f; + F32 t_scale = 1.f; + if( tep ) + { + tep->getScale( &s_scale, &t_scale ); + } + // Use the nudged south when coming from above sun angle, such + // that emboss mapping always shows up on the upward faces of cubes when + // it's noon (since a lot of builders build with the sun forced to noon). + LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir; + LLVector3 moon_ray = gSky.getMoonDirection(); + LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray; + + bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV); + bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV); } - if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) - { //don't override texture transform during tc bake - tex_mode = 0; + U8 texgen = getTextureEntry()->getTexGen(); + if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT) + { //planar texgen needs binormals + mVObjp->getVolume()->genBinormals(f); } - } - LLVector4a scalea; - scalea.load3(scale.mV); + U8 tex_mode = 0; + + if (isState(TEXTURE_ANIM)) + { + LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp; + tex_mode = vobj->mTexAnimMode; + + if (!tex_mode) + { + clearState(TEXTURE_ANIM); + } + else + { + os = ot = 0.f; + r = 0.f; + cos_ang = 1.f; + sin_ang = 0.f; + ms = mt = 1.f; - bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); - bool do_tex_mat = tex_mode && mTextureMatrix; + do_xform = false; + } - if (!in_atlas && !do_bump) - { //not in atlas or not bump mapped, might be able to do a cheap update - mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount); + if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) + { //don't override texture transform during tc bake + tex_mode = 0; + } + } - if (texgen != LLTextureEntry::TEX_GEN_PLANAR) - { - if (!do_tex_mat) + LLVector4a scalea; + scalea.load3(scale.mV); + + bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); + bool do_tex_mat = tex_mode && mTextureMatrix; + + if (!in_atlas && !do_bump) + { //not in atlas or not bump mapped, might be able to do a cheap update + mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount); + + if (texgen != LLTextureEntry::TEX_GEN_PLANAR) { - if (!do_xform) + LLFastTimer t(FTM_FACE_TEX_QUICK); + if (!do_tex_mat) { - LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); + if (!do_xform) + { + LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM); + S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, tc_size); + } + else + { + 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++) + { + LLVector4a res = *src++; + xform4a(res, trans, mask, rot0, rot1, offset, scale); + res.store4a(dst); + dst += 4; + } + } } else - { + { //do tex mat, no texgen, no atlas, no bump for (S32 i = 0; i < num_vertices; i++) { LLVector2 tc(vf.mTexCoords[i]); - xform(tc, cos_ang, sin_ang, os, ot, ms, mt); + //LLVector4a& norm = vf.mNormals[i]; + //LLVector4a& center = *(vf.mCenter); + + LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); + tmp = tmp * *mTextureMatrix; + tc.mV[0] = tmp.mV[0]; + tc.mV[1] = tmp.mV[1]; *tex_coords++ = tc; } } } else - { //do tex mat, no texgen, no atlas, no bump - for (S32 i = 0; i < num_vertices; i++) - { - LLVector2 tc(vf.mTexCoords[i]); - //LLVector4a& norm = vf.mNormals[i]; - //LLVector4a& center = *(vf.mCenter); - - LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); - tmp = tmp * *mTextureMatrix; - tc.mV[0] = tmp.mV[0]; - tc.mV[1] = tmp.mV[1]; - *tex_coords++ = tc; - } - } - } - else - { //no bump, no atlas, tex gen planar - if (do_tex_mat) - { - for (S32 i = 0; i < num_vertices; i++) - { - LLVector2 tc(vf.mTexCoords[i]); - LLVector4a& norm = vf.mNormals[i]; - LLVector4a& center = *(vf.mCenter); - LLVector4a vec = vf.mPositions[i]; - vec.mul(scalea); - planarProjection(tc, norm, center, vec); + { //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++) + { + LLVector2 tc(vf.mTexCoords[i]); + LLVector4a& norm = vf.mNormals[i]; + LLVector4a& center = *(vf.mCenter); + LLVector4a vec = vf.mPositions[i]; + vec.mul(scalea); + planarProjection(tc, norm, center, vec); - LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); - tmp = tmp * *mTextureMatrix; - tc.mV[0] = tmp.mV[0]; - tc.mV[1] = tmp.mV[1]; + LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); + tmp = tmp * *mTextureMatrix; + tc.mV[0] = tmp.mV[0]; + tc.mV[1] = tmp.mV[1]; - *tex_coords++ = tc; + *tex_coords++ = tc; + } } - } - else - { - for (S32 i = 0; i < num_vertices; i++) - { - LLVector2 tc(vf.mTexCoords[i]); - LLVector4a& norm = vf.mNormals[i]; - LLVector4a& center = *(vf.mCenter); - LLVector4a vec = vf.mPositions[i]; - vec.mul(scalea); - planarProjection(tc, norm, center, vec); + else + { + for (S32 i = 0; i < num_vertices; i++) + { + LLVector2 tc(vf.mTexCoords[i]); + LLVector4a& norm = vf.mNormals[i]; + LLVector4a& center = *(vf.mCenter); + LLVector4a vec = vf.mPositions[i]; + vec.mul(scalea); + planarProjection(tc, norm, center, vec); - xform(tc, cos_ang, sin_ang, os, ot, ms, mt); + xform(tc, cos_ang, sin_ang, os, ot, ms, mt); - *tex_coords++ = tc; + *tex_coords++ = tc; + } } } - } - if (map_range) - { - mVertexBuffer->flush(); + if (map_range) + { + mVertexBuffer->flush(); + } } - } - else - { //either bump mapped or in atlas, just do the whole expensive loop - mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range); + 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; + std::vector<LLVector2> bump_tc; - for (S32 i = 0; i < num_vertices; i++) - { - LLVector2 tc(vf.mTexCoords[i]); + for (S32 i = 0; i < num_vertices; i++) + { + LLVector2 tc(vf.mTexCoords[i]); - LLVector4a& norm = vf.mNormals[i]; + LLVector4a& norm = vf.mNormals[i]; - LLVector4a& center = *(vf.mCenter); + LLVector4a& center = *(vf.mCenter); - if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) - { - LLVector4a vec = vf.mPositions[i]; + if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) + { + LLVector4a vec = vf.mPositions[i]; - vec.mul(scalea); + vec.mul(scalea); + + switch (texgen) + { + case LLTextureEntry::TEX_GEN_PLANAR: + planarProjection(tc, norm, center, vec); + break; + case LLTextureEntry::TEX_GEN_SPHERICAL: + sphericalProjection(tc, norm, center, vec); + break; + case LLTextureEntry::TEX_GEN_CYLINDRICAL: + cylindricalProjection(tc, norm, center, vec); + break; + default: + break; + } + } - switch (texgen) + if (tex_mode && mTextureMatrix) { - case LLTextureEntry::TEX_GEN_PLANAR: - planarProjection(tc, norm, center, vec); + LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); + tmp = tmp * *mTextureMatrix; + tc.mV[0] = tmp.mV[0]; + tc.mV[1] = tmp.mV[1]; + } + else + { + xform(tc, cos_ang, sin_ang, os, ot, ms, mt); + } + + if(in_atlas) + { + // + //manually calculate tex-coord per vertex for varying address modes. + //should be removed if shader can handle this. + // + + S32 int_part = 0 ; + switch(mTexture->getAddressMode()) + { + case LLTexUnit::TAM_CLAMP: + if(tc.mV[0] < 0.f) + { + tc.mV[0] = 0.f ; + } + else if(tc.mV[0] > 1.f) + { + tc.mV[0] = 1.f; + } + + if(tc.mV[1] < 0.f) + { + tc.mV[1] = 0.f ; + } + else if(tc.mV[1] > 1.f) + { + tc.mV[1] = 1.f; + } break; - case LLTextureEntry::TEX_GEN_SPHERICAL: - sphericalProjection(tc, norm, center, vec); + case LLTexUnit::TAM_MIRROR: + if(tc.mV[0] < 0.f) + { + tc.mV[0] = -tc.mV[0] ; + } + int_part = (S32)tc.mV[0] ; + if(int_part & 1) //odd number + { + tc.mV[0] = int_part + 1 - tc.mV[0] ; + } + else //even number + { + tc.mV[0] -= int_part ; + } + + if(tc.mV[1] < 0.f) + { + tc.mV[1] = -tc.mV[1] ; + } + int_part = (S32)tc.mV[1] ; + if(int_part & 1) //odd number + { + tc.mV[1] = int_part + 1 - tc.mV[1] ; + } + else //even number + { + tc.mV[1] -= int_part ; + } break; - case LLTextureEntry::TEX_GEN_CYLINDRICAL: - cylindricalProjection(tc, norm, center, vec); + case LLTexUnit::TAM_WRAP: + if(tc.mV[0] > 1.f) + tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ; + else if(tc.mV[0] < -1.f) + tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ; + + if(tc.mV[1] > 1.f) + tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ; + else if(tc.mV[1] < -1.f) + tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ; + + if(tc.mV[0] < 0.f) + { + tc.mV[0] = 1.0f + tc.mV[0] ; + } + if(tc.mV[1] < 0.f) + { + tc.mV[1] = 1.0f + tc.mV[1] ; + } break; default: break; - } - } + } + + tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; + tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ; + } + - if (tex_mode && mTextureMatrix) - { - LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); - tmp = tmp * *mTextureMatrix; - tc.mV[0] = tmp.mV[0]; - tc.mV[1] = tmp.mV[1]; + *tex_coords++ = tc; + if (do_bump) + { + bump_tc.push_back(tc); + } } - else + + if (map_range) { - xform(tc, cos_ang, sin_ang, os, ot, ms, mt); + mVertexBuffer->flush(); } - if(in_atlas) + if (do_bump) { - // - //manually calculate tex-coord per vertex for varying address modes. - //should be removed if shader can handle this. - // - - S32 int_part = 0 ; - switch(mTexture->getAddressMode()) + mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range); + + for (S32 i = 0; i < num_vertices; i++) { - case LLTexUnit::TAM_CLAMP: - if(tc.mV[0] < 0.f) - { - tc.mV[0] = 0.f ; - } - else if(tc.mV[0] > 1.f) - { - tc.mV[0] = 1.f; - } - - if(tc.mV[1] < 0.f) - { - tc.mV[1] = 0.f ; - } - else if(tc.mV[1] > 1.f) - { - tc.mV[1] = 1.f; - } - break; - case LLTexUnit::TAM_MIRROR: - if(tc.mV[0] < 0.f) - { - tc.mV[0] = -tc.mV[0] ; - } - int_part = (S32)tc.mV[0] ; - if(int_part & 1) //odd number - { - tc.mV[0] = int_part + 1 - tc.mV[0] ; - } - else //even number + LLVector4a tangent; + tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); + + LLMatrix4a tangent_to_object; + tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]); + LLVector4a t; + tangent_to_object.rotate(binormal_dir, t); + LLVector4a binormal; + mat_normal.rotate(t, binormal); + + //VECTORIZE THIS + if (mDrawablep->isActive()) { - tc.mV[0] -= int_part ; + LLVector3 t; + t.set(binormal.getF32ptr()); + t *= bump_quat; + binormal.load3(t.mV); } - if(tc.mV[1] < 0.f) - { - tc.mV[1] = -tc.mV[1] ; - } - int_part = (S32)tc.mV[1] ; - if(int_part & 1) //odd number - { - tc.mV[1] = int_part + 1 - tc.mV[1] ; - } - else //even number - { - tc.mV[1] -= int_part ; - } - break; - case LLTexUnit::TAM_WRAP: - if(tc.mV[0] > 1.f) - tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ; - else if(tc.mV[0] < -1.f) - tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ; - - if(tc.mV[1] > 1.f) - tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ; - else if(tc.mV[1] < -1.f) - tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ; - - if(tc.mV[0] < 0.f) - { - tc.mV[0] = 1.0f + tc.mV[0] ; - } - if(tc.mV[1] < 0.f) - { - tc.mV[1] = 1.0f + tc.mV[1] ; - } - break; - default: - break; + binormal.normalize3fast(); + LLVector2 tc = bump_tc[i]; + tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() ); + + *tex_coords2++ = tc; } - - tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; - tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ; - } - - - *tex_coords++ = tc; - if (do_bump) - { - bump_tc.push_back(tc); - } - } - - if (map_range) - { - mVertexBuffer->flush(); - } - if (do_bump) - { - mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range); - - for (S32 i = 0; i < num_vertices; i++) - { - LLVector4a tangent; - tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); - - LLMatrix4a tangent_to_object; - tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]); - LLVector4a t; - tangent_to_object.rotate(binormal_dir, t); - LLVector4a binormal; - mat_normal.rotate(t, binormal); - - //VECTORIZE THIS - if (mDrawablep->isActive()) + if (map_range) { - LLVector3 t; - t.set(binormal.getF32ptr()); - t *= bump_quat; - binormal.load3(t.mV); + mVertexBuffer->flush(); } - - binormal.normalize3fast(); - LLVector2 tc = bump_tc[i]; - tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() ); - - *tex_coords2++ = tc; - } - - if (map_range) - { - mVertexBuffer->flush(); } } } - } - if (rebuild_pos) - { - LLFastTimer t(FTM_FACE_GEOM_POSITION); - llassert(num_vertices > 0); + if (rebuild_pos) + { + LLFastTimer t(FTM_FACE_GEOM_POSITION); + llassert(num_vertices > 0); - mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); - vertices = (LLVector4a*) vert.get(); - - LLMatrix4a mat_vert; - mat_vert.loadu(mat_vert_in); + mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); + - LLVector4a* src = vf.mPositions; - LLVector4a* dst = vertices; + LLMatrix4a mat_vert; + mat_vert.loadu(mat_vert_in); - LLVector4a* end = dst+num_vertices; - do - { - mat_vert.affineTransform(*src++, *dst++); - } - while(dst < end); + LLVector4a* src = vf.mPositions; + volatile F32* dst = (volatile F32*) vert.get(); - F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0); + volatile F32* end = dst+num_vertices*4; + LLVector4a res; - llassert(index <= LLGLSLShader::sIndexedTextureChannels-1); - F32 *index_dst = (F32*) vertices; - F32 *index_end = (F32*) end; + LLVector4a texIdx; - index_dst += 3; - index_end += 3; - do - { - *index_dst = index; - index_dst += 4; - } - while (index_dst < index_end); + S32 index = mTextureIndex < 255 ? mTextureIndex : 0; + + F32 val = 0.f; + S32* vp = (S32*) &val; + *vp = index; + + llassert(index <= LLGLSLShader::sIndexedTextureChannels-1); + + LLVector4Logical mask; + mask.clear(); + mask.setElement<3>(); - S32 aligned_pad_vertices = mGeomCount - num_vertices; - LLVector4a* last_vec = end - 1; - while (aligned_pad_vertices > 0) - { - --aligned_pad_vertices; - *dst++ = *last_vec; + texIdx.set(0,0,0,val); + + { + 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); + } + + { + 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(); + } } + - if (map_range) + if (rebuild_normal) { - mVertexBuffer->flush(); - } - } - - if (rebuild_normal) - { - LLFastTimer t(FTM_FACE_GEOM_NORMAL); - mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range); - normals = (LLVector4a*) norm.get(); + LLFastTimer t(FTM_FACE_GEOM_NORMAL); + mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range); + 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; - } + for (S32 i = 0; i < num_vertices; i++) + { + LLVector4a normal; + mat_normal.rotate(vf.mNormals[i], normal); + normal.normalize3fast(); + normal.store4a(normals); + normals += 4; + } - if (map_range) - { - mVertexBuffer->flush(); + if (map_range) + { + mVertexBuffer->flush(); + } } - } - if (rebuild_binormal) - { - LLFastTimer t(FTM_FACE_GEOM_BINORMAL); - mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range); - binormals = (LLVector4a*) binorm.get(); + if (rebuild_binormal) + { + LLFastTimer t(FTM_FACE_GEOM_BINORMAL); + mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range); + 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; - } + for (S32 i = 0; i < num_vertices; i++) + { + LLVector4a binormal; + mat_normal.rotate(vf.mBinormals[i], binormal); + binormal.normalize3fast(); + binormal.store4a(binormals); + binormals += 4; + } - if (map_range) - { - mVertexBuffer->flush(); + if (map_range) + { + mVertexBuffer->flush(); + } } - } - if (rebuild_weights && vf.mWeights) - { - 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)); - if (map_range) + if (rebuild_weights && vf.mWeights) { - mVertexBuffer->flush(); + LLFastTimer t(FTM_FACE_GEOM_WEIGHTS); + mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range); + F32* weights = (F32*) wght.get(); + LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); + if (map_range) + { + mVertexBuffer->flush(); + } } - } - if (rebuild_color) - { - LLFastTimer t(FTM_FACE_GEOM_COLOR); - mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range); + if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) ) + { + LLFastTimer t(FTM_FACE_GEOM_COLOR); + mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range); - LLVector4a src; + LLVector4a src; - U32 vec[4]; - vec[0] = vec[1] = vec[2] = vec[3] = color.mAll; + U32 vec[4]; + vec[0] = vec[1] = vec[2] = vec[3] = color.mAll; - src.loadua((F32*) vec); + src.loadua((F32*) vec); - LLVector4a* dst = (LLVector4a*) colors.get(); - S32 num_vecs = num_vertices/4; - if (num_vertices%4 > 0) - { - ++num_vecs; - } + F32* dst = (F32*) colors.get(); + S32 num_vecs = num_vertices/4; + if (num_vertices%4 > 0) + { + ++num_vecs; + } - for (S32 i = 0; i < num_vecs; i++) - { - dst[i] = src; - } + for (S32 i = 0; i < num_vecs; i++) + { + src.store4a(dst); + dst += 4; + } - if (map_range) - { - mVertexBuffer->flush(); + if (map_range) + { + mVertexBuffer->flush(); + } } - } - if (rebuild_emissive) - { - LLFastTimer t(FTM_FACE_GEOM_EMISSIVE); - LLStrider<LLColor4U> emissive; - mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range); + if (rebuild_emissive) + { + LLFastTimer t(FTM_FACE_GEOM_EMISSIVE); + LLStrider<LLColor4U> emissive; + mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range); - U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); + U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); - LLVector4a src; + LLVector4a src; - U32 glow32 = glow | - (glow << 8) | - (glow << 16) | - (glow << 24); + U32 glow32 = glow | + (glow << 8) | + (glow << 16) | + (glow << 24); - U32 vec[4]; - vec[0] = vec[1] = vec[2] = vec[3] = glow32; + U32 vec[4]; + vec[0] = vec[1] = vec[2] = vec[3] = glow32; - src.loadua((F32*) vec); + src.loadua((F32*) vec); - LLVector4a* dst = (LLVector4a*) emissive.get(); - S32 num_vecs = num_vertices/4; - if (num_vertices%4 > 0) - { - ++num_vecs; - } + F32* dst = (F32*) emissive.get(); + S32 num_vecs = num_vertices/4; + if (num_vertices%4 > 0) + { + ++num_vecs; + } - for (S32 i = 0; i < num_vecs; i++) - { - dst[i] = src; - } + for (S32 i = 0; i < num_vecs; i++) + { + src.store4a(dst); + dst += 4; + } - if (map_range) - { - mVertexBuffer->flush(); + if (map_range) + { + mVertexBuffer->flush(); + } } } + if (rebuild_tcoord) { mTexExtents[0].setVec(0,0); @@ -1821,11 +2142,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mTexExtents[1][1] *= et ; } - mLastVertexBuffer = mVertexBuffer; - mLastGeomCount = mGeomCount; - mLastGeomIndex = mGeomIndex; - mLastIndicesCount = mIndicesCount; - mLastIndicesIndex = mIndicesIndex; return TRUE; } @@ -1848,6 +2164,12 @@ BOOL LLFace::hasMedia() const const F32 LEAST_IMPORTANCE = 0.05f ; const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ; +void LLFace::resetVirtualSize() +{ + setVirtualSize(0.f); + mImportanceToCamera = 0.f; +} + F32 LLFace::getTextureVirtualSize() { F32 radius; @@ -1913,8 +2235,17 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) LLVector4a t; t.load3(camera->getOrigin().mV); lookAt.setSub(center, t); + F32 dist = lookAt.getLength3().getF32(); - dist = llmax(dist-size.getLength3().getF32(), 0.f); + dist = llmax(dist-size.getLength3().getF32(), 0.001f); + //ramp down distance for nearby objects + if (dist < 16.f) + { + dist /= 16.f; + dist *= dist; + dist *= 16.f; + } + lookAt.normalize3fast() ; //get area of circle around node @@ -2405,7 +2736,6 @@ void LLFace::setVertexBuffer(LLVertexBuffer* buffer) void LLFace::clearVertexBuffer() { mVertexBuffer = NULL; - mLastVertexBuffer = NULL; } //static diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 82e4ab61b7..de4d03351c 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -59,6 +59,17 @@ class LLFace { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + + LLFace(const LLFace& rhs) { *this = rhs; @@ -79,10 +90,13 @@ public: USE_FACE_COLOR = 0x0010, TEXTURE_ANIM = 0x0020, RIGGED = 0x0040, + PARTICLE = 0x0080, }; static void initClass(); + static void cacheFaceInVRAM(const LLVolumeFace& vf); + public: LLFace(LLDrawable* drawablep, LLViewerObject* objp) { init(drawablep, objp); } ~LLFace() { destroy(); } @@ -204,6 +218,7 @@ public: F32 getTextureVirtualSize() ; F32 getImportanceToCamera()const {return mImportanceToCamera ;} + void resetVirtualSize(); void setHasMedia(bool has_media) { mHasMedia = has_media ;} BOOL hasMedia() const ; @@ -222,7 +237,7 @@ public: //vertex buffer tracking void setVertexBuffer(LLVertexBuffer* buffer); - void clearVertexBuffer(); //sets mVertexBuffer and mLastVertexBuffer to NULL + void clearVertexBuffer(); //sets mVertexBuffer to NULL LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; } U32 getRiggedVertexBufferDataMask() const; S32 getRiggedIndex(U32 type) const; @@ -255,8 +270,7 @@ public: private: LLPointer<LLVertexBuffer> mVertexBuffer; - LLPointer<LLVertexBuffer> mLastVertexBuffer; - + U32 mState; LLFacePool* mDrawPoolp; U32 mPoolType; @@ -269,12 +283,6 @@ private: U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!) S32 mIndexInTex ; - //previous rebuild's geometry info - U16 mLastGeomCount; - U16 mLastGeomIndex; - U32 mLastIndicesCount; - U32 mLastIndicesIndex; - LLXformMatrix* mXform; LLPointer<LLViewerTexture> mTexture; LLPointer<LLDrawable> mDrawablep; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 065dc5f4be..4dfb93f1bc 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -95,7 +95,6 @@ LLFastTimerView::LLFastTimerView(const LLSD& key) mHoverBarIndex = -1; FTV_NUM_TIMERS = LLFastTimer::NamedTimer::instanceCount(); mPrintStats = -1; - mAverageCyclesPerTimer = 0; } void LLFastTimerView::onPause() @@ -105,6 +104,7 @@ void LLFastTimerView::onPause() if (!LLFastTimer::sPauseHistory) { mScrollIndex = 0; + LLFastTimer::sResetHistory = true; getChild<LLButton>("pause_btn")->setLabel(getString("pause")); } else @@ -148,7 +148,7 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask) LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y) { - S32 idx = (getRect().getHeight() - y) / ((S32) LLFontGL::getFontMonospace()->getLineHeight()+2) - 5; + S32 idx = (getRect().getHeight() - y) / (LLFontGL::getFontMonospace()->getLineHeight()+2) - 5; if (idx >= 0 && idx < (S32)ft_display_idx.size()) { @@ -160,7 +160,7 @@ LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y) BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask) { - for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != end_timer_tree(); ++it) { @@ -257,7 +257,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) } S32 i = 0; - for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != end_timer_tree(); ++it, ++i) { @@ -378,12 +378,6 @@ void LLFastTimerView::draw() S32 xleft = margin; S32 ytop = margin; - mAverageCyclesPerTimer = LLFastTimer::sTimerCalls == 0 - ? 0 - : llround(lerp((F32)mAverageCyclesPerTimer, (F32)(LLFastTimer::sTimerCycles / (U64)LLFastTimer::sTimerCalls), 0.1f)); - LLFastTimer::sTimerCycles = 0; - LLFastTimer::sTimerCalls = 0; - // Draw some help { @@ -391,10 +385,6 @@ void LLFastTimerView::draw() y = height - ytop; texth = (S32)LLFontGL::getFontMonospace()->getLineHeight(); -#if TIME_FAST_TIMERS - tdesc = llformat("Cycles per timer call: %d", mAverageCyclesPerTimer); - LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); -#else char modedesc[][32] = { "2 x Average ", "Max ", @@ -418,7 +408,6 @@ void LLFastTimerView::draw() LLFontGL::getFontMonospace()->renderUTF8(std::string("[Right-Click log selected] [ALT-Click toggle counts] [ALT-SHIFT-Click sub hidden]"), 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); -#endif y -= (texth + 2); } @@ -430,11 +419,11 @@ void LLFastTimerView::draw() y -= (texth + 2); - sTimerColors[&LLFastTimer::NamedTimer::getRootNamedTimer()] = LLColor4::grey; + sTimerColors[&getFrameTimer()] = LLColor4::grey; F32 hue = 0.f; - for (timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != timer_tree_iterator_t(); ++it) { @@ -459,7 +448,7 @@ void LLFastTimerView::draw() S32 cur_line = 0; ft_display_idx.clear(); std::map<LLFastTimer::NamedTimer*, S32> display_line; - for (timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != timer_tree_iterator_t(); ++it) { @@ -525,6 +514,7 @@ void LLFastTimerView::draw() while(!is_child_of_hover_item && next_parent) { is_child_of_hover_item = (mHoverID == next_parent); + if (next_parent->getParent() == next_parent) break; next_parent = next_parent->getParent(); } @@ -551,7 +541,7 @@ void LLFastTimerView::draw() // update rectangle that includes timer bars mBarRect.mLeft = xleft; mBarRect.mRight = getRect().getWidth(); - mBarRect.mTop = ytop - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4); + mBarRect.mTop = ytop - (LLFontGL::getFontMonospace()->getLineHeight() + 4); mBarRect.mBottom = margin + LINE_GRAPH_HEIGHT; y = ytop; @@ -569,7 +559,7 @@ void LLFastTimerView::draw() U64 totalticks; if (!LLFastTimer::sPauseHistory) { - U64 ticks = LLFastTimer::NamedTimer::getRootNamedTimer().getHistoricalCount(mScrollIndex); + U64 ticks = getFrameTimer().getHistoricalCount(mScrollIndex); if (LLFastTimer::getCurFrameIndex() >= 10) { @@ -591,6 +581,7 @@ void LLFastTimerView::draw() { mAvgCountTotal = ticks; mMaxCountTotal = ticks; + LLFastTimer::sResetHistory = false; } } @@ -608,7 +599,7 @@ void LLFastTimerView::draw() totalticks = 0; for (S32 j=0; j<histmax; j++) { - U64 ticks = LLFastTimer::NamedTimer::getRootNamedTimer().getHistoricalCount(j); + U64 ticks = getFrameTimer().getHistoricalCount(j); if (ticks > totalticks) totalticks = ticks; @@ -714,7 +705,7 @@ void LLFastTimerView::draw() LLFastTimer::NamedTimer* prev_id = NULL; S32 i = 0; - for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != end_timer_tree(); ++it, ++i) { @@ -791,6 +782,7 @@ void LLFastTimerView::draw() while(!is_child_of_hover_item && next_parent) { is_child_of_hover_item = (mHoverID == next_parent); + if (next_parent->getParent() == next_parent) break; next_parent = next_parent->getParent(); } @@ -844,7 +836,7 @@ void LLFastTimerView::draw() tdesc = llformat("%4.2f ms", ms); x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(tdesc)-5; - y = mGraphRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight()); + y = mGraphRect.mTop - LLFontGL::getFontMonospace()->getLineHeight(); LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); @@ -877,7 +869,7 @@ void LLFastTimerView::draw() } U64 cur_max = 0; - for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != end_timer_tree(); ++it) { @@ -978,7 +970,7 @@ void LLFastTimerView::draw() { std::string legend_stat; bool first = true; - for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != end_timer_tree(); ++it) { @@ -1000,7 +992,7 @@ void LLFastTimerView::draw() std::string timer_stat; first = true; - for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != end_timer_tree(); ++it) { @@ -1561,3 +1553,9 @@ void LLFastTimerView::onClickCloseBtn() setVisible(false); } +LLFastTimer::NamedTimer& LLFastTimerView::getFrameTimer() +{ + return FTM_FRAME.getNamedTimer(); +} + + diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index a349e7ad4c..5766cfa0b0 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -46,6 +46,7 @@ private: static LLSD analyzePerformanceLogDefault(std::istream& is) ; static void exportCharts(const std::string& base, const std::string& target); void onPause(); + LLFastTimer::NamedTimer& getFrameTimer(); public: @@ -90,7 +91,6 @@ private: S32 mHoverBarIndex; LLFrameTimer mHighlightTimer; S32 mPrintStats; - S32 mAverageCyclesPerTimer; LLRect mGraphRect; }; diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 4f2fd47488..e30dd51acb 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -38,19 +38,22 @@ #include "lltooltip.h" #include "llagent.h" +#include "llavatarnamecache.h" +#include "llclipboard.h" #include "llclipboard.h" -#include "llinventoryclipboard.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llfloatersidepanelcontainer.h" #include "llfloaterworldmap.h" #include "lllandmarkactions.h" +#include "lllogininstance.h" #include "llnotificationsutil.h" #include "lltoggleablemenu.h" #include "llviewerinventory.h" #include "llviewermenu.h" #include "llviewermenu.h" #include "lltooldraganddrop.h" +#include "llsdserialize.h" static LLDefaultChildRegistry::Register<LLFavoritesBarCtrl> r("favorites_bar"); @@ -317,7 +320,8 @@ public: if (item) { - item->setSortField(mSortField); + LLFavoritesOrderStorage::instance().setSortIndex(item, mSortField); + item->setComplete(TRUE); item->updateServer(FALSE); @@ -339,8 +343,8 @@ struct LLFavoritesSort // TODO - made it customizible using gSavedSettings bool operator()(const LLViewerInventoryItem* const& a, const LLViewerInventoryItem* const& b) { - S32 sortField1 = a->getSortField(); - S32 sortField2 = b->getSortField(); + S32 sortField1 = LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID()); + S32 sortField2 = LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID()); if (!(sortField1 < 0 && sortField2 < 0)) { @@ -405,8 +409,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, @@ -528,7 +532,7 @@ void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y) mItems.push_back(gInventory.getItem(mDragItemId)); } - gInventory.saveItemsOrder(mItems); + LLFavoritesOrderStorage::instance().saveItemsOrder(mItems); LLToggleableMenu* menu = (LLToggleableMenu*) mOverflowMenuHandle.get(); @@ -587,7 +591,8 @@ void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, con } else { - currItem->setSortField(++sortField); + LLFavoritesOrderStorage::instance().setSortIndex(currItem, ++sortField); + currItem->setComplete(TRUE); currItem->updateServer(FALSE); @@ -640,7 +645,7 @@ void LLFavoritesBarCtrl::changed(U32 mask) for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) { - (*i)->getSLURL(); + LLFavoritesOrderStorage::instance().getSLURL((*i)->getAssetUUID()); } updateButtons(); } @@ -909,7 +914,7 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it S32 sortField = 0; for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) { - (*i)->setSortField(++sortField); + LLFavoritesOrderStorage::instance().setSortIndex((*i), ++sortField); } } @@ -1118,7 +1123,7 @@ BOOL LLFavoritesBarCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) } void copy_slurl_to_clipboard_cb(std::string& slurl) { - gClipboard.copyFromString(utf8str_to_wstring(slurl)); + LLClipboard::instance().copyToClipboard(utf8str_to_wstring(slurl),0,slurl.size()); LLSD args; args["SLURL"] = slurl; @@ -1187,11 +1192,11 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata) } else if (action == "copy") { - LLInventoryClipboard::instance().store(mSelectedItemID); + LLClipboard::instance().copyToClipboard(mSelectedItemID, LLAssetType::AT_LANDMARK); } else if (action == "paste") { - pastFromClipboard(); + pasteFromClipboard(); } else if (action == "delete") { @@ -1211,13 +1216,13 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata) BOOL LLFavoritesBarCtrl::isClipboardPasteable() const { - if (!LLInventoryClipboard::instance().hasContents()) + if (!LLClipboard::instance().hasContents()) { return FALSE; } LLDynamicArray<LLUUID> objects; - LLInventoryClipboard::instance().retrieve(objects); + LLClipboard::instance().pasteFromClipboard(objects); S32 count = objects.count(); for(S32 i = 0; i < count; i++) { @@ -1239,14 +1244,14 @@ BOOL LLFavoritesBarCtrl::isClipboardPasteable() const return TRUE; } -void LLFavoritesBarCtrl::pastFromClipboard() const +void LLFavoritesBarCtrl::pasteFromClipboard() const { LLInventoryModel* model = &gInventory; if(model && isClipboardPasteable()) { LLInventoryItem* item = NULL; LLDynamicArray<LLUUID> objects; - LLInventoryClipboard::instance().retrieve(objects); + LLClipboard::instance().pasteFromClipboard(objects); S32 count = objects.count(); LLUUID parent_id(mFavoriteFolderId); for(S32 i = 0; i < count; i++) @@ -1355,7 +1360,7 @@ BOOL LLFavoritesBarCtrl::needToSaveItemsOrder(const LLInventoryModel::item_array // if there is an item without sort order field set, we need to save items order for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i) { - if ((*i)->getSortField() < 0) + if (LLFavoritesOrderStorage::instance().getSortIndex((*i)->getUUID()) < 0) { result = TRUE; break; @@ -1390,4 +1395,295 @@ void LLFavoritesBarCtrl::insertItem(LLInventoryModel::item_array_t& items, const } } +const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml"; +const S32 LLFavoritesOrderStorage::NO_INDEX = -1; + +void LLFavoritesOrderStorage::setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index) +{ + mSortIndexes[inv_item->getUUID()] = sort_index; + mIsDirty = true; + getSLURL(inv_item->getAssetUUID()); +} + +S32 LLFavoritesOrderStorage::getSortIndex(const LLUUID& inv_item_id) +{ + sort_index_map_t::const_iterator it = mSortIndexes.find(inv_item_id); + if (it != mSortIndexes.end()) + { + return it->second; + } + return NO_INDEX; +} + +void LLFavoritesOrderStorage::removeSortIndex(const LLUUID& inv_item_id) +{ + mSortIndexes.erase(inv_item_id); + mIsDirty = true; +} + +void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id) +{ + slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id); + if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached + + LLLandmark* lm = gLandmarkList.getAsset(asset_id, + boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1)); + if (lm) + { + onLandmarkLoaded(asset_id, lm); + } +} + +// static +void LLFavoritesOrderStorage::destroyClass() +{ + LLFavoritesOrderStorage::instance().cleanup(); + if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin")) + { + LLFavoritesOrderStorage::instance().saveFavoritesSLURLs(); + } + else + { + LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser(); + } +} + +void LLFavoritesOrderStorage::load() +{ + // load per-resident sorting information + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME); + + LLSD settings_llsd; + llifstream file; + file.open(filename); + if (file.is_open()) + { + LLSDSerialize::fromXML(settings_llsd, file); + } + + for (LLSD::map_const_iterator iter = settings_llsd.beginMap(); + iter != settings_llsd.endMap(); ++iter) + { + mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger())); + } +} + +void LLFavoritesOrderStorage::saveFavoritesSLURLs() +{ + // Do not change the file if we are not logged in yet. + if (!LLLoginInstance::getInstance()->authSuccess()) + { + llwarns << "Cannot save favorites: not logged in" << llendl; + return; + } + + std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""); + if (user_dir.empty()) + { + llwarns << "Cannot save favorites: empty user dir name" << llendl; + return; + } + + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); + llifstream in_file; + in_file.open(filename); + LLSD fav_llsd; + if (in_file.is_open()) + { + LLSDSerialize::fromXML(fav_llsd, in_file); + } + + const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH); + + LLSD user_llsd; + for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++) + { + LLSD value; + value["name"] = (*it)->getName(); + value["asset_id"] = (*it)->getAssetUUID(); + + slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]); + if (slurl_iter != mSLURLs.end()) + { + lldebugs << "Saving favorite: idx=" << LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID()) << ", SLURL=" << slurl_iter->second << ", value=" << value << llendl; + value["slurl"] = slurl_iter->second; + user_llsd[LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID())] = value; + } + else + { + llwarns << "Not saving favorite " << value["name"] << ": no matching SLURL" << llendl; + } + } + + LLAvatarName av_name; + LLAvatarNameCache::get( gAgentID, &av_name ); + // Note : use the "John Doe" and not the "john.doe" version of the name + // as we'll compare it with the stored credentials in the login panel. + lldebugs << "Saved favorites for " << av_name.getUserName() << llendl; + fav_llsd[av_name.getUserName()] = user_llsd; + + llofstream file; + file.open(filename); + LLSDSerialize::toPrettyXML(fav_llsd, file); +} + +void LLFavoritesOrderStorage::removeFavoritesRecordOfUser() +{ + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); + LLSD fav_llsd; + llifstream file; + file.open(filename); + if (!file.is_open()) return; + LLSDSerialize::fromXML(fav_llsd, file); + + LLAvatarName av_name; + LLAvatarNameCache::get( gAgentID, &av_name ); + // Note : use the "John Doe" and not the "john.doe" version of the name. + // See saveFavoritesSLURLs() here above for the reason why. + lldebugs << "Removed favorites for " << av_name.getUserName() << llendl; + if (fav_llsd.has(av_name.getUserName())) + { + fav_llsd.erase(av_name.getUserName()); + } + + llofstream out_file; + out_file.open(filename); + LLSDSerialize::toPrettyXML(fav_llsd, out_file); + +} + +void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark) +{ + if (!landmark) return; + + LLVector3d pos_global; + if (!landmark->getGlobalPos(pos_global)) + { + // If global position was unknown on first getGlobalPos() call + // it should be set for the subsequent calls. + landmark->getGlobalPos(pos_global); + } + + if (!pos_global.isExactlyZero()) + { + LLLandmarkActions::getSLURLfromPosGlobal(pos_global, + boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1)); + } +} + +void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl) +{ + lldebugs << "Saving landmark SLURL: " << slurl << llendl; + mSLURLs[asset_id] = slurl; +} + +void LLFavoritesOrderStorage::save() +{ + // nothing to save if clean + if (!mIsDirty) return; + + // If we quit from the login screen we will not have an SL account + // name. Don't try to save, otherwise we'll dump a file in + // C:\Program Files\SecondLife\ or similar. JC + std::string user_dir = gDirUtilp->getLindenUserDir(); + if (!user_dir.empty()) + { + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME); + LLSD settings_llsd; + + for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter) + { + settings_llsd[iter->first.asString()] = iter->second; + } + + llofstream file; + file.open(filename); + LLSDSerialize::toPrettyXML(settings_llsd, file); + } +} + +void LLFavoritesOrderStorage::cleanup() +{ + // nothing to clean + if (!mIsDirty) return; + + const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH); + + IsNotInFavorites is_not_in_fav(items); + + sort_index_map_t aTempMap; + //copy unremoved values from mSortIndexes to aTempMap + std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(), + inserter(aTempMap, aTempMap.begin()), + is_not_in_fav); + + //Swap the contents of mSortIndexes and aTempMap + mSortIndexes.swap(aTempMap); +} + +void LLFavoritesOrderStorage::saveItemsOrder( const LLInventoryModel::item_array_t& items ) +{ + int sortField = 0; + + // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field + for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i) + { + LLViewerInventoryItem* item = *i; + + setSortIndex(item, ++sortField); + + item->setComplete(TRUE); + item->updateServer(FALSE); + + gInventory.updateItem(item); + + // Tell the parent folder to refresh its sort order. + gInventory.addChangedMask(LLInventoryObserver::SORT, item->getParentUUID()); + } + + gInventory.notifyObservers(); +} + +// See also LLInventorySort where landmarks in the Favorites folder are sorted. +class LLViewerInventoryItemSort +{ +public: + bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b) + { + return LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID()) + < LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID()); + } +}; + +// * @param source_item_id - LLUUID of the source item to be moved into new position +// * @param target_item_id - LLUUID of the target item before which source item should be placed. +void LLFavoritesOrderStorage::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id) +{ + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLIsType is_type(LLAssetType::AT_LANDMARK); + LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); + gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type); + + // ensure items are sorted properly before changing order. EXT-3498 + std::sort(items.begin(), items.end(), LLViewerInventoryItemSort()); + + // update order + gInventory.updateItemsOrder(items, source_item_id, target_item_id); + + saveItemsOrder(items); +} + +void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id) +{ + if (mTargetLandmarkId.isNull()) return; + + LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId); +} // EOF diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 2f75b3bb0e..e000adc4aa 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -33,6 +33,7 @@ #include "llinventoryobserver.h" #include "llinventorymodel.h" +#include "llviewerinventory.h" class LLMenuItemCallGL; class LLToggleableMenu; @@ -90,7 +91,7 @@ protected: bool enableSelected(const LLSD& userdata); void doToSelected(const LLSD& userdata); BOOL isClipboardPasteable() const; - void pastFromClipboard() const; + void pasteFromClipboard() const; void showDropDownMenu(); @@ -161,5 +162,115 @@ private: boost::signals2::connection mEndDragConnection; }; +class AddFavoriteLandmarkCallback : public LLInventoryCallback +{ +public: + AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {} + void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; } + +private: + void fire(const LLUUID& inv_item); + + LLUUID mTargetLandmarkId; +}; + +/** + * Class to store sorting order of favorites landmarks in a local file. EXT-3985. + * It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix. + * Data are stored in user home directory. + */ +class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage> + , public LLDestroyClass<LLFavoritesOrderStorage> +{ + LOG_CLASS(LLFavoritesOrderStorage); +public: + /** + * Sets sort index for specified with LLUUID favorite landmark + */ + void setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index); + + /** + * Gets sort index for specified with LLUUID favorite landmark + */ + S32 getSortIndex(const LLUUID& inv_item_id); + void removeSortIndex(const LLUUID& inv_item_id); + + void getSLURL(const LLUUID& asset_id); + + // Saves current order of the passed items using inventory item sort field. + // Resets 'items' sort fields and saves them on server. + // Is used to save order for Favorites folder. + void saveItemsOrder(const LLInventoryModel::item_array_t& items); + + void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id); + + /** + * Implementation of LLDestroyClass. Calls cleanup() instance method. + * + * It is important this callback is called before gInventory is cleaned. + * For now it is called from LLAppViewer::cleanup() -> LLAppViewer::disconnectViewer(), + * Inventory is cleaned later from LLAppViewer::cleanup() after LLAppViewer::disconnectViewer() is called. + * @see cleanup() + */ + static void destroyClass(); + + const static S32 NO_INDEX; +private: + friend class LLSingleton<LLFavoritesOrderStorage>; + LLFavoritesOrderStorage() : mIsDirty(false) { load(); } + ~LLFavoritesOrderStorage() { save(); } + + /** + * Removes sort indexes for items which are not in Favorites bar for now. + */ + void cleanup(); + + const static std::string SORTING_DATA_FILE_NAME; + + void load(); + void save(); + + void saveFavoritesSLURLs(); + + // Remove record of current user's favorites from file on disk. + void removeFavoritesRecordOfUser(); + + void onLandmarkLoaded(const LLUUID& asset_id, class LLLandmark* landmark); + void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl); + + typedef std::map<LLUUID, S32> sort_index_map_t; + sort_index_map_t mSortIndexes; + + typedef std::map<LLUUID, std::string> slurls_map_t; + slurls_map_t mSLURLs; + + bool mIsDirty; + + struct IsNotInFavorites + { + IsNotInFavorites(const LLInventoryModel::item_array_t& items) + : mFavoriteItems(items) + { + + } + + /** + * Returns true if specified item is not found among inventory items + */ + bool operator()(const sort_index_map_t::value_type& id_index_pair) const + { + LLPointer<LLViewerInventoryItem> item = gInventory.getItem(id_index_pair.first); + if (item.isNull()) return true; + + LLInventoryModel::item_array_t::const_iterator found_it = + std::find(mFavoriteItems.begin(), mFavoriteItems.end(), item); + + return found_it == mFavoriteItems.end(); + } + private: + LLInventoryModel::item_array_t mFavoriteItems; + }; + +}; #endif // LL_LLFAVORITESBARCTRL_H diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 08f9d26705..a4cadcd5dc 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -57,6 +57,7 @@ #include "lldxhardware.h" #endif +#define LL_EXPORT_GPU_TABLE 0 #if LL_DARWIN const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt"; @@ -386,6 +387,13 @@ void LLFeatureManager::parseGPUTable(std::string filename) *i = tolower(*i); } +#if LL_EXPORT_GPU_TABLE + llofstream json; + json.open("gpu_table.json"); + + json << "var gpu_table = [" << std::endl; +#endif + bool gpuFound; U32 lineNumber; for (gpuFound = false, lineNumber = 0; !gpuFound && !file.eof(); lineNumber++) @@ -411,7 +419,7 @@ void LLFeatureManager::parseGPUTable(std::string filename) // setup the tokenizer std::string buf(buffer); - std::string cls, label, expr, supported; + std::string cls, label, expr, supported, stats_based, expected_gl_version; boost_tokenizer tokens(buf, boost::char_separator<char>("\t\n")); boost_tokenizer::iterator token_iter = tokens.begin(); @@ -432,13 +440,29 @@ void LLFeatureManager::parseGPUTable(std::string filename) { supported = *token_iter++; } + if (token_iter != tokens.end()) + { + stats_based = *token_iter++; + } + if (token_iter != tokens.end()) + { + expected_gl_version = *token_iter++; + } if (label.empty() || expr.empty() || cls.empty() || supported.empty()) { LL_WARNS("RenderInit") << "invald gpu_table.txt:" << lineNumber << ": '" << buffer << "'" << LL_ENDL; continue; } - +#if LL_EXPORT_GPU_TABLE + json << "{'label' : '" << label << "',\n" << + "'regexp' : '" << expr << "',\n" << + "'class' : '" << cls << "',\n" << + "'supported' : '" << supported << "',\n" << + "'stats_based' : " << stats_based << ",\n" << + "'gl_version' : " << expected_gl_version << "\n},\n"; +#endif + for (U32 i = 0; i < expr.length(); i++) /*Flawfinder: ignore*/ { expr[i] = tolower(expr[i]); @@ -449,12 +473,19 @@ void LLFeatureManager::parseGPUTable(std::string filename) if(boost::regex_search(renderer, re)) { // if we found it, stop! +#if !LL_EXPORT_GPU_TABLE gpuFound = true; +#endif mGPUString = label; mGPUClass = (EGPUClass) strtol(cls.c_str(), NULL, 10); mGPUSupported = (BOOL) strtol(supported.c_str(), NULL, 10); + sscanf(expected_gl_version.c_str(), "%f", &mExpectedGLVersion); } } +#if LL_EXPORT_GPU_TABLE + json << "];\n\n"; + json.close(); +#endif file.close(); if ( gpuFound ) @@ -469,6 +500,10 @@ void LLFeatureManager::parseGPUTable(std::string filename) { LL_WARNS("RenderInit") << "GPU '" << rawRenderer << "' not recognized" << LL_ENDL; } + +#if LL_DARWIN // never go over "Mid" settings by default on OS X + mGPUClass = llmin(mGPUClass, GPU_CLASS_2); +#endif } // responder saves table into file @@ -585,7 +620,7 @@ void LLFeatureManager::applyRecommendedSettings() { // apply saved settings // cap the level at 2 (high) - S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_2)); + S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5)); llinfos << "Applying Recommended Features" << llendl; @@ -670,15 +705,31 @@ void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures) switch (level) { case 0: - maskFeatures("Low"); + if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel) + { //only use fixed function by default if GL version < 3.0 or this is an intel graphics chip + maskFeatures("LowFixedFunction"); + } + else + { //same as low, but with "Basic Shaders" enabled + maskFeatures("Low"); + } break; case 1: - maskFeatures("Mid"); + maskFeatures("LowMid"); break; case 2: - maskFeatures("High"); + maskFeatures("Mid"); break; case 3: + maskFeatures("MidHigh"); + break; + case 4: + maskFeatures("High"); + break; + case 5: + maskFeatures("HighUltra"); + break; + case 6: maskFeatures("Ultra"); break; default: @@ -690,6 +741,7 @@ void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures) LLViewerShaderMgr::sSkipReload = false; LLViewerShaderMgr::instance()->setShaders(); + gPipeline.refreshCachedSettings(); } void LLFeatureManager::applyBaseMasks() @@ -707,14 +759,16 @@ void LLFeatureManager::applyBaseMasks() mFeatures = maskp->getFeatures(); // mask class - if (mGPUClass >= 0 && mGPUClass < 4) + if (mGPUClass >= 0 && mGPUClass < 6) { const char* class_table[] = { "Class0", "Class1", "Class2", - "Class3" + "Class3", + "Class4", + "Class5", }; LL_INFOS("RenderInit") << "Setting GPU Class to " << class_table[mGPUClass] << LL_ENDL; @@ -779,6 +833,10 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("MapBufferRange"); } + if (gGLManager.mVRAM > 512) + { + maskFeatures("VRAMGT512"); + } // now mask by gpu string // Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h index c9cb397fcc..ad72c16743 100644 --- a/indra/newview/llfeaturemanager.h +++ b/indra/newview/llfeaturemanager.h @@ -39,7 +39,9 @@ typedef enum EGPUClass GPU_CLASS_0 = 0, GPU_CLASS_1 = 1, GPU_CLASS_2 = 2, - GPU_CLASS_3 = 3 + GPU_CLASS_3 = 3, + GPU_CLASS_4 = 4, + GPU_CLASS_5 = 5 } EGPUClass; @@ -101,7 +103,8 @@ public: mTableVersion(0), mSafe(FALSE), mGPUClass(GPU_CLASS_UNKNOWN), - mGPUSupported(FALSE) + mExpectedGLVersion(0.f), + mGPUSupported(FALSE) { } ~LLFeatureManager() {cleanupFeatureTables();} @@ -116,6 +119,7 @@ public: EGPUClass getGPUClass() { return mGPUClass; } std::string& getGPUString() { return mGPUString; } BOOL isGPUSupported() { return mGPUSupported; } + F32 getExpectedGLVersion() { return mExpectedGLVersion; } void cleanupFeatureTables(); @@ -155,6 +159,7 @@ protected: S32 mTableVersion; BOOL mSafe; // Reinitialize everything to the "safe" mask EGPUClass mGPUClass; + F32 mExpectedGLVersion; //expected GL version according to gpu table std::string mGPUString; BOOL mGPUSupported; }; diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 4897cf1885..4bf5b26b3b 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -49,7 +49,7 @@ LLFilePicker LLFilePicker::sInstance; #if LL_WINDOWS #define SOUND_FILTER L"Sounds (*.wav)\0*.wav\0" #define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png\0" -#define ANIM_FILTER L"Animations (*.bvh)\0*.bvh\0" +#define ANIM_FILTER L"Animations (*.bvh; *.anim)\0*.bvh;*.anim\0" #define COLLADA_FILTER L"Scene (*.dae)\0*.dae\0" #ifdef _CORY_TESTING #define GEOMETRY_FILTER L"SL Geometry (*.slg)\0*.slg\0" @@ -58,6 +58,8 @@ 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" +#define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0" #endif // @@ -213,6 +215,14 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter) mOFN.lpstrFilter = MODEL_FILTER \ L"\0"; break; + case FFLOAD_SCRIPT: + mOFN.lpstrFilter = SCRIPT_FILTER \ + L"\0"; + break; + case FFLOAD_DICTIONARY: + mOFN.lpstrFilter = DICTIONARY_FILTER \ + L"\0"; + break; default: res = FALSE; break; @@ -497,6 +507,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; } @@ -580,8 +598,10 @@ Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callB } else if (filter == FFLOAD_ANIM) { - if (fileInfo.filetype != 'BVH ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("bvh"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) + if (fileInfo.filetype != 'BVH ' && + fileInfo.filetype != 'ANIM' && + (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("bvh"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && + fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("anim"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) ) { result = false; @@ -620,6 +640,24 @@ 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; + } + } + else if (filter == FFLOAD_DICTIONARY) + { + if (fileInfo.filetype != 'DIC ' && + fileInfo.filetype != 'XCU ' && + (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dic"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && + fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("xcu"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))) + { + result = false; + } + } if (fileInfo.extension) { @@ -766,6 +804,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 = '\?\?\?\?'; @@ -1046,8 +1090,11 @@ void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer } // set the default path for this usage context. - picker->mContextToPathMap[picker->mCurContextName] = - gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget)); + const char* cur_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget)); + if (cur_folder != NULL) + { + picker->mContextToPathMap[picker->mCurContextName] = cur_folder; + } gtk_widget_destroy(widget); gtk_main_quit(); @@ -1169,10 +1216,14 @@ static std::string add_wav_filter_to_gtkchooser(GtkWindow *picker) LLTrans::getString("sound_files") + " (*.wav)"); } -static std::string add_bvh_filter_to_gtkchooser(GtkWindow *picker) +static std::string add_anim_filter_to_gtkchooser(GtkWindow *picker) { - return add_simple_pattern_filter_to_gtkchooser(picker, "*.bvh", - LLTrans::getString("animation_files") + " (*.bvh)"); + GtkFileFilter *gfilter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(gfilter, "*.bvh"); + gtk_file_filter_add_pattern(gfilter, "*.anim"); + std::string filtername = LLTrans::getString("animation_files") + " (*.bvh; *.anim)"; + add_common_filters_to_gtkchooser(gfilter, picker, filtername); + return filtername; } static std::string add_collada_filter_to_gtkchooser(GtkWindow *picker) @@ -1192,7 +1243,18 @@ 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)"); +} +static std::string add_dictionary_filter_to_gtkchooser(GtkWindow *picker) +{ + return add_simple_mime_filter_to_gtkchooser(picker, "text/plain", + LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)"); +} BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename ) { @@ -1258,6 +1320,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; } @@ -1315,7 +1381,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) filtername = add_wav_filter_to_gtkchooser(picker); break; case FFLOAD_ANIM: - filtername = add_bvh_filter_to_gtkchooser(picker); + filtername = add_anim_filter_to_gtkchooser(picker); break; case FFLOAD_COLLADA: filtername = add_collada_filter_to_gtkchooser(picker); @@ -1323,6 +1389,12 @@ 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; + case FFLOAD_DICTIONARY: + filtername = add_dictionary_filter_to_gtkchooser(picker); + break; default:; break; } diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index cd843a8f33..4f602f63f1 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -39,8 +39,8 @@ #include <Carbon/Carbon.h> // AssertMacros.h does bad things. +#include "fix_macros.h" #undef verify -#undef check #undef require #include <vector> @@ -84,6 +84,8 @@ public: FFLOAD_RAW = 8, FFLOAD_MODEL = 9, FFLOAD_COLLADA = 10, + FFLOAD_SCRIPT = 11, + FFLOAD_DICTIONARY = 12 }; enum ESaveFilter @@ -103,6 +105,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/llfirstuse.cpp b/indra/newview/llfirstuse.cpp index a9f52282a5..e2850f5181 100644 --- a/indra/newview/llfirstuse.cpp +++ b/indra/newview/llfirstuse.cpp @@ -74,7 +74,7 @@ void LLFirstUse::resetFirstUse() // static void LLFirstUse::otherAvatarChatFirst(bool enable) { - firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "chat_bar").with("direction", "top_right").with("distance", 24)); + firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "nearby_chat").with("direction", "top_right").with("distance", 24)); } // static diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 32a533570a..a5ee4607a1 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -44,9 +44,11 @@ #include "llvoavatar.h" /*static*/ F32 LLVolumeImplFlexible::sUpdateFactor = 1.0f; +std::vector<LLVolumeImplFlexible*> LLVolumeImplFlexible::sInstanceList; +std::vector<S32> LLVolumeImplFlexible::sUpdateDelay; static LLFastTimer::DeclareTimer FTM_FLEXIBLE_REBUILD("Rebuild"); -static LLFastTimer::DeclareTimer FTM_DO_FLEXIBLE_UPDATE("Update"); +static LLFastTimer::DeclareTimer FTM_DO_FLEXIBLE_UPDATE("Flexible Update"); // LLFlexibleObjectData::pack/unpack now in llprimitive.cpp @@ -64,14 +66,51 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD mSimulateRes = 0; mFrameNum = 0; mCollisionSphereRadius = 0.f; - mRenderRes = 1; - + mRenderRes = -1; + if(mVO->mDrawable.notNull()) { mVO->mDrawable->makeActive() ; } + + mInstanceIndex = sInstanceList.size(); + sInstanceList.push_back(this); + sUpdateDelay.push_back(0); }//----------------------------------------------- +LLVolumeImplFlexible::~LLVolumeImplFlexible() +{ + S32 end_idx = sInstanceList.size()-1; + + if (end_idx != mInstanceIndex) + { + sInstanceList[mInstanceIndex] = sInstanceList[end_idx]; + sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex; + sUpdateDelay[mInstanceIndex] = sUpdateDelay[end_idx]; + } + + sInstanceList.pop_back(); + sUpdateDelay.pop_back(); +} + +//static +void LLVolumeImplFlexible::updateClass() +{ + std::vector<S32>::iterator delay_iter = sUpdateDelay.begin(); + + for (std::vector<LLVolumeImplFlexible*>::iterator iter = sInstanceList.begin(); + iter != sInstanceList.end(); + ++iter) + { + --(*delay_iter); + if (*delay_iter <= 0) + { + (*iter)->doIdleUpdate(); + } + ++delay_iter; + } +} + LLVector3 LLVolumeImplFlexible::getFramePosition() const { return mVO->getRenderPosition(); @@ -255,50 +294,28 @@ void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, cons { } -//--------------------------------------------------------------------------------- -// This calculates the physics of the flexible object. Note that it has to be 0 -// updated every time step. In the future, perhaps there could be an -// optimization similar to what Havok does for objects that are stationary. -//--------------------------------------------------------------------------------- -static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies"); -BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) -{ - if (mVO->mDrawable.isNull()) - { - // Don't do anything until we have a drawable - return FALSE; // (we are not initialized or updated) - } - BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE; - - //flexible objects never go static - mVO->mDrawable->mQuietCount = 0; - if (!mVO->mDrawable->isRoot()) - { - LLViewerObject* parent = (LLViewerObject*) mVO->getParent(); - parent->mDrawable->mQuietCount = 0; - } +void LLVolumeImplFlexible::updateRenderRes() +{ + LLDrawable* drawablep = mVO->mDrawable; - LLFastTimer ftm(FTM_FLEXIBLE_UPDATE); - S32 new_res = mAttributes->getSimulateLOD(); - //number of segments only cares about z axis - F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, mVO->mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f); +#if 1 //optimal approximation of previous behavior that doesn't rely on atan2 + F32 app_angle = mVO->getScale().mV[2]/drawablep->mDistanceWRTCamera; // Rendering sections increases with visible angle on the screen - mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView()); - if (mRenderRes > FLEXIBLE_OBJECT_MAX_SECTIONS) - { - mRenderRes = FLEXIBLE_OBJECT_MAX_SECTIONS; - } - + mRenderRes = (S32) (12.f*app_angle); +#else //legacy behavior + //number of segments only cares about z axis + F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, drawablep->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f); - // Bottom cap at 1/4 the original number of sections - if (mRenderRes < mAttributes->getSimulateLOD()-1) - { - mRenderRes = mAttributes->getSimulateLOD()-1; - } + // Rendering sections increases with visible angle on the screen + mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView()); +#endif + + mRenderRes = llclamp(mRenderRes, new_res-1, (S32) FLEXIBLE_OBJECT_MAX_SECTIONS); + // Throttle back simulation of segments we're not rendering if (mRenderRes < new_res) { @@ -311,43 +328,87 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6 setAttributesOfAllSections(); mInitialized = TRUE; } - if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE)) - { - return FALSE; // (we are not initialized or updated) - } - - bool visible = mVO->mDrawable->isVisible(); +} +//--------------------------------------------------------------------------------- +// This calculates the physics of the flexible object. Note that it has to be 0 +// updated every time step. In the future, perhaps there could be an +// optimization similar to what Havok does for objects that are stationary. +//--------------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies"); +void LLVolumeImplFlexible::doIdleUpdate() +{ + LLDrawable* drawablep = mVO->mDrawable; - if (force_update && visible) - { - gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE); - } - else if (visible && - !mVO->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) && - mVO->getPixelArea() > 256.f) + if (drawablep) { - U32 id; - F32 pixel_area = mVO->getPixelArea(); + //LLFastTimer ftm(FTM_FLEXIBLE_UPDATE); - if (mVO->isRootEdit()) - { - id = mID; - } - else + //ensure drawable is active + drawablep->makeActive(); + + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE)) { - LLVOVolume* parent = (LLVOVolume*) mVO->getParent(); - id = parent->getVolumeInterfaceID(); - } + bool visible = drawablep->isVisible(); - U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1; + if (mRenderRes == -1) + { + updateRenderRes(); + gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); + sUpdateDelay[mInstanceIndex] = 0; + } + else + { + F32 pixel_area = mVO->getPixelArea(); + + U32 update_period = (U32) (llmax((S32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f))),0)+1); + // MAINT-1890 Clamp the update period to ensure that the update_period is no greater than 32 frames + update_period = llclamp(update_period, 0U, 32U); + + if (visible) + { + if (!drawablep->isState(LLDrawable::IN_REBUILD_Q1) && + pixel_area > 256.f) + { + U32 id; + + if (mVO->isRootEdit()) + { + id = mID; + } + else + { + LLVOVolume* parent = (LLVOVolume*) mVO->getParent(); + id = parent->getVolumeInterfaceID(); + } + + if (mVO->isRootEdit()) + { + id = mID; + } + else + { + LLVOVolume* parent = (LLVOVolume*) mVO->getParent(); + id = parent->getVolumeInterfaceID(); + } + + if ((LLDrawable::getCurrentFrame()+id)%update_period == 0) + { + sUpdateDelay[mInstanceIndex] = (S32) update_period-1; + + updateRenderRes(); + + gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); + } + } + } + else + { + sUpdateDelay[mInstanceIndex] = (S32) update_period; + } +} - if ((LLDrawable::getCurrentFrame()+id)%update_period == 0) - { - gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE); } } - - return force_update; } inline S32 log2(S32 x) @@ -368,8 +429,10 @@ void LLVolumeImplFlexible::doFlexibleUpdate() LLPath *path = &volume->getPath(); if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible()) { - mVO->markForUpdate(TRUE); - if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0)) + BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE; + doIdleUpdate(); + + if (!force_update || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE)) { return; // we did not get updated or initialized, proceeding without can be dangerous } @@ -380,6 +443,15 @@ void LLVolumeImplFlexible::doFlexibleUpdate() //the object is not visible return ; } + + // Fix for MAINT-1894 + // Skipping the flexible update if render res is negative. If we were to continue with a negative value, + // the subsequent S32 num_render_sections = 1<<mRenderRes; code will specify a really large number of + // render sections which will then create a length exception in the std::vector::resize() method. + if (mRenderRes < 0) + { + return; + } S32 num_sections = 1 << mSimulateRes; @@ -588,6 +660,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate() mSection[i].mdPosition = (mSection[i].mPosition - mSection[i-1].mPosition) * inv_section_length; // Create points + llassert(mRenderRes > -1) S32 num_render_sections = 1<<mRenderRes; if (path->getPathLength() != num_render_sections+1) { @@ -729,7 +802,11 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable) else if (!mUpdated || rotated) { volume->mDrawable->setState(LLDrawable::REBUILD_POSITION); - volume->dirtyMesh(); + LLSpatialGroup* group = volume->mDrawable->getSpatialGroup(); + if (group) + { + group->dirtyMesh(); + } volume->genBBoxes(isVolumeGlobal()); } @@ -814,15 +891,17 @@ LLQuaternion LLVolumeImplFlexible::getEndRotation() }//------------------------------------------------------------------ -void LLVolumeImplFlexible::updateRelativeXform() +void LLVolumeImplFlexible::updateRelativeXform(bool force_identity) { LLQuaternion delta_rot; LLVector3 delta_pos, delta_scale; LLVOVolume* vo = (LLVOVolume*) mVO; + bool use_identity = vo->mDrawable->isSpatialRoot() || force_identity; + //matrix from local space to parent relative/global space - delta_rot = vo->mDrawable->isSpatialRoot() ? LLQuaternion() : vo->mDrawable->getRotation(); - delta_pos = vo->mDrawable->isSpatialRoot() ? LLVector3(0,0,0) : vo->mDrawable->getPosition(); + delta_rot = use_identity ? LLQuaternion() : vo->mDrawable->getRotation(); + delta_pos = use_identity ? LLVector3(0,0,0) : vo->mDrawable->getPosition(); delta_scale = LLVector3(1,1,1); // Vertex transform (4x4) diff --git a/indra/newview/llflexibleobject.h b/indra/newview/llflexibleobject.h index fef43d464d..beb281a906 100644 --- a/indra/newview/llflexibleobject.h +++ b/indra/newview/llflexibleobject.h @@ -70,15 +70,24 @@ struct LLFlexibleObjectSection //--------------------------------------------------------- class LLVolumeImplFlexible : public LLVolumeInterface { +private: + static std::vector<LLVolumeImplFlexible*> sInstanceList; + static std::vector<S32> sUpdateDelay; + S32 mInstanceIndex; + public: + static void updateClass(); + LLVolumeImplFlexible(LLViewerObject* volume, LLFlexibleObjectData* attributes); + ~LLVolumeImplFlexible(); // Implements LLVolumeInterface U32 getID() const { return mID; } LLVector3 getFramePosition() const; LLQuaternion getFrameRotation() const; LLVolumeInterfaceType getInterfaceType() const { return INTERFACE_FLEXIBLE; } - BOOL doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + void updateRenderRes(); + void doIdleUpdate(); BOOL doUpdateGeometry(LLDrawable *drawable); LLVector3 getPivotPosition() const; void onSetVolume(const LLVolumeParams &volume_params, const S32 detail); @@ -89,7 +98,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface bool isVolumeGlobal() const { return true; } bool isActive() const { return true; } const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const; - void updateRelativeXform(); + void updateRelativeXform(bool force_identity); void doFlexibleUpdate(); // Called to update the simulation void doFlexibleRebuild(); // Called to rebuild the geometry void preRebuild(); @@ -128,7 +137,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface LLVector3 mCollisionSpherePosition; F32 mCollisionSphereRadius; U32 mID; - + //-------------------------------------- // private methods //-------------------------------------- diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp new file mode 100644 index 0000000000..6e56e929df --- /dev/null +++ b/indra/newview/llfloaterautoreplacesettings.cpp @@ -0,0 +1,665 @@ +/** + * @file llfloaterautoreplacesettings.cpp + * @brief Auto Replace List floater + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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; either + * version 2.1 of the License, or (at your option) any later version. + * + * 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 + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterautoreplacesettings.h" + +#include "llagentdata.h" +#include "llcommandhandler.h" +#include "llfloater.h" +#include "lluictrlfactory.h" +#include "llagent.h" +#include "llpanel.h" +#include "llbutton.h" +#include "llcolorswatch.h" +#include "llcombobox.h" +#include "llview.h" +#include "llhttpclient.h" +#include "llbufferstream.h" +#include "llcheckboxctrl.h" +#include "llviewercontrol.h" + +#include "llui.h" +#include "llcontrol.h" +#include "llscrollingpanellist.h" +#include "llautoreplace.h" +#include "llfilepicker.h" +#include "llfile.h" +#include "llsdserialize.h" +#include "llsdutil.h" + +#include "llchat.h" +#include "llinventorymodel.h" +#include "llhost.h" +#include "llassetstorage.h" +#include "roles_constants.h" +#include "llviewertexteditor.h" +#include <boost/tokenizer.hpp> + +#include <iosfwd> +#include "llfloaterreg.h" +#include "llinspecttoast.h" +#include "llnotificationhandler.h" +#include "llnotificationmanager.h" +#include "llnotificationsutil.h" + + +LLFloaterAutoReplaceSettings::LLFloaterAutoReplaceSettings(const LLSD& key) + : LLFloater(key) + , mSelectedListName("") + , mListNames(NULL) + , mReplacementsList(NULL) + , mKeyword(NULL) + , mPreviousKeyword("") + , mReplacement(NULL) +{ +} + +void LLFloaterAutoReplaceSettings::onClose(bool app_quitting) +{ + cleanUp(); +} + +BOOL LLFloaterAutoReplaceSettings::postBuild(void) +{ + // get copies of the current settings that we will operate on + mEnabled = gSavedSettings.getBOOL("AutoReplace"); + LL_DEBUGS("AutoReplace") << ( mEnabled ? "enabled" : "disabled") << LL_ENDL; + + mSettings = LLAutoReplace::getInstance()->getSettings(); + + // global checkbox for whether or not autoreplace is active + LLUICtrl* enabledCheckbox = getChild<LLUICtrl>("autoreplace_enable"); + enabledCheckbox->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onAutoReplaceToggled, this)); + enabledCheckbox->setValue(LLSD(mEnabled)); + + // top row list creation and deletion + getChild<LLUICtrl>("autoreplace_import_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onImportList,this)); + getChild<LLUICtrl>("autoreplace_export_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onExportList,this)); + getChild<LLUICtrl>("autoreplace_new_list")->setCommitCallback( boost::bind(&LLFloaterAutoReplaceSettings::onNewList,this)); + getChild<LLUICtrl>("autoreplace_delete_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onDeleteList,this)); + + // the list of keyword->replacement lists + mListNames = getChild<LLScrollListCtrl>("autoreplace_list_name"); + mListNames->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSelectList, this)); + mListNames->setCommitOnSelectionChange(true); + + // list ordering + getChild<LLUICtrl>("autoreplace_list_up")->setCommitCallback( boost::bind(&LLFloaterAutoReplaceSettings::onListUp,this)); + getChild<LLUICtrl>("autoreplace_list_down")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onListDown,this)); + + // keyword->replacement entry add / delete + getChild<LLUICtrl>("autoreplace_add_entry")->setCommitCallback( boost::bind(&LLFloaterAutoReplaceSettings::onAddEntry,this)); + getChild<LLUICtrl>("autoreplace_delete_entry")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onDeleteEntry,this)); + + // entry edits + mKeyword = getChild<LLLineEditor>("autoreplace_keyword"); + mReplacement = getChild<LLLineEditor>("autoreplace_replacement"); + getChild<LLUICtrl>("autoreplace_save_entry")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSaveEntry, this)); + + // dialog termination ( Save Changes / Cancel ) + getChild<LLUICtrl>("autoreplace_save_changes")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSaveChanges, this)); + getChild<LLUICtrl>("autoreplace_cancel")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onCancel, this)); + + // the list of keyword->replacement pairs + mReplacementsList = getChild<LLScrollListCtrl>("autoreplace_list_replacements"); + mReplacementsList->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSelectEntry, this)); + mReplacementsList->setCommitOnSelectionChange(true); + + center(); + + mSelectedListName.clear(); + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + + return true; +} + + +void LLFloaterAutoReplaceSettings::updateListNames() +{ + mListNames->deleteAllItems(); // start from scratch + + LLSD listNames = mSettings.getListNames(); // Array of Strings + + for ( LLSD::array_const_iterator entry = listNames.beginArray(), end = listNames.endArray(); + entry != end; + ++entry + ) + { + const std::string& listName = entry->asString(); + mListNames->addSimpleElement(listName); + } + + if (!mSelectedListName.empty()) + { + mListNames->setSelectedByValue( LLSD(mSelectedListName), true ); + } +} + +void LLFloaterAutoReplaceSettings::updateListNamesControls() +{ + if ( mSelectedListName.empty() ) + { + // There is no selected list + + // Disable all controls that operate on the selected list + getChild<LLButton>("autoreplace_export_list")->setEnabled(false); + getChild<LLButton>("autoreplace_delete_list")->setEnabled(false); + getChild<LLButton>("autoreplace_list_up")->setEnabled(false); + getChild<LLButton>("autoreplace_list_down")->setEnabled(false); + + mReplacementsList->deleteAllItems(); + } + else + { + // Enable the controls that operate on the selected list + getChild<LLButton>("autoreplace_export_list")->setEnabled(true); + getChild<LLButton>("autoreplace_delete_list")->setEnabled(true); + getChild<LLButton>("autoreplace_list_up")->setEnabled(!selectedListIsFirst()); + getChild<LLButton>("autoreplace_list_down")->setEnabled(!selectedListIsLast()); + } +} + +void LLFloaterAutoReplaceSettings::onSelectList() +{ + std::string previousSelectedListName = mSelectedListName; + // only one selection allowed + LLSD selected = mListNames->getSelectedValue(); + if (selected.isDefined()) + { + mSelectedListName = selected.asString(); + LL_DEBUGS("AutoReplace")<<"selected list '"<<mSelectedListName<<"'"<<LL_ENDL; + } + else + { + mSelectedListName.clear(); + LL_DEBUGS("AutoReplace")<<"unselected"<<LL_ENDL; + } + + updateListNamesControls(); + + if ( previousSelectedListName != mSelectedListName ) + { + updateReplacementsList(); + } +} + +void LLFloaterAutoReplaceSettings::onSelectEntry() +{ + LLSD selectedRow = mReplacementsList->getSelectedValue(); + if (selectedRow.isDefined()) + { + mPreviousKeyword = selectedRow.asString(); + LL_DEBUGS("AutoReplace")<<"selected entry '"<<mPreviousKeyword<<"'"<<LL_ENDL; + mKeyword->setValue(selectedRow); + std::string replacement = mSettings.replacementFor(mPreviousKeyword, mSelectedListName ); + mReplacement->setValue(replacement); + enableReplacementEntry(); + mReplacement->setFocus(true); + } + else + { + // no entry selection, so the entry panel should be off + disableReplacementEntry(); + LL_DEBUGS("AutoReplace")<<"no row selected"<<LL_ENDL; + } +} + +void LLFloaterAutoReplaceSettings::updateReplacementsList() +{ + // start from scratch, since this should only be called when the list changes + mReplacementsList->deleteAllItems(); + + if ( mSelectedListName.empty() ) + { + mReplacementsList->setEnabled(false); + getChild<LLButton>("autoreplace_add_entry")->setEnabled(false); + disableReplacementEntry(); + } + else + { + // Populate the keyword->replacement list from the selected list + const LLSD* mappings = mSettings.getListEntries(mSelectedListName); + for ( LLSD::map_const_iterator entry = mappings->beginMap(), end = mappings->endMap(); + entry != end; + entry++ + ) + { + LLSD row; + row["id"] = entry->first; + row["columns"][0]["column"] = "keyword"; + row["columns"][0]["value"] = entry->first; + row["columns"][1]["column"] = "replacement"; + row["columns"][1]["value"] = entry->second; + + mReplacementsList->addElement(row, ADD_BOTTOM); + } + + mReplacementsList->deselectAllItems(false /* don't call commit */); + mReplacementsList->setEnabled(true); + + getChild<LLButton>("autoreplace_add_entry")->setEnabled(true); + disableReplacementEntry(); + } +} + +void LLFloaterAutoReplaceSettings::enableReplacementEntry() +{ + LL_DEBUGS("AutoReplace")<<LL_ENDL; + mKeyword->setEnabled(true); + mReplacement->setEnabled(true); + getChild<LLButton>("autoreplace_save_entry")->setEnabled(true); + getChild<LLButton>("autoreplace_delete_entry")->setEnabled(true); +} + +void LLFloaterAutoReplaceSettings::disableReplacementEntry() +{ + LL_DEBUGS("AutoReplace")<<LL_ENDL; + mPreviousKeyword.clear(); + mKeyword->clear(); + mKeyword->setEnabled(false); + mReplacement->clear(); + mReplacement->setEnabled(false); + getChild<LLButton>("autoreplace_save_entry")->setEnabled(false); + getChild<LLButton>("autoreplace_delete_entry")->setEnabled(false); +} + +// called when the global settings checkbox is changed +void LLFloaterAutoReplaceSettings::onAutoReplaceToggled() +{ + // set our local copy of the flag, copied to the global preference in onOk + mEnabled = childGetValue("autoreplace_enable").asBoolean(); + LL_DEBUGS("AutoReplace")<< "autoreplace_enable " << ( mEnabled ? "on" : "off" ) << LL_ENDL; +} + +// called when the List Up button is pressed +void LLFloaterAutoReplaceSettings::onListUp() +{ + S32 selectedRow = mListNames->getFirstSelectedIndex(); + LLSD selectedName = mListNames->getSelectedValue().asString(); + + if ( mSettings.increaseListPriority(selectedName) ) + { + updateListNames(); + updateListNamesControls(); + } + else + { + LL_WARNS("AutoReplace") + << "invalid row ("<<selectedRow<<") selected '"<<selectedName<<"'" + <<LL_ENDL; + } +} + +// called when the List Down button is pressed +void LLFloaterAutoReplaceSettings::onListDown() +{ + S32 selectedRow = mListNames->getFirstSelectedIndex(); + std::string selectedName = mListNames->getSelectedValue().asString(); + + if ( mSettings.decreaseListPriority(selectedName) ) + { + updateListNames(); + updateListNamesControls(); + } + else + { + LL_WARNS("AutoReplace") + << "invalid row ("<<selectedRow<<") selected '"<<selectedName<<"'" + <<LL_ENDL; + } +} + +// called when the Delete Entry button is pressed +void LLFloaterAutoReplaceSettings::onDeleteEntry() +{ + LLSD selectedRow = mReplacementsList->getSelectedValue(); + if (selectedRow.isDefined()) + { + std::string keyword = selectedRow.asString(); + mReplacementsList->deleteSelectedItems(); // delete from the control + mSettings.removeEntryFromList(keyword, mSelectedListName); // delete from the local settings copy + disableReplacementEntry(); // no selection active, so turn off the buttons + } +} + +// called when the Import List button is pressed +void LLFloaterAutoReplaceSettings::onImportList() +{ + LLFilePicker& picker = LLFilePicker::instance(); + if( picker.getOpenFile( LLFilePicker::FFLOAD_XML) ) + { + llifstream file; + file.open(picker.getFirstFile().c_str()); + LLSD newList; + if (file.is_open()) + { + LLSDSerialize::fromXMLDocument(newList, file); + } + file.close(); + + switch ( mSettings.addList(newList) ) + { + case LLAutoReplaceSettings::AddListOk: + mSelectedListName = LLAutoReplaceSettings::getListName(newList); + + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + break; + + case LLAutoReplaceSettings::AddListDuplicateName: + { + std::string newName = LLAutoReplaceSettings::getListName(newList); + LL_WARNS("AutoReplace")<<"name '"<<newName<<"' is in use; prompting for new name"<<LL_ENDL; + LLSD newPayload; + newPayload["list"] = newList; + LLSD args; + args["DUPNAME"] = newName; + + LLNotificationsUtil::add("RenameAutoReplaceList", args, newPayload, + boost::bind(&LLFloaterAutoReplaceSettings::callbackListNameConflict, this, _1, _2)); + } + break; + + case LLAutoReplaceSettings::AddListInvalidList: + LLNotificationsUtil::add("InvalidAutoReplaceList"); + LL_WARNS("AutoReplace") << "imported list was invalid" << LL_ENDL; + + mSelectedListName.clear(); + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + break; + + default: + LL_ERRS("AutoReplace") << "invalid AddListResult" << LL_ENDL; + + } + + } + else + { + LL_DEBUGS("AutoReplace") << "file selection failed for import list" << LL_ENDL; + } +} + +void LLFloaterAutoReplaceSettings::onNewList() +{ + LLSD payload; + LLSD emptyList; + LLAutoReplaceSettings::createEmptyList(emptyList); + payload["list"] = emptyList; + LLSD args; + + LLNotificationsUtil::add("AddAutoReplaceList", args, payload, + boost::bind(&LLFloaterAutoReplaceSettings::callbackNewListName, this, _1, _2)); +} + +bool LLFloaterAutoReplaceSettings::callbackNewListName(const LLSD& notification, const LLSD& response) +{ + LL_DEBUGS("AutoReplace")<<"called"<<LL_ENDL; + + LLSD newList = notification["payload"]["list"]; + + if ( response.has("listname") && response["listname"].isString() ) + { + std::string newName = response["listname"].asString(); + LLAutoReplaceSettings::setListName(newList, newName); + + switch ( mSettings.addList(newList) ) + { + case LLAutoReplaceSettings::AddListOk: + LL_INFOS("AutoReplace") << "added new list '"<<newName<<"'"<<LL_ENDL; + mSelectedListName = newName; + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + break; + + case LLAutoReplaceSettings::AddListDuplicateName: + { + LL_WARNS("AutoReplace")<<"name '"<<newName<<"' is in use; prompting for new name"<<LL_ENDL; + LLSD newPayload; + newPayload["list"] = notification["payload"]["list"]; + LLSD args; + args["DUPNAME"] = newName; + + LLNotificationsUtil::add("RenameAutoReplaceList", args, newPayload, + boost::bind(&LLFloaterAutoReplaceSettings::callbackListNameConflict, this, _1, _2)); + } + break; + + case LLAutoReplaceSettings::AddListInvalidList: + LLNotificationsUtil::add("InvalidAutoReplaceList"); + + mSelectedListName.clear(); + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + break; + + default: + LL_ERRS("AutoReplace") << "invalid AddListResult" << LL_ENDL; + } + } + else + { + LL_ERRS("AutoReplace") << "adding notification response" << LL_ENDL; + } + return false; +} + +// callback for the RenameAutoReplaceList notification +bool LLFloaterAutoReplaceSettings::callbackListNameConflict(const LLSD& notification, const LLSD& response) +{ + LLSD newList = notification["payload"]["list"]; + std::string listName = LLAutoReplaceSettings::getListName(newList); + + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch ( option ) + { + case 0: + // Replace current list + if ( LLAutoReplaceSettings::AddListOk == mSettings.replaceList(newList) ) + { + LL_INFOS("AutoReplace") << "replaced list '"<<listName<<"'"<<LL_ENDL; + mSelectedListName = listName; + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + } + else + { + LL_WARNS("AutoReplace")<<"failed to replace list '"<<listName<<"'"<<LL_ENDL; + } + break; + + case 1: + // Use New Name + LL_INFOS("AutoReplace")<<"option 'use new name' selected"<<LL_ENDL; + callbackNewListName(notification, response); + break; + + default: + LL_ERRS("AutoReplace")<<"invalid selected option "<<option<<LL_ENDL; + } + + return false; +} + +void LLFloaterAutoReplaceSettings::onDeleteList() +{ + std::string listName = mListNames->getSelectedValue().asString(); + if ( ! listName.empty() ) + { + if ( mSettings.removeReplacementList(listName) ) + { + LL_INFOS("AutoReplace")<<"deleted list '"<<listName<<"'"<<LL_ENDL; + mReplacementsList->deleteSelectedItems(); // remove from the scrolling list + mSelectedListName.clear(); + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + } + else + { + LL_WARNS("AutoReplace")<<"failed to delete list '"<<listName<<"'"<<LL_ENDL; + } + } + else + { + LL_DEBUGS("AutoReplace")<<"no list selected for delete"<<LL_ENDL; + } +} + +void LLFloaterAutoReplaceSettings::onExportList() +{ + std::string listName=mListNames->getFirstSelected()->getColumn(0)->getValue().asString(); + const LLSD* list = mSettings.exportList(listName); + std::string listFileName = listName + ".xml"; + LLFilePicker& picker = LLFilePicker::instance(); + if( picker.getSaveFile( LLFilePicker::FFSAVE_XML, listFileName) ) + { + llofstream file; + file.open(picker.getFirstFile().c_str()); + LLSDSerialize::toPrettyXML(*list, file); + file.close(); + } +} + +void LLFloaterAutoReplaceSettings::onAddEntry() +{ + mPreviousKeyword.clear(); + mReplacementsList->deselectAllItems(false /* don't call commit */); + mKeyword->clear(); + mReplacement->clear(); + enableReplacementEntry(); + mKeyword->setFocus(true); +} + +void LLFloaterAutoReplaceSettings::onSaveEntry() +{ + LL_DEBUGS("AutoReplace")<<"called"<<LL_ENDL; + + if ( ! mPreviousKeyword.empty() ) + { + // delete any existing value for the key that was editted + LL_INFOS("AutoReplace") + << "list '" << mSelectedListName << "' " + << "removed '" << mPreviousKeyword + << "'" << LL_ENDL; + mSettings.removeEntryFromList( mPreviousKeyword, mSelectedListName ); + } + + LLWString keyword = mKeyword->getWText(); + LLWString replacement = mReplacement->getWText(); + if ( mSettings.addEntryToList(keyword, replacement, mSelectedListName) ) + { + // insert the new keyword->replacement pair + LL_INFOS("AutoReplace") + << "list '" << mSelectedListName << "' " + << "added '" << wstring_to_utf8str(keyword) + << "' -> '" << wstring_to_utf8str(replacement) + << "'" << LL_ENDL; + + updateReplacementsList(); + } + else + { + LLNotificationsUtil::add("InvalidAutoReplaceEntry"); + LL_WARNS("AutoReplace")<<"invalid entry " + << "keyword '" << wstring_to_utf8str(keyword) + << "' replacement '" << wstring_to_utf8str(replacement) + << "'" << LL_ENDL; + } +} + +void LLFloaterAutoReplaceSettings::onCancel() +{ + cleanUp(); + closeFloater(false /* not quitting */); +} + +void LLFloaterAutoReplaceSettings::onSaveChanges() +{ + // put our local copy of the settings into the active copy + LLAutoReplace::getInstance()->setSettings( mSettings ); + // save our local copy of the global feature enable/disable value + gSavedSettings.setBOOL("AutoReplace", mEnabled); + cleanUp(); + closeFloater(false /* not quitting */); +} + +void LLFloaterAutoReplaceSettings::cleanUp() +{ + +} + +bool LLFloaterAutoReplaceSettings::selectedListIsFirst() +{ + bool isFirst = false; + + if (!mSelectedListName.empty()) + { + LLSD lists = mSettings.getListNames(); // an Array of Strings + LLSD first = lists.get(0); + if ( first.isString() && first.asString() == mSelectedListName ) + { + isFirst = true; + } + } + return isFirst; +} + +bool LLFloaterAutoReplaceSettings::selectedListIsLast() +{ + bool isLast = false; + + if (!mSelectedListName.empty()) + { + LLSD last; + LLSD lists = mSettings.getListNames(); // an Array of Strings + for ( LLSD::array_const_iterator list = lists.beginArray(), listEnd = lists.endArray(); + list != listEnd; + list++ + ) + { + last = *list; + } + if ( last.isString() && last.asString() == mSelectedListName ) + { + isLast = true; + } + } + return isLast; +} + +/* TBD +mOldText = getChild<LLLineEditor>("autoreplace_old_text"); +mNewText = getChild<LLLineEditor>("autoreplace_new_text"); +*/ diff --git a/indra/newview/llfloaterautoreplacesettings.h b/indra/newview/llfloaterautoreplacesettings.h new file mode 100644 index 0000000000..629aea3e3c --- /dev/null +++ b/indra/newview/llfloaterautoreplacesettings.h @@ -0,0 +1,117 @@ +/** + * @file llfloaterautoreplacesettings.h + * @brief Auto Replace List floater + * @copyright Copyright (c) 2011 LordGregGreg Back + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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; either + * version 2.1 of the License, or (at your option) any later version. + * + * 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 + * $/LicenseInfo$ + */ + +#ifndef LLFLOATERAUTOREPLACESETTINGS_H +#define LLFLOATERAUTOREPLACESETTINGS_H + +#include "llfloater.h" +#include "llmediactrl.h" +#include "llscrolllistctrl.h" +#include "lllineeditor.h" + +#include "llviewerinventory.h" +#include <boost/bind.hpp> +#include "llautoreplace.h" + +class LLFloaterAutoReplaceSettings : public LLFloater +{ +public: + LLFloaterAutoReplaceSettings(const LLSD& key); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onClose(bool app_quitting); + + void setData(void * data); + +private: + + /** @{ @name Local Copies of Settings + * These are populated in the postBuild method with the values + * current when the floater is instantiated, and then either + * discarded when Cancel is pressed, or copied back to the active + * settings if Ok is pressed. + */ + bool mEnabled; ///< the global preference for AutoReplace + LLAutoReplaceSettings mSettings; ///< settings being modified + /** @} */ + + /// convenience variable - the name of the currently selected list (if any) + std::string mSelectedListName; + /// the scrolling list of list names (one column, no headings, order manually controlled) + LLScrollListCtrl* mListNames; + /// the scroling list of keyword->replacement pairs + LLScrollListCtrl* mReplacementsList; + + /// the keyword for the entry editing pane + LLLineEditor* mKeyword; + /// saved keyword value + std::string mPreviousKeyword; + /// the replacement for the entry editing pane + LLLineEditor* mReplacement; + + /// callback for when the feature enable/disable checkbox changes + void onAutoReplaceToggled(); + /// callback for when an entry in the list of list names is selected + void onSelectList(); + + void onImportList(); + void onExportList(); + void onNewList(); + void onDeleteList(); + + void onListUp(); + void onListDown(); + + void onSelectEntry(); + void onAddEntry(); + void onDeleteEntry(); + void onSaveEntry(); + + void onSaveChanges(); + void onCancel(); + + /// updates the contents of the mListNames + void updateListNames(); + /// updates the controls associated with mListNames (depends on whether a name is selected or not) + void updateListNamesControls(); + /// updates the contents of the mReplacementsList + void updateReplacementsList(); + /// enables the components that should only be active when a keyword is selected + void enableReplacementEntry(); + /// disables the components that should only be active when a keyword is selected + void disableReplacementEntry(); + + /// called from the AddAutoReplaceList notification dialog + bool callbackNewListName(const LLSD& notification, const LLSD& response); + /// called from the RenameAutoReplaceList notification dialog + bool callbackListNameConflict(const LLSD& notification, const LLSD& response); + + bool selectedListIsFirst(); + bool selectedListIsLast(); + + void cleanUp(); +}; + +#endif // LLFLOATERAUTOREPLACESETTINGS_H diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index aa66fcf9b8..f7dd4a4a6b 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -49,6 +49,8 @@ #include "llscrolllistcell.h" #include "lltabcontainer.h" #include "lluictrlfactory.h" +#include "llfocusmgr.h" +#include "lldraghandle.h" #include "message.h" //#include "llsdserialize.h" @@ -58,16 +60,25 @@ static std::map<LLUUID, LLAvatarName> sAvatarNameMap; LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback, BOOL allow_multiple, - BOOL closeOnSelect) + BOOL closeOnSelect, + BOOL skip_agent, + const std::string& name, + LLView * frustumOrigin) { // *TODO: Use a key to allow this not to be an effective singleton LLFloaterAvatarPicker* floater = - LLFloaterReg::showTypedInstance<LLFloaterAvatarPicker>("avatar_picker"); + LLFloaterReg::showTypedInstance<LLFloaterAvatarPicker>("avatar_picker", LLSD(name)); + if (!floater) + { + llwarns << "Cannot instantiate avatar picker" << llendl; + return NULL; + } floater->mSelectionCallback = callback; floater->setAllowMultiple(allow_multiple); floater->mNearMeListComplete = FALSE; floater->mCloseOnSelect = closeOnSelect; + floater->mExcludeAgentFromSearchResults = skip_agent; if (!closeOnSelect) { @@ -78,6 +89,11 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback, floater->getChild<LLButton>("cancel_btn")->setLabel(close_string); } + if(frustumOrigin) + { + floater->mFrustumOrigin = frustumOrigin->getHandle(); + } + return floater; } @@ -86,9 +102,17 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key) : LLFloater(key), mNumResultsReturned(0), mNearMeListComplete(FALSE), - mCloseOnSelect(FALSE) + mCloseOnSelect(FALSE), + mContextConeOpacity (0.f), + mContextConeInAlpha(0.f), + mContextConeOutAlpha(0.f), + mContextConeFadeTime(0.f) { mCommitCallbackRegistrar.add("Refresh.FriendList", boost::bind(&LLFloaterAvatarPicker::populateFriend, this)); + + mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha"); + mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha"); + mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime"); } BOOL LLFloaterAvatarPicker::postBuild() @@ -283,9 +307,9 @@ void LLFloaterAvatarPicker::populateNearMe() else { element["columns"][0]["column"] = "name"; - element["columns"][0]["value"] = av_name.mDisplayName; + element["columns"][0]["value"] = av_name.getDisplayName(); element["columns"][1]["column"] = "username"; - element["columns"][1]["value"] = av_name.mUsername; + element["columns"][1]["value"] = av_name.getUserName(); sAvatarNameMap[av] = av_name; } @@ -333,8 +357,67 @@ void LLFloaterAvatarPicker::populateFriend() friends_scroller->sortByColumnIndex(0, TRUE); } +void LLFloaterAvatarPicker::drawFrustum() +{ + if(mFrustumOrigin.get()) + { + LLView * frustumOrigin = mFrustumOrigin.get(); + LLRect origin_rect; + frustumOrigin->localRectToOtherView(frustumOrigin->getLocalRect(), &origin_rect, this); + // draw context cone connecting color picker with color swatch in parent floater + LLRect local_rect = getLocalRect(); + if (hasFocus() && frustumOrigin->isInVisibleChain() && mContextConeOpacity > 0.001f) + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLEnable(GL_CULL_FACE); + gGL.begin(LLRender::QUADS); + { + gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity); + gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop); + gGL.vertex2i(origin_rect.mRight, origin_rect.mTop); + gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity); + gGL.vertex2i(local_rect.mRight, local_rect.mTop); + gGL.vertex2i(local_rect.mLeft, local_rect.mTop); + + gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity); + gGL.vertex2i(local_rect.mLeft, local_rect.mTop); + gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity); + gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom); + gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop); + + gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity); + gGL.vertex2i(local_rect.mRight, local_rect.mBottom); + gGL.vertex2i(local_rect.mRight, local_rect.mTop); + gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity); + gGL.vertex2i(origin_rect.mRight, origin_rect.mTop); + gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom); + + gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity); + gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); + gGL.vertex2i(local_rect.mRight, local_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity); + gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom); + gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom); + } + gGL.end(); + } + + if (gFocusMgr.childHasMouseCapture(getDragHandle())) + { + mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(mContextConeFadeTime)); + } + else + { + mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime)); + } + } +} + void LLFloaterAvatarPicker::draw() { + drawFrustum(); + // sometimes it is hard to determine when Select/Ok button should be disabled (see LLAvatarActions::shareWithAvatars). // lets check this via mOkButtonValidateSignal callback periodically. static LLFrameTimer timer; @@ -377,8 +460,9 @@ class LLAvatarPickerResponder : public LLHTTPClient::Responder { public: LLUUID mQueryID; + std::string mName; - LLAvatarPickerResponder(const LLUUID& id) : mQueryID(id) { } + LLAvatarPickerResponder(const LLUUID& id, const std::string& name) : mQueryID(id), mName(name) { } /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) { @@ -391,7 +475,7 @@ public: if (isGoodStatus(status) || status == 400) { LLFloaterAvatarPicker* floater = - LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker"); + LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", mName); if (floater) { floater->processResponse(mQueryID, content); @@ -421,9 +505,7 @@ void LLFloaterAvatarPicker::find() LLViewerRegion* region = gAgent.getRegion(); url = region->getCapability("AvatarPickerSearch"); // Prefer use of capabilities to search on both SLID and display name - // but allow display name search to be manually turned off for test - if (!url.empty() - && LLAvatarNameCache::useDisplayNames()) + if (!url.empty()) { // capability urls don't end in '/', but we need one to parse // query parameters correctly @@ -434,7 +516,7 @@ void LLFloaterAvatarPicker::find() url += "?page_size=100&names="; url += LLURI::escape(text); llinfos << "avatar picker " << url << llendl; - LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID)); + LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID, getKey().asString())); } else { @@ -576,35 +658,36 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* msg->getUUIDFast( _PREHASH_Data,_PREHASH_AvatarID, avatar_id, i); msg->getStringFast(_PREHASH_Data,_PREHASH_FirstName, first_name, i); msg->getStringFast(_PREHASH_Data,_PREHASH_LastName, last_name, i); - - std::string avatar_name; - if (avatar_id.isNull()) - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = floater->getChild<LLUICtrl>("Edit")->getValue().asString(); - avatar_name = floater->getString("not_found", map); - search_results->setEnabled(FALSE); - floater->getChildView("ok_btn")->setEnabled(FALSE); - } - else + + if (avatar_id != agent_id || !floater->isExcludeAgentFromSearchResults()) // exclude agent from search results? { - avatar_name = LLCacheName::buildFullName(first_name, last_name); - search_results->setEnabled(TRUE); - found_one = TRUE; + std::string avatar_name; + if (avatar_id.isNull()) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = floater->getChild<LLUICtrl>("Edit")->getValue().asString(); + avatar_name = floater->getString("not_found", map); + search_results->setEnabled(FALSE); + floater->getChildView("ok_btn")->setEnabled(FALSE); + } + else + { + avatar_name = LLCacheName::buildFullName(first_name, last_name); + search_results->setEnabled(TRUE); + found_one = TRUE; - LLAvatarName av_name; - av_name.mLegacyFirstName = first_name; - av_name.mLegacyLastName = last_name; - av_name.mDisplayName = avatar_name; - const LLUUID& agent_id = avatar_id; - sAvatarNameMap[agent_id] = av_name; + LLAvatarName av_name; + av_name.fromString(avatar_name); + const LLUUID& agent_id = avatar_id; + sAvatarNameMap[agent_id] = av_name; + } + LLSD element; + element["id"] = avatar_id; // value + element["columns"][0]["column"] = "name"; + element["columns"][0]["value"] = avatar_name; + search_results->addElement(element); } - LLSD element; - element["id"] = avatar_id; // value - element["columns"][0]["column"] = "name"; - element["columns"][0]["value"] = avatar_name; - search_results->addElement(element); } if (found_one) @@ -619,52 +702,58 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD& content) { // Check for out-of-date query - if (query_id != mQueryID) return; + if (query_id == mQueryID) + { + LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults"); - LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults"); + LLSD agents = content["agents"]; + + // clear "Searching" label on first results + search_results->deleteAllItems(); - LLSD agents = content["agents"]; - if (agents.size() == 0) - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = childGetText("Edit"); LLSD item; - item["id"] = LLUUID::null; - item["columns"][0]["column"] = "name"; - item["columns"][0]["value"] = getString("not_found", map); - search_results->addElement(item); - search_results->setEnabled(false); - getChildView("ok_btn")->setEnabled(false); - return; - } + LLSD::array_const_iterator it = agents.beginArray(); + for ( ; it != agents.endArray(); ++it) + { + const LLSD& row = *it; + if (row["id"].asUUID() != gAgent.getID() || !mExcludeAgentFromSearchResults) + { + item["id"] = row["id"]; + LLSD& columns = item["columns"]; + columns[0]["column"] = "name"; + columns[0]["value"] = row["display_name"]; + columns[1]["column"] = "username"; + columns[1]["value"] = row["username"]; + search_results->addElement(item); + + // add the avatar name to our list + LLAvatarName avatar_name; + avatar_name.fromLLSD(row); + sAvatarNameMap[row["id"].asUUID()] = avatar_name; + } + } - // clear "Searching" label on first results - search_results->deleteAllItems(); - - LLSD item; - LLSD::array_const_iterator it = agents.beginArray(); - for ( ; it != agents.endArray(); ++it) - { - const LLSD& row = *it; - item["id"] = row["id"]; - LLSD& columns = item["columns"]; - columns[0]["column"] = "name"; - columns[0]["value"] = row["display_name"]; - columns[1]["column"] = "username"; - columns[1]["value"] = row["username"]; - search_results->addElement(item); - - // add the avatar name to our list - LLAvatarName avatar_name; - avatar_name.fromLLSD(row); - sAvatarNameMap[row["id"].asUUID()] = avatar_name; - } - - getChildView("ok_btn")->setEnabled(true); - search_results->setEnabled(true); - search_results->selectFirstItem(); - onList(); - search_results->setFocus(TRUE); + if (search_results->isEmpty()) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = childGetText("Edit"); + LLSD item; + item["id"] = LLUUID::null; + item["columns"][0]["column"] = "name"; + item["columns"][0]["value"] = getString("not_found", map); + search_results->addElement(item); + search_results->setEnabled(false); + getChildView("ok_btn")->setEnabled(false); + } + else + { + getChildView("ok_btn")->setEnabled(true); + search_results->setEnabled(true); + search_results->selectFirstItem(); + onList(); + search_results->setFocus(TRUE); + } + } } //static diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index 96c039443a..ed3e51c56f 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -34,7 +34,7 @@ class LLAvatarName; class LLScrollListCtrl; -class LLFloaterAvatarPicker : public LLFloater +class LLFloaterAvatarPicker :public LLFloater { public: typedef boost::signals2::signal<bool(const uuid_vec_t&), boost_boolean_combiner> validate_signal_t; @@ -45,7 +45,10 @@ public: // Call this to select an avatar. static LLFloaterAvatarPicker* show(select_callback_t callback, BOOL allow_multiple = FALSE, - BOOL closeOnSelect = FALSE); + BOOL closeOnSelect = FALSE, + BOOL skip_agent = FALSE, + const std::string& name = "", + LLView * frustumOrigin = NULL); LLFloaterAvatarPicker(const LLSD& key); virtual ~LLFloaterAvatarPicker(); @@ -63,6 +66,7 @@ public: std::string& tooltip_msg); void openFriendsTab(); + BOOL isExcludeAgentFromSearchResults() {return mExcludeAgentFromSearchResults;} private: void editKeystroke(class LLLineEditor* caller, void* user_data); @@ -84,13 +88,20 @@ private: void setAllowMultiple(BOOL allow_multiple); LLScrollListCtrl* getActiveList(); + void drawFrustum(); virtual void draw(); virtual BOOL handleKeyHere(KEY key, MASK mask); LLUUID mQueryID; - int mNumResultsReturned; + int mNumResultsReturned; BOOL mNearMeListComplete; BOOL mCloseOnSelect; + BOOL mExcludeAgentFromSearchResults; + LLHandle <LLView> mFrustumOrigin; + F32 mContextConeOpacity; + F32 mContextConeInAlpha; + F32 mContextConeOutAlpha; + F32 mContextConeFadeTime; validate_signal_t mOkButtonValidateSignal; select_callback_t mSelectionCallback; diff --git a/indra/newview/llfloaterbuildoptions.cpp b/indra/newview/llfloaterbuildoptions.cpp index 86c1bf0534..1b65d8d683 100644 --- a/indra/newview/llfloaterbuildoptions.cpp +++ b/indra/newview/llfloaterbuildoptions.cpp @@ -41,13 +41,9 @@ // Methods // -void commit_grid_mode(LLUICtrl *); - LLFloaterBuildOptions::LLFloaterBuildOptions(const LLSD& key) - : LLFloater(key), - mComboGridMode(NULL) + : LLFloater(key) { - mCommitCallbackRegistrar.add("GridOptions.gridMode", boost::bind(&commit_grid_mode,_1)); } LLFloaterBuildOptions::~LLFloaterBuildOptions() @@ -55,45 +51,9 @@ LLFloaterBuildOptions::~LLFloaterBuildOptions() BOOL LLFloaterBuildOptions::postBuild() { - mComboGridMode = getChild<LLComboBox>("combobox grid mode"); - return TRUE; } -void LLFloaterBuildOptions::setGridMode(EGridMode mode) -{ - mComboGridMode->setCurrentByIndex((S32)mode); -} - -void LLFloaterBuildOptions::updateGridMode() -{ - if (mComboGridMode) - { - S32 index = mComboGridMode->getCurrentIndex(); - mComboGridMode->removeall(); - - switch (mObjectSelection->getSelectType()) - { - case SELECT_TYPE_HUD: - mComboGridMode->add(getString("grid_screen_text")); - mComboGridMode->add(getString("grid_local_text")); - break; - case SELECT_TYPE_WORLD: - mComboGridMode->add(getString("grid_world_text")); - mComboGridMode->add(getString("grid_local_text")); - mComboGridMode->add(getString("grid_reference_text")); - break; - case SELECT_TYPE_ATTACHMENT: - mComboGridMode->add(getString("grid_attachment_text")); - mComboGridMode->add(getString("grid_local_text")); - mComboGridMode->add(getString("grid_reference_text")); - break; - } - - mComboGridMode->setCurrentByIndex(index); - } -} - // virtual void LLFloaterBuildOptions::onOpen(const LLSD& key) { @@ -105,10 +65,3 @@ void LLFloaterBuildOptions::onClose(bool app_quitting) { mObjectSelection = NULL; } - -void commit_grid_mode(LLUICtrl *ctrl) -{ - LLComboBox* combo = (LLComboBox*)ctrl; - - LLSelectMgr::getInstance()->setGridMode((EGridMode)combo->getCurrentIndex()); -} diff --git a/indra/newview/llfloaterbuildoptions.h b/indra/newview/llfloaterbuildoptions.h index 7f3811bf1c..02c56cb6a9 100644 --- a/indra/newview/llfloaterbuildoptions.h +++ b/indra/newview/llfloaterbuildoptions.h @@ -35,7 +35,6 @@ #include "llfloater.h" #include "llselectmgr.h" -class LLComboBox; class LLObjectSelection; typedef LLSafeHandle<LLObjectSelection> LLObjectSelectionHandle; @@ -44,23 +43,17 @@ class LLFloaterBuildOptions : public LLFloater { public: - virtual BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ void onClose(bool app_quitting); - void setGridMode(EGridMode mode); - void updateGridMode(); - private: - friend class LLFloaterReg; LLFloaterBuildOptions(const LLSD& key); ~LLFloaterBuildOptions(); - LLComboBox* mComboGridMode; LLObjectSelectionHandle mObjectSelection; }; #endif diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp index 90f40628a8..76f62a7880 100644 --- a/indra/newview/llfloaterbulkpermission.cpp +++ b/indra/newview/llfloaterbulkpermission.cpp @@ -57,6 +57,7 @@ LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed) mDone(FALSE) { mID.generate(); + mCommitCallbackRegistrar.add("BulkPermission.Ok", boost::bind(&LLFloaterBulkPermission::onOkBtn, this)); mCommitCallbackRegistrar.add("BulkPermission.Apply", boost::bind(&LLFloaterBulkPermission::onApplyBtn, this)); mCommitCallbackRegistrar.add("BulkPermission.Close", boost::bind(&LLFloaterBulkPermission::onCloseBtn, this)); mCommitCallbackRegistrar.add("BulkPermission.CheckAll", boost::bind(&LLFloaterBulkPermission::onCheckAll, this)); @@ -66,6 +67,21 @@ LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed) BOOL LLFloaterBulkPermission::postBuild() { + mBulkChangeIncludeAnimations = gSavedSettings.getBOOL("BulkChangeIncludeAnimations"); + mBulkChangeIncludeBodyParts = gSavedSettings.getBOOL("BulkChangeIncludeBodyParts"); + mBulkChangeIncludeClothing = gSavedSettings.getBOOL("BulkChangeIncludeClothing"); + mBulkChangeIncludeGestures = gSavedSettings.getBOOL("BulkChangeIncludeGestures"); + mBulkChangeIncludeNotecards = gSavedSettings.getBOOL("BulkChangeIncludeNotecards"); + mBulkChangeIncludeObjects = gSavedSettings.getBOOL("BulkChangeIncludeObjects"); + mBulkChangeIncludeScripts = gSavedSettings.getBOOL("BulkChangeIncludeScripts"); + mBulkChangeIncludeSounds = gSavedSettings.getBOOL("BulkChangeIncludeSounds"); + mBulkChangeIncludeTextures = gSavedSettings.getBOOL("BulkChangeIncludeTextures"); + mBulkChangeShareWithGroup = gSavedSettings.getBOOL("BulkChangeShareWithGroup"); + mBulkChangeEveryoneCopy = gSavedSettings.getBOOL("BulkChangeEveryoneCopy"); + mBulkChangeNextOwnerModify = gSavedSettings.getBOOL("BulkChangeNextOwnerModify"); + mBulkChangeNextOwnerCopy = gSavedSettings.getBOOL("BulkChangeNextOwnerCopy"); + mBulkChangeNextOwnerTransfer = gSavedSettings.getBOOL("BulkChangeNextOwnerTransfer"); + return TRUE; } @@ -144,6 +160,12 @@ void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object, } } +void LLFloaterBulkPermission::onOkBtn() +{ + doApply(); + closeFloater(); +} + void LLFloaterBulkPermission::onApplyBtn() { doApply(); @@ -151,6 +173,20 @@ void LLFloaterBulkPermission::onApplyBtn() void LLFloaterBulkPermission::onCloseBtn() { + gSavedSettings.setBOOL("BulkChangeIncludeAnimations", mBulkChangeIncludeAnimations); + gSavedSettings.setBOOL("BulkChangeIncludeBodyParts", mBulkChangeIncludeBodyParts); + gSavedSettings.setBOOL("BulkChangeIncludeClothing", mBulkChangeIncludeClothing); + gSavedSettings.setBOOL("BulkChangeIncludeGestures", mBulkChangeIncludeGestures); + gSavedSettings.setBOOL("BulkChangeIncludeNotecards", mBulkChangeIncludeNotecards); + gSavedSettings.setBOOL("BulkChangeIncludeObjects", mBulkChangeIncludeObjects); + gSavedSettings.setBOOL("BulkChangeIncludeScripts", mBulkChangeIncludeScripts); + gSavedSettings.setBOOL("BulkChangeIncludeSounds", mBulkChangeIncludeSounds); + gSavedSettings.setBOOL("BulkChangeIncludeTextures", mBulkChangeIncludeTextures); + gSavedSettings.setBOOL("BulkChangeShareWithGroup", mBulkChangeShareWithGroup); + gSavedSettings.setBOOL("BulkChangeEveryoneCopy", mBulkChangeEveryoneCopy); + gSavedSettings.setBOOL("BulkChangeNextOwnerModify", mBulkChangeNextOwnerModify); + gSavedSettings.setBOOL("BulkChangeNextOwnerCopy", mBulkChangeNextOwnerCopy); + gSavedSettings.setBOOL("BulkChangeNextOwnerTransfer", mBulkChangeNextOwnerTransfer); closeFloater(); } @@ -336,8 +372,6 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInve void LLFloaterBulkPermission::updateInventory(LLViewerObject* object, LLViewerInventoryItem* item, U8 key, bool is_new) { - LLMemType mt(LLMemType::MTYPE_OBJECT); - // This slices the object into what we're concerned about on the viewer. // The simulator will take the permissions and transfer ownership. LLPointer<LLViewerInventoryItem> task_item = diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h index 7dd05df7ee..25e76eca65 100644 --- a/indra/newview/llfloaterbulkpermission.h +++ b/indra/newview/llfloaterbulkpermission.h @@ -72,6 +72,7 @@ private: bool is_new); void onCloseBtn(); + void onOkBtn(); void onApplyBtn(); void onCommitCopy(); void onCheckAll() { doCheckUncheckAll(TRUE); } @@ -94,6 +95,21 @@ private: LLUUID mCurrentObjectID; BOOL mDone; + bool mBulkChangeIncludeAnimations; + bool mBulkChangeIncludeBodyParts; + bool mBulkChangeIncludeClothing; + bool mBulkChangeIncludeGestures; + bool mBulkChangeIncludeNotecards; + bool mBulkChangeIncludeObjects; + bool mBulkChangeIncludeScripts; + bool mBulkChangeIncludeSounds; + bool mBulkChangeIncludeTextures; + bool mBulkChangeShareWithGroup; + bool mBulkChangeEveryoneCopy; + bool mBulkChangeNextOwnerModify; + bool mBulkChangeNextOwnerCopy; + bool mBulkChangeNextOwnerTransfer; + LLUUID mID; const char* mStartString; diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index ee8487b160..087b0007e1 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -239,8 +239,9 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj, // Compute icon for this item BOOL item_is_multi = FALSE; - if ( inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED + if (( inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED || inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS) + && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK)) { item_is_multi = TRUE; } diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index a7388d21a3..fffd724b22 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -80,6 +80,7 @@ BOOL LLFloaterBuyContents::postBuild() LLFloaterBuyContents::~LLFloaterBuyContents() { + removeVOInventoryListener(); } @@ -147,23 +148,26 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj, return; } - if (!inv) + LLScrollListCtrl* item_list = getChild<LLScrollListCtrl>("item_list"); + if (!item_list) { - llwarns << "No inventory in LLFloaterBuyContents::inventoryChanged" - << llendl; removeVOInventoryListener(); return; } - LLCtrlListInterface *item_list = childGetListInterface("item_list"); - if (!item_list) + item_list->deleteAllItems(); + + if (!inv) { - removeVOInventoryListener(); + llwarns << "No inventory in LLFloaterBuyContents::inventoryChanged" + << llendl; + return; } // default to turning off the buy button. - getChildView("buy_btn")->setEnabled(FALSE); + LLView* buy_btn = getChildView("buy_btn"); + buy_btn->setEnabled(FALSE); LLUUID owner_id; BOOL is_group_owned; @@ -204,13 +208,15 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj, // There will be at least one item shown in the display, so go // ahead and enable the buy button. - getChildView("buy_btn")->setEnabled(TRUE); + buy_btn->setEnabled(TRUE); // Create the line in the list LLSD row; BOOL item_is_multi = FALSE; - if ( inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED ) + if ((inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED + || inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS) + && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK)) { item_is_multi = TRUE; } @@ -253,8 +259,6 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj, getChildView("wear_check")->setEnabled(TRUE); getChild<LLUICtrl>("wear_check")->setValue(LLSD(false) ); } - - removeVOInventoryListener(); } diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 2a3512e21a..62848586cd 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -1,6 +1,6 @@ /** - * @file llfloateranimpreview.cpp - * @brief LLFloaterAnimPreview class implementation + * @file llfloaterbvhpreview.cpp + * @brief LLFloaterBvhPreview class implementation * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code @@ -26,7 +26,7 @@ #include "llviewerprecompiledheaders.h" -#include "llfloateranimpreview.h" +#include "llfloaterbvhpreview.h" #include "llbvhloader.h" #include "lldatapacker.h" @@ -115,9 +115,9 @@ std::string STATUS[] = }; //----------------------------------------------------------------------------- -// LLFloaterAnimPreview() +// LLFloaterBvhPreview() //----------------------------------------------------------------------------- -LLFloaterAnimPreview::LLFloaterAnimPreview(const std::string& filename) : +LLFloaterBvhPreview::LLFloaterBvhPreview(const std::string& filename) : LLFloaterNameDesc(filename) { mLastMouseX = 0; @@ -153,35 +153,35 @@ LLFloaterAnimPreview::LLFloaterAnimPreview(const std::string& filename) : //----------------------------------------------------------------------------- // setAnimCallbacks() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::setAnimCallbacks() +void LLFloaterBvhPreview::setAnimCallbacks() { - getChild<LLUICtrl>("playback_slider")->setCommitCallback(boost::bind(&LLFloaterAnimPreview::onSliderMove, this)); + getChild<LLUICtrl>("playback_slider")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onSliderMove, this)); - getChild<LLUICtrl>("preview_base_anim")->setCommitCallback(boost::bind(&LLFloaterAnimPreview::onCommitBaseAnim, this)); + getChild<LLUICtrl>("preview_base_anim")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitBaseAnim, this)); getChild<LLUICtrl>("preview_base_anim")->setValue("Standing"); - getChild<LLUICtrl>("priority")->setCommitCallback(boost::bind(&LLFloaterAnimPreview::onCommitPriority, this)); - getChild<LLUICtrl>("loop_check")->setCommitCallback(boost::bind(&LLFloaterAnimPreview::onCommitLoop, this)); - getChild<LLUICtrl>("loop_in_point")->setCommitCallback(boost::bind(&LLFloaterAnimPreview::onCommitLoopIn, this)); - getChild<LLUICtrl>("loop_in_point")->setValidateBeforeCommit( boost::bind(&LLFloaterAnimPreview::validateLoopIn, this, _1)); - getChild<LLUICtrl>("loop_out_point")->setCommitCallback(boost::bind(&LLFloaterAnimPreview::onCommitLoopOut, this)); - getChild<LLUICtrl>("loop_out_point")->setValidateBeforeCommit( boost::bind(&LLFloaterAnimPreview::validateLoopOut, this, _1)); + getChild<LLUICtrl>("priority")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitPriority, this)); + getChild<LLUICtrl>("loop_check")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoop, this)); + getChild<LLUICtrl>("loop_in_point")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoopIn, this)); + getChild<LLUICtrl>("loop_in_point")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateLoopIn, this, _1)); + getChild<LLUICtrl>("loop_out_point")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoopOut, this)); + getChild<LLUICtrl>("loop_out_point")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateLoopOut, this, _1)); - getChild<LLUICtrl>("hand_pose_combo")->setCommitCallback(boost::bind(&LLFloaterAnimPreview::onCommitHandPose, this)); + getChild<LLUICtrl>("hand_pose_combo")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitHandPose, this)); - getChild<LLUICtrl>("emote_combo")->setCommitCallback(boost::bind(&LLFloaterAnimPreview::onCommitEmote, this)); + getChild<LLUICtrl>("emote_combo")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitEmote, this)); getChild<LLUICtrl>("emote_combo")->setValue("[None]"); - getChild<LLUICtrl>("ease_in_time")->setCommitCallback(boost::bind(&LLFloaterAnimPreview::onCommitEaseIn, this)); - getChild<LLUICtrl>("ease_in_time")->setValidateBeforeCommit( boost::bind(&LLFloaterAnimPreview::validateEaseIn, this, _1)); - getChild<LLUICtrl>("ease_out_time")->setCommitCallback(boost::bind(&LLFloaterAnimPreview::onCommitEaseOut, this)); - getChild<LLUICtrl>("ease_out_time")->setValidateBeforeCommit( boost::bind(&LLFloaterAnimPreview::validateEaseOut, this, _1)); + getChild<LLUICtrl>("ease_in_time")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitEaseIn, this)); + getChild<LLUICtrl>("ease_in_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseIn, this, _1)); + getChild<LLUICtrl>("ease_out_time")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitEaseOut, this)); + getChild<LLUICtrl>("ease_out_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseOut, this, _1)); } //----------------------------------------------------------------------------- // postBuild() //----------------------------------------------------------------------------- -BOOL LLFloaterAnimPreview::postBuild() +BOOL LLFloaterBvhPreview::postBuild() { LLKeyframeMotion* motionp = NULL; LLBVHLoader* loaderp = NULL; @@ -191,7 +191,7 @@ BOOL LLFloaterAnimPreview::postBuild() return FALSE; } - getChild<LLUICtrl>("name_form")->setCommitCallback(boost::bind(&LLFloaterAnimPreview::onCommitName, this)); + getChild<LLUICtrl>("name_form")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitName, this)); childSetAction("ok_btn", onBtnOK, this); setDefaultBtn(); @@ -203,15 +203,15 @@ BOOL LLFloaterAnimPreview::postBuild() mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f); mPlayButton = getChild<LLButton>( "play_btn"); - mPlayButton->setClickedCallback(boost::bind(&LLFloaterAnimPreview::onBtnPlay, this)); + mPlayButton->setClickedCallback(boost::bind(&LLFloaterBvhPreview::onBtnPlay, this)); mPlayButton->setVisible(true); mPauseButton = getChild<LLButton>( "pause_btn"); - mPauseButton->setClickedCallback(boost::bind(&LLFloaterAnimPreview::onBtnPause, this)); + mPauseButton->setClickedCallback(boost::bind(&LLFloaterBvhPreview::onBtnPause, this)); mPauseButton->setVisible(false); mStopButton = getChild<LLButton>( "stop_btn"); - mStopButton->setClickedCallback(boost::bind(&LLFloaterAnimPreview::onBtnStop, this)); + mStopButton->setClickedCallback(boost::bind(&LLFloaterBvhPreview::onBtnStop, this)); getChildView("bad_animation_text")->setVisible(FALSE); @@ -363,9 +363,9 @@ BOOL LLFloaterAnimPreview::postBuild() } //----------------------------------------------------------------------------- -// LLFloaterAnimPreview() +// LLFloaterBvhPreview() //----------------------------------------------------------------------------- -LLFloaterAnimPreview::~LLFloaterAnimPreview() +LLFloaterBvhPreview::~LLFloaterBvhPreview() { mAnimPreview = NULL; @@ -375,7 +375,7 @@ LLFloaterAnimPreview::~LLFloaterAnimPreview() //----------------------------------------------------------------------------- // draw() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::draw() +void LLFloaterBvhPreview::draw() { LLFloater::draw(); LLRect r = getRect(); @@ -414,18 +414,22 @@ void LLFloaterAnimPreview::draw() //----------------------------------------------------------------------------- // resetMotion() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::resetMotion() +void LLFloaterBvhPreview::resetMotion() { + if (!mAnimPreview) + return; + LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); BOOL paused = avatarp->areAnimationsPaused(); - // *TODO: Fix awful casting hack - LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); - - // Set emotion - std::string emote = getChild<LLUICtrl>("emote_combo")->getValue().asString(); - motionp->setEmote(mIDList[emote]); - + LLKeyframeMotion* motionp = dynamic_cast<LLKeyframeMotion*>(avatarp->findMotion(mMotionID)); + if( motionp ) + { + // Set emotion + std::string emote = getChild<LLUICtrl>("emote_combo")->getValue().asString(); + motionp->setEmote(mIDList[emote]); + } + LLUUID base_id = mIDList[getChild<LLUICtrl>("preview_base_anim")->getValue().asString()]; avatarp->deactivateAllMotions(); avatarp->startMotion(mMotionID, 0.0f); @@ -435,8 +439,12 @@ void LLFloaterAnimPreview::resetMotion() // Set pose std::string handpose = getChild<LLUICtrl>("hand_pose_combo")->getValue().asString(); avatarp->startMotion( ANIM_AGENT_HAND_MOTION, 0.0f ); - motionp->setHandPose(LLHandMotion::getHandPose(handpose)); + if( motionp ) + { + motionp->setHandPose(LLHandMotion::getHandPose(handpose)); + } + if (paused) { mPauseRequest = avatarp->requestPause(); @@ -450,7 +458,7 @@ void LLFloaterAnimPreview::resetMotion() //----------------------------------------------------------------------------- // handleMouseDown() //----------------------------------------------------------------------------- -BOOL LLFloaterAnimPreview::handleMouseDown(S32 x, S32 y, MASK mask) +BOOL LLFloaterBvhPreview::handleMouseDown(S32 x, S32 y, MASK mask) { if (mPreviewRect.pointInRect(x, y)) { @@ -468,7 +476,7 @@ BOOL LLFloaterAnimPreview::handleMouseDown(S32 x, S32 y, MASK mask) //----------------------------------------------------------------------------- // handleMouseUp() //----------------------------------------------------------------------------- -BOOL LLFloaterAnimPreview::handleMouseUp(S32 x, S32 y, MASK mask) +BOOL LLFloaterBvhPreview::handleMouseUp(S32 x, S32 y, MASK mask) { gFocusMgr.setMouseCapture(FALSE); gViewerWindow->showCursor(); @@ -478,7 +486,7 @@ BOOL LLFloaterAnimPreview::handleMouseUp(S32 x, S32 y, MASK mask) //----------------------------------------------------------------------------- // handleHover() //----------------------------------------------------------------------------- -BOOL LLFloaterAnimPreview::handleHover(S32 x, S32 y, MASK mask) +BOOL LLFloaterBvhPreview::handleHover(S32 x, S32 y, MASK mask) { MASK local_mask = mask & ~MASK_ALT; @@ -533,8 +541,11 @@ BOOL LLFloaterAnimPreview::handleHover(S32 x, S32 y, MASK mask) //----------------------------------------------------------------------------- // handleScrollWheel() //----------------------------------------------------------------------------- -BOOL LLFloaterAnimPreview::handleScrollWheel(S32 x, S32 y, S32 clicks) +BOOL LLFloaterBvhPreview::handleScrollWheel(S32 x, S32 y, S32 clicks) { + if (!mAnimPreview) + return false; + mAnimPreview->zoom((F32)clicks * -0.2f); mAnimPreview->requestUpdate(); @@ -544,7 +555,7 @@ BOOL LLFloaterAnimPreview::handleScrollWheel(S32 x, S32 y, S32 clicks) //----------------------------------------------------------------------------- // onMouseCaptureLost() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onMouseCaptureLost() +void LLFloaterBvhPreview::onMouseCaptureLost() { gViewerWindow->showCursor(); } @@ -552,7 +563,7 @@ void LLFloaterAnimPreview::onMouseCaptureLost() //----------------------------------------------------------------------------- // onBtnPlay() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onBtnPlay() +void LLFloaterBvhPreview::onBtnPlay() { if (!getEnabled()) return; @@ -576,7 +587,7 @@ void LLFloaterAnimPreview::onBtnPlay() //----------------------------------------------------------------------------- // onBtnPause() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onBtnPause() +void LLFloaterBvhPreview::onBtnPause() { if (!getEnabled()) return; @@ -598,7 +609,7 @@ void LLFloaterAnimPreview::onBtnPause() //----------------------------------------------------------------------------- // onBtnStop() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onBtnStop() +void LLFloaterBvhPreview::onBtnStop() { if (!getEnabled()) return; @@ -614,7 +625,7 @@ void LLFloaterAnimPreview::onBtnStop() //----------------------------------------------------------------------------- // onSliderMove() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onSliderMove() +void LLFloaterBvhPreview::onSliderMove() { if (!getEnabled()) return; @@ -639,7 +650,7 @@ void LLFloaterAnimPreview::onSliderMove() //----------------------------------------------------------------------------- // onCommitBaseAnim() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onCommitBaseAnim() +void LLFloaterBvhPreview::onCommitBaseAnim() { if (!getEnabled()) return; @@ -668,9 +679,9 @@ void LLFloaterAnimPreview::onCommitBaseAnim() //----------------------------------------------------------------------------- // onCommitLoop() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onCommitLoop() +void LLFloaterBvhPreview::onCommitLoop() { - if (!getEnabled()) + if (!getEnabled() || !mAnimPreview) return; LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); @@ -687,9 +698,9 @@ void LLFloaterAnimPreview::onCommitLoop() //----------------------------------------------------------------------------- // onCommitLoopIn() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onCommitLoopIn() +void LLFloaterBvhPreview::onCommitLoopIn() { - if (!getEnabled()) + if (!getEnabled() || !mAnimPreview) return; LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); @@ -707,9 +718,9 @@ void LLFloaterAnimPreview::onCommitLoopIn() //----------------------------------------------------------------------------- // onCommitLoopOut() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onCommitLoopOut() +void LLFloaterBvhPreview::onCommitLoopOut() { - if (!getEnabled()) + if (!getEnabled() || !mAnimPreview) return; LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); @@ -727,9 +738,9 @@ void LLFloaterAnimPreview::onCommitLoopOut() //----------------------------------------------------------------------------- // onCommitName() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onCommitName() +void LLFloaterBvhPreview::onCommitName() { - if (!getEnabled()) + if (!getEnabled() || !mAnimPreview) return; LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); @@ -746,7 +757,7 @@ void LLFloaterAnimPreview::onCommitName() //----------------------------------------------------------------------------- // onCommitHandPose() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onCommitHandPose() +void LLFloaterBvhPreview::onCommitHandPose() { if (!getEnabled()) return; @@ -757,7 +768,7 @@ void LLFloaterAnimPreview::onCommitHandPose() //----------------------------------------------------------------------------- // onCommitEmote() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onCommitEmote() +void LLFloaterBvhPreview::onCommitEmote() { if (!getEnabled()) return; @@ -768,9 +779,9 @@ void LLFloaterAnimPreview::onCommitEmote() //----------------------------------------------------------------------------- // onCommitPriority() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onCommitPriority() +void LLFloaterBvhPreview::onCommitPriority() { - if (!getEnabled()) + if (!getEnabled() || !mAnimPreview) return; LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); @@ -782,9 +793,9 @@ void LLFloaterAnimPreview::onCommitPriority() //----------------------------------------------------------------------------- // onCommitEaseIn() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onCommitEaseIn() +void LLFloaterBvhPreview::onCommitEaseIn() { - if (!getEnabled()) + if (!getEnabled() || !mAnimPreview) return; LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); @@ -797,9 +808,9 @@ void LLFloaterAnimPreview::onCommitEaseIn() //----------------------------------------------------------------------------- // onCommitEaseOut() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onCommitEaseOut() +void LLFloaterBvhPreview::onCommitEaseOut() { - if (!getEnabled()) + if (!getEnabled() || !mAnimPreview) return; LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); @@ -812,9 +823,9 @@ void LLFloaterAnimPreview::onCommitEaseOut() //----------------------------------------------------------------------------- // validateEaseIn() //----------------------------------------------------------------------------- -bool LLFloaterAnimPreview::validateEaseIn(const LLSD& data) +bool LLFloaterBvhPreview::validateEaseIn(const LLSD& data) { - if (!getEnabled()) + if (!getEnabled() || !mAnimPreview) return false; LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); @@ -832,9 +843,9 @@ bool LLFloaterAnimPreview::validateEaseIn(const LLSD& data) //----------------------------------------------------------------------------- // validateEaseOut() //----------------------------------------------------------------------------- -bool LLFloaterAnimPreview::validateEaseOut(const LLSD& data) +bool LLFloaterBvhPreview::validateEaseOut(const LLSD& data) { - if (!getEnabled()) + if (!getEnabled() || !mAnimPreview) return false; LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); @@ -852,7 +863,7 @@ bool LLFloaterAnimPreview::validateEaseOut(const LLSD& data) //----------------------------------------------------------------------------- // validateLoopIn() //----------------------------------------------------------------------------- -bool LLFloaterAnimPreview::validateLoopIn(const LLSD& data) +bool LLFloaterBvhPreview::validateLoopIn(const LLSD& data) { if (!getEnabled()) return false; @@ -880,7 +891,7 @@ bool LLFloaterAnimPreview::validateLoopIn(const LLSD& data) //----------------------------------------------------------------------------- // validateLoopOut() //----------------------------------------------------------------------------- -bool LLFloaterAnimPreview::validateLoopOut(const LLSD& data) +bool LLFloaterBvhPreview::validateLoopOut(const LLSD& data) { if (!getEnabled()) return false; @@ -909,7 +920,7 @@ bool LLFloaterAnimPreview::validateLoopOut(const LLSD& data) //----------------------------------------------------------------------------- // refresh() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::refresh() +void LLFloaterBvhPreview::refresh() { // Are we showing the play button (default) or the pause button? bool show_play = true; @@ -958,9 +969,9 @@ void LLFloaterAnimPreview::refresh() //----------------------------------------------------------------------------- // onBtnOK() //----------------------------------------------------------------------------- -void LLFloaterAnimPreview::onBtnOK(void* userdata) +void LLFloaterBvhPreview::onBtnOK(void* userdata) { - LLFloaterAnimPreview* floaterp = (LLFloaterAnimPreview*)userdata; + LLFloaterBvhPreview* floaterp = (LLFloaterBvhPreview*)userdata; if (!floaterp->getEnabled()) return; if (floaterp->mAnimPreview) @@ -1118,9 +1129,13 @@ BOOL LLPreviewAnimation::render() LLVertexBuffer::unbind(); LLGLDepthTest gls_depth(GL_TRUE); - LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool(); - avatarp->dirtyMesh(); - avatarPoolp->renderAvatars(avatarp); // renders only one avatar + LLFace* face = avatarp->mDrawable->getFace(0); + if (face) + { + LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool(); + avatarp->dirtyMesh(); + avatarPoolp->renderAvatars(avatarp); // renders only one avatar + } } gGL.color4f(1,1,1,1); diff --git a/indra/newview/llfloateranimpreview.h b/indra/newview/llfloaterbvhpreview.h index f1ffb6547f..b81cc6e3a5 100644 --- a/indra/newview/llfloateranimpreview.h +++ b/indra/newview/llfloaterbvhpreview.h @@ -1,6 +1,6 @@ /** - * @file llfloateranimpreview.h - * @brief LLFloaterAnimPreview class definition + * @file llfloaterbvhpreview.h + * @brief LLFloaterBvhPreview class definition * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code @@ -24,14 +24,15 @@ * $/LicenseInfo$ */ -#ifndef LL_LLFLOATERANIMPREVIEW_H -#define LL_LLFLOATERANIMPREVIEW_H +#ifndef LL_LLFLOATERBVHPREVIEW_H +#define LL_LLFLOATERBVHPREVIEW_H #include "llassettype.h" #include "llfloaternamedesc.h" #include "lldynamictexture.h" #include "llcharacter.h" #include "llquaternion.h" +#include "llextendedstatus.h" class LLVOAvatar; class LLViewerJointMesh; @@ -67,11 +68,11 @@ protected: LLPointer<LLVOAvatar> mDummyAvatar; }; -class LLFloaterAnimPreview : public LLFloaterNameDesc +class LLFloaterBvhPreview : public LLFloaterNameDesc { public: - LLFloaterAnimPreview(const std::string& filename); - virtual ~LLFloaterAnimPreview(); + LLFloaterBvhPreview(const std::string& filename); + virtual ~LLFloaterBvhPreview(); BOOL postBuild(); @@ -128,4 +129,4 @@ protected: std::map<std::string, LLUUID> mIDList; }; -#endif // LL_LLFLOATERANIMPREVIEW_H +#endif // LL_LLFLOATERBVHPREVIEW_H diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index b33dea4890..c85d048c5a 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -330,6 +330,10 @@ void LLFloaterCamera::onClose(bool app_quitting) //We don't care of camera mode if app is quitting if(app_quitting) return; + // It is necessary to reset mCurrMode to CAMERA_CTRL_MODE_PAN so + // to avoid seeing an empty floater when reopening the control. + if (mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA) + mCurrMode = CAMERA_CTRL_MODE_PAN; // When mCurrMode is in CAMERA_CTRL_MODE_PAN // switchMode won't modify mPrevMode, so force it here. // It is needed to correctly return to previous mode on open, see EXT-2727. @@ -346,7 +350,7 @@ LLFloaterCamera::LLFloaterCamera(const LLSD& val) mCurrMode(CAMERA_CTRL_MODE_PAN), mPrevMode(CAMERA_CTRL_MODE_PAN) { - LLHints::registerHintTarget("view_popup", LLView::getHandle()); + LLHints::registerHintTarget("view_popup", getHandle()); mCommitCallbackRegistrar.add("CameraPresets.ChangeView", boost::bind(&LLFloaterCamera::onClickCameraItem, _2)); } @@ -433,26 +437,6 @@ void LLFloaterCamera::setMode(ECameraControlMode mode) updateState(); } -void LLFloaterCamera::setModeTitle(const ECameraControlMode mode) -{ - std::string title; - switch(mode) - { - case CAMERA_CTRL_MODE_MODES: - title = getString("camera_modes_title"); - break; - case CAMERA_CTRL_MODE_PAN: - title = getString("pan_mode_title"); - break; - case CAMERA_CTRL_MODE_PRESETS: - title = getString("presets_mode_title"); - break; - default: - break; - } - setTitle(title); -} - void LLFloaterCamera::switchMode(ECameraControlMode mode) { setMode(mode); @@ -532,7 +516,6 @@ void LLFloaterCamera::updateState() { iter->second->setToggleState(iter->first == mCurrMode); } - setModeTitle(mCurrMode); } void LLFloaterCamera::updateItemsSelection() diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h index 4572932853..4d6d03f22d 100644 --- a/indra/newview/llfloatercamera.h +++ b/indra/newview/llfloatercamera.h @@ -102,9 +102,6 @@ private: /* sets a new mode preserving previous one and updates ui*/ void setMode(ECameraControlMode mode); - /** set title appropriate to passed mode */ - void setModeTitle(const ECameraControlMode mode); - /* updates the state (UI) according to the current mode */ void updateState(); diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp deleted file mode 100644 index 2679dbb78b..0000000000 --- a/indra/newview/llfloaterchat.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/** - * @file llfloaterchat.cpp - * @brief LLFloaterChat class implementation - * - * $LicenseInfo:firstyear=2002&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$ - */ - -/** - * Actually the "Chat History" floater. - * Should be llfloaterchathistory, not llfloaterchat. - */ - -#include "llviewerprecompiledheaders.h" - -// project include -#include "llagent.h" -#include "llappviewer.h" -#include "llbutton.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" -#include "llconsole.h" -#include "llfloateractivespeakers.h" -#include "llfloaterchatterbox.h" -#include "llfloaterreg.h" -#include "llfloaterscriptdebug.h" -#include "llkeyboard.h" -//#include "lllineeditor.h" -#include "llmutelist.h" -//#include "llresizehandle.h" -#include "llchatbar.h" -#include "llrecentpeople.h" -#include "llpanelblockedlist.h" -#include "llslurl.h" -#include "llstatusbar.h" -#include "llviewertexteditor.h" -#include "llviewergesture.h" // for triggering gestures -#include "llviewermessage.h" -#include "llviewerwindow.h" -#include "llviewercontrol.h" -#include "lluictrlfactory.h" -#include "lllogchat.h" -#include "lltexteditor.h" -#include "lltextparser.h" -#include "llweb.h" -#include "llstylemap.h" - -// linden library includes -#include "llaudioengine.h" -#include "llchat.h" -#include "llfontgl.h" -#include "llrect.h" -#include "llerror.h" -#include "llstring.h" -#include "llwindow.h" -#include "message.h" - -// -// Constants -// -const F32 INSTANT_MSG_SIZE = 8.0f; -const F32 CHAT_MSG_SIZE = 8.0f; - - -// -// Global statics -// -LLColor4 get_text_color(const LLChat& chat); - -// -// Member Functions -// -LLFloaterChat::LLFloaterChat(const LLSD& seed) - : LLFloater(seed), - mPanel(NULL) -{ - mFactoryMap["chat_panel"] = LLCallbackMap(createChatPanel, NULL); - mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, NULL); - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_chat_history.xml"); - -} - -LLFloaterChat::~LLFloaterChat() -{ - // Children all cleaned up by default view destructor. -} - -void LLFloaterChat::draw() -{ - // enable say and shout only when text available - - childSetValue("toggle_active_speakers_btn", childIsVisible("active_speakers_panel")); - - LLChatBar* chat_barp = findChild<LLChatBar>("chat_panel", TRUE); - if (chat_barp) - { - chat_barp->refresh(); - } - - mPanel->refreshSpeakers(); - LLFloater::draw(); -} - -BOOL LLFloaterChat::postBuild() -{ - // Hide the chat overlay when our history is visible. - setVisibleCallback(boost::bind(&LLFloaterChat::updateConsoleVisibility, this)); - - mPanel = (LLPanelActiveSpeakers*)getChild<LLPanel>("active_speakers_panel"); - - childSetCommitCallback("show mutes",onClickToggleShowMute,this); //show mutes - childSetVisible("Chat History Editor with mute",FALSE); - childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this); - - return TRUE; -} - -void LLFloaterChat::updateConsoleVisibility() -{ - if(gDisconnected) - { - return; - } - // determine whether we should show console due to not being visible - gConsole->setVisible( !isInVisibleChain() // are we not in part of UI being drawn? - || isMinimized() // are we minimized? - || (getHost() && getHost()->isMinimized() )); // are we hosted in a minimized floater? -} - -void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color) -{ - std::string line = chat.mText; - bool prepend_newline = true; - if (gSavedSettings.getBOOL("ChatShowTimestamps")) - { - edit->appendTime(prepend_newline); - prepend_newline = false; - } - - // If the msg is from an agent (not yourself though), - // extract out the sender name and replace it with the hotlinked name. - if (chat.mSourceType == CHAT_SOURCE_AGENT && - chat.mFromID != LLUUID::null) - { - chat.mURL = LLSLURL("agent", chat.mFromID, "inspect").getSLURLString(); - } - - // If the chat line has an associated url, link it up to the name. - if (!chat.mURL.empty() - && (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0)) - { - std::string start_line = line.substr(0, chat.mFromName.length() + 1); - line = line.substr(chat.mFromName.length() + 1); - edit->appendText(start_line, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,chat.mURL)); - edit->blockUndo(); - prepend_newline = false; - } - edit->appendText(line, prepend_newline, LLStyle::Params().color(color)); - edit->blockUndo(); -} - -// static -void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file) -{ - if (log_to_file && (gSavedPerAccountSettings.getBOOL("LogChat"))) - { - if (chat.mChatType != CHAT_TYPE_WHISPER && chat.mChatType != CHAT_TYPE_SHOUT) - { - LLLogChat::saveHistory("chat", chat.mFromName, chat.mFromID, chat.mText); - } - else - { - LLLogChat::saveHistory("chat", "", chat.mFromID, chat.mFromName + " " + chat.mText); - } - } - - LLColor4 color = get_text_color(chat); - - if (!log_to_file) color = LLColor4::grey; //Recap from log file. - - if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) - { - if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE) - return; - if (gSavedSettings.getS32("ShowScriptErrorsLocation") == 1) - { - LLFloaterScriptDebug::addScriptLine(chat.mText, - chat.mFromName, - color, - chat.mFromID); - return; - } - } - - // could flash the chat button in the status bar here. JC - LLFloaterChat* chat_floater = LLFloaterChat::getInstance(); - LLViewerTextEditor* history_editor = chat_floater->getChild<LLViewerTextEditor>("Chat History Editor"); - LLViewerTextEditor* history_editor_with_mute = chat_floater->getChild<LLViewerTextEditor>("Chat History Editor with mute"); - - if (!chat.mMuted) - { - add_timestamped_line(history_editor, chat, color); - add_timestamped_line(history_editor_with_mute, chat, color); - } - else - { - // desaturate muted chat - LLColor4 muted_color = lerp(color, LLColor4::grey, 0.5f); - add_timestamped_line(history_editor_with_mute, chat, color); - } - - // add objects as transient speakers that can be muted - if (chat.mSourceType == CHAT_SOURCE_OBJECT) - { - chat_floater->mPanel->setSpeaker(chat.mFromID, chat.mFromName, LLSpeaker::STATUS_NOT_IN_CHANNEL, LLSpeaker::SPEAKER_OBJECT); - } - - // start tab flashing on incoming text from other users (ignoring system text, etc) - if (!chat_floater->isInVisibleChain() && chat.mSourceType == CHAT_SOURCE_AGENT) - { - LLFloaterChatterBox::getInstance()->setFloaterFlashing(chat_floater, TRUE); - } -} - -// static -void LLFloaterChat::setHistoryCursorAndScrollToEnd() -{ - LLViewerTextEditor* history_editor = LLFloaterChat::getInstance()->getChild<LLViewerTextEditor>("Chat History Editor"); - LLViewerTextEditor* history_editor_with_mute = LLFloaterChat::getInstance()->getChild<LLViewerTextEditor>("Chat History Editor with mute"); - - if (history_editor) - { - history_editor->setCursorAndScrollToEnd(); - } - if (history_editor_with_mute) - { - history_editor_with_mute->setCursorAndScrollToEnd(); - } -} - - -//static -void LLFloaterChat::onClickMute(void *data) -{ - LLFloaterChat* self = (LLFloaterChat*)data; - - LLComboBox* chatter_combo = self->getChild<LLComboBox>("chatter combobox"); - - const std::string& name = chatter_combo->getSimple(); - LLUUID id = chatter_combo->getCurrentID(); - - if (name.empty()) return; - - LLMute mute(id); - mute.setFromDisplayName(name); - LLMuteList::getInstance()->add(mute); - LLPanelBlockedList::showPanelAndSelect(mute.mID); -} - -//static -void LLFloaterChat::onClickToggleShowMute(LLUICtrl* caller, void *data) -{ - LLFloaterChat* floater = (LLFloaterChat*)data; - - - //LLCheckBoxCtrl* - BOOL show_mute = floater->getChild<LLCheckBoxCtrl>("show mutes")->get(); - LLViewerTextEditor* history_editor = floater->getChild<LLViewerTextEditor>("Chat History Editor"); - LLViewerTextEditor* history_editor_with_mute = floater->getChild<LLViewerTextEditor>("Chat History Editor with mute"); - - if (!history_editor || !history_editor_with_mute) - return; - - //BOOL show_mute = floater->mShowMuteCheckBox->get(); - if (show_mute) - { - history_editor->setVisible(FALSE); - history_editor_with_mute->setVisible(TRUE); - history_editor_with_mute->setCursorAndScrollToEnd(); - } - else - { - history_editor->setVisible(TRUE); - history_editor_with_mute->setVisible(FALSE); - history_editor->setCursorAndScrollToEnd(); - } -} - -// Put a line of chat in all the right places -void LLFloaterChat::addChat(const LLChat& chat, BOOL local_agent) -{ - triggerAlerts(chat.mText); - - // Add the sender to the list of people with which we've recently interacted. - // this is not the best place to add _all_ messages to recent list - // comment this for now, may remove later on code cleanup - //if(chat.mSourceType == CHAT_SOURCE_AGENT && chat.mFromID.notNull()) - // LLRecentPeople::instance().add(chat.mFromID); - - addChatHistory(chat, true); -} - -// Moved from lltextparser.cpp to break llui/llaudio library dependency. -//static -void LLFloaterChat::triggerAlerts(const std::string& text) -{ - LLTextParser* parser = LLTextParser::getInstance(); -// bool spoken=FALSE; - for (S32 i=0;i<parser->mHighlights.size();i++) - { - LLSD& highlight = parser->mHighlights[i]; - if (parser->findPattern(text,highlight) >= 0 ) - { - if(gAudiop) - { - if ((std::string)highlight["sound_lluuid"] != LLUUID::null.asString()) - { - gAudiop->triggerSound(highlight["sound_lluuid"].asUUID(), - gAgent.getID(), - 1.f, - LLAudioEngine::AUDIO_TYPE_UI, - gAgent.getPositionGlobal() ); - } -/* - if (!spoken) - { - LLTextToSpeech* text_to_speech = NULL; - text_to_speech = LLTextToSpeech::getInstance(); - spoken = text_to_speech->speak((LLString)highlight["voice"],text); - } - */ - } - if (highlight["flash"]) - { - LLWindow* viewer_window = gViewerWindow->getWindow(); - if (viewer_window && viewer_window->getMinimized()) - { - viewer_window->flashIcon(5.f); - } - } - } - } -} - -LLColor4 get_text_color(const LLChat& chat) -{ - LLColor4 text_color; - - if(chat.mMuted) - { - text_color.setVec(0.8f, 0.8f, 0.8f, 1.f); - } - else - { - switch(chat.mSourceType) - { - case CHAT_SOURCE_SYSTEM: - text_color = LLUIColorTable::instance().getColor("SystemChatColor"); - break; - case CHAT_SOURCE_AGENT: - if (chat.mFromID.isNull()) - { - text_color = LLUIColorTable::instance().getColor("SystemChatColor"); - } - else - { - if(gAgent.getID() == chat.mFromID) - { - text_color = LLUIColorTable::instance().getColor("UserChatColor"); - } - else - { - text_color = LLUIColorTable::instance().getColor("AgentChatColor"); - } - } - break; - case CHAT_SOURCE_OBJECT: - if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) - { - text_color = LLUIColorTable::instance().getColor("ScriptErrorColor"); - } - else if ( chat.mChatType == CHAT_TYPE_OWNER ) - { - text_color = LLUIColorTable::instance().getColor("llOwnerSayChatColor"); - } - else - { - text_color = LLUIColorTable::instance().getColor("ObjectChatColor"); - } - break; - default: - text_color.setToWhite(); - } - - if (!chat.mPosAgent.isExactlyZero()) - { - LLVector3 pos_agent = gAgent.getPositionAgent(); - F32 distance_squared = dist_vec_squared(pos_agent, chat.mPosAgent); - F32 dist_near_chat = gAgent.getNearChatRadius(); - if (distance_squared > dist_near_chat * dist_near_chat) - { - // diminish far-off chat - text_color.mV[VALPHA] = 0.8f; - } - } - } - - return text_color; -} - -//static -void LLFloaterChat::loadHistory() -{ - LLLogChat::loadHistory(std::string("chat"), &chatFromLogFile, (void *)LLFloaterChat::getInstance()); -} - -//static -void LLFloaterChat::chatFromLogFile(LLLogChat::ELogLineType type , const LLSD& line, void* userdata) -{ - switch (type) - { - case LLLogChat::LOG_EMPTY: - case LLLogChat::LOG_END: - // *TODO: nice message from XML file here - break; - case LLLogChat::LOG_LINE: - case LLLogChat::LOG_LLSD: - { - LLChat chat; - chat.mText = line["message"].asString(); - get_text_color(chat); - addChatHistory(chat, FALSE); - } - break; - default: - // nothing - break; - } -} - -//static -void* LLFloaterChat::createSpeakersPanel(void* data) -{ - return new LLPanelActiveSpeakers(LLLocalSpeakerMgr::getInstance(), TRUE); -} - -//static -void* LLFloaterChat::createChatPanel(void* data) -{ - LLChatBar* chatp = new LLChatBar(); - return chatp; -} - -// static -void LLFloaterChat::onClickToggleActiveSpeakers(void* userdata) -{ - LLFloaterChat* self = (LLFloaterChat*)userdata; - - self->childSetVisible("active_speakers_panel", !self->childIsVisible("active_speakers_panel")); -} - -//static - LLFloaterChat* LLFloaterChat::getInstance() - { - return LLFloaterReg::getTypedInstance<LLFloaterChat>("chat", LLSD()) ; - - } diff --git a/indra/newview/llfloaterchat.h b/indra/newview/llfloaterchat.h deleted file mode 100644 index fb2aabbfdf..0000000000 --- a/indra/newview/llfloaterchat.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file llfloaterchat.h - * @brief LLFloaterChat class definition - * - * $LicenseInfo:firstyear=2002&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$ - */ - -/* - * Actually the "Chat History" floater. - * Should be llfloaterchathistory, not llfloaterchat. - */ - -#ifndef LL_LLFLOATERCHAT_H -#define LL_LLFLOATERCHAT_H - -#include "llfloater.h" -#include "lllogchat.h" - -class LLChat; -class LLPanelActiveSpeakers; -class LLLogChat; - -class LLFloaterChat : public LLFloater -{ -public: - LLFloaterChat(const LLSD& seed); - ~LLFloaterChat(); - - virtual void draw(); - virtual BOOL postBuild(); - - void updateConsoleVisibility(); - - static void setHistoryCursorAndScrollToEnd(); - - // *TODO:Skinning - move these to LLChat (or LLViewerChat?) - // Add chat to console and history list. - // Color based on source, type, distance. - static void addChat(const LLChat& chat, BOOL local_agent = FALSE); - // Add chat to history alone. - static void addChatHistory(const LLChat& chat, bool log_to_file = true); - - static void triggerAlerts(const std::string& text); - - static void onClickMute(void *data); - static void onClickToggleShowMute(LLUICtrl* caller, void *data); - static void onClickToggleActiveSpeakers(void* userdata); - static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& line, void* userdata); - static void loadHistory(); - static void* createSpeakersPanel(void* data); - static void* createChatPanel(void* data); - - static LLFloaterChat* getInstance(); // *TODO:Skinning Deprecate - - LLPanelActiveSpeakers* mPanel; - BOOL mScrolledToEnd; -}; - -#endif diff --git a/indra/newview/llfloaterchatterbox.cpp b/indra/newview/llfloaterchatterbox.cpp deleted file mode 100644 index dc33e45dd4..0000000000 --- a/indra/newview/llfloaterchatterbox.cpp +++ /dev/null @@ -1,344 +0,0 @@ -/** - * @file llfloaterchatterbox.cpp - * @author Richard - * @date 2007-05-08 - * @brief Implementation of the chatterbox integrated conversation ui - * - * $LicenseInfo:firstyear=2007&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 "llfloaterreg.h" -#include "llfloaterchatterbox.h" -#include "lluictrlfactory.h" -#include "llfloaterfriends.h" -#include "llfloatergroups.h" -#include "llviewercontrol.h" -#include "llvoicechannel.h" -#include "llimpanel.h" -#include "llimview.h" - -// -// LLFloaterMyFriends -// - -LLFloaterMyFriends::LLFloaterMyFriends(const LLSD& seed) - : LLFloater(seed) -{ - mFactoryMap["friends_panel"] = LLCallbackMap(LLFloaterMyFriends::createFriendsPanel, NULL); - mFactoryMap["groups_panel"] = LLCallbackMap(LLFloaterMyFriends::createGroupsPanel, NULL); - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_my_friends.xml"); -} - -LLFloaterMyFriends::~LLFloaterMyFriends() -{ -} - -BOOL LLFloaterMyFriends::postBuild() -{ - return TRUE; -} - -void LLFloaterMyFriends::onOpen(const LLSD& key) -{ - if (key.asString() == "friends") - { - childShowTab("friends_and_groups", "friends_panel"); - } - else if (key.asString() == "groups") - { - childShowTab("friends_and_groups", "groups_panel"); - } -} - -//static -void* LLFloaterMyFriends::createFriendsPanel(void* data) -{ - return new LLPanelFriends(); -} - -//static -void* LLFloaterMyFriends::createGroupsPanel(void* data) -{ - return new LLPanelGroups(); -} - -//static -LLFloaterMyFriends* LLFloaterMyFriends::getInstance() -{ - return LLFloaterReg::getTypedInstance<LLFloaterMyFriends>("contacts", "friends") ; -} - -// -// LLFloaterChatterBox -// -LLFloaterChatterBox::LLFloaterChatterBox(const LLSD& seed) -: LLMultiFloater(seed), - mActiveVoiceFloater(NULL) -{ - mAutoResize = FALSE; - - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_chatterbox.xml", FALSE); -} - -LLFloaterChatterBox::~LLFloaterChatterBox() -{ -} - -BOOL LLFloaterChatterBox::postBuild() -{ - setVisibleCallback(boost::bind(&LLFloaterChatterBox::onVisibilityChange, this, _2)); - - if (gSavedSettings.getBOOL("ContactsTornOff")) - { - LLFloaterMyFriends* floater_contacts = LLFloaterMyFriends::getInstance(); - if(floater_contacts) - { - // add then remove to set up relationship for re-attach - addFloater(floater_contacts, FALSE); - removeFloater(floater_contacts); - // reparent to floater view - gFloaterView->addChild(floater_contacts); - } - } - else - { - addFloater(LLFloaterMyFriends::getInstance(), TRUE); - } - - mTabContainer->lockTabs(); - return TRUE; -} - -BOOL LLFloaterChatterBox::handleKeyHere(KEY key, MASK mask) -{ - if (key == 'W' && mask == MASK_CONTROL) - { - LLFloater* floater = getActiveFloater(); - // is user closeable and is system closeable - if (floater && floater->canClose()) - { - if (floater->isCloseable()) - { - floater->closeFloater(); - } - else - { - // close chatterbox window if frontmost tab is reserved, non-closeable tab - // such as contacts or near me - closeFloater(); - } - } - return TRUE; - } - - return LLMultiFloater::handleKeyHere(key, mask); -} - -void LLFloaterChatterBox::draw() -{ - // clear new im notifications when chatterbox is visible - if (!isMinimized()) - { - gIMMgr->clearNewIMNotification(); - } - LLFloater* current_active_floater = getCurrentVoiceFloater(); - // set icon on tab for floater currently associated with active voice channel - if(mActiveVoiceFloater != current_active_floater) - { - // remove image from old floater's tab - if (mActiveVoiceFloater) - { - mTabContainer->setTabImage(mActiveVoiceFloater, ""); - } - } - - // update image on current active tab - if (current_active_floater) - { - LLColor4 icon_color = LLColor4::white; - LLVoiceChannel* channelp = LLVoiceChannel::getCurrentVoiceChannel(); - if (channelp) - { - if (channelp->isActive()) - { - icon_color = LLColor4::green; - } - else if (channelp->getState() == LLVoiceChannel::STATE_ERROR) - { - icon_color = LLColor4::red; - } - else // active, but not connected - { - icon_color = LLColor4::yellow; - } - } - mTabContainer->setTabImage(current_active_floater, "active_voice_tab.tga", icon_color); - } - - mActiveVoiceFloater = current_active_floater; - - LLMultiFloater::draw(); -} - -void LLFloaterChatterBox::onOpen(const LLSD& key) -{ - //*TODO:Skinning show the session id associated with key - if (key.asString() == "local") - { - } - else if (key.isDefined()) - { - /*LLFloaterIMPanel* impanel = gIMMgr->findFloaterBySession(key.asUUID()); - if (impanel) - { - impanel->openFloater(); - }*/ - } -} - -void LLFloaterChatterBox::onVisibilityChange ( const LLSD& new_visibility ) -{ -} - -void LLFloaterChatterBox::removeFloater(LLFloater* floaterp) -{ - if(!floaterp) return; - - if (floaterp->getName() == "chat floater") - { - // only my friends floater now locked - mTabContainer->lockTabs(mTabContainer->getNumLockedTabs() - 1); - gSavedSettings.setBOOL("ChatHistoryTornOff", TRUE); - floaterp->setCanClose(TRUE); - } - else if (floaterp->getName() == "floater_my_friends") - { - // only chat floater now locked - mTabContainer->lockTabs(mTabContainer->getNumLockedTabs() - 1); - gSavedSettings.setBOOL("ContactsTornOff", TRUE); - floaterp->setCanClose(TRUE); - } - LLMultiFloater::removeFloater(floaterp); -} - -void LLFloaterChatterBox::addFloater(LLFloater* floaterp, - BOOL select_added_floater, - LLTabContainer::eInsertionPoint insertion_point) -{ - if(!floaterp) return; - - S32 num_locked_tabs = mTabContainer->getNumLockedTabs(); - - // already here - if (floaterp->getHost() == this) - { - openFloater(floaterp->getKey()); - return; - } - - // make sure my friends and chat history both locked when re-attaching chat history - if (floaterp->getName() == "chat floater") - { - mTabContainer->unlockTabs(); - // add chat history as second tab if contact window is present, first tab otherwise - if (getChildView("floater_my_friends")) - { - // assuming contacts window is first tab, select it - mTabContainer->selectFirstTab(); - // and add ourselves after - LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::RIGHT_OF_CURRENT); - } - else - { - LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::START); - } - - // make sure first two tabs are now locked - mTabContainer->lockTabs(num_locked_tabs + 1); - gSavedSettings.setBOOL("ChatHistoryTornOff", FALSE); - floaterp->setCanClose(FALSE); - } - else if (floaterp->getName() == "floater_my_friends") - { - mTabContainer->unlockTabs(); - // add contacts window as first tab - LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::START); - // make sure first two tabs are now locked - mTabContainer->lockTabs(num_locked_tabs + 1); - gSavedSettings.setBOOL("ContactsTornOff", FALSE); - floaterp->setCanClose(FALSE); - } - else - { - LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point); - // openFloater(floaterp->getKey()); - } - - // make sure active voice icon shows up for new tab - if (floaterp == mActiveVoiceFloater) - { - mTabContainer->setTabImage(floaterp, "active_voice_tab.tga"); - } -} - -//static -LLFloaterChatterBox* LLFloaterChatterBox::getInstance() -{ - return LLFloaterReg::getTypedInstance<LLFloaterChatterBox>("communicate", LLSD()) ; -} - -//static -LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater() -{ - if (!LLVoiceClient::getInstance()->voiceEnabled()) - { - return NULL; - } - if (LLVoiceChannelProximal::getInstance() == LLVoiceChannel::getCurrentVoiceChannel()) - { - return NULL; - } - else - { - LLFloaterChatterBox* floater = LLFloaterChatterBox::getInstance(); - if(!floater) return NULL; - // iterator over all IM tabs (skip friends and near me) - for (S32 i = 0; i < floater->getFloaterCount(); i++) - { - LLPanel* panelp = floater->mTabContainer->getPanelByIndex(i); - if (panelp->getName() == "im_floater") - { - // only LLFloaterIMPanels are called "im_floater" - LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)panelp; - LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(im_floaterp->getSessionID()); - if (voice_channel == LLVoiceChannel::getCurrentVoiceChannel()) - { - return im_floaterp; - } - } - } - } - return NULL; -} diff --git a/indra/newview/llfloaterchatterbox.h b/indra/newview/llfloaterchatterbox.h deleted file mode 100644 index 3a8bfe2fa4..0000000000 --- a/indra/newview/llfloaterchatterbox.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file llfloaterchatterbox.h - * @author Richard - * @date 2007-05-04 - * @brief Integrated friends and group management/communication tool - * - * $LicenseInfo:firstyear=2007&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_LLFLOATERCHATTERBOX_H -#define LL_LLFLOATERCHATTERBOX_H - -#include "llfloater.h" -#include "llmultifloater.h" -#include "llstring.h" -#include "llimpanel.h" - -class LLTabContainer; - -class LLFloaterChatterBox : public LLMultiFloater -{ -public: - LLFloaterChatterBox(const LLSD& seed); - virtual ~LLFloaterChatterBox(); - - /*virtual*/ BOOL postBuild(); - /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); - /*virtual*/ void draw(); - /*virtual*/ void onOpen(const LLSD& key); - - /*virtual*/ void removeFloater(LLFloater* floaterp); - /*virtual*/ void addFloater(LLFloater* floaterp, - BOOL select_added_floater, - LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END); - - static LLFloaterChatterBox* getInstance(); // *TODO:Skinning Deprecate - static LLFloater* getCurrentVoiceFloater(); - -protected: - void onVisibilityChange ( const LLSD& new_visibility ); - - LLFloater* mActiveVoiceFloater; -}; - - -class LLFloaterMyFriends : public LLFloater -{ -public: - LLFloaterMyFriends(const LLSD& seed); - virtual ~LLFloaterMyFriends(); - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); - - static LLFloaterMyFriends* getInstance(); // *TODO:Skinning Deprecate - - static void* createFriendsPanel(void* data); - static void* createGroupsPanel(void* data); -}; - -#endif // LL_LLFLOATERCHATTERBOX_H diff --git a/indra/newview/llfloaterchatvoicevolume.cpp b/indra/newview/llfloaterchatvoicevolume.cpp new file mode 100644 index 0000000000..3c76a3a43c --- /dev/null +++ b/indra/newview/llfloaterchatvoicevolume.cpp @@ -0,0 +1,44 @@ +/** + * @file llfloaterchatvoicevolume.cpp + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "llfloaterchatvoicevolume.h" + +LLFloaterChatVoiceVolume::LLFloaterChatVoiceVolume(const LLSD& key) +: LLInspect(key) +{ +} + +void LLFloaterChatVoiceVolume::onOpen(const LLSD& key) +{ + LLInspect::onOpen(key); + LLUI::positionViewNearMouse(this); +} + +LLFloaterChatVoiceVolume::~LLFloaterChatVoiceVolume() +{ + LLTransientFloaterMgr::getInstance()->removeControlView(this); +}; diff --git a/indra/newview/llfloaterchatvoicevolume.h b/indra/newview/llfloaterchatvoicevolume.h new file mode 100644 index 0000000000..61ad92b6da --- /dev/null +++ b/indra/newview/llfloaterchatvoicevolume.h @@ -0,0 +1,44 @@ +/** + * @file llfloaterchatvoicevolume.h + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 LLFLOATERCHATVOICEVOLUME_H_ +#define LLFLOATERCHATVOICEVOLUME_H_ + +#include "llinspect.h" +#include "lltransientfloatermgr.h" + +class LLFloaterChatVoiceVolume : public LLInspect, LLTransientFloater +{ +public: + + LLFloaterChatVoiceVolume(const LLSD& key); + virtual ~LLFloaterChatVoiceVolume(); + + virtual void onOpen(const LLSD& key); + + /*virtual*/ LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; } +}; + +#endif /* LLFLOATERCHATVOICEVOLUME_H_ */ diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index 659e52271a..a03425649f 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -62,10 +62,6 @@ #include <sstream> #include <iomanip> -const F32 CONTEXT_CONE_IN_ALPHA = 0.0f; -const F32 CONTEXT_CONE_OUT_ALPHA = 1.f; -const F32 CONTEXT_FADE_TIME = 0.08f; - ////////////////////////////////////////////////////////////////////////////// // // Class LLFloaterColorPicker @@ -105,7 +101,10 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show mSwatch ( swatch ), mActive ( TRUE ), mCanApplyImmediately ( show_apply_immediate ), - mContextConeOpacity ( 0.f ) + mContextConeOpacity ( 0.f ), + mContextConeInAlpha ( 0.f ), + mContextConeOutAlpha ( 0.f ), + mContextConeFadeTime ( 0.f ) { buildFromFile ( "floater_color_picker.xml"); @@ -117,6 +116,10 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show mApplyImmediateCheck->setEnabled(FALSE); mApplyImmediateCheck->set(FALSE); } + + mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha"); + mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha"); + mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime"); } LLFloaterColorPicker::~LLFloaterColorPicker() @@ -172,9 +175,9 @@ void LLFloaterColorPicker::createUI () // void LLFloaterColorPicker::showUI () { + openFloater(getKey()); setVisible ( TRUE ); setFocus ( TRUE ); - openFloater(getKey()); // HACK: if system color picker is required - close the SL one we made and use default system dialog if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) ) @@ -271,7 +274,7 @@ void LLFloaterColorPicker::destroyUI () if ( mSwatchView ) { this->removeChild ( mSwatchView ); - delete mSwatchView; + mSwatchView->die();; mSwatchView = NULL; } } @@ -486,37 +489,37 @@ void LLFloaterColorPicker::draw() mSwatch->localRectToOtherView(mSwatch->getLocalRect(), &swatch_rect, this); // draw context cone connecting color picker with color swatch in parent floater LLRect local_rect = getLocalRect(); - if (gFocusMgr.childHasKeyboardFocus(this) && mSwatch->isInVisibleChain() && mContextConeOpacity > 0.001f) + if (hasFocus() && mSwatch->isInVisibleChain() && mContextConeOpacity > 0.001f) { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLGLEnable(GL_CULL_FACE); gGL.begin(LLRender::QUADS); { - gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); + gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity); gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop); gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop); - gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); + gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity); gGL.vertex2i(local_rect.mRight, local_rect.mTop); gGL.vertex2i(local_rect.mLeft, local_rect.mTop); - gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); + gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity); gGL.vertex2i(local_rect.mLeft, local_rect.mTop); gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); - gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); + gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity); gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom); gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop); - gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); + gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity); gGL.vertex2i(local_rect.mRight, local_rect.mBottom); gGL.vertex2i(local_rect.mRight, local_rect.mTop); - gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); + gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity); gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop); gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom); - gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); + gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity); gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); gGL.vertex2i(local_rect.mRight, local_rect.mBottom); - gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); + gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity); gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom); gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom); } @@ -525,11 +528,12 @@ void LLFloaterColorPicker::draw() if (gFocusMgr.childHasMouseCapture(getDragHandle())) { - mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); + mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), + LLCriticalDamp::getInterpolant(mContextConeFadeTime)); } else { - mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); + mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime)); } mPipetteBtn->setToggleState(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h index 8e387c4f7c..bab0617712 100644 --- a/indra/newview/llfloatercolorpicker.h +++ b/indra/newview/llfloatercolorpicker.h @@ -189,6 +189,10 @@ class LLFloaterColorPicker LLButton* mPipetteBtn; F32 mContextConeOpacity; + F32 mContextConeInAlpha; + F32 mContextConeOutAlpha; + F32 mContextConeFadeTime; + }; #endif // LL_LLFLOATERCOLORPICKER_H diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp new file mode 100644 index 0000000000..4c910c5655 --- /dev/null +++ b/indra/newview/llfloaterconversationlog.cpp @@ -0,0 +1,134 @@ +/** + * @file llfloaterconversationlog.cpp + * @brief Functionality of the "conversation log" floater + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "llconversationloglist.h" +#include "llfiltereditor.h" +#include "llfloaterconversationlog.h" +#include "llfloaterreg.h" +#include "llmenubutton.h" + +LLFloaterConversationLog::LLFloaterConversationLog(const LLSD& key) +: LLFloater(key), + mConversationLogList(NULL) +{ + mCommitCallbackRegistrar.add("CallLog.Action", boost::bind(&LLFloaterConversationLog::onCustomAction, this, _2)); + mEnableCallbackRegistrar.add("CallLog.Check", boost::bind(&LLFloaterConversationLog::isActionChecked, this, _2)); +} + +BOOL LLFloaterConversationLog::postBuild() +{ + mConversationLogList = getChild<LLConversationLogList>("conversation_log_list"); + + switch (gSavedSettings.getU32("CallLogSortOrder")) + { + case LLConversationLogList::E_SORT_BY_NAME: + mConversationLogList->sortByName(); + break; + + case LLConversationLogList::E_SORT_BY_DATE: + mConversationLogList->sortByDate(); + break; + } + + // Use the context menu of the Conversation list for the Conversation tab gear menu. + LLToggleableMenu* conversations_gear_menu = mConversationLogList->getContextMenu(); + if (conversations_gear_menu) + { + getChild<LLMenuButton>("conversations_gear_btn")->setMenu(conversations_gear_menu, LLMenuButton::MP_BOTTOM_LEFT); + } + + getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterConversationLog::onFilterEdit, this, _2)); + + return LLFloater::postBuild(); +} + +void LLFloaterConversationLog::draw() +{ + getChild<LLMenuButton>("conversations_gear_btn")->setEnabled(mConversationLogList->getSelectedItem() != NULL); + LLFloater::draw(); +} + +void LLFloaterConversationLog::onFilterEdit(const std::string& search_string) +{ + std::string filter = search_string; + LLStringUtil::trimHead(filter); + + mConversationLogList->setNameFilter(filter); +} + + +void LLFloaterConversationLog::onCustomAction (const LLSD& userdata) +{ + const std::string command_name = userdata.asString(); + + if ("sort_by_name" == command_name) + { + mConversationLogList->sortByName(); + gSavedSettings.setU32("CallLogSortOrder", LLConversationLogList::E_SORT_BY_NAME); + } + else if ("sort_by_date" == command_name) + { + mConversationLogList->sortByDate(); + gSavedSettings.setU32("CallLogSortOrder", LLConversationLogList::E_SORT_BY_DATE); + } + else if ("sort_friends_on_top" == command_name) + { + mConversationLogList->toggleSortFriendsOnTop(); + } + else if ("view_nearby_chat_history" == command_name) + { + LLFloaterReg::showInstance("preview_conversation", LLSD(LLUUID::null), true); + } +} + +bool LLFloaterConversationLog::isActionEnabled(const LLSD& userdata) +{ + return true; +} + +bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata) +{ + const std::string command_name = userdata.asString(); + + U32 sort_order = gSavedSettings.getU32("CallLogSortOrder"); + + if ("sort_by_name" == command_name) + { + return sort_order == LLConversationLogList::E_SORT_BY_NAME; + } + else if ("sort_by_date" == command_name) + { + return sort_order == LLConversationLogList::E_SORT_BY_DATE; + } + else if ("sort_friends_on_top" == command_name) + { + return gSavedSettings.getBOOL("SortFriendsFirst"); + } + + return false; +} + diff --git a/indra/newview/llfloaterconversationlog.h b/indra/newview/llfloaterconversationlog.h new file mode 100644 index 0000000000..e971330f3d --- /dev/null +++ b/indra/newview/llfloaterconversationlog.h @@ -0,0 +1,56 @@ +/** + * @file llfloaterconversationlog.h + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLFLOATERCONVERSATIONLOG_H_ +#define LL_LLFLOATERCONVERSATIONLOG_H_ + +#include "llfloater.h" + +class LLConversationLogList; + +class LLFloaterConversationLog : public LLFloater +{ +public: + + LLFloaterConversationLog(const LLSD& key); + virtual ~LLFloaterConversationLog(){}; + + virtual BOOL postBuild(); + + virtual void draw(); + + void onFilterEdit(const std::string& search_string); + +private: + + void onCustomAction (const LLSD& userdata); + bool isActionEnabled(const LLSD& userdata); + bool isActionChecked(const LLSD& userdata); + + LLConversationLogList* mConversationLogList; +}; + + +#endif /* LLFLOATERCONVERSATIONLOG_H_ */ diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp new file mode 100644 index 0000000000..a3d715530d --- /dev/null +++ b/indra/newview/llfloaterconversationpreview.cpp @@ -0,0 +1,186 @@ +/** + * @file llfloaterconversationpreview.cpp + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "llconversationlog.h" +#include "llfloaterconversationpreview.h" +#include "llimview.h" +#include "lllineeditor.h" +#include "llfloaterimnearbychat.h" +#include "llspinctrl.h" +#include "lltrans.h" + +const std::string LL_FCP_COMPLETE_NAME("complete_name"); +const std::string LL_FCP_ACCOUNT_NAME("user_name"); + +LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_id) +: LLFloater(session_id), + mChatHistory(NULL), + mSessionID(session_id.asUUID()), + mCurrentPage(0), + mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize")), + mAccountName(session_id[LL_FCP_ACCOUNT_NAME]), + mCompleteName(session_id[LL_FCP_COMPLETE_NAME]) +{ +} + +BOOL LLFloaterConversationPreview::postBuild() +{ + mChatHistory = getChild<LLChatHistory>("chat_history"); + + const LLConversation* conv = LLConversationLog::instance().getConversation(mSessionID); + std::string name; + std::string file; + + if (mAccountName != "") + { + name = mCompleteName; + file = mAccountName; + } + else if (mSessionID != LLUUID::null && conv) + { + name = conv->getConversationName(); + file = conv->getHistoryFileName(); + } + else + { + name = LLTrans::getString("NearbyChatTitle"); + file = "chat"; + } + + LLStringUtil::format_map_t args; + args["[NAME]"] = name; + std::string title = getString("Title", args); + setTitle(title); + + LLSD load_params; + load_params["load_all_history"] = true; + load_params["cut_off_todays_date"] = false; + + LLLogChat::loadChatHistory(file, mMessages, load_params); + mCurrentPage = mMessages.size() / mPageSize; + + mPageSpinner = getChild<LLSpinCtrl>("history_page_spin"); + mPageSpinner->setCommitCallback(boost::bind(&LLFloaterConversationPreview::onMoreHistoryBtnClick, this)); + mPageSpinner->setMinValue(1); + mPageSpinner->setMaxValue(mCurrentPage + 1); + mPageSpinner->set(mCurrentPage + 1); + + std::string total_page_num = llformat("/ %d", mCurrentPage + 1); + getChild<LLTextBox>("page_num_label")->setValue(total_page_num); + + return LLFloater::postBuild(); +} + +void LLFloaterConversationPreview::draw() +{ + LLFloater::draw(); +} + +void LLFloaterConversationPreview::onOpen(const LLSD& key) +{ + showHistory(); +} + +void LLFloaterConversationPreview::showHistory() +{ + if (!mMessages.size()) + { + return; + } + + mChatHistory->clear(); + + std::ostringstream message; + std::list<LLSD>::const_iterator iter = mMessages.begin(); + + int delta = 0; + if (mCurrentPage) + { + int remainder = mMessages.size() % mPageSize; + delta = (remainder == 0) ? 0 : (mPageSize - remainder); + } + + std::advance(iter, (mCurrentPage * mPageSize) - delta); + + for (int msg_num = 0; (iter != mMessages.end() && msg_num < mPageSize); ++iter, ++msg_num) + { + LLSD msg = *iter; + + LLUUID from_id = LLUUID::null; + std::string time = msg["time"].asString(); + std::string from = msg["from"].asString(); + std::string message = msg["message"].asString(); + + if (msg["from_id"].isDefined()) + { + from_id = msg["from_id"].asUUID(); + } + else + { + std::string legacy_name = gCacheName->buildLegacyName(from); + gCacheName->getUUID(legacy_name, from_id); + } + + LLChat chat; + chat.mFromID = from_id; + chat.mSessionID = mSessionID; + chat.mFromName = from; + chat.mTimeStr = time; + chat.mChatStyle = CHAT_STYLE_HISTORY; + chat.mText = message; + + if (from_id.isNull() && SYSTEM_FROM == from) + { + chat.mSourceType = CHAT_SOURCE_SYSTEM; + + } + else if (from_id.isNull()) + { + chat.mSourceType = LLFloaterIMNearbyChat::isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT; + } + + LLSD chat_args; + chat_args["use_plain_text_chat_history"] = + gSavedSettings.getBOOL("PlainTextChatHistory"); + chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime"); + chat_args["show_names_for_p2p_conv"] = gSavedSettings.getBOOL("IMShowNamesForP2PConv"); + + mChatHistory->appendMessage(chat,chat_args); + } + +} + +void LLFloaterConversationPreview::onMoreHistoryBtnClick() +{ + mCurrentPage = (int)(mPageSpinner->getValueF32()); + if (--mCurrentPage < 0) + { + return; + } + + showHistory(); +} diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h new file mode 100644 index 0000000000..b17ae84b63 --- /dev/null +++ b/indra/newview/llfloaterconversationpreview.h @@ -0,0 +1,64 @@ +/** + * @file llfloaterconversationpreview.h + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 LLFLOATERCONVERSATIONPREVIEW_H_ +#define LLFLOATERCONVERSATIONPREVIEW_H_ + +#include "llchathistory.h" +#include "llfloater.h" + +extern const std::string LL_FCP_COMPLETE_NAME; //"complete_name" +extern const std::string LL_FCP_ACCOUNT_NAME; //"user_name" + +class LLSpinCtrl; + +class LLFloaterConversationPreview : public LLFloater +{ +public: + + LLFloaterConversationPreview(const LLSD& session_id); + virtual ~LLFloaterConversationPreview(){}; + + virtual BOOL postBuild(); + + virtual void draw(); + virtual void onOpen(const LLSD& key); + +private: + void onMoreHistoryBtnClick(); + void showHistory(); + + LLSpinCtrl* mPageSpinner; + LLChatHistory* mChatHistory; + LLUUID mSessionID; + int mCurrentPage; + int mPageSize; + + std::list<LLSD> mMessages; + std::string mAccountName; + std::string mCompleteName; +}; + +#endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */ diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp index ac8f107928..e2cef5630b 100644 --- a/indra/newview/llfloaterdisplayname.cpp +++ b/indra/newview/llfloaterdisplayname.cpp @@ -44,7 +44,7 @@ class LLFloaterDisplayName : public LLFloater { public: LLFloaterDisplayName(const LLSD& key); - virtual ~LLFloaterDisplayName() {}; + virtual ~LLFloaterDisplayName() { } /*virtual*/ BOOL postBuild(); void onSave(); void onReset(); @@ -58,8 +58,8 @@ private: const LLSD& content); }; -LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) - : LLFloater(key) +LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) : + LLFloater(key) { } @@ -122,10 +122,6 @@ void LLFloaterDisplayName::onCacheSetName(bool success, LLSD args; args["DISPLAY_NAME"] = content["display_name"]; LLNotificationsUtil::add("SetDisplayNameSuccess", args); - - // Re-fetch my name, as it may have been sanitized by the service - //LLAvatarNameCache::get(getAvatarId(), - // boost::bind(&LLPanelMyProfileEdit::onNameCache, this, _1, _2)); return; } @@ -164,10 +160,9 @@ void LLFloaterDisplayName::onCancel() void LLFloaterDisplayName::onReset() { - if (LLAvatarNameCache::useDisplayNames()) + if (LLAvatarNameCache::hasNameLookupURL()) { - LLViewerDisplayName::set("", - boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3)); + LLViewerDisplayName::set("",boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3)); } else { @@ -199,10 +194,9 @@ void LLFloaterDisplayName::onSave() return; } - if (LLAvatarNameCache::useDisplayNames()) + if (LLAvatarNameCache::hasNameLookupURL()) { - LLViewerDisplayName::set(display_name_utf8, - boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3)); + LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3)); } else { diff --git a/indra/newview/llfloatereditsky.cpp b/indra/newview/llfloatereditsky.cpp index abee7b5dc9..352361ce9e 100644 --- a/indra/newview/llfloatereditsky.cpp +++ b/indra/newview/llfloatereditsky.cpp @@ -151,8 +151,8 @@ void LLFloaterEditSky::initCallbacks(void) getChild<LLUICtrl>("WLBlueHorizon")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, ¶m_mgr.mBlueHorizon)); // haze density, horizon, mult, and altitude - getChild<LLUICtrl>("WLHazeDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mHazeDensity)); - getChild<LLUICtrl>("WLHazeHorizon")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mHazeHorizon)); + getChild<LLUICtrl>("WLHazeDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mHazeDensity)); + getChild<LLUICtrl>("WLHazeHorizon")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mHazeHorizon)); getChild<LLUICtrl>("WLDensityMult")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mDensityMult)); getChild<LLUICtrl>("WLMaxAltitude")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mMaxAlt)); @@ -220,15 +220,14 @@ void LLFloaterEditSky::syncControls() setColorSwatch("WLBlueHorizon", param_mgr->mBlueHorizon, WL_BLUE_HORIZON_DENSITY_SCALE); // haze density, horizon, mult, and altitude - param_mgr->mHazeDensity = cur_params.getVector(param_mgr->mHazeDensity.mName, err); - childSetValue("WLHazeDensity", param_mgr->mHazeDensity.r); - param_mgr->mHazeHorizon = cur_params.getVector(param_mgr->mHazeHorizon.mName, err); - childSetValue("WLHazeHorizon", param_mgr->mHazeHorizon.r); - param_mgr->mDensityMult = cur_params.getVector(param_mgr->mDensityMult.mName, err); - childSetValue("WLDensityMult", param_mgr->mDensityMult.x * - param_mgr->mDensityMult.mult); - param_mgr->mMaxAlt = cur_params.getVector(param_mgr->mMaxAlt.mName, err); - childSetValue("WLMaxAltitude", param_mgr->mMaxAlt.x); + param_mgr->mHazeDensity = cur_params.getFloat(param_mgr->mHazeDensity.mName, err); + childSetValue("WLHazeDensity", (F32) param_mgr->mHazeDensity); + param_mgr->mHazeHorizon = cur_params.getFloat(param_mgr->mHazeHorizon.mName, err); + childSetValue("WLHazeHorizon", (F32) param_mgr->mHazeHorizon); + param_mgr->mDensityMult = cur_params.getFloat(param_mgr->mDensityMult.mName, err); + childSetValue("WLDensityMult", ((F32) param_mgr->mDensityMult) * param_mgr->mDensityMult.mult); + param_mgr->mMaxAlt = cur_params.getFloat(param_mgr->mMaxAlt.mName, err); + childSetValue("WLMaxAltitude", (F32) param_mgr->mMaxAlt); // blue density param_mgr->mBlueDensity = cur_params.getVector(param_mgr->mBlueDensity.mName, err); @@ -273,10 +272,10 @@ void LLFloaterEditSky::syncControls() childSetValue("WLCloudDetailDensity", param_mgr->mCloudDetail.b); // Cloud extras - param_mgr->mCloudCoverage = cur_params.getVector(param_mgr->mCloudCoverage.mName, err); - param_mgr->mCloudScale = cur_params.getVector(param_mgr->mCloudScale.mName, err); - childSetValue("WLCloudCoverage", param_mgr->mCloudCoverage.x); - childSetValue("WLCloudScale", param_mgr->mCloudScale.x); + param_mgr->mCloudCoverage = cur_params.getFloat(param_mgr->mCloudCoverage.mName, err); + param_mgr->mCloudScale = cur_params.getFloat(param_mgr->mCloudScale.mName, err); + childSetValue("WLCloudCoverage", (F32) param_mgr->mCloudCoverage); + childSetValue("WLCloudScale", (F32) param_mgr->mCloudScale); // cloud scrolling bool lockX = !param_mgr->mCurParams.getEnableCloudScrollX(); @@ -306,13 +305,13 @@ void LLFloaterEditSky::syncControls() childSetValue("WLCloudScrollX", param_mgr->mCurParams.getCloudScrollX() - 10.0f); childSetValue("WLCloudScrollY", param_mgr->mCurParams.getCloudScrollY() - 10.0f); - param_mgr->mDistanceMult = cur_params.getVector(param_mgr->mDistanceMult.mName, err); - childSetValue("WLDistanceMult", param_mgr->mDistanceMult.x); + param_mgr->mDistanceMult = cur_params.getFloat(param_mgr->mDistanceMult.mName, err); + childSetValue("WLDistanceMult", (F32) param_mgr->mDistanceMult); // Tweak extras - param_mgr->mWLGamma = cur_params.getVector(param_mgr->mWLGamma.mName, err); - childSetValue("WLGamma", param_mgr->mWLGamma.x); + param_mgr->mWLGamma = cur_params.getFloat(param_mgr->mWLGamma.mName, err); + childSetValue("WLGamma", (F32) param_mgr->mWLGamma); childSetValue("WLStarAlpha", param_mgr->mCurParams.getStarBrightness()); } diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp deleted file mode 100644 index f93568d617..0000000000 --- a/indra/newview/llfloaterfriends.cpp +++ /dev/null @@ -1,807 +0,0 @@ -/** - * @file llfloaterfriends.cpp - * @author Phoenix - * @date 2005-01-13 - * @brief Implementation of the friends floater - * - * $LicenseInfo:firstyear=2005&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 "llfloaterfriends.h" - -#include <sstream> - -#include "lldir.h" - -#include "llagent.h" -#include "llappviewer.h" // for gLastVersionChannel -#include "llfloateravatarpicker.h" -#include "llviewerwindow.h" -#include "llbutton.h" -#include "llavataractions.h" -#include "llinventorymodel.h" -#include "llnamelistctrl.h" -#include "llnotificationsutil.h" -#include "llresmgr.h" -#include "llscrolllistctrl.h" -#include "llscrolllistitem.h" -#include "llscrolllistcell.h" -#include "lluictrlfactory.h" -#include "llmenucommands.h" -#include "llviewercontrol.h" -#include "llviewermessage.h" -#include "lleventtimer.h" -#include "lltextbox.h" -#include "llvoiceclient.h" - -// *TODO: Move more common stuff to LLAvatarActions? - -//Maximum number of people you can select to do an operation on at once. -#define MAX_FRIEND_SELECT 20 -#define DEFAULT_PERIOD 5.0 -#define RIGHTS_CHANGE_TIMEOUT 5.0 -#define OBSERVER_TIMEOUT 0.5 - -#define ONLINE_SIP_ICON_NAME "slim_icon_16_viewer.tga" - -// simple class to observe the calling cards. -class LLLocalFriendsObserver : public LLFriendObserver, public LLEventTimer -{ -public: - LLLocalFriendsObserver(LLPanelFriends* floater) : mFloater(floater), LLEventTimer(OBSERVER_TIMEOUT) - { - mEventTimer.stop(); - } - virtual ~LLLocalFriendsObserver() - { - mFloater = NULL; - } - virtual void changed(U32 mask) - { - // events can arrive quickly in bulk - we need not process EVERY one of them - - // so we wait a short while to let others pile-in, and process them in aggregate. - mEventTimer.start(); - - // save-up all the mask-bits which have come-in - mMask |= mask; - } - virtual BOOL tick() - { - mFloater->updateFriends(mMask); - - mEventTimer.stop(); - mMask = 0; - - return FALSE; - } - -protected: - LLPanelFriends* mFloater; - U32 mMask; -}; - -LLPanelFriends::LLPanelFriends() : - LLPanel(), - LLEventTimer(DEFAULT_PERIOD), - mObserver(NULL), - mShowMaxSelectWarning(TRUE), - mAllowRightsChange(TRUE), - mNumRightsChanged(0) -{ - mEventTimer.stop(); - mObserver = new LLLocalFriendsObserver(this); - LLAvatarTracker::instance().addObserver(mObserver); - // For notification when SIP online status changes. - LLVoiceClient::getInstance()->addObserver(mObserver); -} - -LLPanelFriends::~LLPanelFriends() -{ - // For notification when SIP online status changes. - LLVoiceClient::getInstance()->removeObserver(mObserver); - LLAvatarTracker::instance().removeObserver(mObserver); - delete mObserver; -} - -BOOL LLPanelFriends::tick() -{ - mEventTimer.stop(); - mPeriod = DEFAULT_PERIOD; - mAllowRightsChange = TRUE; - updateFriends(LLFriendObserver::ADD); - return FALSE; -} - -void LLPanelFriends::updateFriends(U32 changed_mask) -{ - LLUUID selected_id; - LLCtrlListInterface *friends_list = childGetListInterface("friend_list"); - if (!friends_list) return; - LLCtrlScrollInterface *friends_scroll = childGetScrollInterface("friend_list"); - if (!friends_scroll) return; - - // We kill the selection warning, otherwise we'll spam with warning popups - // if the maximum amount of friends are selected - mShowMaxSelectWarning = false; - - std::vector<LLUUID> selected_friends = getSelectedIDs(); - if(changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE)) - { - refreshNames(changed_mask); - } - else if(changed_mask & LLFriendObserver::POWERS) - { - --mNumRightsChanged; - if(mNumRightsChanged > 0) - { - mPeriod = RIGHTS_CHANGE_TIMEOUT; - mEventTimer.start(); - mAllowRightsChange = FALSE; - } - else - { - tick(); - } - } - if(selected_friends.size() > 0) - { - // only non-null if friends was already found. This may fail, - // but we don't really care here, because refreshUI() will - // clean up the interface. - friends_list->setCurrentByID(selected_id); - for(std::vector<LLUUID>::iterator itr = selected_friends.begin(); itr != selected_friends.end(); ++itr) - { - friends_list->setSelectedByValue(*itr, true); - } - } - - refreshUI(); - mShowMaxSelectWarning = true; -} - -// virtual -BOOL LLPanelFriends::postBuild() -{ - mFriendsList = getChild<LLScrollListCtrl>("friend_list"); - mFriendsList->setMaxSelectable(MAX_FRIEND_SELECT); - mFriendsList->setMaximumSelectCallback(boost::bind(&LLPanelFriends::onMaximumSelect)); - mFriendsList->setCommitOnSelectionChange(TRUE); - mFriendsList->setContextMenu(LLScrollListCtrl::MENU_AVATAR); - childSetCommitCallback("friend_list", onSelectName, this); - getChild<LLScrollListCtrl>("friend_list")->setDoubleClickCallback(onClickIM, this); - - U32 changed_mask = LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE; - refreshNames(changed_mask); - - childSetAction("im_btn", onClickIM, this); - childSetAction("profile_btn", onClickProfile, this); - childSetAction("offer_teleport_btn", onClickOfferTeleport, this); - childSetAction("pay_btn", onClickPay, this); - childSetAction("add_btn", onClickAddFriend, this); - childSetAction("remove_btn", onClickRemove, this); - - setDefaultBtn("im_btn"); - - updateFriends(LLFriendObserver::ADD); - refreshUI(); - - // primary sort = online status, secondary sort = name - mFriendsList->sortByColumn(std::string("friend_name"), TRUE); - mFriendsList->sortByColumn(std::string("icon_online_status"), FALSE); - - return TRUE; -} - -BOOL LLPanelFriends::addFriend(const LLUUID& agent_id) -{ - LLAvatarTracker& at = LLAvatarTracker::instance(); - const LLRelationship* relationInfo = at.getBuddyInfo(agent_id); - if(!relationInfo) return FALSE; - - bool isOnlineSIP = LLVoiceClient::getInstance()->isOnlineSIP(agent_id); - bool isOnline = relationInfo->isOnline(); - - std::string fullname; - BOOL have_name = gCacheName->getFullName(agent_id, fullname); - - LLSD element; - element["id"] = agent_id; - LLSD& friend_column = element["columns"][LIST_FRIEND_NAME]; - friend_column["column"] = "friend_name"; - friend_column["value"] = fullname; - friend_column["font"]["name"] = "SANSSERIF"; - friend_column["font"]["style"] = "NORMAL"; - - LLSD& online_status_column = element["columns"][LIST_ONLINE_STATUS]; - online_status_column["column"] = "icon_online_status"; - online_status_column["type"] = "icon"; - - if (isOnline) - { - friend_column["font"]["style"] = "BOLD"; - online_status_column["value"] = "icon_avatar_online.tga"; - } - else if(isOnlineSIP) - { - friend_column["font"]["style"] = "BOLD"; - online_status_column["value"] = ONLINE_SIP_ICON_NAME; - } - - LLSD& online_column = element["columns"][LIST_VISIBLE_ONLINE]; - online_column["column"] = "icon_visible_online"; - online_column["type"] = "checkbox"; - online_column["value"] = relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS); - - LLSD& visible_map_column = element["columns"][LIST_VISIBLE_MAP]; - visible_map_column["column"] = "icon_visible_map"; - visible_map_column["type"] = "checkbox"; - visible_map_column["value"] = relationInfo->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION); - - LLSD& edit_my_object_column = element["columns"][LIST_EDIT_MINE]; - edit_my_object_column["column"] = "icon_edit_mine"; - edit_my_object_column["type"] = "checkbox"; - edit_my_object_column["value"] = relationInfo->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS); - - LLSD& edit_their_object_column = element["columns"][LIST_EDIT_THEIRS]; - edit_their_object_column["column"] = "icon_edit_theirs"; - edit_their_object_column["type"] = "checkbox"; - edit_their_object_column["enabled"] = ""; - edit_their_object_column["value"] = relationInfo->isRightGrantedFrom(LLRelationship::GRANT_MODIFY_OBJECTS); - - LLSD& update_gen_column = element["columns"][LIST_FRIEND_UPDATE_GEN]; - update_gen_column["column"] = "friend_last_update_generation"; - update_gen_column["value"] = have_name ? relationInfo->getChangeSerialNum() : -1; - - mFriendsList->addElement(element, ADD_BOTTOM); - return have_name; -} - -// propagate actual relationship to UI. -// Does not resort the UI list because it can be called frequently. JC -BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationship* info) -{ - if (!info) return FALSE; - LLScrollListItem* itemp = mFriendsList->getItem(agent_id); - if (!itemp) return FALSE; - - bool isOnlineSIP = LLVoiceClient::getInstance()->isOnlineSIP(itemp->getUUID()); - bool isOnline = info->isOnline(); - - std::string fullname; - BOOL have_name = gCacheName->getFullName(agent_id, fullname); - - // Name of the status icon to use - std::string statusIcon; - - if(isOnline) - { - statusIcon = "icon_avatar_online.tga"; - } - else if(isOnlineSIP) - { - statusIcon = ONLINE_SIP_ICON_NAME; - } - - itemp->getColumn(LIST_ONLINE_STATUS)->setValue(statusIcon); - - itemp->getColumn(LIST_FRIEND_NAME)->setValue(fullname); - // render name of online friends in bold text - ((LLScrollListText*)itemp->getColumn(LIST_FRIEND_NAME))->setFontStyle((isOnline || isOnlineSIP) ? LLFontGL::BOLD : LLFontGL::NORMAL); - itemp->getColumn(LIST_VISIBLE_ONLINE)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS)); - itemp->getColumn(LIST_VISIBLE_MAP)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION)); - itemp->getColumn(LIST_EDIT_MINE)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS)); - S32 change_generation = have_name ? info->getChangeSerialNum() : -1; - itemp->getColumn(LIST_FRIEND_UPDATE_GEN)->setValue(change_generation); - - // enable this item, in case it was disabled after user input - itemp->setEnabled(TRUE); - - // Do not resort, this function can be called frequently. - return have_name; -} - -void LLPanelFriends::refreshRightsChangeList() -{ - std::vector<LLUUID> friends = getSelectedIDs(); - S32 num_selected = friends.size(); - - bool can_offer_teleport = num_selected >= 1; - bool selected_friends_online = true; - - const LLRelationship* friend_status = NULL; - for(std::vector<LLUUID>::iterator itr = friends.begin(); itr != friends.end(); ++itr) - { - friend_status = LLAvatarTracker::instance().getBuddyInfo(*itr); - if (friend_status) - { - if(!friend_status->isOnline()) - { - can_offer_teleport = false; - selected_friends_online = false; - } - } - else // missing buddy info, don't allow any operations - { - can_offer_teleport = false; - } - } - - if (num_selected == 0) // nothing selected - { - childSetEnabled("im_btn", FALSE); - childSetEnabled("offer_teleport_btn", FALSE); - } - else // we have at least one friend selected... - { - // only allow IMs to groups when everyone in the group is online - // to be consistent with context menus in inventory and because otherwise - // offline friends would be silently dropped from the session - childSetEnabled("im_btn", selected_friends_online || num_selected == 1); - childSetEnabled("offer_teleport_btn", can_offer_teleport); - } -} - -struct SortFriendsByID -{ - bool operator() (const LLScrollListItem* const a, const LLScrollListItem* const b) const - { - return a->getValue().asUUID() < b->getValue().asUUID(); - } -}; - -void LLPanelFriends::refreshNames(U32 changed_mask) -{ - std::vector<LLUUID> selected_ids = getSelectedIDs(); - S32 pos = mFriendsList->getScrollPos(); - - // get all buddies we know about - LLAvatarTracker::buddy_map_t all_buddies; - LLAvatarTracker::instance().copyBuddyList(all_buddies); - - BOOL have_names = TRUE; - - if(changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE)) - { - have_names &= refreshNamesSync(all_buddies); - } - - if(changed_mask & LLFriendObserver::ONLINE) - { - have_names &= refreshNamesPresence(all_buddies); - } - - if (!have_names) - { - mEventTimer.start(); - } - // Changed item in place, need to request sort and update columns - // because we might have changed data in a column on which the user - // has already sorted. JC - mFriendsList->updateSort(); - - // re-select items - mFriendsList->selectMultiple(selected_ids); - mFriendsList->setScrollPos(pos); -} - -BOOL LLPanelFriends::refreshNamesSync(const LLAvatarTracker::buddy_map_t & all_buddies) -{ - mFriendsList->deleteAllItems(); - - BOOL have_names = TRUE; - LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin(); - - for(; buddy_it != all_buddies.end(); ++buddy_it) - { - have_names &= addFriend(buddy_it->first); - } - - return have_names; -} - -BOOL LLPanelFriends::refreshNamesPresence(const LLAvatarTracker::buddy_map_t & all_buddies) -{ - std::vector<LLScrollListItem*> items = mFriendsList->getAllData(); - std::sort(items.begin(), items.end(), SortFriendsByID()); - - LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin(); - std::vector<LLScrollListItem*>::const_iterator item_it = items.begin(); - BOOL have_names = TRUE; - - while(true) - { - if(item_it == items.end() || buddy_it == all_buddies.end()) - { - break; - } - - const LLUUID & buddy_uuid = buddy_it->first; - const LLUUID & item_uuid = (*item_it)->getValue().asUUID(); - if(item_uuid == buddy_uuid) - { - const LLRelationship* info = buddy_it->second; - if (!info) - { - ++item_it; - continue; - } - - S32 last_change_generation = (*item_it)->getColumn(LIST_FRIEND_UPDATE_GEN)->getValue().asInteger(); - if (last_change_generation < info->getChangeSerialNum()) - { - // update existing item in UI - have_names &= updateFriendItem(buddy_it->first, info); - } - - ++buddy_it; - ++item_it; - } - else if(item_uuid < buddy_uuid) - { - ++item_it; - } - else //if(item_uuid > buddy_uuid) - { - ++buddy_it; - } - } - - return have_names; -} - -void LLPanelFriends::refreshUI() -{ - BOOL single_selected = FALSE; - BOOL multiple_selected = FALSE; - int num_selected = mFriendsList->getAllSelected().size(); - if(num_selected > 0) - { - single_selected = TRUE; - if(num_selected > 1) - { - multiple_selected = TRUE; - } - } - - - //Options that can only be performed with one friend selected - childSetEnabled("profile_btn", single_selected && !multiple_selected); - childSetEnabled("pay_btn", single_selected && !multiple_selected); - - //Options that can be performed with up to MAX_FRIEND_SELECT friends selected - //(single_selected will always be true in this situations) - childSetEnabled("remove_btn", single_selected); - childSetEnabled("im_btn", single_selected); -// childSetEnabled("friend_rights", single_selected); - - refreshRightsChangeList(); -} - -std::vector<LLUUID> LLPanelFriends::getSelectedIDs() -{ - LLUUID selected_id; - std::vector<LLUUID> friend_ids; - std::vector<LLScrollListItem*> selected = mFriendsList->getAllSelected(); - for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr) - { - friend_ids.push_back((*itr)->getUUID()); - } - return friend_ids; -} - -// static -void LLPanelFriends::onSelectName(LLUICtrl* ctrl, void* user_data) -{ - LLPanelFriends* panelp = (LLPanelFriends*)user_data; - - if(panelp) - { - panelp->refreshUI(); - // check to see if rights have changed - panelp->applyRightsToFriends(); - } -} - -//static -void LLPanelFriends::onMaximumSelect() -{ - LLSD args; - args["MAX_SELECT"] = llformat("%d", MAX_FRIEND_SELECT); - LLNotificationsUtil::add("MaxListSelectMessage", args); -}; - -// static -void LLPanelFriends::onClickProfile(void* user_data) -{ - LLPanelFriends* panelp = (LLPanelFriends*)user_data; - - std::vector<LLUUID> ids = panelp->getSelectedIDs(); - if(ids.size() > 0) - { - LLUUID agent_id = ids[0]; - LLAvatarActions::showProfile(agent_id); - } -} - -// static -void LLPanelFriends::onClickIM(void* user_data) -{ - LLPanelFriends* panelp = (LLPanelFriends*)user_data; - - std::vector<LLUUID> ids = panelp->getSelectedIDs(); - if(ids.size() > 0) - { - if(ids.size() == 1) - { - LLAvatarActions::startIM(ids[0]); - } - else - { - LLAvatarActions::startConference(ids); - } - } -} - -// static -void LLPanelFriends::onPickAvatar(const std::vector<std::string>& names, - const std::vector<LLUUID>& ids) -{ - if (names.empty()) return; - if (ids.empty()) return; - LLAvatarActions::requestFriendshipDialog(ids[0], names[0]); -} - -// static -void LLPanelFriends::onClickAddFriend(void* user_data) -{ - LLPanelFriends* panelp = (LLPanelFriends*)user_data; - LLFloater* root_floater = gFloaterView->getParentFloater(panelp); - LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelFriends::onPickAvatar, _1,_2), FALSE, TRUE); - if (root_floater) - { - root_floater->addDependentFloater(picker); - } -} - -// static -void LLPanelFriends::onClickRemove(void* user_data) -{ - LLPanelFriends* panelp = (LLPanelFriends*)user_data; - LLAvatarActions::removeFriendsDialog(panelp->getSelectedIDs()); -} - -// static -void LLPanelFriends::onClickOfferTeleport(void* user_data) -{ - LLPanelFriends* panelp = (LLPanelFriends*)user_data; - LLAvatarActions::offerTeleport(panelp->getSelectedIDs()); -} - -// static -void LLPanelFriends::onClickPay(void* user_data) -{ - LLPanelFriends* panelp = (LLPanelFriends*)user_data; - - std::vector<LLUUID> ids = panelp->getSelectedIDs(); - if(ids.size() == 1) - { - LLAvatarActions::pay(ids[0]); - } -} - -void LLPanelFriends::confirmModifyRights(rights_map_t& ids, EGrantRevoke command) -{ - if (ids.empty()) return; - - LLSD args; - if(ids.size() > 0) - { - rights_map_t* rights = new rights_map_t(ids); - - // for single friend, show their name - if(ids.size() == 1) - { - LLUUID agent_id = ids.begin()->first; - std::string first, last; - if(gCacheName->getName(agent_id, first, last)) - { - args["FIRST_NAME"] = first; - args["LAST_NAME"] = last; - } - if (command == GRANT) - { - LLNotificationsUtil::add("GrantModifyRights", - args, - LLSD(), - boost::bind(&LLPanelFriends::modifyRightsConfirmation, this, _1, _2, rights)); - } - else - { - LLNotificationsUtil::add("RevokeModifyRights", - args, - LLSD(), - boost::bind(&LLPanelFriends::modifyRightsConfirmation, this, _1, _2, rights)); - } - } - else - { - if (command == GRANT) - { - LLNotificationsUtil::add("GrantModifyRightsMultiple", - args, - LLSD(), - boost::bind(&LLPanelFriends::modifyRightsConfirmation, this, _1, _2, rights)); - } - else - { - LLNotificationsUtil::add("RevokeModifyRightsMultiple", - args, - LLSD(), - boost::bind(&LLPanelFriends::modifyRightsConfirmation, this, _1, _2, rights)); - } - } - } -} - -bool LLPanelFriends::modifyRightsConfirmation(const LLSD& notification, const LLSD& response, rights_map_t* rights) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if(0 == option) - { - sendRightsGrant(*rights); - } - else - { - // need to resync view with model, since user cancelled operation - rights_map_t::iterator rights_it; - for (rights_it = rights->begin(); rights_it != rights->end(); ++rights_it) - { - const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(rights_it->first); - updateFriendItem(rights_it->first, info); - } - } - refreshUI(); - - delete rights; - return false; -} - -void LLPanelFriends::applyRightsToFriends() -{ - BOOL rights_changed = FALSE; - - // store modify rights separately for confirmation - rights_map_t rights_updates; - - BOOL need_confirmation = FALSE; - EGrantRevoke confirmation_type = GRANT; - - // this assumes that changes only happened to selected items - std::vector<LLScrollListItem*> selected = mFriendsList->getAllSelected(); - for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr) - { - LLUUID id = (*itr)->getValue(); - const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(id); - if (buddy_relationship == NULL) continue; - - bool show_online_staus = (*itr)->getColumn(LIST_VISIBLE_ONLINE)->getValue().asBoolean(); - bool show_map_location = (*itr)->getColumn(LIST_VISIBLE_MAP)->getValue().asBoolean(); - bool allow_modify_objects = (*itr)->getColumn(LIST_EDIT_MINE)->getValue().asBoolean(); - - S32 rights = buddy_relationship->getRightsGrantedTo(); - if(buddy_relationship->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS) != show_online_staus) - { - rights_changed = TRUE; - if(show_online_staus) - { - rights |= LLRelationship::GRANT_ONLINE_STATUS; - } - else - { - // ONLINE_STATUS necessary for MAP_LOCATION - rights &= ~LLRelationship::GRANT_ONLINE_STATUS; - rights &= ~LLRelationship::GRANT_MAP_LOCATION; - // propagate rights constraint to UI - (*itr)->getColumn(LIST_VISIBLE_MAP)->setValue(FALSE); - } - } - if(buddy_relationship->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION) != show_map_location) - { - rights_changed = TRUE; - if(show_map_location) - { - // ONLINE_STATUS necessary for MAP_LOCATION - rights |= LLRelationship::GRANT_MAP_LOCATION; - rights |= LLRelationship::GRANT_ONLINE_STATUS; - (*itr)->getColumn(LIST_VISIBLE_ONLINE)->setValue(TRUE); - } - else - { - rights &= ~LLRelationship::GRANT_MAP_LOCATION; - } - } - - // now check for change in modify object rights, which requires confirmation - if(buddy_relationship->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects) - { - rights_changed = TRUE; - need_confirmation = TRUE; - - if(allow_modify_objects) - { - rights |= LLRelationship::GRANT_MODIFY_OBJECTS; - confirmation_type = GRANT; - } - else - { - rights &= ~LLRelationship::GRANT_MODIFY_OBJECTS; - confirmation_type = REVOKE; - } - } - - if (rights_changed) - { - rights_updates.insert(std::make_pair(id, rights)); - // disable these ui elements until response from server - // to avoid race conditions - (*itr)->setEnabled(FALSE); - } - } - - // separately confirm grant and revoke of modify rights - if (need_confirmation) - { - confirmModifyRights(rights_updates, confirmation_type); - } - else - { - sendRightsGrant(rights_updates); - } -} - -void LLPanelFriends::sendRightsGrant(rights_map_t& ids) -{ - if (ids.empty()) return; - - LLMessageSystem* msg = gMessageSystem; - - // setup message header - msg->newMessageFast(_PREHASH_GrantUserRights); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUID(_PREHASH_AgentID, gAgent.getID()); - msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); - - rights_map_t::iterator id_it; - rights_map_t::iterator end_it = ids.end(); - for(id_it = ids.begin(); id_it != end_it; ++id_it) - { - msg->nextBlockFast(_PREHASH_Rights); - msg->addUUID(_PREHASH_AgentRelated, id_it->first); - msg->addS32(_PREHASH_RelatedRights, id_it->second); - } - - mNumRightsChanged = ids.size(); - gAgent.sendReliableMessage(); -} diff --git a/indra/newview/llfloaterfriends.h b/indra/newview/llfloaterfriends.h deleted file mode 100644 index a303477c95..0000000000 --- a/indra/newview/llfloaterfriends.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file llfloaterfriends.h - * @author Phoenix - * @date 2005-01-13 - * @brief Declaration of class for displaying the local agent's friends. - * - * $LicenseInfo:firstyear=2005&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_LLFLOATERFRIENDS_H -#define LL_LLFLOATERFRIENDS_H - -#include "llpanel.h" -#include "llstring.h" -#include "lluuid.h" -#include "lltimer.h" -#include "llcallingcard.h" - -class LLFriendObserver; -class LLRelationship; -class LLScrollListItem; -class LLScrollListCtrl; - -/** - * @class LLPanelFriends - * @brief An instance of this class is used for displaying your friends - * and gives you quick access to all agents which a user relationship. - * - * @sa LLFloater - */ -class LLPanelFriends : public LLPanel, public LLEventTimer -{ -public: - LLPanelFriends(); - virtual ~LLPanelFriends(); - - /** - * @brief This method either creates or brings to the front the - * current instantiation of this floater. There is only once since - * you can currently only look at your local friends. - */ - virtual BOOL tick(); - - /** - * @brief This method is called in response to the LLAvatarTracker - * sending out a changed() message. - */ - void updateFriends(U32 changed_mask); - - virtual BOOL postBuild(); - - // *HACK Made public to remove friends from LLAvatarIconCtrl context menu - static bool handleRemove(const LLSD& notification, const LLSD& response); - -private: - - enum FRIENDS_COLUMN_ORDER - { - LIST_ONLINE_STATUS, - LIST_FRIEND_NAME, - LIST_VISIBLE_ONLINE, - LIST_VISIBLE_MAP, - LIST_EDIT_MINE, - LIST_EDIT_THEIRS, - LIST_FRIEND_UPDATE_GEN - }; - - // protected members - typedef std::map<LLUUID, S32> rights_map_t; - void refreshNames(U32 changed_mask); - BOOL refreshNamesSync(const LLAvatarTracker::buddy_map_t & all_buddies); - BOOL refreshNamesPresence(const LLAvatarTracker::buddy_map_t & all_buddies); - void refreshUI(); - void refreshRightsChangeList(); - void applyRightsToFriends(); - BOOL addFriend(const LLUUID& agent_id); - BOOL updateFriendItem(const LLUUID& agent_id, const LLRelationship* relationship); - - typedef enum - { - GRANT, - REVOKE - } EGrantRevoke; - void confirmModifyRights(rights_map_t& ids, EGrantRevoke command); - void sendRightsGrant(rights_map_t& ids); - - // return empty vector if nothing is selected - std::vector<LLUUID> getSelectedIDs(); - - // callback methods - static void onSelectName(LLUICtrl* ctrl, void* user_data); - static bool callbackAddFriend(const LLSD& notification, const LLSD& response); - static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response); - static void onPickAvatar(const std::vector<std::string>& names, const std::vector<LLUUID>& ids); - static void onMaximumSelect(); - - static void onClickIM(void* user_data); - static void onClickProfile(void* user_data); - static void onClickAddFriend(void* user_data); - static void onClickRemove(void* user_data); - - static void onClickOfferTeleport(void* user_data); - static void onClickPay(void* user_data); - - static void onClickModifyStatus(LLUICtrl* ctrl, void* user_data); - - bool modifyRightsConfirmation(const LLSD& notification, const LLSD& response, rights_map_t* rights); - -private: - // member data - LLFriendObserver* mObserver; - LLUUID mAddFriendID; - std::string mAddFriendName; - LLScrollListCtrl* mFriendsList; - BOOL mShowMaxSelectWarning; - BOOL mAllowRightsChange; - S32 mNumRightsChanged; -}; - - -#endif // LL_LLFLOATERFRIENDS_H diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index d495f20a9a..56051ff684 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -32,7 +32,7 @@ #include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" -#include "llinventoryclipboard.h" +#include "llclipboard.h" #include "llagent.h" #include "llappearancemgr.h" @@ -90,6 +90,12 @@ public: if(mFloater) { mFloater->addGesture(inv_item,NULL,mFloater->getChild<LLScrollListCtrl>("gesture_list")); + + // EXP-1909 (Pasted gesture displayed twice) + // The problem is that addGesture is called here for the second time for the same item (which is copied) + // First time addGesture is called from LLFloaterGestureObserver::changed(), which is a callback for inventory + // change. So we need to refresh the gesture list to avoid duplicates. + mFloater->refreshAll(); } } }; @@ -391,11 +397,11 @@ bool LLFloaterGesture::isActionEnabled(const LLSD& command) std::string command_name = command.asString(); if("paste" == command_name) { - if(!LLInventoryClipboard::instance().hasContents()) + if(!LLClipboard::instance().hasContents()) return false; LLDynamicArray<LLUUID> ids; - LLInventoryClipboard::instance().retrieve(ids); + LLClipboard::instance().pasteFromClipboard(ids); for(LLDynamicArray<LLUUID>::iterator it = ids.begin(); it != ids.end(); it++) { LLInventoryItem* item = gInventory.getItem(*it); @@ -490,27 +496,26 @@ void LLFloaterGesture::onActivateBtnClick() void LLFloaterGesture::onCopyPasteAction(const LLSD& command) { std::string command_name = command.asString(); - // since we select this comman inventory item had already arrived . + // Since we select this command, the inventory items must have already arrived if("copy_gesture" == command_name) { uuid_vec_t ids; getSelectedIds(ids); - // make sure that clopboard is empty - LLInventoryClipboard::instance().reset(); + // Make sure the clipboard is empty + LLClipboard::instance().reset(); for(uuid_vec_t::iterator it = ids.begin(); it != ids.end(); it++) { LLInventoryItem* item = gInventory.getItem(*it); if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE) { - LLInventoryClipboard::instance().add(item->getUUID()); + LLClipboard::instance().addToClipboard(item->getUUID(),LLAssetType::AT_GESTURE); } } } else if ("paste" == command_name) { - LLInventoryClipboard& clipbord = LLInventoryClipboard::instance(); LLDynamicArray<LLUUID> ids; - clipbord.retrieve(ids); + LLClipboard::instance().pasteFromClipboard(ids); if(ids.empty() || !gInventory.isCategoryComplete(mGestureFolderID)) return; LLInventoryCategory* gesture_dir = gInventory.getCategory(mGestureFolderID); @@ -530,11 +535,11 @@ void LLFloaterGesture::onCopyPasteAction(const LLSD& command) gesture_dir->getUUID(), getString("copy_name", string_args), cb); } } - clipbord.reset(); + LLClipboard::instance().reset(); } else if ("copy_uuid" == command_name) { - gClipboard.copyFromString(utf8str_to_wstring(mGestureList->getCurrentID().asString()), mGestureList->getCurrentID()); + LLClipboard::instance().copyToClipboard(mGestureList->getCurrentID(),LLAssetType::AT_GESTURE); } } diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp index a34e0353ec..38abdcc830 100644 --- a/indra/newview/llfloatergodtools.cpp +++ b/indra/newview/llfloatergodtools.cpp @@ -1123,8 +1123,14 @@ bool LLPanelObjectTools::callbackSimWideDeletes( const LLSD& notification, const void LLPanelObjectTools::onClickSet() { + LLView * button = findChild<LLButton>("Set Target"); + LLFloater * root_floater = gFloaterView->getParentFloater(this); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelObjectTools::callbackAvatarID, this, _1,_2), FALSE, FALSE, FALSE, root_floater->getName(), button); // grandparent is a floater, which can have a dependent - gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelObjectTools::callbackAvatarID, this, _1,_2))); + if (picker) + { + root_floater->addDependentFloater(picker); + } } void LLPanelObjectTools::onClickSetBySelection(void* data) diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index f9a403cf9f..116bd241c4 100644 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -37,6 +37,7 @@ #include "llspinctrl.h" #include "llstartup.h" #include "lltextbox.h" +#include "llcombobox.h" #include "pipeline.h" // Linden library includes @@ -99,6 +100,12 @@ void LLFloaterHardwareSettings::refreshEnabledState() getChildView("vbo")->setEnabled(FALSE); } + if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") || + !gGLManager.mHasVertexBufferObject) + { + getChildView("texture compression")->setEnabled(FALSE); + } + // if no windlight shaders, turn off nighttime brightness, gamma, and fog distance LLSpinCtrl* gamma_ctrl = getChild<LLSpinCtrl>("gamma"); gamma_ctrl->setEnabled(!gPipeline.canUseWindLightShaders()); @@ -142,6 +149,13 @@ BOOL LLFloaterHardwareSettings::postBuild() { childSetAction("OK", onBtnOK, this); + if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f) + { //remove FSAA settings above "4x" + LLComboBox* combo = getChild<LLComboBox>("fsaa"); + combo->remove("8x"); + combo->remove("16x"); + } + refresh(); center(); diff --git a/indra/newview/llfloaterhelpbrowser.cpp b/indra/newview/llfloaterhelpbrowser.cpp index fd9c37ae73..4cb632bd6a 100644 --- a/indra/newview/llfloaterhelpbrowser.cpp +++ b/indra/newview/llfloaterhelpbrowser.cpp @@ -77,15 +77,7 @@ void LLFloaterHelpBrowser::onOpen(const LLSD& key) gSavedSettings.setBOOL("HelpFloaterOpen", TRUE); std::string topic = key.asString(); - - if (topic == "__local") - { - mBrowser->navigateToLocalPage( "help-offline" , "index.html" ); - } - else - { - mBrowser->navigateTo(LLViewerHelp::instance().getURL(topic)); - } + mBrowser->navigateTo(LLViewerHelp::instance().getURL(topic)); } //virtual diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 69de15d9ea..2575f6f817 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(); @@ -703,9 +704,13 @@ BOOL LLImagePreviewAvatar::render() // make sure alpha=0 shows avatar material color LLGLDisable no_blend(GL_BLEND); - LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool(); - gPipeline.enableLightsPreview(); - avatarPoolp->renderAvatars(avatarp); // renders only one avatar + LLFace* face = avatarp->mDrawable->getFace(0); + if (face) + { + LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool(); + gPipeline.enableLightsPreview(); + avatarPoolp->renderAvatars(avatarp); // renders only one avatar + } } gGL.popUIMatrix(); @@ -896,11 +901,13 @@ BOOL LLImagePreviewSculpted::render() { gObjectPreviewProgram.bind(); } + gPipeline.enableLightsPreview(); + gGL.pushMatrix(); const F32 SCALE = 1.25f; gGL.scalef(SCALE, SCALE, SCALE); const F32 BRIGHTNESS = 0.9f; - gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); + gGL.diffuseColor3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0); diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp new file mode 100644 index 0000000000..7437dd8cda --- /dev/null +++ b/indra/newview/llfloaterimcontainer.cpp @@ -0,0 +1,1980 @@ +/** + * @file llfloaterimcontainer.cpp + * @brief Multifloater containing active IM sessions in separate tab container tabs + * + * $LicenseInfo:firstyear=2009&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 "llfloaterimsession.h" +#include "llfloaterimcontainer.h" + +#include "llfloaterreg.h" +#include "lllayoutstack.h" +#include "llfloaterimnearbychat.h" + +#include "llagent.h" +#include "llavataractions.h" +#include "llavatariconctrl.h" +#include "llavatarnamecache.h" +#include "llcallbacklist.h" +#include "lldonotdisturbnotificationstorage.h" +#include "llgroupactions.h" +#include "llgroupiconctrl.h" +#include "llflashtimer.h" +#include "llfloateravatarpicker.h" +#include "llfloaterpreference.h" +#include "llimview.h" +#include "llnotificationsutil.h" +#include "lltransientfloatermgr.h" +#include "llviewercontrol.h" +#include "llconversationview.h" +#include "llcallbacklist.h" +#include "llworld.h" +#include "llsdserialize.h" + +// +// LLFloaterIMContainer +// +LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& params /*= getDefaultParams()*/) +: LLMultiFloater(seed, params), + mExpandCollapseBtn(NULL), + mConversationsRoot(NULL), + mConversationsEventStream("ConversationsEvents"), + mInitialized(false), + mIsFirstLaunch(false) +{ + mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLFloaterIMContainer::isActionChecked, this, _2)); + mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLFloaterIMContainer::onCustomAction, this, _2)); + + mEnableCallbackRegistrar.add("Avatar.CheckItem", boost::bind(&LLFloaterIMContainer::checkContextMenuItem, this, _2)); + mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMContainer::enableContextMenuItem, this, _2)); + mEnableCallbackRegistrar.add("Avatar.VisibleItem", boost::bind(&LLFloaterIMContainer::visibleContextMenuItem, this, _2)); + mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMContainer::doToSelected, this, _2)); + + mCommitCallbackRegistrar.add("Group.DoToSelected", boost::bind(&LLFloaterIMContainer::doToSelectedGroup, this, _2)); + + // Firstly add our self to IMSession observers, so we catch session events + LLIMMgr::getInstance()->addSessionObserver(this); + + mAutoResize = FALSE; + LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this); +} + +LLFloaterIMContainer::~LLFloaterIMContainer() +{ + mConversationsEventStream.stopListening("ConversationsRefresh"); + + gIdleCallbacks.deleteFunction(idle, this); + + mNewMessageConnection.disconnect(); + LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this); + + if (mMicroChangedSignal.connected()) + { + mMicroChangedSignal.disconnect(); + } + + gSavedPerAccountSettings.setBOOL("ConversationsListPaneCollapsed", mConversationsPane->isCollapsed()); + gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed()); + + if (!LLSingleton<LLIMMgr>::destroyed()) + { + LLIMMgr::getInstance()->removeSessionObserver(this); + } +} + +void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg) +{ + addConversationListItem(session_id); + LLFloaterIMSessionTab::addToHost(session_id); +} + +void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) +{ + selectConversationPair(session_id, true); + collapseMessagesPane(false); +} + +void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id) +{ + addConversationListItem(session_id); + LLFloaterIMSessionTab::addToHost(session_id); +} + +void LLFloaterIMContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) +{ + // The general strategy when a session id is modified is to delete all related objects and create them anew. + + // Note however that the LLFloaterIMSession has its session id updated through a call to sessionInitReplyReceived() + // and do not need to be deleted and recreated (trying this creates loads of problems). We do need however to suppress + // its related mSessions record as it's indexed with the wrong id. + // Grabbing the updated LLFloaterIMSession and readding it in mSessions will eventually be done by addConversationListItem(). + mSessions.erase(old_session_id); + + // Delete the model and participants related to the old session + bool change_focus = removeConversationListItem(old_session_id); + + // Create a new conversation with the new id + addConversationListItem(new_session_id, change_focus); + LLFloaterIMSessionTab::addToHost(new_session_id); +} + +void LLFloaterIMContainer::sessionRemoved(const LLUUID& session_id) +{ + removeConversationListItem(session_id); +} + +// static +void LLFloaterIMContainer::onCurrentChannelChanged(const LLUUID& session_id) +{ + if (session_id != LLUUID::null) + { + LLFloaterIMContainer::getInstance()->showConversation(session_id); + } +} + +BOOL LLFloaterIMContainer::postBuild() +{ + mOrigMinWidth = getMinWidth(); + mOrigMinHeight = getMinHeight(); + + mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLFloaterIMContainer::onNewMessageReceived, this, _1)); + // Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button + // mTabContainer will be initialized in LLMultiFloater::addChild() + + setTabContainer(getChild<LLTabContainer>("im_box_tab_container")); + mStubPanel = getChild<LLPanel>("stub_panel"); + mStubTextBox = getChild<LLTextBox>("stub_textbox"); + mStubTextBox->setURLClickedCallback(boost::bind(&LLFloaterIMContainer::returnFloaterToHost, this)); + + mConversationsStack = getChild<LLLayoutStack>("conversations_stack"); + mConversationsPane = getChild<LLLayoutPanel>("conversations_layout_panel"); + mMessagesPane = getChild<LLLayoutPanel>("messages_layout_panel"); + + mConversationsListPanel = getChild<LLPanel>("conversations_list_panel"); + + // Open IM session with selected participant on double click event + mConversationsListPanel->setDoubleClickCallback(boost::bind(&LLFloaterIMContainer::doToSelected, this, LLSD("im"))); + + // The resize limits for LLFloaterIMContainer should be updated, based on current values of width of conversation and message panels + mConversationsPane->getResizeBar()->setResizeListener(boost::bind(&LLFloaterIMContainer::assignResizeLimits, this)); + + // Create the root model and view for all conversation sessions + LLConversationItem* base_item = new LLConversationItem(getRootViewModel()); + + LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>()); + p.name = getName(); + p.title = getLabel(); + p.rect = LLRect(0, 0, getRect().getWidth(), 0); + p.parent_panel = mConversationsListPanel; + p.tool_tip = p.name; + p.listener = base_item; + p.view_model = &mConversationViewModel; + p.root = NULL; + p.use_ellipses = true; + p.options_menu = "menu_conversation.xml"; + mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p); + mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); + + // Add listener to conversation model events + mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLFloaterIMContainer::onConversationModelEvent, this, _1)); + + // a scroller for folder view + LLRect scroller_view_rect = mConversationsListPanel->getRect(); + scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); + LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>()); + scroller_params.rect(scroller_view_rect); + + LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params); + scroller->setFollowsAll(); + mConversationsListPanel->addChild(scroller); + scroller->addChild(mConversationsRoot); + mConversationsRoot->setScrollContainer(scroller); + mConversationsRoot->setFollowsAll(); + mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox); + + addConversationListItem(LLUUID()); // manually add nearby chat + + mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn"); + mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onExpandCollapseButtonClicked, this)); + mStubCollapseBtn = getChild<LLButton>("stub_collapse_btn"); + mStubCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onStubCollapseButtonClicked, this)); + getChild<LLButton>("speak_btn")->setClickedCallback(boost::bind(&LLFloaterIMContainer::onSpeakButtonClicked, this)); + + childSetAction("add_btn", boost::bind(&LLFloaterIMContainer::onAddButtonClicked, this)); + + collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed")); + collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"), false); + LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false)); + mMicroChangedSignal = LLVoiceClient::getInstance()->MicroChangedCallback(boost::bind(&LLFloaterIMContainer::updateSpeakBtnState, this)); + + if (! mMessagesPane->isCollapsed() && ! mConversationsPane->isCollapsed()) + { + S32 conversations_panel_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth"); + LLRect conversations_panel_rect = mConversationsPane->getRect(); + conversations_panel_rect.mRight = conversations_panel_rect.mLeft + conversations_panel_width; + mConversationsPane->handleReshape(conversations_panel_rect, TRUE); + } + + // Init the sort order now that the root had been created + setSortOrder(LLConversationSort(gSavedSettings.getU32("ConversationSortOrder"))); + + // Keep the xml set title around for when we have to overwrite it + mGeneralTitle = getTitle(); + + mInitialized = true; + mIsFirstLaunch = true; + + // Add callbacks: + // We'll take care of view updates on idle + gIdleCallbacks.addFunction(idle, this); + // When display name option change, we need to reload all participant names + LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMContainer::processParticipantsStyleUpdate, this)); + + return TRUE; +} + +void LLFloaterIMContainer::onOpen(const LLSD& key) +{ + LLMultiFloater::onOpen(key); + openNearbyChat(); + reSelectConversation(); + assignResizeLimits(); +} + +// virtual +void LLFloaterIMContainer::addFloater(LLFloater* floaterp, + BOOL select_added_floater, + LLTabContainer::eInsertionPoint insertion_point) +{ + if(!floaterp) return; + + // already here + if (floaterp->getHost() == this) + { + openFloater(floaterp->getKey()); + return; + } + + LLUUID session_id = floaterp->getKey(); + + // Make sure the message panel is open when adding a floater or it stays mysteriously hidden + if (!mIsFirstLaunch) + { + collapseMessagesPane(false); + } + + // Add the floater + LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point); + + + + LLIconCtrl* icon = 0; + + if(gAgent.isInGroup(session_id, TRUE)) + { + LLGroupIconCtrl::Params icon_params; + icon_params.group_id = session_id; + icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params); + + mSessions[session_id] = floaterp; + floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id)); + } + else + { LLUUID avatar_id = session_id.notNull()? + LLIMModel::getInstance()->getOtherParticipantID(session_id) : LLUUID(); + + LLAvatarIconCtrl::Params icon_params; + icon_params.avatar_id = avatar_id; + icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params); + + mSessions[session_id] = floaterp; + floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id)); + } + + // forced resize of the floater + LLRect wrapper_rect = this->mTabContainer->getLocalRect(); + floaterp->setRect(wrapper_rect); + + mTabContainer->setTabImage(floaterp, icon); +} + + +void LLFloaterIMContainer::onCloseFloater(LLUUID& id) +{ + mSessions.erase(id); + setFocus(TRUE); +} + +void LLFloaterIMContainer::onNewMessageReceived(const LLSD& data) +{ + LLUUID session_id = data["session_id"].asUUID(); + LLFloater* floaterp = get_ptr_in_map(mSessions, session_id); + LLFloater* current_floater = LLMultiFloater::getActiveFloater(); + + if(floaterp && current_floater && floaterp != current_floater) + { + if(LLMultiFloater::isFloaterFlashing(floaterp)) + LLMultiFloater::setFloaterFlashing(floaterp, FALSE); + LLMultiFloater::setFloaterFlashing(floaterp, TRUE); + } +} + +void LLFloaterIMContainer::onStubCollapseButtonClicked() +{ + collapseMessagesPane(true); +} + +void LLFloaterIMContainer::onSpeakButtonClicked() +{ + LLAgent::toggleMicrophone("speak"); + updateSpeakBtnState(); +} +void LLFloaterIMContainer::onExpandCollapseButtonClicked() +{ + if (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed() + && gSavedPerAccountSettings.getBOOL("ConversationsExpandMessagePaneFirst")) + { + // Expand the messages pane from ultra minimized state + // if it was collapsed last in order. + collapseMessagesPane(false); + } + else + { + collapseConversationsPane(!mConversationsPane->isCollapsed()); + } + reSelectConversation(); +} + +LLFloaterIMContainer* LLFloaterIMContainer::findInstance() +{ + return LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container"); +} + +LLFloaterIMContainer* LLFloaterIMContainer::getInstance() +{ + return LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); +} + +// Update all participants in the conversation lists +void LLFloaterIMContainer::processParticipantsStyleUpdate() +{ + // On each session in mConversationsItems + for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++) + { + // Get the current session descriptors + LLConversationItem* session_model = it_session->second; + // Iterate through each model participant child + LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = session_model->getChildrenBegin(); + LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = session_model->getChildrenEnd(); + while (current_participant_model != end_participant_model) + { + LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model); + // Get the avatar name for this participant id from the cache and update the model + participant_model->updateName(); + // Next participant + current_participant_model++; + } + } +} + +// static +void LLFloaterIMContainer::idle(void* user_data) +{ + LLFloaterIMContainer* self = static_cast<LLFloaterIMContainer*>(user_data); + + // Update the distance to agent in the nearby chat session if required + // Note: it makes no sense of course to update the distance in other session + if (self->mConversationViewModel.getSorter().getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE) + { + self->setNearbyDistances(); + } + self->mConversationsRoot->update(); +} + +bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event) +{ + // For debug only + //std::ostringstream llsd_value; + //llsd_value << LLSDOStreamer<LLSDNotationFormatter>(event) << std::endl; + //llinfos << "LLFloaterIMContainer::onConversationModelEvent, event = " << llsd_value.str() << llendl; + // end debug + + // Note: In conversations, the model is not responsible for creating the view, which is a good thing. This means that + // the model could change substantially and the view could echo only a portion of this model (though currently the + // conversation view does echo the conversation model 1 to 1). + // Consequently, the participant views need to be created either by the session view or by the container panel. + // For the moment, we create them here, at the container level, to conform to the pattern implemented in llinventorypanel.cpp + // (see LLInventoryPanel::buildNewViews()). + + std::string type = event.get("type").asString(); + LLUUID session_id = event.get("session_uuid").asUUID(); + LLUUID participant_id = event.get("participant_uuid").asUUID(); + + LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,session_id)); + if (!session_view) + { + // We skip events that are not associated with a session + return false; + } + LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id); + LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ? + (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) + : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(session_id))); + + if (type == "remove_participant") + { + // Remove a participant view from the hierarchical conversation list + if (participant_view) + { + session_view->extractItem(participant_view); + delete participant_view; + session_view->refresh(); + mConversationsRoot->arrangeAll(); + } + // Remove a participant view from the conversation floater + if (conversation_floater) + { + conversation_floater->removeConversationViewParticipant(participant_id); + } + } + else if (type == "add_participant") + { + LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]); + LLConversationItemParticipant* participant_model = (session_model ? session_model->findParticipant(participant_id) : NULL); + if (!participant_view && session_model && participant_model) + { + LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(session_id); + if (session_id.isNull() || (im_sessionp && !im_sessionp->isP2PSessionType())) + { + participant_view = createConversationViewParticipant(participant_model); + participant_view->addToFolder(session_view); + participant_view->setVisible(TRUE); + } + } + // Add a participant view to the conversation floater + if (conversation_floater && participant_model) + { + conversation_floater->addConversationViewParticipant(participant_model); + } + } + else if (type == "update_participant") + { + // Update the participant view in the hierarchical conversation list + if (participant_view) + { + participant_view->refresh(); + } + // Update the participant view in the conversation floater + if (conversation_floater) + { + conversation_floater->updateConversationViewParticipant(participant_id); + } + } + else if (type == "update_session") + { + session_view->refresh(); + } + + mConversationViewModel.requestSortAll(); + mConversationsRoot->arrangeAll(); + if (conversation_floater) + { + conversation_floater->refreshConversation(); + } + + return false; +} + +void LLFloaterIMContainer::draw() +{ + if (mTabContainer->getTabCount() == 0) + { + // Do not close the container when every conversation is torn off because the user + // still needs the conversation list. Simply collapse the message pane in that case. + collapseMessagesPane(true); + } + + const LLConversationItem *current_session = getCurSelectedViewModelItem(); + if (current_session) + { + // Update moderator options visibility + LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin(); + LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd(); + while (current_participant_model != end_participant_model) + { + LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model); + participant_model->setModeratorOptionsVisible(isGroupModerator() && participant_model->getUUID() != gAgentID); + + current_participant_model++; + } + // Update floater's title as required by the currently selected session or use the default title + LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(current_session->getUUID()); + setTitle(conversation_floaterp && conversation_floaterp->needsTitleOverwrite() ? conversation_floaterp->getTitle() : mGeneralTitle); + } + + // "Manually" resize of mConversationsPane: same as temporarity cancellation of the flag "auto_resize=false" for it + if (!mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed()) + { + LLRect stack_rect = mConversationsStack->getRect(); + mConversationsPane->reshape(stack_rect.getWidth(), stack_rect.getHeight(), true); + } + + LLFloater::draw(); +} + +void LLFloaterIMContainer::tabClose() +{ + if (mTabContainer->getTabCount() == 0) + { + // Do not close the container when every conversation is torn off because the user + // still needs the conversation list. Simply collapse the message pane in that case. + collapseMessagesPane(true); + } +} + +//Shows/hides the stub panel when a conversation floater is torn off +void LLFloaterIMContainer::showStub(bool stub_is_visible) +{ + S32 tabCount = 0; + LLPanel * tabPanel = NULL; + + if(stub_is_visible) + { + tabCount = mTabContainer->getTabCount(); + + //Hide all tabs even stub + for(S32 i = 0; i < tabCount; ++i) + { + tabPanel = mTabContainer->getPanelByIndex(i); + + if(tabPanel) + { + tabPanel->setVisible(false); + } + } + + //Set the index to the stub panel since we will be showing the stub + mTabContainer->setCurrentPanelIndex(0); + } + + //Now show/hide the stub + mStubPanel->setVisible(stub_is_visible); +} + +// listener for click on mStubTextBox2 +void LLFloaterIMContainer::returnFloaterToHost() +{ + LLUUID session_id = this->getSelectedSession(); + LLFloaterIMSessionTab* floater = LLFloaterIMSessionTab::getConversation(session_id); + floater->onTearOffClicked(); +} + +void LLFloaterIMContainer::setVisible(BOOL visible) +{ LLFloaterIMNearbyChat* nearby_chat; + if (visible) + { + // Make sure we have the Nearby Chat present when showing the conversation container + nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + if (nearby_chat == NULL) + { + // If not found, force the creation of the nearby chat conversation panel + // *TODO: find a way to move this to XML as a default panel or something like that + LLSD name("nearby_chat"); + LLFloaterReg::toggleInstanceOrBringToFront(name); + setSelectedSession(LLUUID(NULL)); + } + openNearbyChat(); + selectConversationPair(getSelectedSession(), false, false); + } + + nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + if (nearby_chat) + { + LLFloaterIMSessionTab::addToHost(LLUUID()); + } + + // We need to show/hide all the associated conversations that have been torn off + // (and therefore, are not longer managed by the multifloater), + // so that they show/hide with the conversations manager. + conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin(); + for (;widget_it != mConversationsWidgets.end(); ++widget_it) + { + LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second); + if (widget) + { + widget->setVisibleIfDetached(visible); + } + } + + // Now, do the normal multifloater show/hide + LLMultiFloater::setVisible(visible); +} + +void LLFloaterIMContainer::updateResizeLimits() +{ + LLMultiFloater::updateResizeLimits(); + assignResizeLimits(); +} + +void LLFloaterIMContainer::collapseMessagesPane(bool collapse) +{ + if (mMessagesPane->isCollapsed() == collapse) + { + return; + } + + mIsFirstLaunch = false; + + // Save current width of panels before collapsing/expanding right pane. + S32 conv_pane_width = mConversationsPane->getRect().getWidth(); + S32 msg_pane_width = mMessagesPane->getRect().getWidth(); + + if (collapse) + { + // Save the messages pane width before collapsing it. + gSavedPerAccountSettings.setS32("ConversationsMessagePaneWidth", msg_pane_width); + + // Save the order in which the panels are closed to reverse user's last action. + gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", mConversationsPane->isCollapsed()); + } + + mConversationsPane->setIgnoreReshape(collapse); + + // Show/hide the messages pane. + mConversationsStack->collapsePanel(mMessagesPane, collapse); + + // Make sure layout is updated before resizing conversation pane. + mConversationsStack->updateLayout(); + + reshapeFloaterAndSetResizeLimits(collapse, gSavedPerAccountSettings.getS32("ConversationsMessagePaneWidth")); + + if (!collapse) + { + // Restore conversation's pane previous width after expanding messages pane. + mConversationsPane->setTargetDim(conv_pane_width); + } +} + +void LLFloaterIMContainer::collapseConversationsPane(bool collapse, bool save_is_allowed /*=true*/) +{ + if (mConversationsPane->isCollapsed() == collapse) + { + return; + } + + LLView* button_panel = getChild<LLView>("conversations_pane_buttons_expanded"); + button_panel->setVisible(!collapse); + mExpandCollapseBtn->setImageOverlay(getString(collapse ? "expand_icon" : "collapse_icon")); + + // Save current width of Conversation panel before collapsing/expanding right pane. + S32 conv_pane_width = mConversationsPane->getRect().getWidth(); + + if (collapse && save_is_allowed) + { + // Save the conversations pane width before collapsing it. + gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", conv_pane_width); + + // Save the order in which the panels are closed to reverse user's last action. + gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", !mMessagesPane->isCollapsed()); + } + + mConversationsStack->collapsePanel(mConversationsPane, collapse); + if (!collapse) + { + // Make sure layout is updated before resizing conversation pane. + mConversationsStack->updateLayout(); + // Restore conversation's pane previous width. + mConversationsPane->setTargetDim(gSavedPerAccountSettings.getS32("ConversationsListPaneWidth")); + } + + S32 delta_width = + gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") - mConversationsPane->getMinDim(); + + reshapeFloaterAndSetResizeLimits(collapse, delta_width); + + for (conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin(); + widget_it != mConversationsWidgets.end(); ++widget_it) + { + LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second); + if (widget) + { + widget->toggleCollapsedMode(collapse); + + // force closing all open conversations when collapsing to minimized state + if (collapse) + { + widget->setOpen(false); + } + widget->requestArrange(); + } + } +} + +void LLFloaterIMContainer::reshapeFloaterAndSetResizeLimits(bool collapse, S32 delta_width) +{ + LLRect floater_rect = getRect(); + floater_rect.mRight += ((collapse ? -1 : 1) * delta_width); + + // Set by_user = true so that reshaped rect is saved in user_settings. + setShape(floater_rect, true); + updateResizeLimits(); + + bool at_least_one_panel_is_expanded = + ! (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed()); + + setCanResize(at_least_one_panel_is_expanded); + setCanMinimize(at_least_one_panel_is_expanded); + + assignResizeLimits(); + + // force set correct size for the title after show/hide minimize button + LLRect cur_rect = getRect(); + LLRect force_rect = cur_rect; + force_rect.mRight = cur_rect.mRight + 1; + setRect(force_rect); + setRect(cur_rect); +} + +void LLFloaterIMContainer::assignResizeLimits() +{ + bool is_conv_pane_expanded = !mConversationsPane->isCollapsed(); + bool is_msg_pane_expanded = !mMessagesPane->isCollapsed(); + + // With two panels visible number of borders is three, because the borders + // between the panels are merged into one + S32 number_of_visible_borders = llmin((is_conv_pane_expanded? 2 : 0) + (is_msg_pane_expanded? 2 : 0), 3); + S32 summary_width_of_visible_borders = number_of_visible_borders * LLPANEL_BORDER_WIDTH; + S32 conv_pane_target_width = is_conv_pane_expanded? + (is_msg_pane_expanded? + mConversationsPane->getRect().getWidth() + : mConversationsPane->getExpandedMinDim()) + : mConversationsPane->getMinDim(); + S32 msg_pane_min_width = is_msg_pane_expanded ? mMessagesPane->getExpandedMinDim() : 0; + S32 new_min_width = conv_pane_target_width + msg_pane_min_width + summary_width_of_visible_borders; + + setResizeLimits(new_min_width, getMinHeight()); + + mConversationsStack->updateLayout(); +} + +void LLFloaterIMContainer::onAddButtonClicked() +{ + LLView * button = findChild<LLView>("conversations_pane_buttons_expanded")->findChild<LLButton>("add_btn"); + LLFloater* root_floater = gFloaterView->getParentFloater(this); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterIMContainer::onAvatarPicked, this, _1), TRUE, TRUE, TRUE, root_floater->getName(), button); + + if (picker && root_floater) + { + root_floater->addDependentFloater(picker); + } +} + +void LLFloaterIMContainer::onAvatarPicked(const uuid_vec_t& ids) +{ + if (ids.size() == 1) + { + LLAvatarActions::startIM(ids.back()); + } + else + { + LLAvatarActions::startConference(ids); + } +} + +void LLFloaterIMContainer::onCustomAction(const LLSD& userdata) +{ + std::string command = userdata.asString(); + + if ("sort_sessions_by_type" == command) + { + setSortOrderSessions(LLConversationFilter::SO_SESSION_TYPE); + } + if ("sort_sessions_by_name" == command) + { + setSortOrderSessions(LLConversationFilter::SO_NAME); + } + if ("sort_sessions_by_recent" == command) + { + setSortOrderSessions(LLConversationFilter::SO_DATE); + } + if ("sort_participants_by_name" == command) + { + setSortOrderParticipants(LLConversationFilter::SO_NAME); + } + if ("sort_participants_by_recent" == command) + { + setSortOrderParticipants(LLConversationFilter::SO_DATE); + } + if ("sort_participants_by_distance" == command) + { + setSortOrderParticipants(LLConversationFilter::SO_DISTANCE); + } + if ("chat_preferences" == command) + { + LLFloaterPreference * floater_prefp = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences"); + if (floater_prefp) + { + floater_prefp->selectChatPanel(); + } + } + if ("privacy_preferences" == command) + { + LLFloaterPreference * floater_prefp = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences"); + if (floater_prefp) + { + floater_prefp->selectPrivacyPanel(); + } + } + if ("Translating.Toggle" == command) + { + gSavedSettings.setBOOL("TranslateChat", !gSavedSettings.getBOOL("TranslateChat")); + } +} + +BOOL LLFloaterIMContainer::isActionChecked(const LLSD& userdata) +{ + LLConversationSort order = mConversationViewModel.getSorter(); + std::string command = userdata.asString(); + if ("sort_sessions_by_type" == command) + { + return (order.getSortOrderSessions() == LLConversationFilter::SO_SESSION_TYPE); + } + if ("sort_sessions_by_name" == command) + { + return (order.getSortOrderSessions() == LLConversationFilter::SO_NAME); + } + if ("sort_sessions_by_recent" == command) + { + return (order.getSortOrderSessions() == LLConversationFilter::SO_DATE); + } + if ("sort_participants_by_name" == command) + { + return (order.getSortOrderParticipants() == LLConversationFilter::SO_NAME); + } + if ("sort_participants_by_recent" == command) + { + return (order.getSortOrderParticipants() == LLConversationFilter::SO_DATE); + } + if ("sort_participants_by_distance" == command) + { + return (order.getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE); + } + if ("Translating.Enabled" == command) + { + return gSavedPerAccountSettings.getBOOL("TranslatingEnabled"); + } + if ("Translating.On" == command) + { + return gSavedSettings.getBOOL("TranslateChat"); + } + return FALSE; +} + +void LLFloaterIMContainer::setSortOrderSessions(const LLConversationFilter::ESortOrderType order) +{ + LLConversationSort old_order = mConversationViewModel.getSorter(); + if (order != old_order.getSortOrderSessions()) + { + old_order.setSortOrderSessions(order); + setSortOrder(old_order); + } +} + +void LLFloaterIMContainer::setSortOrderParticipants(const LLConversationFilter::ESortOrderType order) +{ + LLConversationSort old_order = mConversationViewModel.getSorter(); + if (order != old_order.getSortOrderParticipants()) + { + old_order.setSortOrderParticipants(order); + setSortOrder(old_order); + } +} + +void LLFloaterIMContainer::setSortOrder(const LLConversationSort& order) +{ + mConversationViewModel.setSorter(order); + mConversationsRoot->arrangeAll(); + // try to keep selection onscreen, even if it wasn't to start with + mConversationsRoot->scrollToShowSelection(); + + // Notify all conversation (torn off or not) of the change to the sort order + // Note: For the moment, the sort order is *unique* across all conversations. That might change in the future. + for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++) + { + LLUUID session_id = it_session->first; + LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ? (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(session_id))); + if (conversation_floater) + { + conversation_floater->setSortOrder(order); + } + } + + gSavedSettings.setU32("ConversationSortOrder", (U32)order); +} + +void LLFloaterIMContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids) +{ + const std::set<LLFolderViewItem*> selectedItems = mConversationsRoot->getSelectionList(); + + std::set<LLFolderViewItem*>::const_iterator it = selectedItems.begin(); + const std::set<LLFolderViewItem*>::const_iterator it_end = selectedItems.end(); + LLConversationItem * conversationItem; + + for (; it != it_end; ++it) + { + conversationItem = static_cast<LLConversationItem *>((*it)->getViewModelItem()); + + //When a one-on-one conversation exists, retrieve the participant id from the conversation floater + if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1) + { + LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(conversationItem->getUUID()); + LLUUID participant_id = conversation_floaterp->getOtherParticipantUUID(); + selected_uuids.push_back(participant_id); + } + else + { + selected_uuids.push_back(conversationItem->getUUID()); + } + } +} + +const LLConversationItem * LLFloaterIMContainer::getCurSelectedViewModelItem() +{ + LLConversationItem * conversation_item = NULL; + + if(mConversationsRoot && + mConversationsRoot->getCurSelectedItem() && + mConversationsRoot->getCurSelectedItem()->getViewModelItem()) + { + LLFloaterIMSessionTab *selected_session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession); + if (selected_session_floater && !selected_session_floater->getHost() && selected_session_floater->getCurSelectedViewModelItem()) + { + conversation_item = selected_session_floater->getCurSelectedViewModelItem(); + } + else + { + conversation_item = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem()); + } + } + + return conversation_item; +} + +void LLFloaterIMContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids) +{ + //Find the conversation floater associated with the selected id + const LLConversationItem * conversation_item = getCurSelectedViewModelItem(); + + if (NULL == conversation_item) + { + return; + } + + getSelectedUUIDs(selected_uuids); +} + +void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec_t& selectedIDS) +{ + if (selectedIDS.size() == 1) + { + const LLUUID& userID = selectedIDS.front(); + if ("view_profile" == command) + { + LLAvatarActions::showProfile(userID); + } + else if ("im" == command) + { + if (gAgent.getID() != userID) + { + LLAvatarActions::startIM(userID); + } + } + else if ("offer_teleport" == command) + { + LLAvatarActions::offerTeleport(selectedIDS); + } + else if ("voice_call" == command) + { + LLAvatarActions::startCall(userID); + } + else if ("chat_history" == command) + { + LLAvatarActions::viewChatHistory(userID); + } + else if ("add_friend" == command) + { + LLAvatarActions::requestFriendshipDialog(userID); + } + else if ("remove_friend" == command) + { + LLAvatarActions::removeFriendDialog(userID); + } + else if ("invite_to_group" == command) + { + LLAvatarActions::inviteToGroup(userID); + } + else if ("map" == command) + { + LLAvatarActions::showOnMap(userID); + } + else if ("share" == command) + { + LLAvatarActions::share(userID); + } + else if ("pay" == command) + { + LLAvatarActions::pay(userID); + } + else if ("block_unblock" == command) + { + toggleMute(userID, LLMute::flagVoiceChat); + } + else if ("mute_unmute" == command) + { + toggleMute(userID, LLMute::flagTextChat); + } + else if ("selected" == command || "mute_all" == command || "unmute_all" == command) + { + moderateVoice(command, userID); + } + else if ("toggle_allow_text_chat" == command) + { + toggleAllowTextChat(userID); + } + } + else if (selectedIDS.size() > 1) + { + if ("im" == command) + { + LLAvatarActions::startConference(selectedIDS); + } + else if ("offer_teleport" == command) + { + LLAvatarActions::offerTeleport(selectedIDS); + } + else if ("voice_call" == command) + { + LLAvatarActions::startAdhocCall(selectedIDS); + } + else if ("remove_friend" == command) + { + LLAvatarActions::removeFriendsDialog(selectedIDS); + } + } +} + +void LLFloaterIMContainer::doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS) +{ + //Find the conversation floater associated with the selected id + const LLConversationItem * conversationItem = getCurSelectedViewModelItem(); + LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(conversationItem->getUUID()); + + if(conversationFloater) + { + //Close the selected conversation + if("close_conversation" == command) + { + LLFloater::onClickClose(conversationFloater); + } + else if("open_voice_conversation" == command) + { + gIMMgr->startCall(conversationItem->getUUID()); + } + else if("disconnect_from_voice" == command) + { + gIMMgr->endCall(conversationItem->getUUID()); + } + else if("chat_history" == command) + { + if (selectedIDS.size() > 0) + { + LLAvatarActions::viewChatHistory(selectedIDS.front()); + } + } + else + { + if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1) + { + doToParticipants(command, selectedIDS); + } + } + } +} + +void LLFloaterIMContainer::doToSelected(const LLSD& userdata) +{ + std::string command = userdata.asString(); + const LLConversationItem * conversationItem = getCurSelectedViewModelItem(); + uuid_vec_t selected_uuids; + + if(conversationItem != NULL) + { + getParticipantUUIDs(selected_uuids); + + if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT) + { + doToParticipants(command, selected_uuids); + } + else + { + doToSelectedConversation(command, selected_uuids); + } + } +} + +void LLFloaterIMContainer::doToSelectedGroup(const LLSD& userdata) +{ + std::string action = userdata.asString(); + + if (action == "group_profile") + { + LLGroupActions::show(mSelectedSession); + } + else if (action == "activate_group") + { + LLGroupActions::activate(mSelectedSession); + } + else if (action == "leave_group") + { + LLGroupActions::leave(mSelectedSession); + } +} + +bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata) +{ + const std::string& item = userdata.asString(); + uuid_vec_t uuids; + getParticipantUUIDs(uuids); + + if ("conversation_log" == item) + { + return gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0; + } + + //Enable Chat history item for ad-hoc and group conversations + if ("can_chat_history" == item && uuids.size() > 0) + { + return LLLogChat::isTranscriptExist(uuids.front()); + } + + // If nothing is selected(and selected item is not group chat), everything needs to be disabled + if (uuids.size() <= 0) + { + if(getCurSelectedViewModelItem()) + { + return getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_GROUP; + } + return false; + } + + if("can_activate_group" == item) + { + LLUUID selected_group_id = getCurSelectedViewModelItem()->getUUID(); + return gAgent.getGroupID() != selected_group_id; + } + + return enableContextMenuItem(item, uuids); +} + +bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_vec_t& uuids) +{ + // Extract the single select info + bool is_single_select = (uuids.size() == 1); + const LLUUID& single_id = uuids.front(); + + // Handle options that are applicable to all including the user agent + if ("can_view_profile" == item) + { + return is_single_select; + } + + // Beyond that point, if only the user agent is selected, everything is disabled + if (is_single_select && (single_id == gAgentID)) + { + return false; + } + + // If the user agent is selected with others, everything is disabled + for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id) + { + if (gAgent.getID() == *id) + { + return false; + } + } + + // Handle all other options + if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item)) + { + // Those menu items are enable only if a single avatar is selected + return is_single_select; + } + else if ("can_block" == item) + { + return (is_single_select ? LLAvatarActions::canBlock(single_id) : false); + } + else if ("can_add" == item) + { + // We can add friends if: + // - there is only 1 selected avatar (EXT-7389) + // - this avatar is not already a friend + return (is_single_select ? !LLAvatarActions::isFriend(single_id) : false); + } + else if ("can_delete" == item) + { + // We can remove friends if there are only friends among the selection + bool result = true; + for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id) + { + result &= LLAvatarActions::isFriend(*id); + } + return result; + } + else if ("can_call" == item) + { + return LLAvatarActions::canCall(); + } + else if ("can_show_on_map" == item) + { + return (is_single_select ? (LLAvatarTracker::instance().isBuddyOnline(single_id) && is_agent_mappable(single_id)) || gAgent.isGodlike() : false); + } + else if ("can_offer_teleport" == item) + { + return LLAvatarActions::canOfferTeleport(uuids); + } + else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item)) + { + // *TODO : get that out of here... + return enableModerateContextMenuItem(item); + } + + // By default, options that not explicitely disabled are enabled + return true; +} + +bool LLFloaterIMContainer::checkContextMenuItem(const LLSD& userdata) +{ + std::string item = userdata.asString(); + uuid_vec_t uuids; + getParticipantUUIDs(uuids); + + return checkContextMenuItem(item, uuids); +} + +bool LLFloaterIMContainer::checkContextMenuItem(const std::string& item, uuid_vec_t& uuids) +{ + if (uuids.size() == 1) + { + if ("is_blocked" == item) + { + return LLMuteList::getInstance()->isMuted(uuids.front(), LLMute::flagVoiceChat); + } + else if (item == "is_muted") + { + return LLMuteList::getInstance()->isMuted(uuids.front(), LLMute::flagTextChat); + } + else if ("is_allowed_text_chat" == item) + { + const LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant()); + + if (NULL != speakerp) + { + return !speakerp->mModeratorMutedText; + } + } + } + + return false; +} + +bool LLFloaterIMContainer::visibleContextMenuItem(const LLSD& userdata) +{ + const std::string& item = userdata.asString(); + + if ("show_mute" == item) + { + return !isMuted(getCurSelectedViewModelItem()->getUUID()); + } + else if ("show_unmute" == item) + { + return isMuted(getCurSelectedViewModelItem()->getUUID()); + } + + return true; +} + +void LLFloaterIMContainer::showConversation(const LLUUID& session_id) +{ + setVisibleAndFrontmost(false); + selectConversationPair(session_id, true); +} + +void LLFloaterIMContainer::clearAllFlashStates() +{ + conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin(); + for (;widget_it != mConversationsWidgets.end(); ++widget_it) + { + LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second); + if (widget) + { + widget->setFlashState(false); + } + } +} + +void LLFloaterIMContainer::selectConversation(const LLUUID& session_id) +{ + selectConversationPair(session_id, true); +} + +// Select the conversation *after* (or before if none after) the passed uuid conversation +// Used to change the selection on key hits +void LLFloaterIMContainer::selectNextConversationByID(const LLUUID& uuid) +{ + bool new_selection = false; + selectConversation(uuid); + new_selection = selectNextorPreviousConversation(true); + if (!new_selection) + { + selectNextorPreviousConversation(false); + } +} + +// Synchronous select the conversation item and the conversation floater +BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater/*=true*/) +{ + BOOL handled = TRUE; + LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id); + + /* widget processing */ + if (select_widget && mConversationsRoot->getSelectedCount() <= 1) + { + LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id); + if (widget && widget->getParentFolder()) + { + widget->getParentFolder()->setSelection(widget, FALSE, FALSE); + mConversationsRoot->scrollToShowSelection(); + } + + //When in DND mode, remove stored IM notifications + //Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal + if(gAgent.isDoNotDisturb() && session_id.notNull()) + { + LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, session_id); + } + } + + /* floater processing */ + + if (NULL != session_floater) + { + if (session_id != getSelectedSession()) + { + // Store the active session + setSelectedSession(session_id); + + + + if (session_floater->getHost()) + { + // Always expand the message pane if the panel is hosted by the container + collapseMessagesPane(false); + // Switch to the conversation floater that is being selected + selectFloater(session_floater); + } + else + { + showStub(true); + } + } + + // Set the focus on the selected floater + if (!session_floater->hasFocus()) + { + BOOL is_minimized = session_floater->isMinimized(); + session_floater->setFocus(focus_floater); + session_floater->setMinimized(is_minimized); + } + } + + return handled; +} + +void LLFloaterIMContainer::setTimeNow(const LLUUID& session_id, const LLUUID& participant_id) +{ + LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,session_id)); + if (item) + { + item->setTimeNow(participant_id); + mConversationViewModel.requestSortAll(); + mConversationsRoot->arrangeAll(); + } +} + +void LLFloaterIMContainer::setNearbyDistances() +{ + // Get the nearby chat session: that's the one with uuid nul + LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,LLUUID())); + if (item) + { + // Get the positions of the nearby avatars and their ids + std::vector<LLVector3d> positions; + uuid_vec_t avatar_ids; + LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange")); + // Get the position of the agent + const LLVector3d& me_pos = gAgent.getPositionGlobal(); + // For each nearby avatar, compute and update the distance + int avatar_count = positions.size(); + for (int i = 0; i < avatar_count; i++) + { + F64 dist = dist_vec_squared(positions[i], me_pos); + item->setDistance(avatar_ids[i],dist); + } + // Also does it for the agent itself + item->setDistance(gAgent.getID(),0.0f); + // Request resort + mConversationViewModel.requestSortAll(); + mConversationsRoot->arrangeAll(); + } +} + +LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID& uuid, bool isWidgetSelected /*= false*/) +{ + bool is_nearby_chat = uuid.isNull(); + + // Stores the display name for the conversation line item + std::string display_name = is_nearby_chat ? LLTrans::getString("NearbyChatLabel") : LLIMModel::instance().getName(uuid); + + // Check if the item is not already in the list, exit (nothing to do) + // Note: this happens often, when reattaching a torn off conversation for instance + conversations_items_map::iterator item_it = mConversationsItems.find(uuid); + if (item_it != mConversationsItems.end()) + { + return item_it->second; + } + + // Create a conversation session model + LLConversationItemSession* item = NULL; + LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid)); + if (speaker_manager) + { + item = new LLParticipantList(speaker_manager, getRootViewModel()); + } + if (!item) + { + llwarns << "Couldn't create conversation session item : " << display_name << llendl; + return NULL; + } + item->renameItem(display_name); + item->updateName(NULL); + + mConversationsItems[uuid] = item; + + // Create a widget from it + LLConversationViewSession* widget = createConversationItemWidget(item); + mConversationsWidgets[uuid] = widget; + + // Add a new conversation widget to the root folder of the folder view + widget->addToFolder(mConversationsRoot); + widget->requestArrange(); + + LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(uuid); + + // Create the participants widgets now + // Note: usually, we do not get an updated avatar list at that point + if (uuid.isNull() || im_sessionp && !im_sessionp->isP2PSessionType()) + { + LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin(); + LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd(); + while (current_participant_model != end_participant_model) + { + LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model); + LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model); + participant_view->addToFolder(widget); + current_participant_model++; + } + } + + if (uuid.notNull() && im_sessionp->isP2PSessionType()) + { + item->fetchAvatarName(false); + } + + // Do that too for the conversation dialog + LLFloaterIMSessionTab *conversation_floater = (uuid.isNull() ? (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(uuid))); + if (conversation_floater) + { + conversation_floater->buildConversationViewParticipant(); + } + + // set the widget to minimized mode if conversations pane is collapsed + widget->toggleCollapsedMode(mConversationsPane->isCollapsed()); + + if (isWidgetSelected || 0 == mConversationsRoot->getSelectedCount()) + { + selectConversationPair(uuid, true); + widget->requestArrange(); + + // scroll to newly added item + mConversationsRoot->scrollToShowSelection(); + } + + return item; +} + +bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool change_focus) +{ + // Delete the widget and the associated conversation item + // Note : since the mConversationsItems is also the listener to the widget, deleting + // the widget will also delete its listener + bool is_widget_selected = false; + LLFolderViewItem* new_selection = NULL; + LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid); + if (widget) + { + is_widget_selected = widget->isSelected(); + new_selection = mConversationsRoot->getNextFromChild(widget, FALSE); + if (!new_selection) + { + new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE); + } + widget->destroyView(); + } + + // Suppress the conversation items and widgets from their respective maps + mConversationsItems.erase(uuid); + mConversationsWidgets.erase(uuid); + + // Don't let the focus fall IW, select and refocus on the first conversation in the list + if (change_focus) + { + setFocus(TRUE); + if (new_selection) + { + if (mConversationsWidgets.size() == 1) + { + // If only one widget is left, it has to be the Nearby Chat. Select it directly. + selectConversationPair(LLUUID(NULL), true); + } + else + { + LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem()); + if (vmi) + { + selectConversationPair(vmi->getUUID(), true); + } + } + } + } + return is_widget_selected; +} + +LLConversationViewSession* LLFloaterIMContainer::createConversationItemWidget(LLConversationItem* item) +{ + LLConversationViewSession::Params params; + + params.name = item->getDisplayName(); + params.root = mConversationsRoot; + params.listener = item; + params.tool_tip = params.name; + params.container = this; + + //Indentation for aligning the p2p converstation image with the nearby chat arrow + if(item->getType() == LLConversationItem::CONV_SESSION_1_ON_1) + { + params.folder_indentation = 3; + } + + return LLUICtrlFactory::create<LLConversationViewSession>(params); +} + +LLConversationViewParticipant* LLFloaterIMContainer::createConversationViewParticipant(LLConversationItem* item) +{ + LLConversationViewParticipant::Params params; + LLRect panel_rect = mConversationsListPanel->getRect(); + + params.name = item->getDisplayName(); + params.root = mConversationsRoot; + params.listener = item; + + //24 is the the current hight of an item (itemHeight) loaded from conversation_view_participant.xml. + params.rect = LLRect (0, 24, panel_rect.getWidth(), 0); + params.tool_tip = params.name; + params.participant_id = item->getUUID(); + params.folder_indentation = 27; + + return LLUICtrlFactory::create<LLConversationViewParticipant>(params); +} + +bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& userdata) +{ + // only group moderators can perform actions related to this "enable callback" + if (!isGroupModerator()) + { + return false; + } + + LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant()); + if (NULL == speakerp) + { + return false; + } + + bool voice_channel = speakerp->isInVoiceChannel(); + + if ("can_moderate_voice" == userdata) + { + return voice_channel; + } + else if ("can_mute" == userdata) + { + return voice_channel && !isMuted(getCurSelectedViewModelItem()->getUUID()); + } + else if ("can_unmute" == userdata) + { + return voice_channel && isMuted(getCurSelectedViewModelItem()->getUUID()); + } + + // The last invoke is used to check whether the "can_allow_text_chat" will enabled + return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID()); +} + +bool LLFloaterIMContainer::isGroupModerator() +{ + LLSpeakerMgr * speaker_manager = getSpeakerMgrForSelectedParticipant(); + if (NULL == speaker_manager) + { + llwarns << "Speaker manager is missing" << llendl; + return false; + } + + // Is session a group call/chat? + if(gAgent.isInGroup(speaker_manager->getSessionID())) + { + LLSpeaker * speaker = speaker_manager->findSpeaker(gAgentID).get(); + + // Is agent a moderator? + return speaker && speaker->mIsModerator; + } + + return false; +} + +void LLFloaterIMContainer::moderateVoice(const std::string& command, const LLUUID& userID) +{ + if (!gAgent.getRegion()) return; + + if (command.compare("selected")) + { + moderateVoiceAllParticipants(command.compare("mute_all")); + } + else + { + moderateVoiceParticipant(userID, isMuted(userID)); + } +} + +bool LLFloaterIMContainer::isMuted(const LLUUID& avatar_id) +{ + const LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant()); + return NULL == speakerp ? true : speakerp->mStatus == LLSpeaker::STATUS_MUTED; +} + +void LLFloaterIMContainer::moderateVoiceAllParticipants(bool unmute) +{ + LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr*>(getSpeakerMgrForSelectedParticipant()); + + if (NULL != speaker_managerp) + { + if (!unmute) + { + LLSD payload; + payload["session_id"] = speaker_managerp->getSessionID(); + LLNotificationsUtil::add("ConfirmMuteAll", LLSD(), payload, confirmMuteAllCallback); + return; + } + + speaker_managerp->moderateVoiceAllParticipants(unmute); + } +} + +// static +void LLFloaterIMContainer::confirmMuteAllCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + // if Cancel pressed + if (option == 1) + { + return; + } + + const LLSD& payload = notification["payload"]; + const LLUUID& session_id = payload["session_id"]; + + LLIMSpeakerMgr * speaker_manager = dynamic_cast<LLIMSpeakerMgr*> ( + LLIMModel::getInstance()->getSpeakerManager(session_id)); + if (speaker_manager) + { + speaker_manager->moderateVoiceAllParticipants(false); + } + + return; +} + +void LLFloaterIMContainer::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute) +{ + LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr *>(getSpeakerMgrForSelectedParticipant()); + + if (NULL != speaker_managerp) + { + speaker_managerp->moderateVoiceParticipant(avatar_id, unmute); + } +} + +LLSpeakerMgr * LLFloaterIMContainer::getSpeakerMgrForSelectedParticipant() +{ + LLFolderViewItem *selectedItem = mConversationsRoot->getCurSelectedItem(); + if (NULL == selectedItem) + { + llwarns << "Current selected item is null" << llendl; + return NULL; + } + + conversations_widgets_map::const_iterator iter = mConversationsWidgets.begin(); + conversations_widgets_map::const_iterator end = mConversationsWidgets.end(); + const LLUUID * conversation_uuidp = NULL; + while(iter != end) + { + if (iter->second == selectedItem || iter->second == selectedItem->getParentFolder()) + { + conversation_uuidp = &iter->first; + break; + } + ++iter; + } + if (NULL == conversation_uuidp) + { + llwarns << "Cannot find conversation item widget" << llendl; + return NULL; + } + + return conversation_uuidp->isNull() ? (LLSpeakerMgr *)LLLocalSpeakerMgr::getInstance() + : LLIMModel::getInstance()->getSpeakerManager(*conversation_uuidp); +} + +LLSpeaker * LLFloaterIMContainer::getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp) +{ + if (NULL == speaker_managerp) + { + llwarns << "Speaker manager is missing" << llendl; + return NULL; + } + + const LLConversationItem * participant_itemp = getCurSelectedViewModelItem(); + if (NULL == participant_itemp) + { + llwarns << "Cannot evaluate current selected view model item" << llendl; + return NULL; + } + + return speaker_managerp->findSpeaker(participant_itemp->getUUID()); +} + +void LLFloaterIMContainer::toggleAllowTextChat(const LLUUID& participant_uuid) +{ + LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr*>(getSpeakerMgrForSelectedParticipant()); + if (NULL != speaker_managerp) + { + speaker_managerp->toggleAllowTextChat(participant_uuid); + } +} + +void LLFloaterIMContainer::toggleMute(const LLUUID& participant_id, U32 flags) +{ + BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags); + std::string name; + gCacheName->getFullName(participant_id, name); + LLMute mute(participant_id, name, LLMute::AGENT); + + if (!is_muted) + { + LLMuteList::getInstance()->add(mute, flags); + } + else + { + LLMuteList::getInstance()->remove(mute, flags); + } +} + +void LLFloaterIMContainer::openNearbyChat() +{ + // If there's only one conversation in the container and that conversation is the nearby chat + //(which it should be...), open it so to make the list of participants visible. This happens to be the most common case when opening the Chat floater. + if((mConversationsItems.size() == 1)&&(!mConversationsPane->isCollapsed())) + { + LLConversationViewSession* nearby_chat = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,LLUUID())); + if (nearby_chat) + { + reSelectConversation(); + nearby_chat->setOpen(TRUE); + } + } +} + +void LLFloaterIMContainer::onNearbyChatClosed() +{ + // If nearby chat is the only remaining conversation and it is closed, close whole conversation floater as well + if (mConversationsItems.size() == 1) + closeFloater(); +} + +void LLFloaterIMContainer::reSelectConversation() +{ + LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession); + if (session_floater->getHost()) + { + selectFloater(session_floater); + } +} + +void LLFloaterIMContainer::updateSpeakBtnState() +{ + LLButton* mSpeakBtn = getChild<LLButton>("speak_btn"); + mSpeakBtn->setToggleState(LLVoiceClient::getInstance()->getUserPTTState()); + mSpeakBtn->setEnabled(LLAgent::isActionAllowed("speak")); +} + +bool LLFloaterIMContainer::isConversationLoggingAllowed() +{ + return gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0; +} + +void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes) +{ + //Finds the conversation line item to flash using the session_id + LLConversationViewSession * widget = dynamic_cast<LLConversationViewSession *>(get_ptr_in_map(mConversationsWidgets,session_id)); + + if (widget) + { + widget->setFlashState(is_flashes); + } +} + +bool LLFloaterIMContainer::isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget) +{ + llassert(conversation_item_widget != NULL); + + // make sure the widget is actually in the right spot first + mConversationsRoot->arrange(NULL, NULL); + + // check whether the widget is in the visible portion of the scroll container + LLRect widget_rect; + conversation_item_widget->localRectToOtherView(conversation_item_widget->getLocalRect(), &widget_rect, mConversationsRoot); + return !mConversationsRoot->getVisibleRect().overlaps(widget_rect); +} + +BOOL LLFloaterIMContainer::handleKeyHere(KEY key, MASK mask ) +{ + if(mask == MASK_ALT) + { + if (KEY_RETURN == key ) + { + expandConversation(); + } + + if ((KEY_DOWN == key ) || (KEY_RIGHT == key)) + { + selectNextorPreviousConversation(true); + } + if ((KEY_UP == key) || (KEY_LEFT == key)) + { + selectNextorPreviousConversation(false); + } + } + return TRUE; +} + +bool LLFloaterIMContainer::selectAdjacentConversation(bool focus_selected) +{ + bool selectedAdjacentConversation = selectNextorPreviousConversation(true, focus_selected); + + if(!selectedAdjacentConversation) + { + selectedAdjacentConversation = selectNextorPreviousConversation(false, focus_selected); + } + + return selectedAdjacentConversation; +} + +bool LLFloaterIMContainer::selectNextorPreviousConversation(bool select_next, bool focus_selected) +{ + if (mConversationsWidgets.size() > 1) + { + LLFolderViewItem* new_selection = NULL; + LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,getSelectedSession()); + if (widget) + { + if(select_next) + { + new_selection = mConversationsRoot->getNextFromChild(widget, FALSE); + } + else + { + new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE); + } + if (new_selection) + { + LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem()); + if (vmi) + { + selectConversationPair(vmi->getUUID(), true, focus_selected); + return true; + } + } + } + } + return false; +} + +void LLFloaterIMContainer::expandConversation() +{ + LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,getSelectedSession())); + if (widget) + { + widget->setOpen(!widget->isOpen()); + } +} + +void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/) +{ + // Always unminimize before trying to close. + // Most of the time the user will never see this state. + setMinimized(FALSE); + + LLFloater::closeFloater(app_quitting); +} + +// EOF diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h new file mode 100644 index 0000000000..5139651d8d --- /dev/null +++ b/indra/newview/llfloaterimcontainer.h @@ -0,0 +1,210 @@ +/** + * @file llfloaterimcontainer.h + * @brief Multifloater containing active IM sessions in separate tab container tabs + * + * $LicenseInfo:firstyear=2009&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_LLFLOATERIMCONTAINER_H +#define LL_LLFLOATERIMCONTAINER_H + +#include <map> +#include <vector> + +#include "llimview.h" +#include "llevents.h" +#include "../llui/llfloater.h" +#include "../llui/llmultifloater.h" +#include "llavatarpropertiesprocessor.h" +#include "llgroupmgr.h" +#include "../llui/lltrans.h" +#include "llconversationmodel.h" +#include "llconversationview.h" + +class LLButton; +class LLLayoutPanel; +class LLLayoutStack; +class LLTabContainer; +class LLFloaterIMContainer; +class LLSpeaker; +class LLSpeakerMgr; + +class LLFloaterIMContainer + : public LLMultiFloater + , public LLIMSessionObserver +{ +public: + LLFloaterIMContainer(const LLSD& seed, const Params& params = getDefaultParams()); + virtual ~LLFloaterIMContainer(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void draw(); + /*virtual*/ void setVisible(BOOL visible); + /*virtual*/ void updateResizeLimits(); + void onCloseFloater(LLUUID& id); + + /*virtual*/ void addFloater(LLFloater* floaterp, + BOOL select_added_floater, + LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END); + void returnFloaterToHost(); + void showConversation(const LLUUID& session_id); + void selectConversation(const LLUUID& session_id); + void selectNextConversationByID(const LLUUID& session_id); + BOOL selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater = true); + void clearAllFlashStates(); + bool selectAdjacentConversation(bool focus_selected); + bool selectNextorPreviousConversation(bool select_next, bool focus_selected = true); + void expandConversation(); + + /*virtual*/ void tabClose(); + void showStub(bool visible); + + static LLFloater* getCurrentVoiceFloater(); + static LLFloaterIMContainer* findInstance(); + static LLFloaterIMContainer* getInstance(); + + static void onCurrentChannelChanged(const LLUUID& session_id); + + void collapseMessagesPane(bool collapse); + + // Callbacks + static void idle(void* user_data); + + // LLIMSessionObserver observe triggers + /*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg); + /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id); + /*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id); + /*virtual*/ void sessionRemoved(const LLUUID& session_id); + /*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id); + + LLConversationViewModel& getRootViewModel() { return mConversationViewModel; } + LLUUID getSelectedSession() { return mSelectedSession; } + void setSelectedSession(LLUUID sessionID) { mSelectedSession = sessionID; } + LLConversationItem* getSessionModel(const LLUUID& session_id) { return get_ptr_in_map(mConversationsItems,session_id); } + LLConversationSort& getSortOrder() { return mConversationViewModel.getSorter(); } + + void onNearbyChatClosed(); + + // Handling of lists of participants is public so to be common with llfloatersessiontab + // *TODO : Find a better place for this. + bool checkContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS); + bool enableContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS); + void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS); + + void assignResizeLimits(); + virtual BOOL handleKeyHere(KEY key, MASK mask ); + /*virtual*/ void closeFloater(bool app_quitting = false); + +private: + typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t; + avatarID_panel_map_t mSessions; + boost::signals2::connection mNewMessageConnection; + + /*virtual*/ void computeResizeLimits(S32& new_min_width, S32& new_min_height) {} + + void onNewMessageReceived(const LLSD& data); + + void onExpandCollapseButtonClicked(); + void onStubCollapseButtonClicked(); + void processParticipantsStyleUpdate(); + void onSpeakButtonClicked(); + + void collapseConversationsPane(bool collapse, bool save_is_allowed=true); + + void reshapeFloaterAndSetResizeLimits(bool collapse, S32 delta_width); + + void onAddButtonClicked(); + void onAvatarPicked(const uuid_vec_t& ids); + + BOOL isActionChecked(const LLSD& userdata); + void onCustomAction (const LLSD& userdata); + void setSortOrderSessions(const LLConversationFilter::ESortOrderType order); + void setSortOrderParticipants(const LLConversationFilter::ESortOrderType order); + void setSortOrder(const LLConversationSort& order); + + void getSelectedUUIDs(uuid_vec_t& selected_uuids); + const LLConversationItem * getCurSelectedViewModelItem(); + void getParticipantUUIDs(uuid_vec_t& selected_uuids); + void doToSelected(const LLSD& userdata); + bool checkContextMenuItem(const LLSD& userdata); + bool enableContextMenuItem(const LLSD& userdata); + bool visibleContextMenuItem(const LLSD& userdata); + void doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS); + void doToSelectedGroup(const LLSD& userdata); + + static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response); + bool enableModerateContextMenuItem(const std::string& userdata); + LLSpeaker * getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp); + LLSpeakerMgr * getSpeakerMgrForSelectedParticipant(); + bool isGroupModerator(); + bool isMuted(const LLUUID& avatar_id); + void moderateVoice(const std::string& command, const LLUUID& userID); + void moderateVoiceAllParticipants(bool unmute); + void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute); + void toggleAllowTextChat(const LLUUID& participant_uuid); + void toggleMute(const LLUUID& participant_id, U32 flags); + void openNearbyChat(); + + LLButton* mExpandCollapseBtn; + LLButton* mStubCollapseBtn; + LLPanel* mStubPanel; + LLTextBox* mStubTextBox; + LLLayoutPanel* mMessagesPane; + LLLayoutPanel* mConversationsPane; + LLLayoutStack* mConversationsStack; + + bool mInitialized; + bool mIsFirstLaunch; + + LLUUID mSelectedSession; + std::string mGeneralTitle; + + // Conversation list implementation +public: + bool removeConversationListItem(const LLUUID& uuid, bool change_focus = true); + LLConversationItem* addConversationListItem(const LLUUID& uuid, bool isWidgetSelected = false); + void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id); + void setNearbyDistances(); + void reSelectConversation(); + void updateSpeakBtnState(); + static bool isConversationLoggingAllowed(); + void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes); + bool isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget); + boost::signals2::connection mMicroChangedSignal; + S32 getConversationListItemSize() { return mConversationsWidgets.size(); } + +private: + LLConversationViewSession* createConversationItemWidget(LLConversationItem* item); + LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item); + bool onConversationModelEvent(const LLSD& event); + + // Conversation list data + LLPanel* mConversationsListPanel; // This is the main widget we add conversation widget to + conversations_items_map mConversationsItems; + conversations_widgets_map mConversationsWidgets; + LLConversationViewModel mConversationViewModel; + LLFolderView* mConversationsRoot; + LLEventStream mConversationsEventStream; +}; + +#endif // LL_LLFLOATERIMCONTAINER_H diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp new file mode 100644 index 0000000000..cfee5001a6 --- /dev/null +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -0,0 +1,860 @@ +/** + * @file LLFloaterIMNearbyChat.cpp + * @brief LLFloaterIMNearbyChat class implementation + * + * $LicenseInfo:firstyear=2002&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 "message.h" + +#include "lliconctrl.h" +#include "llappviewer.h" +#include "llchatentry.h" +#include "llfloaterreg.h" +#include "lltrans.h" +#include "llfloaterimcontainer.h" +#include "llfloatersidepanelcontainer.h" +#include "llfocusmgr.h" +#include "lllogchat.h" +#include "llresizebar.h" +#include "llresizehandle.h" +#include "lldraghandle.h" +#include "llmenugl.h" +#include "llviewermenu.h" // for gMenuHolder +#include "llfloaterimnearbychathandler.h" +#include "llchannelmanager.h" +#include "llchathistory.h" +#include "llstylemap.h" +#include "llavatarnamecache.h" +#include "llfloaterreg.h" +#include "lltrans.h" + +#include "llfirstuse.h" +#include "llfloaterimnearbychat.h" +#include "llagent.h" // gAgent +#include "llgesturemgr.h" +#include "llmultigesture.h" +#include "llkeyboard.h" +#include "llanimationstates.h" +#include "llviewerstats.h" +#include "llcommandhandler.h" +#include "llviewercontrol.h" +#include "llnavigationbar.h" +#include "llwindow.h" +#include "llviewerwindow.h" +#include "llrootview.h" +#include "llviewerchat.h" +#include "lltranslate.h" +#include "llautoreplace.h" + +S32 LLFloaterIMNearbyChat::sLastSpecialChatChannel = 0; + +const S32 EXPANDED_HEIGHT = 266; +const S32 COLLAPSED_HEIGHT = 60; +const S32 EXPANDED_MIN_HEIGHT = 150; + +// legacy callback glue +void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); + +struct LLChatTypeTrigger { + std::string name; + EChatType type; +}; + +static LLChatTypeTrigger sChatTypeTriggers[] = { + { "/whisper" , CHAT_TYPE_WHISPER}, + { "/shout" , CHAT_TYPE_SHOUT} +}; + + +LLFloaterIMNearbyChat::LLFloaterIMNearbyChat(const LLSD& llsd) +: LLFloaterIMSessionTab(llsd), + //mOutputMonitor(NULL), + mSpeakerMgr(NULL), + mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT) +{ + mIsP2PChat = false; + mIsNearbyChat = true; + mSpeakerMgr = LLLocalSpeakerMgr::getInstance(); + mSessionID = LLUUID(); +} + +//static +LLFloaterIMNearbyChat* LLFloaterIMNearbyChat::buildFloater(const LLSD& key) +{ + LLFloaterReg::getInstance("im_container"); + return new LLFloaterIMNearbyChat(key); +} + +//virtual +BOOL LLFloaterIMNearbyChat::postBuild() +{ + setIsSingleInstance(TRUE); + BOOL result = LLFloaterIMSessionTab::postBuild(); + + mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5)); + mInputEditor->setCommitCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxCommit, this)); + mInputEditor->setKeystrokeCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxKeystroke, this)); + mInputEditor->setFocusLostCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusLost, this)); + mInputEditor->setFocusReceivedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusReceived, this)); + mInputEditor->setLabel(LLTrans::getString("NearbyChatTitle")); + + // Title must be defined BEFORE call to addConversationListItem() because + // it is used to show the item's name in the conversations list + setTitle(LLTrans::getString("NearbyChatTitle")); + + // obsolete, but may be needed for backward compatibility? + gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true); + + if (gSavedPerAccountSettings.getBOOL("LogShowHistory")) + { + loadHistory(); + } + + return result; +} + +// virtual +void LLFloaterIMNearbyChat::closeHostedFloater() +{ + // Should check how many conversations are ongoing. Close all if 1 only (the Nearby Chat), select next one otherwise + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + if (floater_container->getConversationListItemSize() == 1) + { + floater_container->closeFloater(); + } + else + { + if (!getHost()) + { + setVisible(FALSE); + } + floater_container->selectNextConversationByID(LLUUID()); + } +} + +// virtual +void LLFloaterIMNearbyChat::refresh() +{ + displaySpeakingIndicator(); + updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState()); + + // *HACK: Update transparency type depending on whether our children have focus. + // This is needed because this floater is chrome and thus cannot accept focus, so + // the transparency type setting code from LLFloater::setFocus() isn't reached. + if (getTransparencyType() != TT_DEFAULT) + { + setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE); + } +} + +void LLFloaterIMNearbyChat::reloadMessages(bool clean_messages/* = false*/) +{ + if (clean_messages) + { + mMessageArchive.clear(); + loadHistory(); + } + + mChatHistory->clear(); + + LLSD do_not_log; + do_not_log["do_not_log"] = true; + for(std::vector<LLChat>::iterator it = mMessageArchive.begin();it!=mMessageArchive.end();++it) + { + // Update the messages without re-writing them to a log file. + addMessage(*it,false, do_not_log); + } +} + +void LLFloaterIMNearbyChat::loadHistory() +{ + LLSD do_not_log; + do_not_log["do_not_log"] = true; + + std::list<LLSD> history; + LLLogChat::loadChatHistory("chat", history); + + std::list<LLSD>::const_iterator it = history.begin(); + while (it != history.end()) + { + const LLSD& msg = *it; + + std::string from = msg[LL_IM_FROM]; + LLUUID from_id; + if (msg[LL_IM_FROM_ID].isDefined()) + { + from_id = msg[LL_IM_FROM_ID].asUUID(); + } + else + { + std::string legacy_name = gCacheName->buildLegacyName(from); + gCacheName->getUUID(legacy_name, from_id); + } + + LLChat chat; + chat.mFromName = from; + chat.mFromID = from_id; + chat.mText = msg[LL_IM_TEXT].asString(); + chat.mTimeStr = msg[LL_IM_TIME].asString(); + chat.mChatStyle = CHAT_STYLE_HISTORY; + + chat.mSourceType = CHAT_SOURCE_AGENT; + if (from_id.isNull() && SYSTEM_FROM == from) + { + chat.mSourceType = CHAT_SOURCE_SYSTEM; + + } + else if (from_id.isNull()) + { + chat.mSourceType = isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT; + } + + addMessage(chat, true, do_not_log); + + it++; + } +} + +void LLFloaterIMNearbyChat::removeScreenChat() +{ + LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID"))); + if(chat_channel) + { + chat_channel->removeToastsFromChannel(); + } +} + + +void LLFloaterIMNearbyChat::setVisible(BOOL visible) +{ + LLFloaterIMSessionTab::setVisible(visible); + + if(visible) + { + removeScreenChat(); + } +} + + +void LLFloaterIMNearbyChat::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key) +{ + LLFloaterIMSessionTab::setVisibleAndFrontmost(take_focus, key); + + if(!isTornOff() && matchesKey(key)) + { + LLFloaterIMContainer::getInstance()->selectConversationPair(mSessionID, true, false); + } +} + +// virtual +void LLFloaterIMNearbyChat::onTearOffClicked() +{ + LLFloaterIMSessionTab::onTearOffClicked(); + + // see CHUI-170: Save torn-off state of the nearby chat between sessions + BOOL in_the_multifloater = !isTornOff(); + gSavedSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater); +} + + +// virtual +void LLFloaterIMNearbyChat::onOpen(const LLSD& key) +{ + LLFloaterIMSessionTab::onOpen(key); + showTranslationCheckbox(LLTranslate::isTranslationConfigured()); +} + +// virtual +void LLFloaterIMNearbyChat::onClose(bool app_quitting) +{ + // Override LLFloaterIMSessionTab::onClose() so that Nearby Chat is not removed from the conversation floater + onClickCloseBtn(); +} + +// virtual +void LLFloaterIMNearbyChat::onClickCloseBtn() +{ + if (!isTornOff()) + return; + onTearOffClicked(); + + LLFloaterIMContainer *im_box = LLFloaterIMContainer::findInstance(); + if (im_box) + { + im_box->onNearbyChatClosed(); + } +} + +void LLFloaterIMNearbyChat::onChatFontChange(LLFontGL* fontp) +{ + // Update things with the new font whohoo + if (mInputEditor) + { + mInputEditor->setFont(fontp); + } +} + + +void LLFloaterIMNearbyChat::show() +{ + if (isChatMultiTab()) + { + openFloater(getKey()); + } +} + +bool LLFloaterIMNearbyChat::isChatVisible() const +{ + bool isVisible = false; + LLFloaterIMContainer* im_box = LLFloaterIMContainer::getInstance(); + // Is the IM floater container ever null? + llassert(im_box != NULL); + if (im_box != NULL) + { + isVisible = + isChatMultiTab() && gSavedSettings.getBOOL("NearbyChatIsNotTornOff")? + im_box->getVisible() && !im_box->isMinimized() : + getVisible() && !isMinimized(); + } + + return isVisible; +} + +void LLFloaterIMNearbyChat::showHistory() +{ + openFloater(); + setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT); +} + +std::string LLFloaterIMNearbyChat::getCurrentChat() +{ + return mInputEditor ? mInputEditor->getText() : LLStringUtil::null; +} + +// virtual +BOOL LLFloaterIMNearbyChat::handleKeyHere( KEY key, MASK mask ) +{ + BOOL handled = FALSE; + + if( KEY_RETURN == key && mask == MASK_CONTROL) + { + // shout + sendChat(CHAT_TYPE_SHOUT); + handled = TRUE; + } + else if (KEY_RETURN == key && mask == MASK_SHIFT) + { + // whisper + sendChat(CHAT_TYPE_WHISPER); + handled = TRUE; + } + + + if((mask == MASK_ALT) && isTornOff()) + { + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + if ((KEY_UP == key) || (KEY_LEFT == key)) + { + floater_container->selectNextorPreviousConversation(false); + handled = TRUE; + } + if ((KEY_DOWN == key ) || (KEY_RIGHT == key)) + { + floater_container->selectNextorPreviousConversation(true); + handled = TRUE; + } + } + + return handled; +} + +BOOL LLFloaterIMNearbyChat::matchChatTypeTrigger(const std::string& in_str, std::string* out_str) +{ + U32 in_len = in_str.length(); + S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); + + bool string_was_found = false; + + for (S32 n = 0; n < cnt && !string_was_found; n++) + { + if (in_len <= sChatTypeTriggers[n].name.length()) + { + std::string trigger_trunc = sChatTypeTriggers[n].name; + LLStringUtil::truncate(trigger_trunc, in_len); + + if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc)) + { + *out_str = sChatTypeTriggers[n].name; + string_was_found = true; + } + } + } + + return string_was_found; +} + +void LLFloaterIMNearbyChat::onChatBoxKeystroke() +{ + LLFirstUse::otherAvatarChatFirst(false); + + LLWString raw_text = mInputEditor->getWText(); + + // Can't trim the end, because that will cause autocompletion + // to eat trailing spaces that might be part of a gesture. + LLWStringUtil::trimHead(raw_text); + + S32 length = raw_text.length(); + + if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences + { + gAgent.startTyping(); + } + else + { + gAgent.stopTyping(); + } + + /* Doesn't work -- can't tell the difference between a backspace + that killed the selection vs. backspace at the end of line. + if (length > 1 + && text[0] == '/' + && key == KEY_BACKSPACE) + { + // the selection will already be deleted, but we need to trim + // off the character before + std::string new_text = raw_text.substr(0, length-1); + mInputEditor->setText( new_text ); + mInputEditor->setCursorToEnd(); + length = length - 1; + } + */ + + KEY key = gKeyboard->currentKey(); + + // Ignore "special" keys, like backspace, arrows, etc. + if (length > 1 + && raw_text[0] == '/' + && key < KEY_SPECIAL) + { + // we're starting a gesture, attempt to autocomplete + + std::string utf8_trigger = wstring_to_utf8str(raw_text); + std::string utf8_out_str(utf8_trigger); + + if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str)) + { + std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); + mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part + + // Select to end of line, starting from the character + // after the last one the user typed. + mInputEditor->selectNext(rest_of_match, false); + } + else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str)) + { + std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); + mInputEditor->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part + mInputEditor->endOfDoc(); + } + + //llinfos << "GESTUREDEBUG " << trigger + // << " len " << length + // << " outlen " << out_str.getLength() + // << llendl; + } +} + +// static +void LLFloaterIMNearbyChat::onChatBoxFocusLost() +{ + // stop typing animation + gAgent.stopTyping(); +} + +void LLFloaterIMNearbyChat::onChatBoxFocusReceived() +{ + mInputEditor->setEnabled(!gDisconnected); +} + +EChatType LLFloaterIMNearbyChat::processChatTypeTriggers(EChatType type, std::string &str) +{ + U32 length = str.length(); + S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); + + for (S32 n = 0; n < cnt; n++) + { + if (length >= sChatTypeTriggers[n].name.length()) + { + std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length()); + + if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name)) + { + U32 trigger_length = sChatTypeTriggers[n].name.length(); + + // It's to remove space after trigger name + if (length > trigger_length && str[trigger_length] == ' ') + trigger_length++; + + str = str.substr(trigger_length, length); + + if (CHAT_TYPE_NORMAL == type) + return sChatTypeTriggers[n].type; + else + break; + } + } + } + + return type; +} + +void LLFloaterIMNearbyChat::sendChat( EChatType type ) +{ + if (mInputEditor) + { + LLWString text = mInputEditor->getWText(); + LLWStringUtil::trim(text); + LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines. + if (!text.empty()) + { + // Check if this is destined for another channel + S32 channel = 0; + stripChannelNumber(text, &channel); + + std::string utf8text = wstring_to_utf8str(text); + // Try to trigger a gesture, if not chat to a script. + std::string utf8_revised_text; + if (0 == channel) + { + // discard returned "found" boolean + LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text); + } + else + { + utf8_revised_text = utf8text; + } + + utf8_revised_text = utf8str_trim(utf8_revised_text); + + type = processChatTypeTriggers(type, utf8_revised_text); + + if (!utf8_revised_text.empty()) + { + // Chat with animation + sendChatFromViewer(utf8_revised_text, type, TRUE); + } + } + + mInputEditor->setText(LLStringExplicit("")); + } + + gAgent.stopTyping(); + + // If the user wants to stop chatting on hitting return, lose focus + // and go out of chat mode. + if (gSavedSettings.getBOOL("CloseChatOnReturn")) + { + stopChat(); + } +} + +void LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args) +{ + appendMessage(chat, args); + + if(archive) + { + mMessageArchive.push_back(chat); + if(mMessageArchive.size() > 200) + { + mMessageArchive.erase(mMessageArchive.begin()); + } + } + + // logging + if (!args["do_not_log"].asBoolean() && gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 1) + { + std::string from_name = chat.mFromName; + + if (chat.mSourceType == CHAT_SOURCE_AGENT) + { + // if the chat is coming from an agent, log the complete name + LLAvatarName av_name; + LLAvatarNameCache::get(chat.mFromID, &av_name); + + if (!av_name.isDisplayNameDefault()) + { + from_name = av_name.getCompleteName(); + } + } + + LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText); + } +} + + +void LLFloaterIMNearbyChat::onChatBoxCommit() +{ + if (mInputEditor->getText().length() > 0) + { + sendChat(CHAT_TYPE_NORMAL); + } + + gAgent.stopTyping(); +} + +void LLFloaterIMNearbyChat::displaySpeakingIndicator() +{ + LLSpeakerMgr::speaker_list_t speaker_list; + LLUUID id; + + id.setNull(); + mSpeakerMgr->update(FALSE); + mSpeakerMgr->getSpeakerList(&speaker_list, FALSE); + + for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i) + { + LLPointer<LLSpeaker> s = *i; + if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING) + { + id = s->mID; + break; + } + } +} + +void LLFloaterIMNearbyChat::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate) +{ + sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate); +} + +void LLFloaterIMNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate) +{ + // Look for "/20 foo" channel chats. + S32 channel = 0; + LLWString out_text = stripChannelNumber(wtext, &channel); + std::string utf8_out_text = wstring_to_utf8str(out_text); + std::string utf8_text = wstring_to_utf8str(wtext); + + utf8_text = utf8str_trim(utf8_text); + if (!utf8_text.empty()) + { + utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1); + } + + // Don't animate for chats people can't hear (chat to scripts) + if (animate && (channel == 0)) + { + if (type == CHAT_TYPE_WHISPER) + { + lldebugs << "You whisper " << utf8_text << llendl; + gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START); + } + else if (type == CHAT_TYPE_NORMAL) + { + lldebugs << "You say " << utf8_text << llendl; + gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START); + } + else if (type == CHAT_TYPE_SHOUT) + { + lldebugs << "You shout " << utf8_text << llendl; + gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START); + } + else + { + llinfos << "send_chat_from_viewer() - invalid volume" << llendl; + return; + } + } + else + { + if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP) + { + lldebugs << "Channel chat: " << utf8_text << llendl; + } + } + + send_chat_from_viewer(utf8_out_text, type, channel); +} + +// static +bool LLFloaterIMNearbyChat::isWordsName(const std::string& name) +{ + // checking to see if it's display name plus username in parentheses + S32 open_paren = name.find(" (", 0); + S32 close_paren = name.find(')', 0); + + if (open_paren != std::string::npos && + close_paren == name.length()-1) + { + return true; + } + else + { + //checking for a single space + S32 pos = name.find(' ', 0); + return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos; + } +} + +// static +void LLFloaterIMNearbyChat::startChat(const char* line) +{ + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + if (nearby_chat) + { + nearby_chat->show(); + nearby_chat->setVisible(TRUE); + nearby_chat->setFocus(TRUE); + nearby_chat->mInputEditor->setFocus(TRUE); + + if (line) + { + std::string line_string(line); + nearby_chat->mInputEditor->setText(line_string); + } + + nearby_chat->mInputEditor->endOfDoc(); + } +} + +// Exit "chat mode" and do the appropriate focus changes +// static +void LLFloaterIMNearbyChat::stopChat() +{ + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + if (nearby_chat) + { + nearby_chat->mInputEditor->setFocus(FALSE); + gAgent.stopTyping(); + } +} + +// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20. +// Otherwise returns input and channel 0. +LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32* channel) +{ + if (mesg[0] == '/' + && mesg[1] == '/') + { + // This is a "repeat channel send" + *channel = sLastSpecialChatChannel; + return mesg.substr(2, mesg.length() - 2); + } + else if (mesg[0] == '/' + && mesg[1] + && LLStringOps::isDigit(mesg[1])) + { + // This a special "/20" speak on a channel + S32 pos = 0; + + // Copy the channel number into a string + LLWString channel_string; + llwchar c; + do + { + c = mesg[pos+1]; + channel_string.push_back(c); + pos++; + } + while(c && pos < 64 && LLStringOps::isDigit(c)); + + // Move the pointer forward to the first non-whitespace char + // Check isspace before looping, so we can handle "/33foo" + // as well as "/33 foo" + while(c && iswspace(c)) + { + c = mesg[pos+1]; + pos++; + } + + sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10); + *channel = sLastSpecialChatChannel; + return mesg.substr(pos, mesg.length() - pos); + } + else + { + // This is normal chat. + *channel = 0; + return mesg; + } +} + +void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) +{ + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_ChatFromViewer); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ChatData); + msg->addStringFast(_PREHASH_Message, utf8_out_text); + msg->addU8Fast(_PREHASH_Type, type); + msg->addS32("Channel", channel); + + gAgent.sendReliableMessage(); + + LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); +} + +class LLChatCommandHandler : public LLCommandHandler +{ +public: + // not allowed from outside the app + LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { } + + // Your code here + bool handle(const LLSD& tokens, const LLSD& query_map, + LLMediaCtrl* web) + { + bool retval = false; + // Need at least 2 tokens to have a valid message. + if (tokens.size() < 2) + { + retval = false; + } + else + { + S32 channel = tokens[0].asInteger(); + // VWR-19499 Restrict function to chat channels greater than 0. + if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG)) + { + retval = true; + // Send unescaped message, see EXT-6353. + std::string unescaped_mesg (LLURI::unescape(tokens[1].asString())); + send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel); + } + else + { + retval = false; + // Tell us this is an unsupported SLurl. + } + } + return retval; + } +}; + +// Creating the object registers with the dispatcher. +LLChatCommandHandler gChatHandler; diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llfloaterimnearbychat.h index e9734899b3..05b48cccb0 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llfloaterimnearbychat.h @@ -1,6 +1,6 @@ /** - * @file llnearbychatbar.h - * @brief LLNearbyChatBar class definition + * @file llfloaterimnearbychat.h + * @brief LLFloaterIMNearbyChat class definition * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code @@ -24,33 +24,54 @@ * $/LicenseInfo$ */ -#ifndef LL_LLNEARBYCHATBAR_H -#define LL_LLNEARBYCHATBAR_H +#ifndef LL_LLFLOATERIMNEARBYCHAT_H +#define LL_LLFLOATERIMNEARBYCHAT_H -#include "llfloater.h" +#include "llfloaterimsessiontab.h" #include "llcombobox.h" #include "llgesturemgr.h" #include "llchat.h" #include "llvoiceclient.h" #include "lloutputmonitorctrl.h" #include "llspeakers.h" +#include "llscrollbar.h" +#include "llviewerchat.h" +#include "llpanel.h" -class LLNearbyChatBar : public LLFloater +class LLResizeBar; + +class LLFloaterIMNearbyChat + : public LLFloaterIMSessionTab { public: // constructor for inline chat-bars (e.g. hosted in chat history window) - LLNearbyChatBar(const LLSD& key); - ~LLNearbyChatBar() {} + LLFloaterIMNearbyChat(const LLSD& key = LLSD(LLUUID())); + ~LLFloaterIMNearbyChat() {} + + static LLFloaterIMNearbyChat* buildFloater(const LLSD& key); - virtual BOOL postBuild(); + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void onClose(bool app_quitting); + /*virtual*/ void setVisible(BOOL visible); + /*virtual*/ void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD()); + /*virtual*/ void closeHostedFloater(); - static LLNearbyChatBar* getInstance(); + void loadHistory(); + void reloadMessages(bool clean_messages = false); + void removeScreenChat(); - LLLineEditor* getChatBox() { return mChatBox; } + void show(); + bool isChatVisible() const; - virtual void draw(); + /** @param archive true - to save a message to the chat history log */ + void addMessage (const LLChat& message,bool archive = true, const LLSD &args = LLSD()); + + LLChatEntry* getChatBox() { return mInputEditor; } std::string getCurrentChat(); + S32 getMessageArchiveLength() {return mMessageArchive.size();} + virtual BOOL handleKeyHere( KEY key, MASK mask ); static void startChat(const char* line); @@ -59,22 +80,22 @@ public: static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate); static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); + static bool isWordsName(const std::string& name); + void showHistory(); - /*virtual*/void setMinimized(BOOL b); protected: static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str); - static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata); - static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata); + void onChatBoxKeystroke(); + void onChatBoxFocusLost(); void onChatBoxFocusReceived(); void sendChat( EChatType type ); void onChatBoxCommit(); void onChatFontChange(LLFontGL* fontp); - /* virtual */ bool applyRectControl(); - - void onToggleNearbyChatPanel(); + /*virtual*/ void onTearOffClicked(); + /*virtual*/ void onClickCloseBtn(); static LLWString stripChannelNumber(const LLWString &mesg, S32* channel); EChatType processChatTypeTriggers(EChatType type, std::string &str); @@ -84,11 +105,15 @@ protected: // Which non-zero channel did we last chat on? static S32 sLastSpecialChatChannel; - LLLineEditor* mChatBox; - LLOutputMonitorCtrl* mOutputMonitor; - LLLocalSpeakerMgr* mSpeakerMgr; + LLOutputMonitorCtrl* mOutputMonitor; + LLLocalSpeakerMgr* mSpeakerMgr; S32 mExpandedHeight; + +private: + /*virtual*/ void refresh(); + + std::vector<LLChat> mMessageArchive; }; -#endif +#endif // LL_LLFLOATERIMNEARBYCHAT_H diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index c43c95a366..8870d54cd2 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -1,6 +1,6 @@ /** - * @file LLNearbyChatHandler.cpp - * @brief Nearby chat notification managment + * @file LLFloaterIMNearbyChatHandler.cpp + * @brief Nearby chat chat managment * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code @@ -27,63 +27,67 @@ #include "llviewerprecompiledheaders.h" #include "llagentdata.h" // for gAgentID -#include "llnearbychathandler.h" +#include "llfloaterimnearbychathandler.h" #include "llchatitemscontainerctrl.h" #include "llfirstuse.h" #include "llfloaterscriptdebug.h" #include "llhints.h" -#include "llnearbychat.h" +#include "llfloaterimnearbychat.h" #include "llrecentpeople.h" #include "llviewercontrol.h" #include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance #include "llviewerwindow.h"//for screen channel position -#include "llnearbychatbar.h" +#include "llfloaterimnearbychat.h" +#include "llfloaterimcontainer.h" #include "llrootview.h" #include "lllayoutstack.h" -//add LLNearbyChatHandler to LLNotificationsUI namespace +//add LLFloaterIMNearbyChatHandler to LLNotificationsUI namespace using namespace LLNotificationsUI; -//----------------------------------------------------------------------------------------------- -//LLNearbyChatScreenChannel -//----------------------------------------------------------------------------------------------- -LLToastPanelBase* createToastPanel() +static LLFloaterIMNearbyChatToastPanel* createToastPanel() { - LLNearbyChatToastPanel* item = LLNearbyChatToastPanel::createInstance(); + LLFloaterIMNearbyChatToastPanel* item = LLFloaterIMNearbyChatToastPanel::createInstance(); return item; } -class LLNearbyChatScreenChannel: public LLScreenChannelBase + +//----------------------------------------------------------------------------------------------- +//LLFloaterIMNearbyChatScreenChannel +//----------------------------------------------------------------------------------------------- + +class LLFloaterIMNearbyChatScreenChannel: public LLScreenChannelBase { - LOG_CLASS(LLNearbyChatScreenChannel); + LOG_CLASS(LLFloaterIMNearbyChatScreenChannel); public: typedef std::vector<LLHandle<LLToast> > toast_vec_t; typedef std::list<LLHandle<LLToast> > toast_list_t; - LLNearbyChatScreenChannel(const Params& p):LLScreenChannelBase(p) + LLFloaterIMNearbyChatScreenChannel(const Params& p) + : LLScreenChannelBase(p) { mStopProcessing = false; LLControlVariable* ctrl = gSavedSettings.getControl("NearbyToastLifeTime").get(); if (ctrl) { - ctrl->getSignal()->connect(boost::bind(&LLNearbyChatScreenChannel::updateToastsLifetime, this)); + ctrl->getSignal()->connect(boost::bind(&LLFloaterIMNearbyChatScreenChannel::updateToastsLifetime, this)); } ctrl = gSavedSettings.getControl("NearbyToastFadingTime").get(); if (ctrl) { - ctrl->getSignal()->connect(boost::bind(&LLNearbyChatScreenChannel::updateToastFadingTime, this)); + ctrl->getSignal()->connect(boost::bind(&LLFloaterIMNearbyChatScreenChannel::updateToastFadingTime, this)); } } - void addNotification (LLSD& notification); + void addChat (LLSD& chat); void arrangeToasts (); - typedef boost::function<LLToastPanelBase* (void )> create_toast_panel_callback_t; + typedef boost::function<LLFloaterIMNearbyChatToastPanel* (void )> create_toast_panel_callback_t; void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;} void onToastDestroyed (LLToast* toast, bool app_quitting); @@ -151,17 +155,19 @@ protected: bool mChannelRect; }; + + //----------------------------------------------------------------------------------------------- -// LLNearbyChatToast +// LLFloaterIMNearbyChatToast //----------------------------------------------------------------------------------------------- // We're deriving from LLToast to be able to override onClose() // in order to handle closing nearby chat toasts properly. -class LLNearbyChatToast : public LLToast +class LLFloaterIMNearbyChatToast : public LLToast { - LOG_CLASS(LLNearbyChatToast); + LOG_CLASS(LLFloaterIMNearbyChatToast); public: - LLNearbyChatToast(const LLToast::Params& p, LLNearbyChatScreenChannel* nc_channelp) + LLFloaterIMNearbyChatToast(const LLToast::Params& p, LLFloaterIMNearbyChatScreenChannel* nc_channelp) : LLToast(p), mNearbyChatScreenChannelp(nc_channelp) { @@ -170,14 +176,14 @@ public: /*virtual*/ void onClose(bool app_quitting); private: - LLNearbyChatScreenChannel* mNearbyChatScreenChannelp; + LLFloaterIMNearbyChatScreenChannel* mNearbyChatScreenChannelp; }; //----------------------------------------------------------------------------------------------- -// LLNearbyChatScreenChannel +// LLFloaterIMNearbyChatScreenChannel //----------------------------------------------------------------------------------------------- -void LLNearbyChatScreenChannel::deactivateToast(LLToast* toast) +void LLFloaterIMNearbyChatScreenChannel::deactivateToast(LLToast* toast) { toast_vec_t::iterator pos = std::find(m_active_toasts.begin(), m_active_toasts.end(), toast->getHandle()); @@ -191,12 +197,12 @@ void LLNearbyChatScreenChannel::deactivateToast(LLToast* toast) m_active_toasts.erase(pos); } -void LLNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer) +void LLFloaterIMNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer) { //we don't need overflow toast in nearby chat } -void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast, bool app_quitting) +void LLFloaterIMNearbyChatScreenChannel::onToastDestroyed(LLToast* toast, bool app_quitting) { LL_DEBUGS("NearbyChat") << "Toast destroyed (app_quitting=" << app_quitting << ")" << llendl; @@ -215,7 +221,7 @@ void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast, bool app_quitti } } -void LLNearbyChatScreenChannel::onToastFade(LLToast* toast) +void LLFloaterIMNearbyChatScreenChannel::onToastFade(LLToast* toast) { LL_DEBUGS("NearbyChat") << "Toast fading" << llendl; @@ -230,7 +236,7 @@ void LLNearbyChatScreenChannel::onToastFade(LLToast* toast) arrangeToasts(); } -void LLNearbyChatScreenChannel::updateToastsLifetime() +void LLFloaterIMNearbyChatScreenChannel::updateToastsLifetime() { S32 seconds = gSavedSettings.getS32("NearbyToastLifeTime"); toast_list_t::iterator it; @@ -241,7 +247,7 @@ void LLNearbyChatScreenChannel::updateToastsLifetime() } } -void LLNearbyChatScreenChannel::updateToastFadingTime() +void LLFloaterIMNearbyChatScreenChannel::updateToastFadingTime() { S32 seconds = gSavedSettings.getS32("NearbyToastFadingTime"); toast_list_t::iterator it; @@ -252,9 +258,9 @@ void LLNearbyChatScreenChannel::updateToastFadingTime() } } -bool LLNearbyChatScreenChannel::createPoolToast() +bool LLFloaterIMNearbyChatScreenChannel::createPoolToast() { - LLToastPanelBase* panel= m_create_toast_panel_callback_t(); + LLFloaterIMNearbyChatToastPanel* panel= m_create_toast_panel_callback_t(); if(!panel) return false; @@ -263,20 +269,20 @@ bool LLNearbyChatScreenChannel::createPoolToast() p.lifetime_secs = gSavedSettings.getS32("NearbyToastLifeTime"); p.fading_time_secs = gSavedSettings.getS32("NearbyToastFadingTime"); - LLToast* toast = new LLNearbyChatToast(p, this); + LLToast* toast = new LLFloaterIMNearbyChatToast(p, this); - toast->setOnFadeCallback(boost::bind(&LLNearbyChatScreenChannel::onToastFade, this, _1)); + toast->setOnFadeCallback(boost::bind(&LLFloaterIMNearbyChatScreenChannel::onToastFade, this, _1)); // If the toast gets somehow prematurely destroyed, deactivate it to prevent crash (STORM-1352). - toast->setOnToastDestroyedCallback(boost::bind(&LLNearbyChatScreenChannel::onToastDestroyed, this, _1, false)); + toast->setOnToastDestroyedCallback(boost::bind(&LLFloaterIMNearbyChatScreenChannel::onToastDestroyed, this, _1, false)); LL_DEBUGS("NearbyChat") << "Creating and pooling toast" << llendl; m_toast_pool.push_back(toast->getHandle()); return true; } -void LLNearbyChatScreenChannel::addNotification(LLSD& notification) +void LLFloaterIMNearbyChatScreenChannel::addChat(LLSD& chat) { //look in pool. if there is any message if(mStopProcessing) @@ -288,16 +294,16 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification) if(m_active_toasts.size()) { - LLUUID fromID = notification["from_id"].asUUID(); // agent id or object id - std::string from = notification["from"].asString(); + LLUUID fromID = chat["from_id"].asUUID(); // agent id or object id + std::string from = chat["from"].asString(); LLToast* toast = m_active_toasts[0].get(); if (toast) { - LLNearbyChatToastPanel* panel = dynamic_cast<LLNearbyChatToastPanel*>(toast->getPanel()); + LLFloaterIMNearbyChatToastPanel* panel = dynamic_cast<LLFloaterIMNearbyChatToastPanel*>(toast->getPanel()); if(panel && panel->messageID() == fromID && panel->getFromName() == from && panel->canAddText()) { - panel->addMessage(notification); + panel->addMessage(chat); toast->reshapeToPanel(); toast->startTimer(); @@ -315,11 +321,11 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification) LL_DEBUGS("NearbyChat") << "Empty pool" << llendl; if(!createPoolToast())//created toast will go to pool. so next call will find it return; - addNotification(notification); + addChat(chat); return; } - int chat_type = notification["chat_type"].asInteger(); + int chat_type = chat["chat_type"].asInteger(); if( ((EChatType)chat_type == CHAT_TYPE_DEBUG_MSG)) { @@ -338,10 +344,10 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification) m_toast_pool.pop_back(); - LLToastPanelBase* panel = dynamic_cast<LLToastPanelBase*>(toast->getPanel()); + LLFloaterIMNearbyChatToastPanel* panel = dynamic_cast<LLFloaterIMNearbyChatToastPanel*>(toast->getPanel()); if(!panel) return; - panel->init(notification); + panel->init(chat); toast->reshapeToPanel(); toast->startTimer(); @@ -360,17 +366,20 @@ static bool sort_toasts_predicate(LLHandle<LLToast> first, LLHandle<LLToast> sec return v1 > v2; } -void LLNearbyChatScreenChannel::arrangeToasts() +void LLFloaterIMNearbyChatScreenChannel::arrangeToasts() { if(mStopProcessing || isHovering()) return; - LLView* floater_snap_region = gViewerWindow->getRootView()->getChildView("floater_snap_region"); - + if (mFloaterSnapRegion == NULL) + { + mFloaterSnapRegion = gViewerWindow->getRootView()->getChildView("floater_snap_region"); + } + if (!getParent()) { // connect to floater snap region just to get resize events, we don't care about being a proper widget - floater_snap_region->addChild(this); + mFloaterSnapRegion->addChild(this); setFollows(FOLLOWS_ALL); } @@ -378,13 +387,13 @@ void LLNearbyChatScreenChannel::arrangeToasts() updateRect(); LLRect channel_rect; - floater_snap_region->localRectToOtherView(floater_snap_region->getLocalRect(), &channel_rect, gFloaterView); + mFloaterSnapRegion->localRectToOtherView(mFloaterSnapRegion->getLocalRect(), &channel_rect, gFloaterView); channel_rect.mLeft += 10; channel_rect.mRight = channel_rect.mLeft + 300; S32 channel_bottom = channel_rect.mBottom; - S32 bottom = channel_bottom + 10; + S32 bottom = channel_bottom + 80; S32 margin = gSavedSettings.getS32("ToastGap"); //sort active toasts @@ -437,32 +446,32 @@ void LLNearbyChatScreenChannel::arrangeToasts() //----------------------------------------------------------------------------------------------- -//LLNearbyChatHandler +//LLFloaterIMNearbyChatHandler //----------------------------------------------------------------------------------------------- -boost::scoped_ptr<LLEventPump> LLNearbyChatHandler::sChatWatcher(new LLEventStream("LLChat")); +boost::scoped_ptr<LLEventPump> LLFloaterIMNearbyChatHandler::sChatWatcher(new LLEventStream("LLChat")); -LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id) +LLFloaterIMNearbyChatHandler::LLFloaterIMNearbyChatHandler() { - mType = type; - // Getting a Channel for our notifications - LLNearbyChatScreenChannel::Params p; + LLFloaterIMNearbyChatScreenChannel::Params p; p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID")); - LLNearbyChatScreenChannel* channel = new LLNearbyChatScreenChannel(p); + LLFloaterIMNearbyChatScreenChannel* channel = new LLFloaterIMNearbyChatScreenChannel(p); - LLNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel; + LLFloaterIMNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel; channel->setCreatePanelCallback(callback); - mChannel = LLChannelManager::getInstance()->addChannel(channel); + LLChannelManager::getInstance()->addChannel(channel); + + mChannel = channel->getHandle(); } -LLNearbyChatHandler::~LLNearbyChatHandler() +LLFloaterIMNearbyChatHandler::~LLFloaterIMNearbyChatHandler() { } -void LLNearbyChatHandler::initChannel() +void LLFloaterIMNearbyChatHandler::initChannel() { //LLRect snap_rect = gFloaterView->getSnapRect(); //mChannel->init(snap_rect.mLeft, snap_rect.mLeft + 200); @@ -470,7 +479,7 @@ void LLNearbyChatHandler::initChannel() -void LLNearbyChatHandler::processChat(const LLChat& chat_msg, // WARNING - not really const, see hack below changing chat_msg.mText +void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args) { if(chat_msg.mMuted == TRUE) @@ -479,46 +488,27 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, // WARNING - not if(chat_msg.mText.empty()) return;//don't process empty messages - // Handle irc styled messages for toast panel - // HACK ALERT - changes mText, stripping out IRC style "/me" prefixes - LLChat& tmp_chat = const_cast<LLChat&>(chat_msg); - std::string original_message = tmp_chat.mText; // Save un-modified version of chat text - if (tmp_chat.mChatStyle == CHAT_STYLE_IRC) - { - if(!tmp_chat.mFromName.empty()) - tmp_chat.mText = tmp_chat.mFromName + tmp_chat.mText.substr(3); - else - tmp_chat.mText = tmp_chat.mText.substr(3); - } - - LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar"); - - LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat"); - - { - //sometimes its usefull to have no name at all... - //if(tmp_chat.mFromName.empty() && tmp_chat.mFromID!= LLUUID::null) - // tmp_chat.mFromName = tmp_chat.mFromID.asString(); - } + LLFloaterReg::getInstance("im_container"); + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); // Build notification data - LLSD notification; - notification["message"] = chat_msg.mText; - notification["from"] = chat_msg.mFromName; - notification["from_id"] = chat_msg.mFromID; - notification["time"] = chat_msg.mTime; - notification["source"] = (S32)chat_msg.mSourceType; - notification["chat_type"] = (S32)chat_msg.mChatType; - notification["chat_style"] = (S32)chat_msg.mChatStyle; + LLSD chat; + chat["message"] = chat_msg.mText; + chat["from"] = chat_msg.mFromName; + chat["from_id"] = chat_msg.mFromID; + chat["time"] = chat_msg.mTime; + chat["source"] = (S32)chat_msg.mSourceType; + chat["chat_type"] = (S32)chat_msg.mChatType; + chat["chat_style"] = (S32)chat_msg.mChatStyle; // Pass sender info so that it can be rendered properly (STORM-1021). - notification["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args); + chat["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args); if (chat_msg.mChatType == CHAT_TYPE_DIRECT && chat_msg.mText.length() > 0 && chat_msg.mText[0] == '@') { // Send event on to LLEventStream and exit - sChatWatcher->post(notification); + sChatWatcher->post(chat); return; } @@ -543,7 +533,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, // WARNING - not LLViewerChat::getChatColor(chat_msg,txt_color); - LLFloaterScriptDebug::addScriptLine(original_message, // Send full message with "/me" style prefix + LLFloaterScriptDebug::addScriptLine(chat_msg.mText, chat_msg.mFromName, txt_color, chat_msg.mFromID); @@ -565,18 +555,20 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, // WARNING - not } // Send event on to LLEventStream - sChatWatcher->post(notification); + sChatWatcher->post(chat); + LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); - if( !chat_bar->isMinimized() - && nearby_chat->isInVisibleChain() + if( nearby_chat->hasFocus() + || im_box->hasFocus() || ( chat_msg.mSourceType == CHAT_SOURCE_AGENT && gSavedSettings.getBOOL("UseChatBubbles") ) - || !mChannel->getShowToasts() ) // to prevent toasts in Busy mode + || mChannel.isDead() + || !mChannel.get()->getShowToasts() ) // to prevent toasts in Do Not Disturb mode return;//no need in toast if chat is visible or if bubble chat is enabled // arrange a channel on a screen - if(!mChannel->getVisible()) + if(!mChannel.get()->getVisible()) { initChannel(); } @@ -593,36 +585,62 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, // WARNING - not } */ - LLNearbyChatScreenChannel* channel = dynamic_cast<LLNearbyChatScreenChannel*>(mChannel); + LLFloaterIMNearbyChatScreenChannel* channel = dynamic_cast<LLFloaterIMNearbyChatScreenChannel*>(mChannel.get()); if(channel) { - // Add a nearby chat toast. - LLUUID id; - id.generate(); - notification["id"] = id; - std::string r_color_name = "White"; - F32 r_color_alpha = 1.0f; - LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha); - - notification["text_color"] = r_color_name; - notification["color_alpha"] = r_color_alpha; - notification["font_size"] = (S32)LLViewerChat::getChatFontSize() ; - channel->addNotification(notification); - } -} + // Handle IRC styled messages. + std::string toast_msg; + if (chat_msg.mChatStyle == CHAT_STYLE_IRC) + { + if (!chat_msg.mFromName.empty()) + { + toast_msg += chat_msg.mFromName; + } + toast_msg += chat_msg.mText.substr(3); + } + else + { + toast_msg = chat_msg.mText; + } -void LLNearbyChatHandler::onDeleteToast(LLToast* toast) -{ + //Don't show nearby toast, if conversation is visible but not focused + LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(LLUUID()); + if (session_floater + && session_floater->isInVisibleChain() && !session_floater->isMinimized() + && !(session_floater->getHost() && session_floater->getHost()->isMinimized())) + { + return; + } + + //Will show toast when chat preference is set + if(gSavedSettings.getString("NotificationNearbyChatOptions") == "toast") + { + // Add a nearby chat toast. + LLUUID id; + id.generate(); + chat["id"] = id; + std::string r_color_name = "White"; + F32 r_color_alpha = 1.0f; + LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha); + + chat["text_color"] = r_color_name; + chat["color_alpha"] = r_color_alpha; + chat["font_size"] = (S32)LLViewerChat::getChatFontSize() ; + chat["message"] = toast_msg; + channel->addChat(chat); + } + + } } //----------------------------------------------------------------------------------------------- -// LLNearbyChatToast +// LLFloaterIMNearbyChatToast //----------------------------------------------------------------------------------------------- // virtual -void LLNearbyChatToast::onClose(bool app_quitting) +void LLFloaterIMNearbyChatToast::onClose(bool app_quitting) { mNearbyChatScreenChannelp->onToastDestroyed(this, app_quitting); } diff --git a/indra/newview/llnearbychathandler.h b/indra/newview/llfloaterimnearbychathandler.h index b0e4f62d51..5e6f8cde30 100644 --- a/indra/newview/llnearbychathandler.h +++ b/indra/newview/llfloaterimnearbychathandler.h @@ -1,5 +1,5 @@ /** - * @file llnearbychathandler.h + * @file llfloaterimnearbychathandler.h * @brief nearby chat notify * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ @@ -24,27 +24,26 @@ * $/LicenseInfo$ */ -#ifndef LL_LLNEARBYCHATHANDLER_H -#define LL_LLNEARBYCHATHANDLER_H +#ifndef LL_LLFLOATERIMNEARBYCHATHANDLER_H +#define LL_LLFLOATERIMNEARBYCHATHANDLER_H #include "llnotificationhandler.h" class LLEventPump; -//add LLNearbyChatHandler to LLNotificationsUI namespace +//add LLFloaterIMNearbyChatHandler to LLNotificationsUI namespace namespace LLNotificationsUI{ -class LLNearbyChatHandler : public LLChatHandler +class LLFloaterIMNearbyChatHandler : public LLChatHandler { public: - LLNearbyChatHandler(e_notification_type type,const LLSD& id); - virtual ~LLNearbyChatHandler(); + LLFloaterIMNearbyChatHandler(); + virtual ~LLFloaterIMNearbyChatHandler(); virtual void processChat(const LLChat& chat_msg, const LLSD &args); protected: - virtual void onDeleteToast(LLToast* toast); virtual void initChannel(); static boost::scoped_ptr<LLEventPump> sChatWatcher; @@ -52,4 +51,4 @@ protected: } -#endif /* LL_LLNEARBYCHATHANDLER_H */ +#endif /* LL_LLFLOATERIMNEARBYCHATHANDLER_H */ diff --git a/indra/newview/llnearbychatbarlistener.cpp b/indra/newview/llfloaterimnearbychatlistener.cpp index a63e1fb76e..14a22bcd84 100644 --- a/indra/newview/llnearbychatbarlistener.cpp +++ b/indra/newview/llfloaterimnearbychatlistener.cpp @@ -1,8 +1,8 @@ /** - * @file llnearbychatbarlistener.cpp + * @file llfloaterimnearbychatlistener.cpp * @author Dave Simmons * @date 2011-03-15 - * @brief Implementation for LLNearbyChatBarListener. + * @brief Implementation for LLFloaterIMNearbyChatListener. * * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code @@ -28,15 +28,15 @@ #include "llviewerprecompiledheaders.h" -#include "llnearbychatbarlistener.h" -#include "llnearbychatbar.h" +#include "llfloaterimnearbychatlistener.h" +#include "llfloaterimnearbychat.h" #include "llagent.h" #include "llchat.h" -LLNearbyChatBarListener::LLNearbyChatBarListener(LLNearbyChatBar & chatbar) +LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar) : LLEventAPI("LLChatBar", "LLChatBar listener to (e.g.) sendChat, etc."), mChatbar(chatbar) @@ -46,12 +46,12 @@ LLNearbyChatBarListener::LLNearbyChatBarListener(LLNearbyChatBar & chatbar) "[\"message\"] chat message text [required]\n" "[\"channel\"] chat channel number [default = 0]\n" "[\"type\"] chat type \"whisper\", \"normal\", \"shout\" [default = \"normal\"]", - &LLNearbyChatBarListener::sendChat); + &LLFloaterIMNearbyChatListener::sendChat); } // "sendChat" command -void LLNearbyChatBarListener::sendChat(LLSD const & chat_data) const +void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const { // Extract the data std::string chat_text = chat_data["message"].asString(); diff --git a/indra/newview/llnearbychatbarlistener.h b/indra/newview/llfloaterimnearbychatlistener.h index 9af9bc1f7b..1470a6dc1e 100644 --- a/indra/newview/llnearbychatbarlistener.h +++ b/indra/newview/llfloaterimnearbychatlistener.h @@ -1,8 +1,8 @@ /** - * @file llnearbychatbarlistener.h + * @file llfloaterimnearbychatlistener.h * @author Dave Simmons * @date 2011-03-15 - * @brief Class definition for LLNearbyChatBarListener. + * @brief Class definition for LLFloaterIMNearbyChatListener. * * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code @@ -27,24 +27,24 @@ */ -#ifndef LL_LLNEARBYCHATBARLISTENER_H -#define LL_LLNEARBYCHATBARLISTENER_H +#ifndef LL_LLFLOATERIMNEARBYCHATLISTENER_H +#define LL_LLFLOATERIMNEARBYCHATLISTENER_H #include "lleventapi.h" class LLSD; -class LLNearbyChatBar; +class LLFloaterIMNearbyChat; -class LLNearbyChatBarListener : public LLEventAPI +class LLFloaterIMNearbyChatListener : public LLEventAPI { public: - LLNearbyChatBarListener(LLNearbyChatBar & chatbar); + LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar); private: void sendChat(LLSD const & chat_data) const; - LLNearbyChatBar & mChatbar; + LLFloaterIMNearbyChat & mChatbar; }; -#endif // LL_LLNEARBYCHATBARLISTENER_H +#endif // LL_LLFLOATERIMNEARBYCHATLISTENER_H diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp new file mode 100644 index 0000000000..50b2ed8c51 --- /dev/null +++ b/indra/newview/llfloaterimsession.cpp @@ -0,0 +1,1269 @@ +/** + * @file llfloaterimsession.cpp + * @brief LLFloaterIMSession class definition + * + * $LicenseInfo:firstyear=2009&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 "llfloaterimsession.h" + +#include "lldraghandle.h" +#include "llnotificationsutil.h" + +#include "llagent.h" +#include "llappviewer.h" +#include "llavataractions.h" +#include "llavatarnamecache.h" +#include "llbutton.h" +#include "llchannelmanager.h" +#include "llchiclet.h" +#include "llchicletbar.h" +#include "llfloaterreg.h" +#include "llfloateravatarpicker.h" +#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container +#include "llinventoryfunctions.h" +//#include "lllayoutstack.h" +#include "llchatentry.h" +#include "lllogchat.h" +#include "llscreenchannel.h" +#include "llsyswellwindow.h" +#include "lltrans.h" +#include "llchathistory.h" +#include "llnotifications.h" +#include "llviewerwindow.h" +#include "lltransientfloatermgr.h" +#include "llinventorymodel.h" +#include "llrootview.h" +#include "llspeakers.h" +#include "llviewerchat.h" +#include "llnotificationmanager.h" +#include "llautoreplace.h" + +floater_showed_signal_t LLFloaterIMSession::sIMFloaterShowedSignal; + +LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id) + : LLFloaterIMSessionTab(session_id), + mLastMessageIndex(-1), + mDialog(IM_NOTHING_SPECIAL), + mTypingStart(), + mShouldSendTypingState(false), + mMeTyping(false), + mOtherTyping(false), + mSessionNameUpdatedForTyping(false), + mTypingTimer(), + mTypingTimeoutTimer(), + mPositioned(false), + mSessionInitialized(false) +{ + mIsNearbyChat = false; + + initIMSession(session_id); + + setOverlapsScreenChannel(true); + + LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this); + mEnableCallbackRegistrar.add("Avatar.EnableGearItem", boost::bind(&LLFloaterIMSession::enableGearMenuItem, this, _2)); + mCommitCallbackRegistrar.add("Avatar.GearDoToSelected", boost::bind(&LLFloaterIMSession::GearDoToSelected, this, _2)); + mEnableCallbackRegistrar.add("Avatar.CheckGearItem", boost::bind(&LLFloaterIMSession::checkGearMenuItem, this, _2)); + + setDocked(true); +} + + +// virtual +void LLFloaterIMSession::refresh() +{ + if (mMeTyping) +{ + // Time out if user hasn't typed for a while. + if (mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS) + { + setTyping(false); + } + } +} + +// virtual +void LLFloaterIMSession::onTearOffClicked() +{ + LLFloaterIMSessionTab::onTearOffClicked(); + + if(mIsP2PChat) + { + if(isTornOff()) + { + mSpeakingIndicator->setSpeakerId(mOtherParticipantUUID, mSessionID); + } + else + { + mSpeakingIndicator->setSpeakerId(LLUUID::null); + } + } +} + +// virtual +void LLFloaterIMSession::onClickCloseBtn() +{ + LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID); + + if (session != NULL) + { + bool is_call_with_chat = session->isGroupSessionType() + || session->isAdHocSessionType() || session->isP2PSessionType(); + + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + + if (is_call_with_chat && voice_channel != NULL + && voice_channel->isActive()) + { + LLSD payload; + payload["session_id"] = mSessionID; + LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback); + return; + } + } + else + { + llwarns << "Empty session with id: " << (mSessionID.asString()) << llendl; + return; + } + + LLFloaterIMSessionTab::onClickCloseBtn(); +} + +/* static */ +void LLFloaterIMSession::newIMCallback(const LLSD& data) +{ + if (data["num_unread"].asInteger() > 0 || data["from_id"].asUUID().isNull()) + { + LLUUID session_id = data["session_id"].asUUID(); + + LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id); + + // update if visible, otherwise will be updated when opened + if (floater && floater->isInVisibleChain()) + { + floater->updateMessages(); + } + } +} + +void LLFloaterIMSession::onVisibilityChange(const LLSD& new_visibility) +{ + bool visible = new_visibility.asBoolean(); + + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + + if (visible && voice_channel && + voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED) + { + LLFloaterReg::showInstance("voice_call", mSessionID); + } + else + { + LLFloaterReg::hideInstance("voice_call", mSessionID); + } +} + +void LLFloaterIMSession::onSendMsg( LLUICtrl* ctrl, void* userdata ) +{ + LLFloaterIMSession* self = (LLFloaterIMSession*) userdata; + self->sendMsgFromInputEditor(); + self->setTyping(false); +} + +bool LLFloaterIMSession::enableGearMenuItem(const LLSD& userdata) +{ + std::string command = userdata.asString(); + uuid_vec_t selected_uuids; + selected_uuids.push_back(mOtherParticipantUUID); + + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + return floater_container->enableContextMenuItem(command, selected_uuids); +} + +void LLFloaterIMSession::GearDoToSelected(const LLSD& userdata) +{ + std::string command = userdata.asString(); + uuid_vec_t selected_uuids; + selected_uuids.push_back(mOtherParticipantUUID); + + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + floater_container->doToParticipants(command, selected_uuids); +} + +bool LLFloaterIMSession::checkGearMenuItem(const LLSD& userdata) +{ + std::string command = userdata.asString(); + uuid_vec_t selected_uuids; + selected_uuids.push_back(mOtherParticipantUUID); + + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + return floater_container->checkContextMenuItem(command, selected_uuids); +} + +void LLFloaterIMSession::sendMsgFromInputEditor() +{ + if (gAgent.isGodlike() + || (mDialog != IM_NOTHING_SPECIAL) + || !mOtherParticipantUUID.isNull()) + { + if (mInputEditor) + { + LLWString text = mInputEditor->getWText(); + LLWStringUtil::trim(text); + LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines. + if(!text.empty()) + { + // Truncate and convert to UTF8 for transport + std::string utf8_text = wstring_to_utf8str(text); + + sendMsg(utf8_text); + + mInputEditor->setText(LLStringUtil::null); + } + } + } + else + { + llinfos << "Cannot send IM to everyone unless you're a god." << llendl; + } +} + +void LLFloaterIMSession::sendMsg(const std::string& msg) +{ + const std::string utf8_text = utf8str_truncate(msg, MAX_MSG_BUF_SIZE - 1); + + if (mSessionInitialized) + { + LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog); + } + else + { + //queue up the message to send once the session is initialized + mQueuedMsgsForInit.append(utf8_text); + } + + updateMessages(); +} + +LLFloaterIMSession::~LLFloaterIMSession() +{ + mVoiceChannelStateChangeConnection.disconnect(); + if(LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver(this); + } + + LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this); +} + + +void LLFloaterIMSession::initIMSession(const LLUUID& session_id) +{ + // Change the floater key to bind it to a new session. + setKey(session_id); + + mSessionID = session_id; + mSession = LLIMModel::getInstance()->findIMSession(mSessionID); + + if (mSession) + { + mIsP2PChat = mSession->isP2PSessionType(); + mSessionInitialized = mSession->mSessionInitialized; + mDialog = mSession->mType; + } +} + +void LLFloaterIMSession::initIMFloater() +{ + const LLUUID& other_party_id = + LLIMModel::getInstance()->getOtherParticipantID(mSessionID); + if (other_party_id.notNull()) + { + mOtherParticipantUUID = other_party_id; + } + + boundVoiceChannel(); + + mTypingStart = LLTrans::getString("IM_typing_start_string"); + + // Show control panel in torn off floaters only. + mParticipantListPanel->setVisible(!getHost() && gSavedSettings.getBOOL("IMShowControlPanel")); + + // Disable input editor if session cannot accept text + if ( mSession && !mSession->mTextIMPossible ) + { + mInputEditor->setEnabled(FALSE); + mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label")); + } + + if (!mIsP2PChat) + { + std::string session_name(LLIMModel::instance().getName(mSessionID)); + updateSessionName(session_name); + } +} + +//virtual +BOOL LLFloaterIMSession::postBuild() +{ + BOOL result = LLFloaterIMSessionTab::postBuild(); + + mInputEditor->setMaxTextLength(1023); + mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5)); + mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) ); + mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) ); + mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) ); + mInputEditor->setCommitCallback(boost::bind(onSendMsg, _1, this)); + + setDocked(true); + + LLButton* add_btn = getChild<LLButton>("add_btn"); + + // Allow to add chat participants depending on the session type + add_btn->setEnabled(isInviteAllowed()); + add_btn->setClickedCallback(boost::bind(&LLFloaterIMSession::onAddButtonClicked, this)); + + childSetAction("voice_call_btn", boost::bind(&LLFloaterIMSession::onCallButtonClicked, this)); + + LLVoiceClient::getInstance()->addObserver(this); + + //*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla" + //see LLFloaterIMPanel for how it is done (IB) + + initIMFloater(); + + return result; +} + +void LLFloaterIMSession::onAddButtonClicked() +{ + LLView * button = findChild<LLView>("toolbar_panel")->findChild<LLButton>("add_btn"); + LLFloater* root_floater = gFloaterView->getParentFloater(this); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterIMSession::addSessionParticipants, this, _1), TRUE, TRUE, FALSE, root_floater->getName(), button); + if (!picker) + { + return; + } + + // Need to disable 'ok' button when selected users are already in conversation. + picker->setOkBtnEnableCb(boost::bind(&LLFloaterIMSession::canAddSelectedToChat, this, _1)); + + if (root_floater) + { + root_floater->addDependentFloater(picker); + } +} + +bool LLFloaterIMSession::canAddSelectedToChat(const uuid_vec_t& uuids) +{ + if (!mSession + || mDialog == IM_SESSION_GROUP_START + || mDialog == IM_SESSION_INVITE && gAgent.isInGroup(mSessionID)) + { + return false; + } + + if (mIsP2PChat) + { + // For a P2P session just check if we are not adding the other participant. + + for (uuid_vec_t::const_iterator id = uuids.begin(); + id != uuids.end(); ++id) + { + if (*id == mOtherParticipantUUID) + { + return false; + } + } + } + else + { + // For a conference session we need to check against the list from LLSpeakerMgr, + // because this list may change when participants join or leave the session. + + LLSpeakerMgr::speaker_list_t speaker_list; + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + speaker_mgr->getSpeakerList(&speaker_list, true); + } + + for (uuid_vec_t::const_iterator id = uuids.begin(); + id != uuids.end(); ++id) + { + for (LLSpeakerMgr::speaker_list_t::const_iterator it = speaker_list.begin(); + it != speaker_list.end(); ++it) + { + const LLPointer<LLSpeaker>& speaker = *it; + if (*id == speaker->mID) + { + return false; + } + } + } + } + + return true; +} + +void LLFloaterIMSession::addSessionParticipants(const uuid_vec_t& uuids) +{ + if (mIsP2PChat) + { + LLSD payload; + LLSD args; + + LLNotificationsUtil::add("ConfirmAddingChatParticipants", args, payload, + boost::bind(&LLFloaterIMSession::addP2PSessionParticipants, this, _1, _2, uuids)); + } + else + { + // remember whom we have invited, to notify others later, when the invited ones actually join + mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end()); + + inviteToSession(uuids); + } +} + +void LLFloaterIMSession::addP2PSessionParticipants(const LLSD& notification, const LLSD& response, const uuid_vec_t& uuids) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) + { + return; + } + + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + + // first check whether this is a voice session + bool is_voice_call = voice_channel != NULL && voice_channel->isActive(); + + uuid_vec_t temp_ids; + + // Add the initial participant of a P2P session + temp_ids.push_back(mOtherParticipantUUID); + temp_ids.insert(temp_ids.end(), uuids.begin(), uuids.end()); + + // then we can close the current session + onClose(false); + + // we start a new session so reset the initialization flag + mSessionInitialized = false; + + // remember whom we have invited, to notify others later, when the invited ones actually join + mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end()); + + // Start a new ad hoc voice call if we invite new participants to a P2P call, + // or start a text chat otherwise. + if (is_voice_call) + { + LLAvatarActions::startAdhocCall(temp_ids, mSessionID); + } + else + { + LLAvatarActions::startConference(temp_ids, mSessionID); + } +} + +void LLFloaterIMSession::sendParticipantsAddedNotification(const uuid_vec_t& uuids) +{ + std::string names_string; + LLAvatarActions::buildResidentsString(uuids, names_string); + LLStringUtil::format_map_t args; + args["[NAME]"] = names_string; + + sendMsg(getString(uuids.size() > 1 ? "multiple_participants_added" : "participant_added", args)); +} + +void LLFloaterIMSession::boundVoiceChannel() +{ + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + if(voice_channel) + { + mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback( + boost::bind(&LLFloaterIMSession::onVoiceChannelStateChanged, this, _1, _2)); + + //call (either p2p, group or ad-hoc) can be already in started state + bool callIsActive = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED; + updateCallBtnState(callIsActive); + } +} + +void LLFloaterIMSession::onCallButtonClicked() +{ + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + if (voice_channel) + { + bool is_call_active = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED; + if (is_call_active) + { + gIMMgr->endCall(mSessionID); + } + else + { + gIMMgr->startCall(mSessionID); + } + } +} + +void LLFloaterIMSession::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ + if(status != STATUS_JOINING && status != STATUS_LEFT_CHANNEL) + { + enableDisableCallBtn(); + } +} + +void LLFloaterIMSession::onVoiceChannelStateChanged( + const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state) +{ + bool callIsActive = new_state >= LLVoiceChannel::STATE_CALL_STARTED; + updateCallBtnState(callIsActive); +} + +void LLFloaterIMSession::updateSessionName(const std::string& name) +{ + if (!name.empty()) + { + LLFloaterIMSessionTab::updateSessionName(name); + mTypingStart.setArg("[NAME]", name); + setTitle (mOtherTyping ? mTypingStart.getString() : name); + mSessionNameUpdatedForTyping = mOtherTyping; + } +} + +//static +LLFloaterIMSession* LLFloaterIMSession::show(const LLUUID& session_id) +{ + closeHiddenIMToasts(); + + if (!gIMMgr->hasSession(session_id)) + return NULL; + + // Test the existence of the floater before we try to create it + bool exist = findInstance(session_id); + + // Get the floater: this will create the instance if it didn't exist + LLFloaterIMSession* floater = getInstance(session_id); + if (!floater) + return NULL; + + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + + // Do not add again existing floaters + if (!exist) + { + // LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END; + // TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists + LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END; + if (floater_container) + { + floater_container->addFloater(floater, TRUE, i_pt); + } + } + + floater->openFloater(floater->getKey()); + + floater->setVisible(TRUE); + + return floater; +} +//static +LLFloaterIMSession* LLFloaterIMSession::findInstance(const LLUUID& session_id) +{ + LLFloaterIMSession* conversation = + LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id); + + return conversation; +} + +LLFloaterIMSession* LLFloaterIMSession::getInstance(const LLUUID& session_id) +{ + LLFloaterIMSession* conversation = + LLFloaterReg::getTypedInstance<LLFloaterIMSession>("impanel", session_id); + + return conversation; +} + +void LLFloaterIMSession::onClose(bool app_quitting) +{ + setTyping(false); + + // The source of much argument and design thrashing + // Should the window hide or the session close when the X is clicked? + // + // Last change: + // EXT-3516 X Button should end IM session, _ button should hide + gIMMgr->leaveSession(mSessionID); + + // Clean up the conversation *after* the session has been ended + LLFloaterIMSessionTab::onClose(app_quitting); +} + +void LLFloaterIMSession::setDocked(bool docked, bool pop_on_undock) +{ + // update notification channel state + LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*> + (LLNotificationsUI::LLChannelManager::getInstance()-> + findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + + if(!isChatMultiTab()) + { + LLTransientDockableFloater::setDocked(docked, pop_on_undock); + } + + // update notification channel state + if(channel) + { + channel->updateShowToastsState(); + channel->redrawToasts(); + } +} + +void LLFloaterIMSession::setVisible(BOOL visible) +{ + LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*> + (LLNotificationsUI::LLChannelManager::getInstance()-> + findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + + LLFloaterIMSessionTab::setVisible(visible); + + // update notification channel state + if(channel) + { + channel->updateShowToastsState(); + channel->redrawToasts(); + } + + if(!visible) + { + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) + { + LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(mSessionID); + if(NULL != chicletp) + { + chicletp->setToggleState(false); + } + } + } + + if (visible && isInVisibleChain()) + { + sIMFloaterShowedSignal(mSessionID); + + } + +} + +BOOL LLFloaterIMSession::getVisible() +{ + bool visible; + + if(isChatMultiTab()) + { + LLFloaterIMContainer* im_container = + LLFloaterIMContainer::getInstance(); + + // Treat inactive floater as invisible. + bool is_active = im_container->getActiveFloater() == this; + + //torn off floater is always inactive + if (!is_active && getHost() != im_container) + { + visible = LLTransientDockableFloater::getVisible(); + } + else + { + // getVisible() returns TRUE when Tabbed IM window is minimized. + visible = is_active && !im_container->isMinimized() + && im_container->getVisible(); + } + } + else + { + visible = LLTransientDockableFloater::getVisible(); + } + + return visible; +} + +//static +bool LLFloaterIMSession::toggle(const LLUUID& session_id) +{ + if(!isChatMultiTab()) + { + LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>( + "impanel", session_id); + if (floater && floater->getVisible() && floater->hasFocus()) + { + // clicking on chiclet to close floater just hides it to maintain existing + // scroll/text entry state + floater->setVisible(false); + return false; + } + else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus())) + { + floater->setVisible(TRUE); + floater->setFocus(TRUE); + return true; + } + } + + // ensure the list of messages is updated when floater is made visible + show(session_id); + return true; +} + +void LLFloaterIMSession::sessionInitReplyReceived(const LLUUID& im_session_id) +{ + mSessionInitialized = true; + + //will be different only for an ad-hoc im session + if (mSessionID != im_session_id) + { + initIMSession(im_session_id); + buildConversationViewParticipant(); + } + + initIMFloater(); + LLFloaterIMSessionTab::updateGearBtn(); + //*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB) + + //need to send delayed messages collected while waiting for session initialization + if (mQueuedMsgsForInit.size()) + { + LLSD::array_iterator iter; + for ( iter = mQueuedMsgsForInit.beginArray(); + iter != mQueuedMsgsForInit.endArray(); ++iter) + { + LLIMModel::sendMessage(iter->asString(), mSessionID, + mOtherParticipantUUID, mDialog); + } + + mQueuedMsgsForInit.clear(); + } +} + +void LLFloaterIMSession::updateMessages() +{ + std::list<LLSD> messages; + + // we shouldn't reset unread message counters if IM floater doesn't have focus + LLIMModel::instance().getMessages( + mSessionID, messages, mLastMessageIndex + 1, hasFocus()); + + if (messages.size()) + { + std::ostringstream message; + std::list<LLSD>::const_reverse_iterator iter = messages.rbegin(); + std::list<LLSD>::const_reverse_iterator iter_end = messages.rend(); + for (; iter != iter_end; ++iter) + { + LLSD msg = *iter; + + std::string time = msg["time"].asString(); + LLUUID from_id = msg["from_id"].asUUID(); + std::string from = msg["from"].asString(); + std::string message = msg["message"].asString(); + bool is_history = msg["is_history"].asBoolean(); + + LLChat chat; + chat.mFromID = from_id; + chat.mSessionID = mSessionID; + chat.mFromName = from; + chat.mTimeStr = time; + chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle; + + // process offer notification + if (msg.has("notification_id")) + { + chat.mNotifId = msg["notification_id"].asUUID(); + // if notification exists - embed it + if (LLNotificationsUtil::find(chat.mNotifId) != NULL) + { + // remove embedded notification from channel + LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*> + (LLNotificationsUI::LLChannelManager::getInstance()-> + findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + if (getVisible()) + { + // toast will be automatically closed since it is not storable toast + channel->hideToast(chat.mNotifId); + } + } + // if notification doesn't exist - try to use next message which should be log entry + else + { + continue; + } + } + //process text message + else + { + chat.mText = message; + } + + // Add the message to the chat log + appendMessage(chat); + mLastMessageIndex = msg["index"].asInteger(); + + // if it is a notification - next message is a notification history log, so skip it + if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL) + { + if (++iter == iter_end) + { + break; + } + else + { + mLastMessageIndex++; + } + } + } + } +} + +void LLFloaterIMSession::reloadMessages(bool clean_messages/* = false*/) +{ + if (clean_messages) + { + LLIMModel::LLIMSession * sessionp = LLIMModel::instance().findIMSession(mSessionID); + + if (NULL != sessionp) + { + sessionp->loadHistory(); + } + } + + mChatHistory->clear(); + mLastMessageIndex = -1; + updateMessages(); + mInputEditor->setFont(LLViewerChat::getChatFont()); +} + +// static +void LLFloaterIMSession::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ) +{ + LLFloaterIMSession* self= (LLFloaterIMSession*) userdata; + + // Allow enabling the LLFloaterIMSession input editor only if session can accept text + LLIMModel::LLIMSession* im_session = + LLIMModel::instance().findIMSession(self->mSessionID); + //TODO: While disabled lllineeditor can receive focus we need to check if it is enabled (EK) + if( im_session && im_session->mTextIMPossible && self->mInputEditor->getEnabled()) + { + //in disconnected state IM input editor should be disabled + self->mInputEditor->setEnabled(!gDisconnected); + } +} + +// static +void LLFloaterIMSession::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata) +{ + LLFloaterIMSession* self = (LLFloaterIMSession*) userdata; + self->setTyping(false); +} + +// static +void LLFloaterIMSession::onInputEditorKeystroke(LLTextEditor* caller, void* userdata) +{ + LLFloaterIMSession* self = (LLFloaterIMSession*)userdata; + std::string text = self->mInputEditor->getText(); + + // Deleting all text counts as stopping typing. + self->setTyping(!text.empty()); +} + +void LLFloaterIMSession::setTyping(bool typing) +{ + if ( typing ) + { + // Started or proceeded typing, reset the typing timeout timer + mTypingTimeoutTimer.reset(); + } + + if ( mMeTyping != typing ) + { + // Typing state is changed + mMeTyping = typing; + // So, should send current state + mShouldSendTypingState = true; + // In case typing is started, send state after some delay + mTypingTimer.reset(); + } + + // Don't want to send typing indicators to multiple people, potentially too + // much network traffic. Only send in person-to-person IMs. + if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL ) + { + // Still typing, send 'start typing' notification or + // send 'stop typing' notification immediately + if (!mMeTyping || mTypingTimer.getElapsedTimeF32() > 1.f) + { + LLIMModel::instance().sendTypingState(mSessionID, + mOtherParticipantUUID, mMeTyping); + mShouldSendTypingState = false; + } + } + + if (!mIsNearbyChat) + { + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE); + } + } +} + +void LLFloaterIMSession::processIMTyping(const LLIMInfo* im_info, BOOL typing) +{ + if ( typing ) + { + // other user started typing + addTypingIndicator(im_info); + } + else + { + // other user stopped typing + removeTypingIndicator(im_info); + } +} + +void LLFloaterIMSession::processAgentListUpdates(const LLSD& body) +{ + uuid_vec_t joined_uuids; + + if (body.isMap() && body.has("agent_updates") && body["agent_updates"].isMap()) + { + LLSD::map_const_iterator update_it; + for(update_it = body["agent_updates"].beginMap(); + update_it != body["agent_updates"].endMap(); + ++update_it) + { + LLUUID agent_id(update_it->first); + LLSD agent_data = update_it->second; + + if (agent_data.isMap()) + { + // store the new participants in joined_uuids + if (agent_data.has("transition") && agent_data["transition"].asString() == "ENTER") + { + joined_uuids.push_back(agent_id); + } + + // process the moderator mutes + if (agent_id == gAgentID && agent_data.has("info") && agent_data["info"].has("mutes")) + { + BOOL moderator_muted_text = agent_data["info"]["mutes"]["text"].asBoolean(); + mInputEditor->setEnabled(!moderator_muted_text); + std::string label; + if (moderator_muted_text) + label = LLTrans::getString("IM_muted_text_label"); + else + label = LLTrans::getString("IM_to_label") + " " + LLIMModel::instance().getName(mSessionID); + mInputEditor->setLabel(label); + + if (moderator_muted_text) + LLNotificationsUtil::add("TextChatIsMutedByModerator"); + } + } + } + } + + // the vectors need to be sorted for computing the intersection and difference + std::sort(mInvitedParticipants.begin(), mInvitedParticipants.end()); + std::sort(joined_uuids.begin(), joined_uuids.end()); + + uuid_vec_t intersection; // uuids of invited residents who have joined the conversation + std::set_intersection(mInvitedParticipants.begin(), mInvitedParticipants.end(), + joined_uuids.begin(), joined_uuids.end(), + std::back_inserter(intersection)); + + if (intersection.size() > 0) + { + sendParticipantsAddedNotification(intersection); + } + + // Remove all joined participants from invited array. + // The difference between the two vectors (the elements in mInvitedParticipants which are not in joined_uuids) + // is placed at the beginning of mInvitedParticipants, then all other elements are erased. + mInvitedParticipants.erase(std::set_difference(mInvitedParticipants.begin(), mInvitedParticipants.end(), + joined_uuids.begin(), joined_uuids.end(), + mInvitedParticipants.begin()), + mInvitedParticipants.end()); +} + +void LLFloaterIMSession::processSessionUpdate(const LLSD& session_update) +{ + // *TODO : verify following code when moderated mode will be implemented + if ( false && session_update.has("moderated_mode") && + session_update["moderated_mode"].has("voice") ) + { + BOOL voice_moderated = session_update["moderated_mode"]["voice"]; + const std::string session_label = LLIMModel::instance().getName(mSessionID); + + if (voice_moderated) + { + setTitle(session_label + std::string(" ") + + LLTrans::getString("IM_moderated_chat_label")); + } + else + { + setTitle(session_label); + } + + // *TODO : uncomment this when/if LLPanelActiveSpeakers panel will be added + //update the speakers dropdown too + //mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated); + } +} + +// virtual +void LLFloaterIMSession::draw() +{ + // add people who were added via dropPerson() + if (!mPendingParticipants.empty()) + { + addSessionParticipants(mPendingParticipants); + mPendingParticipants.clear(); + } + + LLFloaterIMSessionTab::draw(); +} + +// virtual +BOOL LLFloaterIMSession::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + if (cargo_type == DAD_PERSON) + { + if (dropPerson(static_cast<LLUUID*>(cargo_data), drop)) + { + *accept = ACCEPT_YES_MULTI; + } + else + { + *accept = ACCEPT_NO; + } + } + else if (mDialog == IM_NOTHING_SPECIAL) + { + LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop, + cargo_type, cargo_data, accept); + } + + return TRUE; +} + +bool LLFloaterIMSession::dropPerson(LLUUID* person_id, bool drop) +{ + bool res = person_id && person_id->notNull(); + if(res) + { + uuid_vec_t ids; + ids.push_back(*person_id); + + res = canAddSelectedToChat(ids); + if(res && drop) + { + // these people will be added during the next draw() call + // (so they can be added all at once) + mPendingParticipants.push_back(*person_id); + } + } + + return res; +} + +BOOL LLFloaterIMSession::isInviteAllowed() const +{ + return ( (IM_SESSION_CONFERENCE_START == mDialog) + || (IM_SESSION_INVITE == mDialog && !gAgent.isInGroup(mSessionID)) + || mIsP2PChat); +} + +class LLSessionInviteResponder : public LLHTTPClient::Responder +{ +public: + LLSessionInviteResponder(const LLUUID& session_id) + { + mSessionID = session_id; + } + + void error(U32 statusNum, const std::string& reason) + { + llinfos << "Error inviting all agents to session" << llendl; + //throw something back to the viewer here? + } + +private: + LLUUID mSessionID; +}; + +BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids) +{ + LLViewerRegion* region = gAgent.getRegion(); + bool is_region_exist = region != NULL; + + if (is_region_exist) + { + S32 count = ids.size(); + + if( isInviteAllowed() && (count > 0) ) + { + llinfos << "LLFloaterIMSession::inviteToSession() - inviting participants" << llendl; + + std::string url = region->getCapability("ChatSessionRequest"); + + LLSD data; + data["params"] = LLSD::emptyArray(); + for (int i = 0; i < count; i++) + { + data["params"].append(ids[i]); + } + data["method"] = "invite"; + data["session-id"] = mSessionID; + LLHTTPClient::post(url, data,new LLSessionInviteResponder(mSessionID)); + } + else + { + llinfos << "LLFloaterIMSession::inviteToSession -" + << " no need to invite agents for " + << mDialog << llendl; + // successful add, because everyone that needed to get added + // was added. + } + } + + return is_region_exist; +} + +void LLFloaterIMSession::addTypingIndicator(const LLIMInfo* im_info) +{ + // We may have lost a "stop-typing" packet, don't add it twice + if (im_info && !mOtherTyping) + { + mOtherTyping = true; + + // Update speaker + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if ( speaker_mgr ) + { + speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE); + } + } +} + +void LLFloaterIMSession::removeTypingIndicator(const LLIMInfo* im_info) +{ + if (mOtherTyping) + { + mOtherTyping = false; + + if (im_info) + { + // Update speaker + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE); + } + } + } +} + +// static +void LLFloaterIMSession::closeHiddenIMToasts() +{ + class IMToastMatcher: public LLNotificationsUI::LLScreenChannel::Matcher + { + public: + bool matches(const LLNotificationPtr notification) const + { + // "notifytoast" type of notifications is reserved for IM notifications + return "notifytoast" == notification->getType(); + } + }; + + LLNotificationsUI::LLScreenChannel* channel = + LLNotificationsUI::LLChannelManager::getNotificationScreenChannel(); + if (channel != NULL) + { + channel->closeHiddenToasts(IMToastMatcher()); + } +} +// static +void LLFloaterIMSession::confirmLeaveCallCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + const LLSD& payload = notification["payload"]; + LLUUID session_id = payload["session_id"]; + + LLFloater* im_floater = findInstance(session_id); + if (option == 0 && im_floater != NULL) + { + im_floater->closeFloater(); + } + + return; +} + +// static +void LLFloaterIMSession::sRemoveTypingIndicator(const LLSD& data) +{ + LLUUID session_id = data["session_id"]; + if (session_id.isNull()) + return; + + LLUUID from_id = data["from_id"]; + if (gAgentID == from_id || LLUUID::null == from_id) + return; + + LLFloaterIMSession* floater = LLFloaterIMSession::findInstance(session_id); + if (!floater) + return; + + if (IM_NOTHING_SPECIAL != floater->mDialog) + return; + + floater->removeTypingIndicator(); +} + +// static +void LLFloaterIMSession::onIMChicletCreated( const LLUUID& session_id ) +{ + LLFloaterIMSession::addToHost(session_id); +} + +boost::signals2::connection LLFloaterIMSession::setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb) +{ + return LLFloaterIMSession::sIMFloaterShowedSignal.connect(cb); +} diff --git a/indra/newview/llimfloater.h b/indra/newview/llfloaterimsession.h index f7cd35b5eb..cb330bca0f 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llfloaterimsession.h @@ -1,6 +1,6 @@ /** - * @file llimfloater.h - * @brief LLIMFloater class definition + * @file llfloaterimsession.h + * @brief LLFloaterIMSession class definition * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code @@ -24,62 +24,79 @@ * $/LicenseInfo$ */ -#ifndef LL_IMFLOATER_H -#define LL_IMFLOATER_H +#ifndef LL_FLOATERIMSESSION_H +#define LL_FLOATERIMSESSION_H +#include "llimview.h" +#include "llfloaterimsessiontab.h" #include "llinstantmessage.h" #include "lllogchat.h" #include "lltooldraganddrop.h" -#include "lltransientdockablefloater.h" +#include "llvoicechannel.h" +#include "llvoiceclient.h" class LLAvatarName; -class LLLineEditor; +class LLButton; +class LLChatEntry; +class LLTextEditor; class LLPanelChatControlPanel; class LLChatHistory; class LLInventoryItem; class LLInventoryCategory; +typedef boost::signals2::signal<void(const LLUUID& session_id)> floater_showed_signal_t; + /** * Individual IM window that appears at the bottom of the screen, * optionally "docked" to the bottom tray. */ -class LLIMFloater : public LLTransientDockableFloater +class LLFloaterIMSession + : public LLVoiceClientStatusObserver + , public LLFloaterIMSessionTab { - LOG_CLASS(LLIMFloater); + LOG_CLASS(LLFloaterIMSession); public: - LLIMFloater(const LLUUID& session_id); + LLFloaterIMSession(const LLUUID& session_id); + + virtual ~LLFloaterIMSession(); + + void initIMSession(const LLUUID& session_id); + void initIMFloater(); - virtual ~LLIMFloater(); - // LLView overrides /*virtual*/ BOOL postBuild(); /*virtual*/ void setVisible(BOOL visible); /*virtual*/ BOOL getVisible(); // Check typing timeout timer. + /*virtual*/ void draw(); + /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + + static LLFloaterIMSession* findInstance(const LLUUID& session_id); + static LLFloaterIMSession* getInstance(const LLUUID& session_id); // LLFloater overrides /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void setDocked(bool docked, bool pop_on_undock = true); - // Make IM conversion visible and update the message history - static LLIMFloater* show(const LLUUID& session_id); + static LLFloaterIMSession* show(const LLUUID& session_id); // Toggle panel specified by session_id // Returns true iff panel became visible static bool toggle(const LLUUID& session_id); - static LLIMFloater* findInstance(const LLUUID& session_id); - - static LLIMFloater* getInstance(const LLUUID& session_id); - void sessionInitReplyReceived(const LLUUID& im_session_id); // get new messages from LLIMModel - void updateMessages(); - void reloadMessages(); - static void onSendMsg( LLUICtrl*, void*); - void sendMsg(); + /*virtual*/ void updateMessages(); + void reloadMessages(bool clean_messages = false); + static void onSendMsg(LLUICtrl*, void*); + void sendMsgFromInputEditor(); + void sendMsg(const std::string& msg); // callback for LLIMModel on new messages // route to specific floater if it is visible @@ -89,62 +106,61 @@ public: void setPositioned(bool b) { mPositioned = b; }; void onVisibilityChange(const LLSD& new_visibility); - void processIMTyping(const LLIMInfo* im_info, BOOL typing); - void processAgentListUpdates(const LLSD& body); - void processSessionUpdate(const LLSD& session_update); + bool enableGearMenuItem(const LLSD& userdata); + void GearDoToSelected(const LLSD& userdata); + bool checkGearMenuItem(const LLSD& userdata); - void updateChatHistoryStyle(); - static void processChatHistoryStyleUpdate(const LLSD& newvalue); + // Implements LLVoiceClientStatusObserver::onChange() to enable the call + // button when voice is available + void onChange(EStatusType status, const std::string &channelURI, + bool proximal); - BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, - BOOL drop, EDragAndDropType cargo_type, - void *cargo_data, EAcceptance *accept, - std::string& tooltip_msg); - - /** - * Returns true if chat is displayed in multi tabbed floater - * false if chat is displayed in multiple windows - */ - static bool isChatMultiTab(); + virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; } + virtual void onVoiceChannelStateChanged( + const LLVoiceChannel::EState& old_state, + const LLVoiceChannel::EState& new_state); - static void initIMFloater(); + void processIMTyping(const LLIMInfo* im_info, BOOL typing); + void processAgentListUpdates(const LLSD& body); + void processSessionUpdate(const LLSD& session_update); //used as a callback on receiving new IM message static void sRemoveTypingIndicator(const LLSD& data); - static void onIMChicletCreated(const LLUUID& session_id); + const LLUUID& getOtherParticipantUUID() {return mOtherParticipantUUID;} - virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; } - -protected: - /* virtual */ - void onClickCloseBtn(); + static boost::signals2::connection setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb); + static floater_showed_signal_t sIMFloaterShowedSignal; + bool needsTitleOverwrite() { return mSessionNameUpdatedForTyping && mOtherTyping; } + S32 getLastChatMessageIndex() {return mLastMessageIndex;} private: - // process focus events to set a currently active session - /* virtual */ void onFocusLost(); - /* virtual */ void onFocusReceived(); - - // Update the window title, input field help text, etc. - void updateSessionName(const std::string& ui_title, const std::string& ui_label); - - // For display name lookups for IM window titles - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); - - BOOL dropCallingCard(LLInventoryItem* item, BOOL drop); - BOOL dropCategory(LLInventoryCategory* category, BOOL drop); + + /*virtual*/ void refresh(); + + /*virtual*/ void onTearOffClicked(); + /*virtual*/ void onClickCloseBtn(); + + // Update the window title and input field help text + /*virtual*/ void updateSessionName(const std::string& name); + + bool dropPerson(LLUUID* person_id, bool drop); BOOL isInviteAllowed() const; BOOL inviteToSession(const uuid_vec_t& agent_ids); - - static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ); - static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata); - static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata); - void setTyping(bool typing); - void onSlide(); - static void* createPanelIMControl(void* userdata); - static void* createPanelGroupControl(void* userdata); - static void* createPanelAdHocControl(void* userdata); + static void onInputEditorFocusReceived( LLFocusableElement* caller,void* userdata ); + static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata); + static void onInputEditorKeystroke(LLTextEditor* caller, void* userdata); + void setTyping(bool typing); + void onAddButtonClicked(); + void addSessionParticipants(const uuid_vec_t& uuids); + void addP2PSessionParticipants(const LLSD& notification, const LLSD& response, const uuid_vec_t& uuids); + void sendParticipantsAddedNotification(const uuid_vec_t& uuids); + bool canAddSelectedToChat(const uuid_vec_t& uuids); + + void onCallButtonClicked(); + + void boundVoiceChannel(); // Add the "User is typing..." indicator. void addTypingIndicator(const LLIMInfo* im_info); @@ -156,27 +172,28 @@ private: static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response); - LLPanelChatControlPanel* mControlPanel; - LLUUID mSessionID; S32 mLastMessageIndex; EInstantMessage mDialog; LLUUID mOtherParticipantUUID; - LLChatHistory* mChatHistory; - LLLineEditor* mInputEditor; bool mPositioned; - std::string mSavedTitle; LLUIString mTypingStart; bool mMeTyping; bool mOtherTyping; bool mShouldSendTypingState; LLFrameTimer mTypingTimer; LLFrameTimer mTypingTimeoutTimer; + bool mSessionNameUpdatedForTyping; bool mSessionInitialized; LLSD mQueuedMsgsForInit; -}; + uuid_vec_t mInvitedParticipants; + uuid_vec_t mPendingParticipants; + + // connection to voice channel state change signal + boost::signals2::connection mVoiceChannelStateChangeConnection; +}; -#endif // LL_IMFLOATER_H +#endif // LL_FLOATERIMSESSION_H diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp new file mode 100644 index 0000000000..9fd22b1537 --- /dev/null +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -0,0 +1,971 @@ +/** + * @file llfloaterimsessiontab.cpp + * @brief LLFloaterIMSessionTab class implements the common behavior of LNearbyChatBar + * @brief and LLFloaterIMSession for hosting both in LLIMContainer + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "llfloaterimsessiontab.h" + +#include "llagent.h" +#include "llavataractions.h" +#include "llchatentry.h" +#include "llchathistory.h" +#include "llchiclet.h" +#include "llchicletbar.h" +#include "lldraghandle.h" +#include "llfloaterreg.h" +#include "llfloaterimsession.h" +#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container +#include "lllayoutstack.h" +#include "lltoolbarview.h" +#include "llfloaterimnearbychat.h" + +const F32 REFRESH_INTERVAL = 1.0f; + +LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id) + : LLTransientDockableFloater(NULL, true, session_id) + , mIsP2PChat(false) + , mExpandCollapseBtn(NULL) + , mTearOffBtn(NULL) + , mCloseBtn(NULL) + , mSessionID(session_id.asUUID()) + , mConversationsRoot(NULL) + , mScroller(NULL) + , mSpeakingIndicator(NULL) + , mChatHistory(NULL) + , mInputEditor(NULL) + , mInputEditorTopPad(0) + , mRefreshTimer(new LLTimer()) + , mIsHostAttached(false) + , mHasVisibleBeenInitialized(false) + , mIsParticipantListExpanded(true) +{ + setAutoFocus(FALSE); + mSession = LLIMModel::getInstance()->findIMSession(mSessionID); + + mCommitCallbackRegistrar.add("IMSession.Menu.Action", + boost::bind(&LLFloaterIMSessionTab::onIMSessionMenuItemClicked, this, _2)); + mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem", + boost::bind(&LLFloaterIMSessionTab::onIMCompactExpandedMenuItemCheck, this, _2)); + mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem", + boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemCheck, this, _2)); + mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable", + boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable, this, _2)); + + // Right click menu handling + mEnableCallbackRegistrar.add("Avatar.CheckItem", boost::bind(&LLFloaterIMSessionTab::checkContextMenuItem, this, _2)); + mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMSessionTab::enableContextMenuItem, this, _2)); + mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMSessionTab::doToSelected, this, _2)); +} + +LLFloaterIMSessionTab::~LLFloaterIMSessionTab() +{ + delete mRefreshTimer; +} + +//static +LLFloaterIMSessionTab* LLFloaterIMSessionTab::findConversation(const LLUUID& uuid) +{ + LLFloaterIMSessionTab* conv; + + if (uuid.isNull()) + { + conv = LLFloaterReg::findTypedInstance<LLFloaterIMSessionTab>("nearby_chat"); + } + else + { + conv = LLFloaterReg::findTypedInstance<LLFloaterIMSessionTab>("impanel", LLSD(uuid)); + } + + return conv; +}; + +//static +LLFloaterIMSessionTab* LLFloaterIMSessionTab::getConversation(const LLUUID& uuid) +{ + LLFloaterIMSessionTab* conv; + + if (uuid.isNull()) + { + conv = LLFloaterReg::getTypedInstance<LLFloaterIMSessionTab>("nearby_chat"); + } + else + { + conv = LLFloaterReg::getTypedInstance<LLFloaterIMSessionTab>("impanel", LLSD(uuid)); + } + + return conv; +}; + +void LLFloaterIMSessionTab::setVisible(BOOL visible) +{ + if(visible && !mHasVisibleBeenInitialized) + { + mHasVisibleBeenInitialized = true; + LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->setVisible(true); + LLFloaterIMSessionTab::addToHost(mSessionID); + } + + LLTransientDockableFloater::setVisible(visible); +} + +/*virtual*/ +void LLFloaterIMSessionTab::setFocus(BOOL focus) +{ + LLTransientDockableFloater::setFocus(focus); + + //Redirect focus to input editor + if (focus) + { + updateMessages(); + + if (mInputEditor) + { + mInputEditor->setFocus(TRUE); + } + } +} + + +void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id) +{ + if ((session_id.notNull() && !gIMMgr->hasSession(session_id)) + || !LLFloaterIMSessionTab::isChatMultiTab()) + { + return; + } + + // Get the floater: this will create the instance if it didn't exist + LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(session_id); + if (conversp) + { + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + + // Do not add again existing floaters + if (floater_container && !conversp->isHostAttached()) + { + conversp->setHostAttached(true); + + if (!conversp->isNearbyChat() + || gSavedSettings.getBOOL("NearbyChatIsNotTornOff")) + { + floater_container->addFloater(conversp, false, LLTabContainer::RIGHT_OF_CURRENT); + } + else + { + // setting of the "potential" host for Nearby Chat: this sequence sets + // LLFloater::mHostHandle = NULL (a current host), but + // LLFloater::mLastHostHandle = floater_container (a "future" host) + conversp->setHost(floater_container); + conversp->setHost(NULL); + + conversp->forceReshape(); + } + // Added floaters share some state (like sort order) with their host + conversp->setSortOrder(floater_container->getSortOrder()); + } + } +} + +BOOL LLFloaterIMSessionTab::postBuild() +{ + BOOL result; + + mCloseBtn = getChild<LLButton>("close_btn"); + mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this)); + + mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn"); + mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onSlide, this)); + + mTearOffBtn = getChild<LLButton>("tear_off_btn"); + mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this)); + + mGearBtn = getChild<LLButton>("gear_btn"); + + mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel"); + + // Add a scroller for the folder (participant) view + LLRect scroller_view_rect = mParticipantListPanel->getRect(); + scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); + LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>()); + scroller_params.rect(scroller_view_rect); + mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params); + mScroller->setFollowsAll(); + + mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator"); + + // Insert that scroller into the panel widgets hierarchy + mParticipantListPanel->addChild(mScroller); + + mChatHistory = getChild<LLChatHistory>("chat_history"); + + mInputEditor = getChild<LLChatEntry>("chat_editor"); + mInputEditor->setTextExpandedCallback(boost::bind(&LLFloaterIMSessionTab::reshapeChatHistory, this)); + mInputEditor->setCommitOnFocusLost( FALSE ); + mInputEditor->setPassDelete(TRUE); + mInputEditor->setFont(LLViewerChat::getChatFont()); + + mInputEditorTopPad = mChatHistory->getRect().mBottom - mInputEditor->getRect().mTop; + + setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE); + + mSaveRect = isNearbyChat() + && !gSavedSettings.getBOOL("NearbyChatIsNotTornOff"); + initRectControl(); + + if (isChatMultiTab()) + { + result = LLFloater::postBuild(); + } + else + { + result = LLDockableFloater::postBuild(); + } + + // Create the root using an ad-hoc base item + LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel); + LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>()); + p.rect = LLRect(0, 0, getRect().getWidth(), 0); + p.parent_panel = mParticipantListPanel; + p.listener = base_item; + p.view_model = &mConversationViewModel; + p.root = NULL; + p.use_ellipses = true; + p.options_menu = "menu_conversation.xml"; + p.name = "root"; + mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p); + mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); + // Attach that root to the scroller + mScroller->addChild(mConversationsRoot); + mConversationsRoot->setScrollContainer(mScroller); + mConversationsRoot->setFollowsAll(); + mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox); + + buildConversationViewParticipant(); + refreshConversation(); + + // Zero expiry time is set only once to allow initial update. + mRefreshTimer->setTimerExpirySec(0); + mRefreshTimer->start(); + initBtns(); + + if (mIsParticipantListExpanded != (bool)gSavedSettings.getBOOL("IMShowControlPanel")) + { + LLFloaterIMSessionTab::onSlide(this); + } + + return result; +} + +LLParticipantList* LLFloaterIMSessionTab::getParticipantList() +{ + return dynamic_cast<LLParticipantList*>(LLFloaterIMContainer::getInstance()->getSessionModel(mSessionID)); +} + +void LLFloaterIMSessionTab::draw() +{ + if (mRefreshTimer->hasExpired()) + { + LLParticipantList* item = getParticipantList(); + if (item) + { + // Update all model items + item->update(); + // If the model and view list diverge in count, rebuild + // Note: this happens sometimes right around init (add participant events fire but get dropped) and is the cause + // of missing participants, often, the user agent itself. As there will be no other event fired, there's + // no other choice but get those inconsistencies regularly (and lightly) checked and scrubbed. + if (item->getChildrenCount() != mConversationsWidgets.size()) + { + buildConversationViewParticipant(); + } + refreshConversation(); + } + + // Restart the refresh timer + mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL); + } + + LLTransientDockableFloater::draw(); +} + +void LLFloaterIMSessionTab::enableDisableCallBtn() +{ + getChildView("voice_call_btn")->setEnabled( + mSessionID.notNull() + && mSession + && mSession->mSessionInitialized + && LLVoiceClient::getInstance()->voiceEnabled() + && LLVoiceClient::getInstance()->isVoiceWorking() + && mSession->mCallBackEnabled); +} + +void LLFloaterIMSessionTab::onFocusReceived() +{ + setBackgroundOpaque(true); + + if (mSessionID.notNull() && isInVisibleChain()) + { + LLIMModel::instance().sendNoUnreadMessages(mSessionID); + } + + LLTransientDockableFloater::onFocusReceived(); +} + +void LLFloaterIMSessionTab::onFocusLost() +{ + setBackgroundOpaque(false); + LLTransientDockableFloater::onFocusLost(); +} + +std::string LLFloaterIMSessionTab::appendTime() +{ + time_t utc_time; + utc_time = time_corrected(); + std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:[" + +LLTrans::getString("TimeMin")+"]"; + + LLSD substitution; + + substitution["datetime"] = (S32) utc_time; + LLStringUtil::format (timeStr, substitution); + + return timeStr; +} + +void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args) +{ + + // Update the participant activity time + LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance(); + if (im_box) + { + im_box->setTimeNow(mSessionID,chat.mFromID); + } + + + LLChat& tmp_chat = const_cast<LLChat&>(chat); + + if(tmp_chat.mTimeStr.empty()) + tmp_chat.mTimeStr = appendTime(); + + if (!chat.mMuted) + { + tmp_chat.mFromName = chat.mFromName; + LLSD chat_args; + if (args) chat_args = args; + chat_args["use_plain_text_chat_history"] = + gSavedSettings.getBOOL("PlainTextChatHistory"); + chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime"); + chat_args["show_names_for_p2p_conv"] = + !mIsP2PChat || gSavedSettings.getBOOL("IMShowNamesForP2PConv"); + + if (mChatHistory) + { + mChatHistory->appendMessage(chat, chat_args); + } + } +} + + +void LLFloaterIMSessionTab::buildConversationViewParticipant() +{ + // Clear the widget list since we are rebuilding afresh from the model + conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin(); + while (widget_it != mConversationsWidgets.end()) + { + removeConversationViewParticipant(widget_it->first); + // Iterators are invalidated by erase so we need to pick begin again + widget_it = mConversationsWidgets.begin(); + } + + // Get the model list + LLParticipantList* item = getParticipantList(); + if (!item) + { + // Nothing to do if the model list is inexistent + return; + } + + // Create the participants widgets now + LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin(); + LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd(); + while (current_participant_model != end_participant_model) + { + LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model); + addConversationViewParticipant(participant_model); + current_participant_model++; + } +} + +void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* participant_model) +{ + // Check if the model already has an associated view + LLUUID uuid = participant_model->getUUID(); + LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid); + + // If not already present, create the participant view and attach it to the root, otherwise, just refresh it + if (widget) + { + updateConversationViewParticipant(uuid); // overkill? + } + else + { + LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model); + mConversationsWidgets[uuid] = participant_view; + participant_view->addToFolder(mConversationsRoot); + participant_view->addToSession(mSessionID); + participant_view->setVisible(TRUE); + } +} + +void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& participant_id) +{ + LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id); + if (widget) + { + mConversationsRoot->extractItem(widget); + delete widget; + mConversationsWidgets.erase(participant_id); + } +} + +void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& participant_id) +{ + LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id); + if (widget) + { + widget->refresh(); + } +} + +void LLFloaterIMSessionTab::refreshConversation() +{ + // Note: We collect participants names to change the session name only in the case of ad-hoc conversations + bool is_ad_hoc = (mSession ? mSession->isAdHocSessionType() : false); + uuid_vec_t participants_uuids; // uuids vector for building the added participants name string + // For P2P chat, we still need to update the session name who may have changed (switch display name for instance) + if (mIsP2PChat && mSession) + { + participants_uuids.push_back(mSession->mOtherParticipantID); + } + + conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin(); + while (widget_it != mConversationsWidgets.end()) + { + // Add the participant to the list except if it's the agent itself (redundant) + if (is_ad_hoc && (widget_it->first != gAgentID)) + { + participants_uuids.push_back(widget_it->first); + } + widget_it->second->refresh(); + widget_it->second->setVisible(TRUE); + ++widget_it; + } + if (is_ad_hoc || mIsP2PChat) + { + // Build the session name and update it + std::string session_name; + if (participants_uuids.size() != 0) + { + LLAvatarActions::buildResidentsString(participants_uuids, session_name); + } + else + { + session_name = LLIMModel::instance().getName(mSessionID); + } + updateSessionName(session_name); + } + + if (mSessionID.notNull()) + { + LLParticipantList* participant_list = getParticipantList(); + if (participant_list) + { + LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = participant_list->getChildrenBegin(); + LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = participant_list->getChildrenEnd(); + LLIMSpeakerMgr *speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + while (current_participant_model != end_participant_model) + { + LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model); + if (speaker_mgr && participant_model) + { + LLSpeaker *participant_speaker = speaker_mgr->findSpeaker(participant_model->getUUID()); + LLSpeaker *agent_speaker = speaker_mgr->findSpeaker(gAgentID); + if (participant_speaker && agent_speaker) + { + participant_model->setDisplayModeratorRole(agent_speaker->mIsModerator && participant_speaker->mIsModerator); + } + } + current_participant_model++; + } + } + } + + mConversationViewModel.requestSortAll(); + if(mConversationsRoot != NULL) + { + mConversationsRoot->arrangeAll(); + mConversationsRoot->update(); + } + updateHeaderAndToolbar(); + refresh(); +} + +// Copied from LLFloaterIMContainer::createConversationViewParticipant(). Refactor opportunity! +LLConversationViewParticipant* LLFloaterIMSessionTab::createConversationViewParticipant(LLConversationItem* item) +{ + LLRect panel_rect = mParticipantListPanel->getRect(); + + LLConversationViewParticipant::Params params; + params.name = item->getDisplayName(); + params.root = mConversationsRoot; + params.listener = item; + params.rect = LLRect (0, 24, panel_rect.getWidth(), 0); // *TODO: use conversation_view_participant.xml itemHeight value in lieu of 24 + params.tool_tip = params.name; + params.participant_id = item->getUUID(); + + return LLUICtrlFactory::create<LLConversationViewParticipant>(params); +} + +void LLFloaterIMSessionTab::setSortOrder(const LLConversationSort& order) +{ + mConversationViewModel.setSorter(order); + mConversationsRoot->arrangeAll(); + refreshConversation(); +} + +void LLFloaterIMSessionTab::onIMSessionMenuItemClicked(const LLSD& userdata) +{ + std::string item = userdata.asString(); + + if (item == "compact_view" || item == "expanded_view") + { + gSavedSettings.setBOOL("PlainTextChatHistory", item == "compact_view"); + } + else + { + bool prev_value = gSavedSettings.getBOOL(item); + gSavedSettings.setBOOL(item, !prev_value); + } + + LLFloaterIMSessionTab::processChatHistoryStyleUpdate(); +} + +bool LLFloaterIMSessionTab::onIMCompactExpandedMenuItemCheck(const LLSD& userdata) +{ + std::string item = userdata.asString(); + bool is_plain_text_mode = gSavedSettings.getBOOL("PlainTextChatHistory"); + + return is_plain_text_mode? item == "compact_view" : item == "expanded_view"; +} + + +bool LLFloaterIMSessionTab::onIMShowModesMenuItemCheck(const LLSD& userdata) +{ + return gSavedSettings.getBOOL(userdata.asString()); +} + +// enable/disable states for the "show time" and "show names" items of the show-modes menu +bool LLFloaterIMSessionTab::onIMShowModesMenuItemEnable(const LLSD& userdata) +{ + std::string item = userdata.asString(); + bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory"); + bool is_not_names = (item != "IMShowNamesForP2PConv"); + return (plain_text && (is_not_names || mIsP2PChat)); +} + +void LLFloaterIMSessionTab::hideOrShowTitle() +{ + const LLFloater::Params& default_params = LLFloater::getDefaultParams(); + S32 floater_header_size = default_params.header_height; + LLView* floater_contents = getChild<LLView>("contents_view"); + + LLRect floater_rect = getLocalRect(); + S32 top_border_of_contents = floater_rect.mTop - (isTornOff()? floater_header_size : 0); + LLRect handle_rect (0, floater_rect.mTop, floater_rect.mRight, top_border_of_contents); + LLRect contents_rect (0, top_border_of_contents, floater_rect.mRight, floater_rect.mBottom); + mDragHandle->setShape(handle_rect); + mDragHandle->setVisible(isTornOff()); + floater_contents->setShape(contents_rect); +} + +void LLFloaterIMSessionTab::updateSessionName(const std::string& name) +{ + mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name); +} + +void LLFloaterIMSessionTab::hideAllStandardButtons() +{ + for (S32 i = 0; i < BUTTON_COUNT; i++) + { + if (mButtons[i]) + { + // Hide the standard header buttons in a docked IM floater. + mButtons[i]->setVisible(false); + } + } +} + +void LLFloaterIMSessionTab::updateHeaderAndToolbar() +{ + // prevent start conversation before its container + LLFloaterIMContainer::getInstance(); + + bool is_not_torn_off = !checkIfTornOff(); + if (is_not_torn_off) + { + hideAllStandardButtons(); + } + + hideOrShowTitle(); + + // Participant list should be visible only in torn off floaters. + bool is_participant_list_visible = + !is_not_torn_off + && mIsParticipantListExpanded + && !mIsP2PChat; + + mParticipantListPanel->setVisible(is_participant_list_visible); + + // Display collapse image (<<) if the floater is hosted + // or if it is torn off but has an open control panel. + bool is_expanded = is_not_torn_off || is_participant_list_visible; + mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon")); + mExpandCollapseBtn->setToolTip( + is_not_torn_off? + getString("expcol_button_not_tearoff_tooltip") : + (is_expanded? + getString("expcol_button_tearoff_and_expanded_tooltip") : + getString("expcol_button_tearoff_and_collapsed_tooltip"))); + + // toggle floater's drag handle and title visibility + if (mDragHandle) + { + mDragHandle->setTitleVisible(!is_not_torn_off); + } + + // The button (>>) should be disabled for torn off P2P conversations. + mExpandCollapseBtn->setEnabled(is_not_torn_off || !mIsP2PChat); + + mTearOffBtn->setImageOverlay(getString(is_not_torn_off? "tear_off_icon" : "return_icon")); + mTearOffBtn->setToolTip(getString(is_not_torn_off? "tooltip_to_separate_window" : "tooltip_to_main_window")); + + mCloseBtn->setVisible(is_not_torn_off && !mIsNearbyChat); + + enableDisableCallBtn(); + + showTranslationCheckbox(); +} + +void LLFloaterIMSessionTab::forceReshape() +{ + LLRect floater_rect = getRect(); + reshape(llmax(floater_rect.getWidth(), this->getMinWidth()), + llmax(floater_rect.getHeight(), this->getMinHeight()), + true); +} + + +void LLFloaterIMSessionTab::reshapeChatHistory() +{ + LLRect chat_rect = mChatHistory->getRect(); + LLRect input_rect = mInputEditor->getRect(); + + int delta_height = chat_rect.mBottom - (input_rect.mTop + mInputEditorTopPad); + + chat_rect.setLeftTopAndSize(chat_rect.mLeft, chat_rect.mTop, chat_rect.getWidth(), chat_rect.getHeight() + delta_height); + mChatHistory->setShape(chat_rect); +} + +void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show) +{ + getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(mIsNearbyChat? show : FALSE); +} + +// static +void LLFloaterIMSessionTab::processChatHistoryStyleUpdate(bool clean_messages/* = false*/) +{ + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); + iter != inst_list.end(); ++iter) + { + LLFloaterIMSession* floater = dynamic_cast<LLFloaterIMSession*>(*iter); + if (floater) + { + floater->reloadMessages(clean_messages); + } + } + + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + if (nearby_chat) + { + nearby_chat->reloadMessages(clean_messages); + } +} + +// static +void LLFloaterIMSessionTab::reloadEmptyFloaters() +{ + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); + iter != inst_list.end(); ++iter) + { + LLFloaterIMSession* floater = dynamic_cast<LLFloaterIMSession*>(*iter); + if (floater && floater->getLastChatMessageIndex() == -1) + { + floater->reloadMessages(true); + } + } + + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + if (nearby_chat && nearby_chat->getMessageArchiveLength() == 0) + { + nearby_chat->reloadMessages(true); + } +} + +void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive) +{ + LLButton* voiceButton = getChild<LLButton>("voice_call_btn"); + voiceButton->setImageOverlay( + callIsActive? getString("call_btn_stop") : getString("call_btn_start")); + + voiceButton->setToolTip( + callIsActive? getString("end_call_button_tooltip") : getString("start_call_button_tooltip")); + + enableDisableCallBtn(); + +} + +void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self) +{ + LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(self->getHost()); + if (host_floater) + { + // Hide the messages pane if a floater is hosted in the Conversations + host_floater->collapseMessagesPane(true); + } + else ///< floater is torn off + { + if (!self->mIsP2PChat) + { + bool expand = !self->mParticipantListPanel->getVisible(); + + // Expand/collapse the IM control panel + self->mParticipantListPanel->setVisible(expand); + gSavedSettings.setBOOL("IMShowControlPanel", expand); + self->mIsParticipantListExpanded = expand; + self->mExpandCollapseBtn->setImageOverlay(self->getString(expand ? "collapse_icon" : "expand_icon")); + } + } +} + +/*virtual*/ +void LLFloaterIMSessionTab::onOpen(const LLSD& key) +{ + if (!checkIfTornOff()) + { + LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(getHost()); + // Show the messages pane when opening a floater hosted in the Conversations + host_floater->collapseMessagesPane(false); + } +} + + +void LLFloaterIMSessionTab::onTearOffClicked() +{ + setFollows(isTornOff()? FOLLOWS_ALL : FOLLOWS_NONE); + mSaveRect = isTornOff(); + initRectControl(); + LLFloater::onClickTearOff(this); + LLFloaterIMContainer* container = LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container"); + + if (isTornOff()) + { + container->selectAdjacentConversation(false); + forceReshape(); + } + //Upon re-docking the torn off floater, select the corresponding conversation line item + else + { + container->selectConversation(mSessionID); + } + refreshConversation(); + updateGearBtn(); +} + +void LLFloaterIMSessionTab::updateGearBtn() +{ + + BOOL prevVisibility = mGearBtn->getVisible(); + mGearBtn->setVisible(checkIfTornOff() && mIsP2PChat); + + + // Move buttons if Gear button changed visibility + if(prevVisibility != mGearBtn->getVisible()) + { + LLRect gear_btn_rect = mGearBtn->getRect(); + LLRect add_btn_rect = getChild<LLButton>("add_btn")->getRect(); + LLRect call_btn_rect = getChild<LLButton>("voice_call_btn")->getRect(); + S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight; + S32 right_shift = gear_btn_rect.getWidth() + gap_width; + if(mGearBtn->getVisible()) + { + // Move buttons to the right to give space for Gear button + add_btn_rect.translate(right_shift,0); + call_btn_rect.translate(right_shift,0); + } + else + { + add_btn_rect.translate(-right_shift,0); + call_btn_rect.translate(-right_shift,0); + } + getChild<LLButton>("add_btn")->setRect(add_btn_rect); + getChild<LLButton>("voice_call_btn")->setRect(call_btn_rect); + } +} + +void LLFloaterIMSessionTab::initBtns() +{ + LLRect gear_btn_rect = mGearBtn->getRect(); + LLRect add_btn_rect = getChild<LLButton>("add_btn")->getRect(); + LLRect call_btn_rect = getChild<LLButton>("voice_call_btn")->getRect(); + S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight; + S32 right_shift = gear_btn_rect.getWidth() + gap_width; + + add_btn_rect.translate(-right_shift,0); + call_btn_rect.translate(-right_shift,0); + + getChild<LLButton>("add_btn")->setRect(add_btn_rect); + getChild<LLButton>("voice_call_btn")->setRect(call_btn_rect); +} + +// static +bool LLFloaterIMSessionTab::isChatMultiTab() +{ + // Restart is required in order to change chat window type. + return true; +} + +bool LLFloaterIMSessionTab::checkIfTornOff() +{ + bool isTorn = !getHost(); + + if (isTorn != isTornOff()) + { + setTornOff(isTorn); + refreshConversation(); + } + + return isTorn; +} + +void LLFloaterIMSessionTab::doToSelected(const LLSD& userdata) +{ + // Get the list of selected items in the tab + std::string command = userdata.asString(); + uuid_vec_t selected_uuids; + getSelectedUUIDs(selected_uuids); + + // Perform the command (IM, profile, etc...) on the list using the general conversation container method + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + // Note: By construction, those can only be participants so we can call doToParticipants() directly + floater_container->doToParticipants(command, selected_uuids); +} + +bool LLFloaterIMSessionTab::enableContextMenuItem(const LLSD& userdata) +{ + // Get the list of selected items in the tab + std::string command = userdata.asString(); + uuid_vec_t selected_uuids; + getSelectedUUIDs(selected_uuids); + + // Perform the item enable test on the list using the general conversation container method + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + return floater_container->enableContextMenuItem(command, selected_uuids); +} + +bool LLFloaterIMSessionTab::checkContextMenuItem(const LLSD& userdata) +{ + // Get the list of selected items in the tab + std::string command = userdata.asString(); + uuid_vec_t selected_uuids; + getSelectedUUIDs(selected_uuids); + + // Perform the item check on the list using the general conversation container method + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + return floater_container->checkContextMenuItem(command, selected_uuids); +} + +void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids) +{ + const std::set<LLFolderViewItem*> selected_items = mConversationsRoot->getSelectionList(); + + std::set<LLFolderViewItem*>::const_iterator it = selected_items.begin(); + const std::set<LLFolderViewItem*>::const_iterator it_end = selected_items.end(); + + for (; it != it_end; ++it) + { + LLConversationItem* conversation_item = static_cast<LLConversationItem *>((*it)->getViewModelItem()); + selected_uuids.push_back(conversation_item->getUUID()); + } +} + +LLConversationItem* LLFloaterIMSessionTab::getCurSelectedViewModelItem() +{ + LLConversationItem *conversationItem = NULL; + + if(mConversationsRoot && + mConversationsRoot->getCurSelectedItem() && + mConversationsRoot->getCurSelectedItem()->getViewModelItem()) + { + conversationItem = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem()) ; + } + + return conversationItem; +} + +BOOL LLFloaterIMSessionTab::handleKeyHere(KEY key, MASK mask ) +{ + if(mask == MASK_ALT) + { + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + if (KEY_RETURN == key && !isTornOff()) + { + floater_container->expandConversation(); + } + if ((KEY_UP == key) || (KEY_LEFT == key)) + { + floater_container->selectNextorPreviousConversation(false); + } + if ((KEY_DOWN == key ) || (KEY_RIGHT == key)) + { + floater_container->selectNextorPreviousConversation(true); + } + } + return TRUE; +} diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h new file mode 100644 index 0000000000..e8ae557412 --- /dev/null +++ b/indra/newview/llfloaterimsessiontab.h @@ -0,0 +1,193 @@ +/** + * @file llfloaterimsessiontab.h + * @brief LLFloaterIMSessionTab class implements the common behavior of LNearbyChatBar + * @brief and LLFloaterIMSession for hosting both in LLIMContainer + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_FLOATERIMSESSIONTAB_H +#define LL_FLOATERIMSESSIONTAB_H + +#include "lllayoutstack.h" +#include "llparticipantlist.h" +#include "lltransientdockablefloater.h" +#include "llviewercontrol.h" +#include "lleventtimer.h" +#include "llimview.h" +#include "llconversationmodel.h" +#include "llconversationview.h" +#include "lltexteditor.h" + +class LLPanelChatControlPanel; +class LLChatEntry; +class LLChatHistory; + +class LLFloaterIMSessionTab + : public LLTransientDockableFloater +{ + +public: + LOG_CLASS(LLFloaterIMSessionTab); + + LLFloaterIMSessionTab(const LLSD& session_id); + ~LLFloaterIMSessionTab(); + + // reload all message with new settings of visual modes + static void processChatHistoryStyleUpdate(bool clean_messages = false); + static void reloadEmptyFloaters(); + + /** + * Returns true if chat is displayed in multi tabbed floater + * false if chat is displayed in multiple windows + */ + static bool isChatMultiTab(); + + // add conversation to container + static void addToHost(const LLUUID& session_id); + + bool isHostAttached() {return mIsHostAttached;} + void setHostAttached(bool is_attached) {mIsHostAttached = is_attached;} + + static LLFloaterIMSessionTab* findConversation(const LLUUID& uuid); + static LLFloaterIMSessionTab* getConversation(const LLUUID& uuid); + + // show/hide the translation check box + void showTranslationCheckbox(const BOOL visible = FALSE); + + bool isNearbyChat() {return mIsNearbyChat;} + + // LLFloater overrides + /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ BOOL postBuild(); + /*virtual*/ void draw(); + /*virtual*/ void setVisible(BOOL visible); + /*virtual*/ void setFocus(BOOL focus); + + // Handle the left hand participant list widgets + void addConversationViewParticipant(LLConversationItem* item); + void removeConversationViewParticipant(const LLUUID& participant_id); + void updateConversationViewParticipant(const LLUUID& participant_id); + void refreshConversation(); + void buildConversationViewParticipant(); + + void setSortOrder(const LLConversationSort& order); + virtual void onTearOffClicked(); + void updateGearBtn(); + void initBtns(); + virtual void updateMessages() {} + LLConversationItem* getCurSelectedViewModelItem(); + void forceReshape(); + virtual BOOL handleKeyHere( KEY key, MASK mask ); + +protected: + + // callback for click on any items of the visual states menu + void onIMSessionMenuItemClicked(const LLSD& userdata); + + // callback for check/uncheck of the expanded/collapse mode's switcher + bool onIMCompactExpandedMenuItemCheck(const LLSD& userdata); + + // + bool onIMShowModesMenuItemCheck(const LLSD& userdata); + bool onIMShowModesMenuItemEnable(const LLSD& userdata); + static void onSlide(LLFloaterIMSessionTab *self); + + // refresh a visual state of the Call button + void updateCallBtnState(bool callIsActive); + + void hideOrShowTitle(); // toggle the floater's drag handle + void hideAllStandardButtons(); + + /// Update floater header and toolbar buttons when hosted/torn off state is toggled. + void updateHeaderAndToolbar(); + + // Update the input field help text and other places that need the session name + virtual void updateSessionName(const std::string& name); + + // set the enable/disable state for the Call button + virtual void enableDisableCallBtn(); + + // process focus events to set a currently active session + /* virtual */ void onFocusLost(); + /* virtual */ void onFocusReceived(); + + // prepare chat's params and out one message to chatHistory + void appendMessage(const LLChat& chat, const LLSD &args = 0); + + std::string appendTime(); + + bool mIsNearbyChat; + bool mIsP2PChat; + bool mIsParticipantListExpanded; + + LLIMModel::LLIMSession* mSession; + + // Participants list: model and view + LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item); + + LLUUID mSessionID; + LLLayoutPanel* mParticipantListPanel; // add the widgets to that see mConversationsListPanel + LLParticipantList* getParticipantList(); + conversations_widgets_map mConversationsWidgets; + LLConversationViewModel mConversationViewModel; + LLFolderView* mConversationsRoot; + LLScrollContainer* mScroller; + + LLOutputMonitorCtrl* mSpeakingIndicator; + LLChatHistory* mChatHistory; + LLChatEntry* mInputEditor; + int mInputEditorTopPad; // padding between input field and chat history + + LLButton* mExpandCollapseBtn; + LLButton* mTearOffBtn; + LLButton* mCloseBtn; + LLButton* mGearBtn; + + +private: + // Handling selection and contextual menu + void doToSelected(const LLSD& userdata); + bool enableContextMenuItem(const LLSD& userdata); + bool checkContextMenuItem(const LLSD& userdata); + + void getSelectedUUIDs(uuid_vec_t& selected_uuids); + + /// Refreshes the floater at a constant rate. + virtual void refresh() = 0; + + /** + * Adjusts chat history height to fit vertically with input chat field + * and avoid overlapping, since input chat field can be vertically expanded. + * Implementation: chat history bottom "follows" top+top_pad of input chat field + */ + void reshapeChatHistory(); + + bool checkIfTornOff(); + bool mIsHostAttached; + bool mHasVisibleBeenInitialized; + + LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called. +}; + + +#endif /* LL_FLOATERIMSESSIONTAB_H */ diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index a09b9ea235..5a1dfc99ab 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -37,6 +37,7 @@ #include "llselectmgr.h" #include "lltoolcomp.h" #include "lltoolmgr.h" +#include "lltrans.h" #include "llviewercontrol.h" #include "llviewerobject.h" #include "lluictrlfactory.h" @@ -45,7 +46,9 @@ LLFloaterInspect::LLFloaterInspect(const LLSD& key) : LLFloater(key), - mDirty(FALSE) + mDirty(FALSE), + mOwnerNameCacheConnection(), + mCreatorNameCacheConnection() { mCommitCallbackRegistrar.add("Inspect.OwnerProfile", boost::bind(&LLFloaterInspect::onClickOwnerProfile, this)); mCommitCallbackRegistrar.add("Inspect.CreatorProfile", boost::bind(&LLFloaterInspect::onClickCreatorProfile, this)); @@ -66,6 +69,14 @@ BOOL LLFloaterInspect::postBuild() LLFloaterInspect::~LLFloaterInspect(void) { + if (mOwnerNameCacheConnection.connected()) + { + mOwnerNameCacheConnection.disconnect(); + } + if (mCreatorNameCacheConnection.connected()) + { + mCreatorNameCacheConnection.disconnect(); + } if(!LLFloaterReg::instanceVisible("build")) { if(LLToolMgr::getInstance()->getBaseTool() == LLToolCompInspect::getInstance()) @@ -79,7 +90,6 @@ LLFloaterInspect::~LLFloaterInspect(void) { LLFloaterReg::showInstance("build", LLSD(), TRUE); } - //sInstance = NULL; } void LLFloaterInspect::onOpen(const LLSD& key) @@ -205,11 +215,40 @@ void LLFloaterInspect::refresh() substitution["datetime"] = (S32) timestamp; LLStringUtil::format (timeStr, substitution); + const LLUUID& idOwner = obj->mPermissions->getOwner(); + const LLUUID& idCreator = obj->mPermissions->getCreator(); LLAvatarName av_name; - LLAvatarNameCache::get(obj->mPermissions->getOwner(), &av_name); - owner_name = av_name.getCompleteName(); - LLAvatarNameCache::get(obj->mPermissions->getCreator(), &av_name); - creator_name = av_name.getCompleteName(); + + // Only work with the names if we actually get a result + // from the name cache. If not, defer setting the + // actual name and set a placeholder. + if (LLAvatarNameCache::get(idOwner, &av_name)) + { + owner_name = av_name.getCompleteName(); + } + else + { + owner_name = LLTrans::getString("RetrievingData"); + if (mOwnerNameCacheConnection.connected()) + { + mOwnerNameCacheConnection.disconnect(); + } + mOwnerNameCacheConnection = LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::onGetOwnerNameCallback, this)); + } + + if (LLAvatarNameCache::get(idCreator, &av_name)) + { + creator_name = av_name.getCompleteName(); + } + else + { + creator_name = LLTrans::getString("RetrievingData"); + if (mCreatorNameCacheConnection.connected()) + { + mCreatorNameCacheConnection.disconnect(); + } + mCreatorNameCacheConnection = LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::onGetCreatorNameCallback, this)); + } row["id"] = obj->getObject()->getID(); row["columns"][0]["column"] = "object_name"; @@ -258,6 +297,18 @@ void LLFloaterInspect::dirty() setDirty(); } +void LLFloaterInspect::onGetOwnerNameCallback() +{ + mOwnerNameCacheConnection.disconnect(); + setDirty(); +} + +void LLFloaterInspect::onGetCreatorNameCallback() +{ + mCreatorNameCacheConnection.disconnect(); + setDirty(); +} + void LLFloaterInspect::draw() { if (mDirty) diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h index d9ffdf114b..44381eac96 100644 --- a/indra/newview/llfloaterinspect.h +++ b/indra/newview/llfloaterinspect.h @@ -29,6 +29,7 @@ #ifndef LL_LLFLOATERINSPECT_H #define LL_LLFLOATERINSPECT_H +#include "llavatarname.h" #include "llfloater.h" //class LLTool; @@ -53,6 +54,7 @@ public: void onClickCreatorProfile(); void onClickOwnerProfile(); void onSelectObject(); + LLScrollListCtrl* mObjectList; protected: // protected members @@ -60,13 +62,15 @@ protected: bool mDirty; private: + void onGetOwnerNameCallback(); + void onGetCreatorNameCallback(); LLFloaterInspect(const LLSD& key); virtual ~LLFloaterInspect(void); - // static data -// static LLFloaterInspect* sInstance; LLSafeHandle<LLObjectSelection> mObjectSelection; + boost::signals2::connection mOwnerNameCacheConnection; + boost::signals2::connection mCreatorNameCacheConnection; }; #endif //LL_LLFLOATERINSPECT_H diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index c37798c330..d0c22d25f2 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -33,6 +33,7 @@ #include "llerror.h" #include "llrect.h" #include "llstring.h" +#include "llstat.h" // project includes #include "lluictrlfactory.h" @@ -83,7 +84,8 @@ BOOL LLFloaterJoystick::postBuild() for (U32 i = 0; i < 6; i++) { - mAxisStats[i] = new LLStat(4); + std::string stat_name(llformat("Joystick axis %d", i)); + mAxisStats[i] = new LLStat(stat_name, 4); std::string axisname = llformat("axis%d", i); mAxisStatsBar[i] = getChild<LLStatBar>(axisname); if (mAxisStatsBar[i]) diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 2bb1075ec4..0a30fef768 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -783,8 +783,9 @@ void LLPanelLandGeneral::refresh() mBtnReleaseLand->setEnabled( can_release ); } - BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned();; + BOOL use_pass = parcel->getOwnerID()!= gAgent.getID() && parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned();; mBtnBuyPass->setEnabled(use_pass); + } } @@ -1045,6 +1046,8 @@ void LLPanelLandGeneral::onCommitAny(LLUICtrl *ctrl, void *userdata) void LLPanelLandGeneral::onClickSellLand(void* data) { LLViewerParcelMgr::getInstance()->startSellLand(); + LLPanelLandGeneral *panelp = (LLPanelLandGeneral *)data; + panelp->refresh(); } // static @@ -1806,7 +1809,6 @@ LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel) mCheckEditGroupObjects(NULL), mCheckAllObjectEntry(NULL), mCheckGroupObjectEntry(NULL), - mCheckEditLand(NULL), mCheckSafe(NULL), mCheckFly(NULL), mCheckGroupScripts(NULL), @@ -1840,10 +1842,6 @@ BOOL LLPanelLandOptions::postBuild() mCheckGroupObjectEntry = getChild<LLCheckBoxCtrl>( "group object entry check"); childSetCommitCallback("group object entry check", onCommitAny, this); - mCheckEditLand = getChild<LLCheckBoxCtrl>( "edit land check"); - childSetCommitCallback("edit land check", onCommitAny, this); - - mCheckGroupScripts = getChild<LLCheckBoxCtrl>( "check group scripts"); childSetCommitCallback("check group scripts", onCommitAny, this); @@ -1870,23 +1868,8 @@ BOOL LLPanelLandOptions::postBuild() childSetCommitCallback("ShowDirectoryCheck", onCommitAny, this); - if (gAgent.getAgentAccess().isInTransition()) - { - // during the AO transition, this combo has an Adult item. - // Post-transition, it goes away. We can remove this conditional - // after the transition and just use the "else" clause. - mCategoryCombo = getChild<LLComboBox>( "land category with adult"); - childSetCommitCallback("land category with adult", onCommitAny, this); - } - else - { - // this is the code that should be preserved post-transition - // you could also change the XML to set visibility and enabled true. - mCategoryCombo = getChild<LLComboBox>( "land category"); - childSetCommitCallback("land category", onCommitAny, this); - } - mCategoryCombo->setVisible(true); - mCategoryCombo->setEnabled(true); + mCategoryCombo = getChild<LLComboBox>( "land category"); + childSetCommitCallback("land category", onCommitAny, this); mMatureCtrl = getChild<LLCheckBoxCtrl>( "MatureCheck"); @@ -1906,6 +1889,7 @@ BOOL LLPanelLandOptions::postBuild() mSnapshotCtrl->setCommitCallback( onCommitAny, this ); mSnapshotCtrl->setAllowNoTexture ( TRUE ); mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + mSnapshotCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); } else @@ -1956,9 +1940,6 @@ void LLPanelLandOptions::refresh() mCheckGroupObjectEntry ->set(FALSE); mCheckGroupObjectEntry ->setEnabled(FALSE); - mCheckEditLand ->set(FALSE); - mCheckEditLand ->setEnabled(FALSE); - mCheckSafe ->set(FALSE); mCheckSafe ->setEnabled(FALSE); @@ -2006,10 +1987,6 @@ void LLPanelLandOptions::refresh() mCheckGroupObjectEntry ->set( parcel->getAllowGroupObjectEntry() || parcel->getAllowAllObjectEntry()); mCheckGroupObjectEntry ->setEnabled( can_change_options && !parcel->getAllowAllObjectEntry() ); - - BOOL can_change_terraform = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_EDIT); - mCheckEditLand ->set( parcel->getAllowTerraform() ); - mCheckEditLand ->setEnabled( can_change_terraform ); mCheckSafe ->set( !parcel->getAllowDamage() ); mCheckSafe ->setEnabled( can_change_options ); @@ -2037,7 +2014,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, @@ -2235,12 +2211,12 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata) BOOL create_group_objects = self->mCheckEditGroupObjects->get() || self->mCheckEditObjects->get(); BOOL all_object_entry = self->mCheckAllObjectEntry->get(); BOOL group_object_entry = self->mCheckGroupObjectEntry->get() || self->mCheckAllObjectEntry->get(); - BOOL allow_terraform = self->mCheckEditLand->get(); + BOOL allow_terraform = false; // removed from UI so always off now - self->mCheckEditLand->get(); BOOL allow_damage = !self->mCheckSafe->get(); BOOL allow_fly = self->mCheckFly->get(); BOOL allow_landmark = TRUE; // cannot restrict landmark creation - BOOL allow_group_scripts = self->mCheckGroupScripts->get() || self->mCheckOtherScripts->get(); BOOL allow_other_scripts = self->mCheckOtherScripts->get(); + BOOL allow_group_scripts = self->mCheckGroupScripts->get() || allow_other_scripts; BOOL allow_publish = FALSE; BOOL mature_publish = self->mMatureCtrl->get(); BOOL push_restriction = self->mPushRestrictionCtrl->get(); @@ -2253,11 +2229,16 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata) LLViewerRegion* region; region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); - if (!allow_other_scripts && region && region->getAllowDamage()) - { - - LLNotificationsUtil::add("UnableToDisableOutsideScripts"); - return; + if (region && region->getAllowDamage()) + { // Damage is allowed on the region - server will always allow scripts + if ( (!allow_other_scripts && parcel->getParcelFlag(PF_ALLOW_OTHER_SCRIPTS)) || + (!allow_group_scripts && parcel->getParcelFlag(PF_ALLOW_GROUP_SCRIPTS)) ) + { // Don't allow turning off "Run Scripts" if damage is allowed in the region + self->mCheckOtherScripts->set(parcel->getParcelFlag(PF_ALLOW_OTHER_SCRIPTS)); // Restore UI to actual settings + self->mCheckGroupScripts->set(parcel->getParcelFlag(PF_ALLOW_GROUP_SCRIPTS)); + LLNotificationsUtil::add("UnableToDisableOutsideScripts"); + return; + } } // Push data into current parcel @@ -2384,12 +2365,6 @@ LLPanelLandAccess::~LLPanelLandAccess() void LLPanelLandAccess::refresh() { LLFloater* parent_floater = gFloaterView->getParentFloater(this); - - if (mListAccess) - mListAccess->deleteAllItems(); - if (mListBanned) - mListBanned->deleteAllItems(); - LLParcel *parcel = mParcel->getParcel(); // Display options @@ -2407,7 +2382,11 @@ void LLPanelLandAccess::refresh() getChild<LLUICtrl>("GroupCheck")->setLabelArg("[GROUP]", group_name ); // Allow list + if (mListAccess) { + // Clear the sort order so we don't re-sort on every add. + mListAccess->clearSortOrder(); + mListAccess->deleteAllItems(); S32 count = parcel->mAccessList.size(); getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count)); getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST)); @@ -2442,13 +2421,17 @@ void LLPanelLandAccess::refresh() } suffix.append(" " + parent_floater->getString("Remaining") + ")"); } - if (mListAccess) - mListAccess->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix); + mListAccess->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix); } + mListAccess->sortByName(TRUE); } // Ban List + if(mListBanned) { + // Clear the sort order so we don't re-sort on every add. + mListBanned->clearSortOrder(); + mListBanned->deleteAllItems(); S32 count = parcel->mBanList.size(); getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count)); @@ -2486,27 +2469,7 @@ 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); + mListBanned->sortByName(TRUE); } if(parcel->getRegionDenyAnonymousOverride()) @@ -2642,13 +2605,13 @@ void LLPanelLandAccess::refresh_ui() getChildView("AccessList")->setEnabled(can_manage_allowed); S32 allowed_list_count = parcel->mAccessList.size(); getChildView("add_allowed")->setEnabled(can_manage_allowed && allowed_list_count < PARCEL_MAX_ACCESS_LIST); - BOOL has_selected = mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0; + BOOL has_selected = (mListAccess && mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0); getChildView("remove_allowed")->setEnabled(can_manage_allowed && has_selected); getChildView("BannedList")->setEnabled(can_manage_banned); S32 banned_list_count = parcel->mBanList.size(); getChildView("add_banned")->setEnabled(can_manage_banned && banned_list_count < PARCEL_MAX_ACCESS_LIST); - has_selected = mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0; + has_selected = (mListBanned && mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0); getChildView("remove_banned")->setEnabled(can_manage_banned && has_selected); } } @@ -2773,7 +2736,14 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata) void LLPanelLandAccess::onClickAddAccess() { - gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1)) ); + LLView * button = findChild<LLButton>("add_allowed"); + LLFloater * root_floater = gFloaterView->getParentFloater(this); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( + boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1), FALSE, FALSE, FALSE, root_floater->getName(), button); + if (picker) + { + root_floater->addDependentFloater(picker); + } } void LLPanelLandAccess::callbackAvatarCBAccess(const uuid_vec_t& ids) @@ -2817,7 +2787,14 @@ void LLPanelLandAccess::onClickRemoveAccess(void* data) // static void LLPanelLandAccess::onClickAddBanned() { - gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1))); + LLView * button = findChild<LLButton>("add_banned"); + LLFloater * root_floater = gFloaterView->getParentFloater(this); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( + boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1), FALSE, FALSE, FALSE, root_floater->getName(), button); + if (picker) + { + root_floater->addDependentFloater(picker); + } } // static diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 6fceca1acd..4f1c10274a 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -330,7 +330,6 @@ private: LLCheckBoxCtrl* mCheckEditGroupObjects; LLCheckBoxCtrl* mCheckAllObjectEntry; LLCheckBoxCtrl* mCheckGroupObjectEntry; - LLCheckBoxCtrl* mCheckEditLand; LLCheckBoxCtrl* mCheckSafe; LLCheckBoxCtrl* mCheckFly; LLCheckBoxCtrl* mCheckGroupScripts; diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index a65e9e911a..473e2938be 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -122,16 +122,13 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask) LLVector3d pos_global = mMap->viewPosToGlobal(x, y); - // If we're not tracking a beacon already, double-click will set one - if (!LLTracker::isTracking(NULL)) + LLTracker::stopTracking(NULL); + LLFloaterWorldMap* world_map = LLFloaterWorldMap::getInstance(); + if (world_map) { - LLFloaterWorldMap* world_map = LLFloaterWorldMap::getInstance(); - if (world_map) - { - world_map->trackLocation(pos_global); - } + world_map->trackLocation(pos_global); } - + if (gSavedSettings.getBOOL("DoubleClickTeleport")) { // If DoubleClickTeleport is on, double clicking the minimap will teleport there @@ -249,3 +246,8 @@ void LLFloaterMap::handleZoom(const LLSD& userdata) mMap->setScale(scale); } } + +LLFloaterMap* LLFloaterMap::getInstance() +{ + return LLFloaterReg::getTypedInstance<LLFloaterMap>("mini_map"); +} diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h index 8a1b965e62..ff2fb20535 100644 --- a/indra/newview/llfloatermap.h +++ b/indra/newview/llfloatermap.h @@ -39,6 +39,7 @@ class LLFloaterMap : public LLFloater { public: LLFloaterMap(const LLSD& key); + static LLFloaterMap* getInstance(); virtual ~LLFloaterMap(); /*virtual*/ BOOL postBuild(); diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp index b5f1b967df..4f2a6ec1b7 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); + } } //////////////////////////////////////////////////////////////////////////////// @@ -309,3 +312,9 @@ bool LLFloaterMediaSettings::haveValuesChanged() const return values_changed; } +bool LLFloaterMediaSettings::instanceExists() +{ + return LLFloaterReg::findTypedInstance<LLFloaterMediaSettings>("media_settings"); +} + + diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h index ecc55d2cbc..1d25530986 100644 --- a/indra/newview/llfloatermediasettings.h +++ b/indra/newview/llfloatermediasettings.h @@ -45,6 +45,7 @@ public: /*virtual*/ void onClose(bool app_quitting); static LLFloaterMediaSettings* getInstance(); + static bool instanceExists(); static void apply(); static void initValues( const LLSD& media_settings , bool editable); static void clearValues( bool editable); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 1148db8b5a..ea839e6f5a 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -26,6 +26,10 @@ #include "llviewerprecompiledheaders.h" +#if LL_MSVC +#pragma warning (disable : 4263) +#pragma warning (disable : 4264) +#endif #include "dae.h" //#include "dom.h" #include "dom/domAsset.h" @@ -47,6 +51,10 @@ #include "dom/domScale.h" #include "dom/domTranslate.h" #include "dom/domVisual_scene.h" +#if LL_MSVC +#pragma warning (default : 4263) +#pragma warning (default : 4264) +#endif #include "llfloatermodelpreview.h" @@ -388,7 +396,6 @@ mCalculateBtn(NULL) sInstance = this; mLastMouseX = 0; mLastMouseY = 0; - mGLName = 0; mStatusLock = new LLMutex(NULL); mModelPreview = NULL; @@ -490,7 +497,7 @@ BOOL LLFloaterModelPreview::postBuild() text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i)); } } - std::string current_grid = LLGridManager::getInstance()->getGridLabel(); + std::string current_grid = LLGridManager::getInstance()->getGridId(); std::transform(current_grid.begin(),current_grid.end(),current_grid.begin(),::tolower); std::string validate_url; if (current_grid == "agni") @@ -530,11 +537,6 @@ LLFloaterModelPreview::~LLFloaterModelPreview() delete mModelPreview; } - if (mGLName) - { - LLImageGL::deleteTextures(1, &mGLName ); - } - delete mStatusLock; mStatusLock = NULL; } @@ -735,6 +737,20 @@ void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata) void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit) { mModelPreview->onLODParamCommit(lod, enforce_tri_limit); + + //refresh LoDs that reference this one + for (S32 i = lod - 1; i >= 0; --i) + { + LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[i]); + if (lod_source_combo->getCurrentIndex() == LLModelPreview::USE_LOD_ABOVE) + { + onLoDSourceCommit(i); + } + else + { + break; + } + } } @@ -1006,38 +1022,38 @@ void LLFloaterModelPreview::onPhysicsBrowse(LLUICtrl* ctrl, void* userdata) //static void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata) { - S32 num_modes = 4; - S32 which_mode = 3; - static S32 previous_mode = which_mode; + S32 num_lods = 4; + S32 which_mode; LLCtrlSelectionInterface* iface = sInstance->childGetSelectionInterface("physics_lod_combo"); if (iface) { which_mode = iface->getFirstSelectedIndex(); } + else + { + llwarns << "no iface" << llendl; + return; + } - S32 file_mode = iface->getItemCount() - 1; - bool file_browse = which_mode == file_mode; - bool lod_to_file = file_browse && (previous_mode != file_mode); - bool file_to_lod = !file_browse && (previous_mode == file_mode); - - if (!lod_to_file) + if (which_mode <= 0) { - which_mode = num_modes - which_mode; - sInstance->mModelPreview->setPhysicsFromLOD(which_mode); + llwarns << "which_mode out of range, " << which_mode << llendl; } - if (lod_to_file || file_to_lod) + S32 file_mode = iface->getItemCount() - 1; + if (which_mode < file_mode) { - LLModelPreview *model_preview = sInstance->mModelPreview; - if (model_preview) - { - model_preview->refresh(); - model_preview->updateStatusMessages(); - } + S32 which_lod = num_lods - which_mode; + sInstance->mModelPreview->setPhysicsFromLOD(which_lod); } - previous_mode = which_mode; + LLModelPreview *model_preview = sInstance->mModelPreview; + if (model_preview) + { + model_preview->refresh(); + model_preview->updateStatusMessages(); + } } //static @@ -3868,15 +3884,30 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim U32 triangle_count = 0; - for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter) + U32 instanced_triangle_count = 0; + + //get the triangle count for the whole scene + for (LLModelLoader::scene::iterator iter = mBaseScene.begin(), endIter = mBaseScene.end(); iter != endIter; ++iter) { - LLModel* mdl = *iter; - for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) + for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance) { - triangle_count += mdl->getVolumeFace(i).mNumIndices/3; + LLModel* mdl = instance->mModel; + if (mdl) + { + instanced_triangle_count += mdl->getNumTriangles(); + } } } + //get the triangle count for the non-instanced set of models + for (U32 i = 0; i < mBaseModel.size(); ++i) + { + triangle_count += mBaseModel[i]->getNumTriangles(); + } + + //get ratio of uninstanced triangles to instanced triangles + F32 triangle_ratio = (F32) triangle_count / (F32) instanced_triangle_count; + U32 base_triangle_count = triangle_count; U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; @@ -3910,6 +3941,8 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim if (which_lod > -1 && which_lod < NUM_LOD) { limit = mFMP->childGetValue("lod_triangle_limit_" + lod_name[which_lod]).asInteger(); + //convert from "scene wide" to "non-instanced" triangle limit + limit = (S32) ( (F32) limit*triangle_ratio ); } } else @@ -3961,7 +3994,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(); @@ -4015,7 +4048,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim U32 actual_verts = 0; U32 submeshes = 0; - mRequestedTriangleCount[lod] = triangle_count; + mRequestedTriangleCount[lod] = (S32) ( (F32) triangle_count / triangle_ratio ); mRequestedErrorThreshold[lod] = lod_error_threshold; glodGroupParameteri(mGroup, GLOD_ADAPT_MODE, lod_mode); @@ -4075,14 +4108,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); @@ -4197,28 +4230,36 @@ void LLModelPreview::updateStatusMessages() //initialize total for this lod to 0 total_tris[lod] = total_verts[lod] = total_submeshes[lod] = 0; - for (U32 i = 0; i < mModel[lod].size(); ++i) - { //for each model in the lod - S32 cur_tris = 0; - S32 cur_verts = 0; - S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces(); - - for (S32 j = 0; j < cur_submeshes; ++j) - { //for each submesh (face), add triangles and vertices to current total - const LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j); - cur_tris += face.mNumIndices/3; - cur_verts += face.mNumVertices; - } + for (LLModelLoader::scene::iterator iter = mScene[lod].begin(), endIter = mScene[lod].end(); iter != endIter; ++iter) + { + for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance) + { + LLModel* model = instance->mModel; + if (model) + { + //for each model in the lod + S32 cur_tris = 0; + S32 cur_verts = 0; + S32 cur_submeshes = model->getNumVolumeFaces(); + + for (S32 j = 0; j < cur_submeshes; ++j) + { //for each submesh (face), add triangles and vertices to current total + const LLVolumeFace& face = model->getVolumeFace(j); + cur_tris += face.mNumIndices/3; + cur_verts += face.mNumVertices; + } - //add this model to the lod total - total_tris[lod] += cur_tris; - total_verts[lod] += cur_verts; - total_submeshes[lod] += cur_submeshes; + //add this model to the lod total + total_tris[lod] += cur_tris; + total_verts[lod] += cur_verts; + total_submeshes[lod] += cur_submeshes; - //store this model's counts to asset data - tris[lod].push_back(cur_tris); - verts[lod].push_back(cur_verts); - submeshes[lod].push_back(cur_submeshes); + //store this model's counts to asset data + tris[lod].push_back(cur_tris); + verts[lod].push_back(cur_verts); + submeshes[lod].push_back(cur_submeshes); + } + } } } @@ -4395,34 +4436,38 @@ void LLModelPreview::updateStatusMessages() } //add up physics triangles etc - S32 start = 0; - S32 end = mModel[LLModel::LOD_PHYSICS].size(); - S32 phys_tris = 0; S32 phys_hulls = 0; S32 phys_points = 0; - for (S32 i = start; i < end; ++i) - { //add up hulls and points and triangles for selected mesh(es) - LLModel* model = mModel[LLModel::LOD_PHYSICS][i]; - S32 cur_submeshes = model->getNumVolumeFaces(); - - LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull; - - if (!decomp.empty()) + //get the triangle count for the whole scene + for (LLModelLoader::scene::iterator iter = mScene[LLModel::LOD_PHYSICS].begin(), endIter = mScene[LLModel::LOD_PHYSICS].end(); iter != endIter; ++iter) + { + for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance) { - phys_hulls += decomp.size(); - for (U32 i = 0; i < decomp.size(); ++i) + LLModel* model = instance->mModel; + if (model) { - phys_points += decomp[i].size(); - } - } - else - { //choose physics shape OR decomposition, can't use both - for (S32 j = 0; j < cur_submeshes; ++j) - { //for each submesh (face), add triangles and vertices to current total - const LLVolumeFace& face = model->getVolumeFace(j); - phys_tris += face.mNumIndices/3; + S32 cur_submeshes = model->getNumVolumeFaces(); + + LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull; + + if (!decomp.empty()) + { + phys_hulls += decomp.size(); + for (U32 i = 0; i < decomp.size(); ++i) + { + phys_points += decomp[i].size(); + } + } + else + { //choose physics shape OR decomposition, can't use both + for (S32 j = 0; j < cur_submeshes; ++j) + { //for each submesh (face), add triangles and vertices to current total + const LLVolumeFace& face = model->getVolumeFace(j); + phys_tris += face.mNumIndices/3; + } + } } } } @@ -4517,7 +4562,17 @@ void LLModelPreview::updateStatusMessages() } } - if (mFMP->childGetValue("physics_lod_combo").asString() == "From file") + + LLCtrlSelectionInterface* iface = fmp->childGetSelectionInterface("physics_lod_combo"); + S32 which_mode = 0; + S32 file_mode = 1; + if (iface) + { + which_mode = iface->getFirstSelectedIndex(); + file_mode = iface->getItemCount() - 1; + } + + if (which_mode == file_mode) { mFMP->childEnable("physics_file"); mFMP->childEnable("physics_browse"); @@ -4576,7 +4631,7 @@ void LLModelPreview::updateLodControls(S32 lod) if (!lod_combo) return; S32 lod_mode = lod_combo->getCurrentIndex(); - if (lod_mode == 0) // LoD from file + if (lod_mode == LOD_FROM_FILE) // LoD from file { fmp->mLODMode[lod] = 0; for (U32 i = 0; i < num_file_controls; ++i) @@ -4589,7 +4644,7 @@ void LLModelPreview::updateLodControls(S32 lod) mFMP->childHide(lod_controls[i] + lod_name[lod]); } } - else if (lod_mode == 2) // use LoD above + else if (lod_mode == USE_LOD_ABOVE) // use LoD above { fmp->mLODMode[lod] = 2; for (U32 i = 0; i < num_file_controls; ++i) @@ -4762,7 +4817,8 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) if (vf.mTexCoords) { vb->getTexCoord0Strider(tc_strider); - LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); + S32 tex_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, tex_size); } if (vf.mNormals) @@ -4872,8 +4928,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 ); @@ -5035,15 +5091,7 @@ BOOL LLModelPreview::render() LLRect preview_rect; - LLFloaterModelWizard* floater_wizard = dynamic_cast<LLFloaterModelWizard*>(mFMP); - if (floater_wizard) - { - preview_rect = floater_wizard->getPreviewRect(); - } - else - { - preview_rect = mFMP->getChildView("preview_panel")->getRect(); - } + preview_rect = mFMP->getChildView("preview_panel")->getRect(); F32 aspect = (F32) preview_rect.getWidth()/preview_rect.getHeight(); @@ -5068,6 +5116,11 @@ BOOL LLModelPreview::render() refresh(); } + if (use_shaders) + { + gObjectPreviewProgram.bind(); + } + gGL.loadIdentity(); gPipeline.enableLightsPreview(); @@ -5093,11 +5146,6 @@ BOOL LLModelPreview::render() const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; - if (use_shaders) - { - gObjectPreviewProgram.bind(); - } - LLGLEnable normalize(GL_NORMALIZE); if (!mBaseModel.empty() && mVertexBuffer[5].empty()) @@ -5286,7 +5334,7 @@ BOOL LLModelPreview::render() hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 128)); } - glColor4ubv(hull_colors[i].mV); + gGL.diffuseColor4ubv(hull_colors[i].mV); LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals); if (explode > 0.f) @@ -5513,6 +5561,15 @@ BOOL LLModelPreview::render() buffer->setBuffer(type_mask & buffer->getTypeMask()); gGL.diffuseColor4fv(material.mDiffuseColor.mV); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + if (material.mDiffuseMap.notNull()) + { + if (material.mDiffuseMap->getDiscardLevel() > -1) + { + gGL.getTexUnit(0)->bind(material.mDiffuseMap, true); + mTextureSet.insert(material.mDiffuseMap.get()); + } + } + buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); gGL.diffuseColor3f(0.4f, 0.4f, 0.4f); @@ -5587,7 +5644,6 @@ void LLModelPreview::setPreviewLOD(S32 lod) combo_box->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order mFMP->childSetText("lod_file_" + lod_name[mPreviewLOD], mLODFile[mPreviewLOD]); - // the wizard has three lod drop downs LLComboBox* combo_box2 = mFMP->getChild<LLComboBox>("preview_lod_combo2"); combo_box2->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order @@ -5749,6 +5805,12 @@ void LLFloaterModelPreview::onLoDSourceCommit(S32 lod) { mModelPreview->updateLodControls(lod); refresh(); + + LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[lod]); + if (lod_source_combo->getCurrentIndex() == LLModelPreview::GENERATE) + { //rebuild LoD to update triangle counts + onLODParamCommit(lod, true); + } } void LLFloaterModelPreview::resetDisplayOptions() diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 64324854a5..e588418f7b 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -30,12 +30,12 @@ #include "llfloaternamedesc.h" #include "lldynamictexture.h" -#include "llfloatermodelwizard.h" #include "llquaternion.h" #include "llmeshrepository.h" #include "llmodel.h" #include "llthread.h" #include "llviewermenufile.h" +#include "llfloatermodeluploadbase.h" class LLComboBox; class LLJoint; @@ -256,7 +256,6 @@ protected: S32 mLastMouseX; S32 mLastMouseY; LLRect mPreviewRect; - U32 mGLName; static S32 sUploadAmount; std::set<LLPointer<DecompRequest> > mCurRequest; @@ -312,6 +311,15 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex typedef boost::signals2::signal<void (bool)> model_updated_signal_t; public: + + typedef enum + { + LOD_FROM_FILE = 0, + GENERATE, + USE_LOD_ABOVE, + } eLoDMode; + +public: LLModelPreview(S32 width, S32 height, LLFloater* fmp); virtual ~LLModelPreview(); @@ -390,9 +398,7 @@ private: protected: friend class LLModelLoader; friend class LLFloaterModelPreview; - friend class LLFloaterModelWizard; friend class LLFloaterModelPreview::DecompRequest; - friend class LLFloaterModelWizard::DecompRequest; friend class LLPhysicsDecomp; LLFloater* mFMP; diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp deleted file mode 100644 index b517b78e5a..0000000000 --- a/indra/newview/llfloatermodelwizard.cpp +++ /dev/null @@ -1,795 +0,0 @@ -/** - * @file llfloatermodelwizard.cpp - * @author Leyla Farazha - * @brief Implementation of the LLFloaterModelWizard class. - * - * $LicenseInfo:firstyear=2002&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 "llbutton.h" -#include "lldrawable.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" -#include "llfloater.h" -#include "llfloatermodelwizard.h" -#include "llfloatermodelpreview.h" -#include "llfloaterreg.h" -#include "llsliderctrl.h" -#include "lltoolmgr.h" -#include "llviewerwindow.h" - -LLFloaterModelWizard* LLFloaterModelWizard::sInstance = NULL; - -static const std::string stateNames[]={ - "choose_file", - "optimize", - "physics", - "review", - "upload"}; - -static void swap_controls(LLUICtrl* first_ctrl, LLUICtrl* second_ctrl, bool first_ctr_visible); - -LLFloaterModelWizard::LLFloaterModelWizard(const LLSD& key) - : LLFloaterModelUploadBase(key) - ,mRecalculateGeometryBtn(NULL) - ,mRecalculatePhysicsBtn(NULL) - ,mRecalculatingPhysicsBtn(NULL) - ,mCalculateWeightsBtn(NULL) - ,mCalculatingWeightsBtn(NULL) - ,mChooseFilePreviewPanel(NULL) - ,mOptimizePreviewPanel(NULL) - ,mPhysicsPreviewPanel(NULL) -{ - mLastEnabledState = CHOOSE_FILE; - sInstance = this; - - mCommitCallbackRegistrar.add("Wizard.Choose", boost::bind(&LLFloaterModelWizard::setState, this, CHOOSE_FILE)); - mCommitCallbackRegistrar.add("Wizard.Optimize", boost::bind(&LLFloaterModelWizard::setState, this, OPTIMIZE)); - mCommitCallbackRegistrar.add("Wizard.Physics", boost::bind(&LLFloaterModelWizard::setState, this, PHYSICS)); - mCommitCallbackRegistrar.add("Wizard.Review", boost::bind(&LLFloaterModelWizard::setState, this, REVIEW)); - mCommitCallbackRegistrar.add("Wizard.Upload", boost::bind(&LLFloaterModelWizard::setState, this, UPLOAD)); -} -LLFloaterModelWizard::~LLFloaterModelWizard() -{ - sInstance = NULL; -} -void LLFloaterModelWizard::setState(int state) -{ - - mState = state; - - for(size_t t=0; t<LL_ARRAY_SIZE(stateNames); ++t) - { - LLView *view = getChildView(stateNames[t]+"_panel"); - if (view) - { - view->setVisible(state == (int) t ? TRUE : FALSE); - } - } - - LLView* current_preview_panel = NULL; - - if (state == CHOOSE_FILE) - { - mModelPreview->mViewOption["show_physics"] = false; - - current_preview_panel = mChooseFilePreviewPanel; - - getChildView("close")->setVisible(false); - getChildView("back")->setVisible(true); - getChildView("back")->setEnabled(false); - getChildView("next")->setVisible(true); - getChildView("upload")->setVisible(false); - getChildView("cancel")->setVisible(true); - mCalculateWeightsBtn->setVisible(false); - mCalculatingWeightsBtn->setVisible(false); - } - - if (state == OPTIMIZE) - { - if (mLastEnabledState < state) - { - mModelPreview->genLODs(-1); - } - - mModelPreview->mViewOption["show_physics"] = false; - - current_preview_panel = mOptimizePreviewPanel; - - getChildView("back")->setVisible(true); - getChildView("back")->setEnabled(true); - getChildView("close")->setVisible(false); - getChildView("next")->setVisible(true); - getChildView("upload")->setVisible(false); - getChildView("cancel")->setVisible(true); - mCalculateWeightsBtn->setVisible(false); - mCalculatingWeightsBtn->setVisible(false); - } - - if (state == PHYSICS) - { - if (mLastEnabledState < state) - { - mModelPreview->setPhysicsFromLOD(1); - - // Trigger the recalculate physics when first entering - // the Physics step. - onClickRecalculatePhysics(); - } - - mModelPreview->mViewOption["show_physics"] = true; - - current_preview_panel = mPhysicsPreviewPanel; - - getChildView("next")->setVisible(false); - getChildView("upload")->setVisible(false); - getChildView("close")->setVisible(false); - getChildView("back")->setVisible(true); - getChildView("back")->setEnabled(true); - getChildView("cancel")->setVisible(true); - mCalculateWeightsBtn->setVisible(true); - mCalculatingWeightsBtn->setVisible(false); - } - - if (state == REVIEW) - { - - mModelPreview->mViewOption["show_physics"] = false; - - getChildView("close")->setVisible(false); - getChildView("next")->setVisible(false); - getChildView("back")->setVisible(true); - getChildView("back")->setEnabled(true); - getChildView("upload")->setVisible(true); - getChildView("cancel")->setVisible(true); - mCalculateWeightsBtn->setVisible(false); - mCalculatingWeightsBtn->setVisible(false); - } - - if (state == UPLOAD) - { - getChildView("close")->setVisible(true); - getChildView("next")->setVisible(false); - getChildView("back")->setVisible(false); - getChildView("upload")->setVisible(false); - getChildView("cancel")->setVisible(false); - mCalculateWeightsBtn->setVisible(false); - mCalculatingWeightsBtn->setVisible(false); - } - - if (current_preview_panel) - { - LLRect rect; - current_preview_panel->localRectToOtherView(current_preview_panel->getLocalRect(), &rect, this); - - // Reduce the preview rect by 1 px to fit the borders - rect.stretch(-1); - - if (rect != mPreviewRect) - { - mPreviewRect = rect; - mModelPreview->refresh(); - } - } - updateButtons(); -} - - - -void LLFloaterModelWizard::updateButtons() -{ - if (mLastEnabledState < mState) - { - mLastEnabledState = mState; - } - - for(size_t i=0; i<LL_ARRAY_SIZE(stateNames); ++i) - { - LLButton *button = getChild<LLButton>(stateNames[i]+"_btn"); - - if (i == mState) - { - button->setEnabled(TRUE); - button->setToggleState(TRUE); - } - else if (i <= mLastEnabledState) - { - button->setEnabled(TRUE); - button->setToggleState(FALSE); - } - else - { - button->setEnabled(FALSE); - } - } -} - -void LLFloaterModelWizard::onClickSwitchToAdvanced() -{ - LLFloaterModelPreview* floater_preview = LLFloaterReg::getTypedInstance<LLFloaterModelPreview>("upload_model"); - if (!floater_preview) - { - llwarns << "FLoater model preview not found." << llendl; - return; - } - - // Open floater model preview - floater_preview->openFloater(); - - // Close the wizard - closeFloater(); - - std::string filename = getChild<LLUICtrl>("lod_file")->getValue().asString(); - if (!filename.empty()) - { - // Re-load the model to the floater model preview if it has been loaded - // into the wizard. - floater_preview->loadModel(3, filename); - } -} - -void LLFloaterModelWizard::onClickRecalculateGeometry() -{ - S32 val = getChild<LLUICtrl>("accuracy_slider")->getValue().asInteger(); - - mModelPreview->genLODs(-1, NUM_LOD - val); - - mModelPreview->refresh(); -} - -void LLFloaterModelWizard::onClickRecalculatePhysics() -{ - // Hide the "Recalculate physics" button and show the "Recalculating..." - // button instead. - swap_controls(mRecalculatePhysicsBtn, mRecalculatingPhysicsBtn, false); - - executePhysicsStage("Decompose"); -} - -void LLFloaterModelWizard::onClickCalculateUploadFee() -{ - swap_controls(mCalculateWeightsBtn, mCalculatingWeightsBtn, false); - - mModelPreview->rebuildUploadData(); - - mUploadModelUrl.clear(); - - gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale, - true, false, false, mUploadModelUrl, false, getWholeModelFeeObserverHandle()); -} - -void LLFloaterModelWizard::loadModel() -{ - mModelPreview->mLoading = TRUE; - - (new LLMeshFilePicker(mModelPreview, 3))->getFile(); -} - -void LLFloaterModelWizard::onClickCancel() -{ - closeFloater(); -} - -void LLFloaterModelWizard::onClickBack() -{ - setState(llmax((int) CHOOSE_FILE, mState-1)); -} - -void LLFloaterModelWizard::onClickNext() -{ - setState(llmin((int) UPLOAD, mState+1)); -} - -bool LLFloaterModelWizard::onEnableNext() -{ - return true; -} - -bool LLFloaterModelWizard::onEnableBack() -{ - return true; -} - - -//----------------------------------------------------------------------------- -// handleMouseDown() -//----------------------------------------------------------------------------- -BOOL LLFloaterModelWizard::handleMouseDown(S32 x, S32 y, MASK mask) -{ - if (mPreviewRect.pointInRect(x, y)) - { - bringToFront( x, y ); - gFocusMgr.setMouseCapture(this); - gViewerWindow->hideCursor(); - mLastMouseX = x; - mLastMouseY = y; - return TRUE; - } - - return LLFloater::handleMouseDown(x, y, mask); -} - -//----------------------------------------------------------------------------- -// handleMouseUp() -//----------------------------------------------------------------------------- -BOOL LLFloaterModelWizard::handleMouseUp(S32 x, S32 y, MASK mask) -{ - gFocusMgr.setMouseCapture(FALSE); - gViewerWindow->showCursor(); - return LLFloater::handleMouseUp(x, y, mask); -} - -//----------------------------------------------------------------------------- -// handleHover() -//----------------------------------------------------------------------------- -BOOL LLFloaterModelWizard::handleHover (S32 x, S32 y, MASK mask) -{ - MASK local_mask = mask & ~MASK_ALT; - - if (mModelPreview && hasMouseCapture()) - { - if (local_mask == MASK_PAN) - { - // pan here - mModelPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f); - } - else if (local_mask == MASK_ORBIT) - { - F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f; - F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f; - - mModelPreview->rotate(yaw_radians, pitch_radians); - } - else - { - - F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f; - F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f; - - mModelPreview->rotate(yaw_radians, 0.f); - mModelPreview->zoom(zoom_amt); - } - - - mModelPreview->refresh(); - - LLUI::setMousePositionLocal(this, mLastMouseX, mLastMouseY); - } - - if (!mPreviewRect.pointInRect(x, y) || !mModelPreview) - { - return LLFloater::handleHover(x, y, mask); - } - else if (local_mask == MASK_ORBIT) - { - gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA); - } - else if (local_mask == MASK_PAN) - { - gViewerWindow->setCursor(UI_CURSOR_TOOLPAN); - } - else - { - gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN); - } - - return TRUE; -} - -//----------------------------------------------------------------------------- -// handleScrollWheel() -//----------------------------------------------------------------------------- -BOOL LLFloaterModelWizard::handleScrollWheel(S32 x, S32 y, S32 clicks) -{ - if (mPreviewRect.pointInRect(x, y) && mModelPreview) - { - mModelPreview->zoom((F32)clicks * -0.2f); - mModelPreview->refresh(); - } - - return TRUE; -} - - -void LLFloaterModelWizard::initDecompControls() -{ - LLSD key; - - static const LLCDStageData* stage = NULL; - static S32 stage_count = 0; - - if (!stage && LLConvexDecomposition::getInstance() != NULL) - { - stage_count = LLConvexDecomposition::getInstance()->getStages(&stage); - } - - static const LLCDParam* param = NULL; - static S32 param_count = 0; - if (!param && LLConvexDecomposition::getInstance() != NULL) - { - param_count = LLConvexDecomposition::getInstance()->getParameters(¶m); - } - - for (S32 j = stage_count-1; j >= 0; --j) - { - gMeshRepo.mDecompThread->mStageID[stage[j].mName] = j; - // protected against stub by stage_count being 0 for stub above - LLConvexDecomposition::getInstance()->registerCallback(j, LLPhysicsDecomp::llcdCallback); - - for (S32 i = 0; i < param_count; ++i) - { - if (param[i].mStage != j) - { - continue; - } - - std::string name(param[i].mName ? param[i].mName : ""); - std::string description(param[i].mDescription ? param[i].mDescription : ""); - - if (param[i].mType == LLCDParam::LLCD_FLOAT) - { - mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mFloat); - } - else if (param[i].mType == LLCDParam::LLCD_INTEGER) - { - mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue); - } - else if (param[i].mType == LLCDParam::LLCD_BOOLEAN) - { - mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mBool); - } - else if (param[i].mType == LLCDParam::LLCD_ENUM) - { - mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue); - } - } - } - - mDecompParams["Simplify Method"] = 0; // set it to retain % -} - -/*virtual*/ -void LLFloaterModelWizard::onPermissionsReceived(const LLSD& result) -{ - std::string upload_status = result["mesh_upload_status"].asString(); - // BAP HACK: handle "" for case that MeshUploadFlag cap is broken. - mHasUploadPerm = (("" == upload_status) || ("valid" == upload_status)); - - getChildView("warning_label")->setVisible(!mHasUploadPerm); - getChildView("warning_text")->setVisible(!mHasUploadPerm); -} - -/*virtual*/ -void LLFloaterModelWizard::setPermissonsErrorStatus(U32 status, const std::string& reason) -{ - llwarns << "LLFloaterModelWizard::setPermissonsErrorStatus(" << status << " : " << reason << ")" << llendl; -} - -/*virtual*/ -void LLFloaterModelWizard::onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url) -{ - swap_controls(mCalculateWeightsBtn, mCalculatingWeightsBtn, true); - - // Enable the "Upload" buton if we have calculated the upload fee - // and have the permission to upload. - getChildView("upload")->setEnabled(mHasUploadPerm); - - mUploadModelUrl = upload_url; - - S32 fee = result["upload_price"].asInteger(); - childSetTextArg("review_fee", "[FEE]", llformat("%d", fee)); - childSetTextArg("charged_fee", "[FEE]", llformat("%d", fee)); - - setState(REVIEW); -} - -/*virtual*/ -void LLFloaterModelWizard::setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason) -{ - swap_controls(mCalculateWeightsBtn, mCalculatingWeightsBtn, true); - - // Disable the "Review" step if it has been previously enabled. - modelChangedCallback(); - - llwarns << "LLFloaterModelWizard::setModelPhysicsFeeErrorStatus(" << status << " : " << reason << ")" << llendl; - - setState(PHYSICS); -} - -/*virtual*/ -void LLFloaterModelWizard::onModelUploadSuccess() -{ - // success! - setState(UPLOAD); -} - -/*virtual*/ -void LLFloaterModelWizard::onModelUploadFailure() -{ - // Failure. Make the user recalculate fees - setState(PHYSICS); - // Disable the "Review" step if it has been previously enabled. - if (mLastEnabledState > PHYSICS) - { - mLastEnabledState = PHYSICS; - } - - updateButtons(); -} - -//static -void LLFloaterModelWizard::executePhysicsStage(std::string stage_name) -{ - if (sInstance) - { - // Invert the slider value so that "performance" end is giving the least detailed physics, - // and the "accuracy" end is giving the most detailed physics - F64 physics_accuracy = 1 - sInstance->getChild<LLSliderCtrl>("physics_slider")->getValue().asReal(); - - sInstance->mDecompParams["Retain%"] = physics_accuracy; - - if (!sInstance->mCurRequest.empty()) - { - llinfos << "Decomposition request still pending." << llendl; - return; - } - - if (sInstance->mModelPreview) - { - for (S32 i = 0; i < sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS].size(); ++i) - { - LLModel* mdl = sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS][i]; - DecompRequest* request = new DecompRequest(stage_name, mdl); - if(request->isValid()) - { - sInstance->mCurRequest.insert(request); - gMeshRepo.mDecompThread->submitRequest(request); - } - } - } - } -} - -LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLModel* mdl) -{ - mStage = stage; - mContinue = 1; - mModel = mdl; - mDecompID = &mdl->mDecompID; - mParams = sInstance->mDecompParams; - - //copy out positions and indices - assignData(mdl) ; -} - - -S32 LLFloaterModelWizard::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2) -{ - setStatusMessage(llformat("%s: %d/%d", status, p1, p2)); - - return mContinue; -} - -void LLFloaterModelWizard::DecompRequest::completed() -{ //called from the main thread - mModel->setConvexHullDecomposition(mHull); - - if (sInstance) - { - if (sInstance->mModelPreview) - { - sInstance->mModelPreview->mDirty = true; - LLFloaterModelWizard::sInstance->mModelPreview->refresh(); - } - - sInstance->mCurRequest.erase(this); - } - - if (mStage == "Decompose") - { - executePhysicsStage("Simplify"); - } - else - { - // Decomp request is complete so we can enable the "Recalculate physics" button again. - swap_controls(sInstance->mRecalculatePhysicsBtn, sInstance->mRecalculatingPhysicsBtn, true); - } -} - - -BOOL LLFloaterModelWizard::postBuild() -{ - childSetValue("import_scale", (F32) 0.67335826); - - getChild<LLUICtrl>("browse")->setCommitCallback(boost::bind(&LLFloaterModelWizard::loadModel, this)); - //getChild<LLUICtrl>("lod_file")->setCommitCallback(boost::bind(&LLFloaterModelWizard::loadModel, this)); - getChild<LLUICtrl>("cancel")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCancel, this)); - getChild<LLUICtrl>("close")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCancel, this)); - getChild<LLUICtrl>("back")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickBack, this)); - getChild<LLUICtrl>("next")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickNext, this)); - getChild<LLUICtrl>("preview_lod_combo")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1)); - getChild<LLUICtrl>("preview_lod_combo2")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1)); - getChild<LLUICtrl>("upload")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onUpload, this)); - getChild<LLUICtrl>("switch_to_advanced")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickSwitchToAdvanced, this)); - - mRecalculateGeometryBtn = getChild<LLButton>("recalculate_geometry_btn"); - mRecalculateGeometryBtn->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickRecalculateGeometry, this)); - - mRecalculatePhysicsBtn = getChild<LLButton>("recalculate_physics_btn"); - mRecalculatePhysicsBtn->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickRecalculatePhysics, this)); - - mRecalculatingPhysicsBtn = getChild<LLButton>("recalculating_physics_btn"); - - mCalculateWeightsBtn = getChild<LLButton>("calculate"); - mCalculateWeightsBtn->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCalculateUploadFee, this)); - - mCalculatingWeightsBtn = getChild<LLButton>("calculating"); - - mChooseFilePreviewPanel = getChild<LLView>("choose_file_preview_panel"); - mOptimizePreviewPanel = getChild<LLView>("optimize_preview_panel"); - mPhysicsPreviewPanel = getChild<LLView>("physics_preview_panel"); - - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - - enable_registrar.add("Next.OnEnable", boost::bind(&LLFloaterModelWizard::onEnableNext, this)); - enable_registrar.add("Back.OnEnable", boost::bind(&LLFloaterModelWizard::onEnableBack, this)); - - mModelPreview = new LLModelPreview(512, 512, this); - mModelPreview->setPreviewTarget(16.f); - mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelWizard::setDetails, this, _1, _2, _3, _4, _5)); - mModelPreview->setModelLoadedCallback(boost::bind(&LLFloaterModelWizard::modelLoadedCallback, this)); - mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelWizard::modelChangedCallback, this)); - mModelPreview->mViewOption["show_textures"] = true; - - center(); - - setState(CHOOSE_FILE); - - childSetTextArg("import_dimensions", "[X]", LLStringUtil::null); - childSetTextArg("import_dimensions", "[Y]", LLStringUtil::null); - childSetTextArg("import_dimensions", "[Z]", LLStringUtil::null); - - initDecompControls(); - - requestAgentUploadPermissions(); - - return TRUE; -} - - -void LLFloaterModelWizard::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost) -{ - // iterate through all the panels, setting the dimensions - for(size_t t=0; t<LL_ARRAY_SIZE(stateNames); ++t) - { - LLPanel *panel = getChild<LLPanel>(stateNames[t]+"_panel"); - if (panel) - { - panel->childSetText("dimension_x", llformat("%.1f", x)); - panel->childSetText("dimension_y", llformat("%.1f", y)); - panel->childSetText("dimension_z", llformat("%.1f", z)); - } - } - - childSetTextArg("review_prim_equiv", "[EQUIV]", llformat("%d", mModelPreview->mResourceCost)); -} - -void LLFloaterModelWizard::modelLoadedCallback() -{ - mLastEnabledState = CHOOSE_FILE; - updateButtons(); -} - -void LLFloaterModelWizard::modelChangedCallback() -{ - // Don't allow to proceed to the "Review" step if the model has changed - // but the new upload fee hasn't been calculated yet. - if (mLastEnabledState > PHYSICS) - { - mLastEnabledState = PHYSICS; - } - - getChildView("upload")->setEnabled(false); - - updateButtons(); -} - -void LLFloaterModelWizard::onUpload() -{ - mModelPreview->rebuildUploadData(); - - gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale, - true, false, false, mUploadModelUrl, true, - LLHandle<LLWholeModelFeeObserver>(), getWholeModelUploadObserverHandle()); -} - -void LLFloaterModelWizard::onPreviewLODCommit(LLUICtrl* ctrl) -{ - if (!mModelPreview) - { - return; - } - - S32 which_mode = 0; - - LLComboBox* combo = (LLComboBox*) ctrl; - - which_mode = (NUM_LOD-1)-combo->getFirstSelectedIndex(); // combo box list of lods is in reverse order - - mModelPreview->setPreviewLOD(which_mode); -} - -void LLFloaterModelWizard::refresh() -{ - if (mState == CHOOSE_FILE) - { - bool model_loaded = false; - - if (mModelPreview && mModelPreview->getLoadState() == LLModelLoader::DONE) - { - model_loaded = true; - } - - getChildView("next")->setEnabled(model_loaded); - } -} - -void LLFloaterModelWizard::draw() -{ - refresh(); - - LLFloater::draw(); - - if (mModelPreview && mState < REVIEW) - { - mModelPreview->update(); - - gGL.color3f(1.f, 1.f, 1.f); - - gGL.getTexUnit(0)->bind(mModelPreview); - - gGL.begin( LLRender::QUADS ); - { - gGL.texCoord2f(0.f, 1.f); - gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop); - gGL.texCoord2f(0.f, 0.f); - gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom); - gGL.texCoord2f(1.f, 0.f); - gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mBottom); - gGL.texCoord2f(1.f, 1.f); - gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mTop); - } - gGL.end(); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - } -} - -// static -void swap_controls(LLUICtrl* first_ctrl, LLUICtrl* second_ctrl, bool first_ctr_visible) -{ - first_ctrl->setVisible(first_ctr_visible); - second_ctrl->setVisible(!first_ctr_visible); -} diff --git a/indra/newview/llfloatermodelwizard.h b/indra/newview/llfloatermodelwizard.h deleted file mode 100644 index db9b605777..0000000000 --- a/indra/newview/llfloatermodelwizard.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file llfloatermodelwizard.h - * - * $LicenseInfo:firstyear=2009&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 LLFLOATERMODELWIZARD_H -#define LLFLOATERMODELWIZARD_H - - -#include "llmeshrepository.h" -#include "llmodel.h" -#include "llthread.h" -#include "llfloatermodeluploadbase.h" - - -class LLModelPreview; - - -class LLFloaterModelWizard : public LLFloaterModelUploadBase -{ -public: - - class DecompRequest : public LLPhysicsDecomp::Request - { - public: - S32 mContinue; - LLPointer<LLModel> mModel; - - DecompRequest(const std::string& stage, LLModel* mdl); - virtual S32 statusCallback(const char* status, S32 p1, S32 p2); - virtual void completed(); - - }; - - static LLFloaterModelWizard* sInstance; - - LLFloaterModelWizard(const LLSD& key); - virtual ~LLFloaterModelWizard(); - /*virtual*/ BOOL postBuild(); - void draw(); - void refresh(); - - BOOL handleMouseDown(S32 x, S32 y, MASK mask); - BOOL handleMouseUp(S32 x, S32 y, MASK mask); - BOOL handleHover(S32 x, S32 y, MASK mask); - BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); - - void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost); - void modelLoadedCallback(); - void modelChangedCallback(); - void initDecompControls(); - - // shows warning message if agent has no permissions to upload model - /*virtual*/ void onPermissionsReceived(const LLSD& result); - - // called when error occurs during permissions request - /*virtual*/ void setPermissonsErrorStatus(U32 status, const std::string& reason); - - /*virtual*/ void onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url); - - /*virtual*/ void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason); - - /*virtual*/ void onModelUploadSuccess(); - - /*virtual*/ void onModelUploadFailure(); - - const LLRect& getPreviewRect() const { return mPreviewRect; } - - LLPhysicsDecomp::decomp_params mDecompParams; - std::set<LLPointer<DecompRequest> > mCurRequest; - std::string mStatusMessage; - static void executePhysicsStage(std::string stage_name); - -private: - enum EWizardState - { - CHOOSE_FILE = 0, - OPTIMIZE, - PHYSICS, - REVIEW, - UPLOAD - }; - - void setState(int state); - void updateButtons(); - void onClickSwitchToAdvanced(); - void onClickRecalculateGeometry(); - void onClickRecalculatePhysics(); - void onClickCalculateUploadFee(); - void onClickCancel(); - void onClickBack(); - void onClickNext(); - bool onEnableNext(); - bool onEnableBack(); - void loadModel(); - void onPreviewLODCommit(LLUICtrl*); - void onUpload(); - - LLModelPreview* mModelPreview; - LLRect mPreviewRect; - int mState; - - S32 mLastMouseX; - S32 mLastMouseY; - - U32 mLastEnabledState; - - LLButton* mRecalculateGeometryBtn; - LLButton* mRecalculatePhysicsBtn; - LLButton* mRecalculatingPhysicsBtn; - LLButton* mCalculateWeightsBtn; - LLButton* mCalculatingWeightsBtn; - - LLView* mChooseFilePreviewPanel; - LLView* mOptimizePreviewPanel; - LLView* mPhysicsPreviewPanel; -}; - - -#endif diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp index ae95d4392a..27b1c3b9cd 100644 --- a/indra/newview/llfloaternamedesc.cpp +++ b/indra/newview/llfloaternamedesc.cpp @@ -204,3 +204,43 @@ BOOL LLFloaterSoundPreview::postBuild() getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this)); return TRUE; } + + +//----------------------------------------------------------------------------- +// LLFloaterAnimPreview() +//----------------------------------------------------------------------------- + +LLFloaterAnimPreview::LLFloaterAnimPreview(const LLSD& filename ) + : LLFloaterNameDesc(filename) +{ +} + +BOOL LLFloaterAnimPreview::postBuild() +{ + if (!LLFloaterNameDesc::postBuild()) + { + return FALSE; + } + 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..41643681ac 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,19 @@ public: LLFloaterSoundPreview(const LLSD& filename ); virtual BOOL postBuild(); }; - + +class LLFloaterAnimPreview : public LLFloaterNameDesc +{ +public: + LLFloaterAnimPreview(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..4f35c325a8 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -44,21 +44,16 @@ public: BOOL postBuild(); private: - bool update(const LLSD& payload, bool passed_filter); + bool update(const LLSD& payload); static void toggleClick(void* user_data); static void onClickNotification(void* user_data); - static void onClickNotificationReject(void* user_data); LLNotificationChannelPtr mChannelPtr; - LLNotificationChannelPtr mChannelRejectsPtr; }; LLNotificationChannelPanel::LLNotificationChannelPanel(const LLNotificationChannelPanel::Params& p) : LLLayoutPanel(p) { mChannelPtr = LLNotifications::instance().getChannel(p.name); - mChannelRejectsPtr = LLNotificationChannelPtr( - LLNotificationChannel::buildChannel(p.name() + "rejects", mChannelPtr->getParentChannelName(), - !boost::bind(mChannelPtr->getFilter(), _1))); buildFromFile( "panel_notifications_channel.xml"); } @@ -68,15 +63,11 @@ BOOL LLNotificationChannelPanel::postBuild() header_button->setLabel(mChannelPtr->getName()); header_button->setClickedCallback(toggleClick, this); - mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, true)); - mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false)); + mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1)); LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list"); scroll->setDoubleClickCallback(onClickNotification, this); scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0)); - scroll = getChild<LLScrollListCtrl>("notification_rejects_list"); - scroll->setDoubleClickCallback(onClickNotificationReject, this); - scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0)); return TRUE; } @@ -97,8 +88,6 @@ void LLNotificationChannelPanel::toggleClick(void *user_data) // turn off tab stop for collapsed panel self->getChild<LLScrollListCtrl>("notifications_list")->setTabStop(!header_button->getToggleState()); self->getChild<LLScrollListCtrl>("notifications_list")->setVisible(!header_button->getToggleState()); - self->getChild<LLScrollListCtrl>("notification_rejects_list")->setTabStop(!header_button->getToggleState()); - self->getChild<LLScrollListCtrl>("notification_rejects_list")->setVisible(!header_button->getToggleState()); } /*static*/ @@ -118,24 +107,7 @@ void LLNotificationChannelPanel::onClickNotification(void* user_data) } } -/*static*/ -void LLNotificationChannelPanel::onClickNotificationReject(void* user_data) -{ - LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data; - if (!self) return; - LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notification_rejects_list")->getFirstSelected(); - llassert(firstselected); - if (firstselected) - { - void* data = firstselected->getUserdata(); - if (data) - { - gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE); - } - } -} - -bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter) +bool LLNotificationChannelPanel::update(const LLSD& payload) { LLNotificationPtr notification = LLNotifications::instance().find(payload["id"].asUUID()); if (notification) @@ -151,9 +123,7 @@ bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter) row["columns"][2]["column"] = "date"; row["columns"][2]["type"] = "date"; - LLScrollListItem* sli = passed_filter ? - getChild<LLScrollListCtrl>("notifications_list")->addElement(row) : - getChild<LLScrollListCtrl>("notification_rejects_list")->addElement(row); + LLScrollListItem* sli = getChild<LLScrollListCtrl>("notifications_list")->addElement(row); sli->setUserdata(&(*notification)); } @@ -220,7 +190,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..29a3e6ac3a --- /dev/null +++ b/indra/newview/llfloateroutbox.cpp @@ -0,0 +1,537 @@ +/** + * @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" + + +///---------------------------------------------------------------------------- +/// LLOutboxNotification class +///---------------------------------------------------------------------------- + +LLNotificationsUI::LLOutboxNotification::LLOutboxNotification() + : LLSystemNotificationHandler("Outbox", "outbox") +{ +} + +bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLNotificationPtr& notify) +{ + LLFloaterOutbox* outbox_floater = LLFloaterReg::getTypedInstance<LLFloaterOutbox>("outbox"); + + outbox_floater->showNotification(notify); + + return false; +} + +void LLNotificationsUI::LLOutboxNotification::onDelete(LLNotificationPtr p) +{ + LLNotificationsUI::LLNotificationHandler * notification_handler = dynamic_cast<LLNotificationsUI::LLNotificationHandler*>(LLNotifications::instance().getChannel("AlertModal").get()); + if (notification_handler) + { + notification_handler->onDelete(p); + } +} + +///---------------------------------------------------------------------------- +/// 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 LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder); + + 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->getFolderViewModel()->setSorter(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 LLNotificationPtr& notification) +{ + LLNotificationsUI::LLNotificationHandler * notification_handler = dynamic_cast<LLNotificationsUI::LLNotificationHandler*>(LLNotifications::instance().getChannel("AlertModal").get()); + llassert(notification_handler); + + notification_handler->processNotification(notification); +} + diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h new file mode 100644 index 0000000000..a91d8c1139 --- /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 LLNotificationPtr& notification); + + 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/llfloaterpathfindingcharacters.cpp b/indra/newview/llfloaterpathfindingcharacters.cpp new file mode 100644 index 0000000000..69c9d94dfa --- /dev/null +++ b/indra/newview/llfloaterpathfindingcharacters.cpp @@ -0,0 +1,326 @@ +/** +* @file llfloaterpathfindingcharacters.cpp +* @brief "Pathfinding characters" floater, allowing for identification of pathfinding characters and their cpu usage. +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llfloaterpathfindingcharacters.h" + +#include <string> + +#include "llcheckboxctrl.h" +#include "llfloaterreg.h" +#include "llfloaterpathfindingobjects.h" +#include "llhandle.h" +#include "llpathfindingcharacter.h" +#include "llpathfindingcharacterlist.h" +#include "llpathfindingmanager.h" +#include "llpathfindingobject.h" +#include "llpathfindingobjectlist.h" +#include "llpathinglib.h" +#include "llquaternion.h" +#include "llsd.h" +#include "lluicolortable.h" +#include "lluuid.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "pipeline.h" +#include "v3math.h" +#include "v4color.h" + +LLHandle<LLFloaterPathfindingCharacters> LLFloaterPathfindingCharacters::sInstanceHandle; + +//--------------------------------------------------------------------------- +// LLFloaterPathfindingCharacters +//--------------------------------------------------------------------------- + +void LLFloaterPathfindingCharacters::onClose(bool pIsAppQuitting) +{ + // Hide any capsule that might be showing on floater close + hideCapsule(); + LLFloaterPathfindingObjects::onClose( pIsAppQuitting ); +} + +BOOL LLFloaterPathfindingCharacters::isShowPhysicsCapsule() const +{ + return mShowPhysicsCapsuleCheckBox->get(); +} + +void LLFloaterPathfindingCharacters::setShowPhysicsCapsule(BOOL pIsShowPhysicsCapsule) +{ + mShowPhysicsCapsuleCheckBox->set(pIsShowPhysicsCapsule && (LLPathingLib::getInstance() != NULL)); +} + +BOOL LLFloaterPathfindingCharacters::isPhysicsCapsuleEnabled(LLUUID& id, LLVector3& pos, LLQuaternion& rot) const +{ + id = mSelectedCharacterId; + // Physics capsule is enable if the checkbox is enabled and if we can get the required render + // parameters for any selected object + return (isShowPhysicsCapsule() && getCapsuleRenderData(pos, rot )); +} + +void LLFloaterPathfindingCharacters::openCharactersWithSelectedObjects() +{ + LLFloaterPathfindingCharacters *charactersFloater = LLFloaterReg::getTypedInstance<LLFloaterPathfindingCharacters>("pathfinding_characters"); + charactersFloater->showFloaterWithSelectionObjects(); +} + +LLHandle<LLFloaterPathfindingCharacters> LLFloaterPathfindingCharacters::getInstanceHandle() +{ + if ( sInstanceHandle.isDead() ) + { + LLFloaterPathfindingCharacters *floaterInstance = LLFloaterReg::findTypedInstance<LLFloaterPathfindingCharacters>("pathfinding_characters"); + if (floaterInstance != NULL) + { + sInstanceHandle = floaterInstance->mSelfHandle; + } + } + + return sInstanceHandle; +} + +LLFloaterPathfindingCharacters::LLFloaterPathfindingCharacters(const LLSD& pSeed) + : LLFloaterPathfindingObjects(pSeed), + mShowPhysicsCapsuleCheckBox(NULL), + mSelectedCharacterId(), + mBeaconColor(), + mSelfHandle() +{ + mSelfHandle.bind(this); +} + +LLFloaterPathfindingCharacters::~LLFloaterPathfindingCharacters() +{ +} + +BOOL LLFloaterPathfindingCharacters::postBuild() +{ + mBeaconColor = LLUIColorTable::getInstance()->getColor("PathfindingCharacterBeaconColor"); + + mShowPhysicsCapsuleCheckBox = findChild<LLCheckBoxCtrl>("show_physics_capsule"); + llassert(mShowPhysicsCapsuleCheckBox != NULL); + mShowPhysicsCapsuleCheckBox->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onShowPhysicsCapsuleClicked, this)); + mShowPhysicsCapsuleCheckBox->setEnabled(LLPathingLib::getInstance() != NULL); + + return LLFloaterPathfindingObjects::postBuild(); +} + +void LLFloaterPathfindingCharacters::requestGetObjects() +{ + LLPathfindingManager::getInstance()->requestGetCharacters(getNewRequestId(), boost::bind(&LLFloaterPathfindingCharacters::handleNewObjectList, this, _1, _2, _3)); +} + +void LLFloaterPathfindingCharacters::buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr) +{ + llassert(pObjectListPtr != NULL); + llassert(!pObjectListPtr->isEmpty()); + + for (LLPathfindingObjectList::const_iterator objectIter = pObjectListPtr->begin(); objectIter != pObjectListPtr->end(); ++objectIter) + { + const LLPathfindingObjectPtr objectPtr = objectIter->second; + const LLPathfindingCharacter *characterPtr = dynamic_cast<const LLPathfindingCharacter *>(objectPtr.get()); + llassert(characterPtr != NULL); + + LLSD scrollListItemData = buildCharacterScrollListItemData(characterPtr); + addObjectToScrollList(objectPtr, scrollListItemData); + } +} + +void LLFloaterPathfindingCharacters::updateControlsOnScrollListChange() +{ + LLFloaterPathfindingObjects::updateControlsOnScrollListChange(); + updateStateOnDisplayControls(); + showSelectedCharacterCapsules(); +} + +S32 LLFloaterPathfindingCharacters::getNameColumnIndex() const +{ + return 0; +} + +S32 LLFloaterPathfindingCharacters::getOwnerNameColumnIndex() const +{ + return 2; +} + +std::string LLFloaterPathfindingCharacters::getOwnerName(const LLPathfindingObject *pObject) const +{ + return (pObject->hasOwner() + ? (pObject->hasOwnerName() + ? (pObject->isGroupOwned() + ? (pObject->getOwnerName() + " " + getString("character_owner_group")) + : pObject->getOwnerName()) + : getString("character_owner_loading")) + : getString("character_owner_unknown")); +} + +const LLColor4 &LLFloaterPathfindingCharacters::getBeaconColor() const +{ + return mBeaconColor; +} + +LLPathfindingObjectListPtr LLFloaterPathfindingCharacters::getEmptyObjectList() const +{ + LLPathfindingObjectListPtr objectListPtr(new LLPathfindingCharacterList()); + return objectListPtr; +} + +void LLFloaterPathfindingCharacters::onShowPhysicsCapsuleClicked() +{ + if (LLPathingLib::getInstance() == NULL) + { + if (isShowPhysicsCapsule()) + { + setShowPhysicsCapsule(FALSE); + } + } + else + { + if (mSelectedCharacterId.notNull() && isShowPhysicsCapsule()) + { + showCapsule(); + } + else + { + hideCapsule(); + } + } +} + +LLSD LLFloaterPathfindingCharacters::buildCharacterScrollListItemData(const LLPathfindingCharacter *pCharacterPtr) const +{ + LLSD columns = LLSD::emptyArray(); + + columns[0]["column"] = "name"; + columns[0]["value"] = pCharacterPtr->getName(); + + columns[1]["column"] = "description"; + columns[1]["value"] = pCharacterPtr->getDescription(); + + columns[2]["column"] = "owner"; + columns[2]["value"] = getOwnerName(pCharacterPtr); + + S32 cpuTime = llround(pCharacterPtr->getCPUTime()); + std::string cpuTimeString = llformat("%d", cpuTime); + LLStringUtil::format_map_t string_args; + string_args["[CPU_TIME]"] = cpuTimeString; + + columns[3]["column"] = "cpu_time"; + columns[3]["value"] = getString("character_cpu_time", string_args); + + columns[4]["column"] = "altitude"; + columns[4]["value"] = llformat("%1.0f m", pCharacterPtr->getLocation()[2]); + + return columns; +} + +void LLFloaterPathfindingCharacters::updateStateOnDisplayControls() +{ + int numSelectedItems = getNumSelectedObjects();; + bool isEditEnabled = ((numSelectedItems == 1) && (LLPathingLib::getInstance() != NULL)); + + mShowPhysicsCapsuleCheckBox->setEnabled(isEditEnabled); + if (!isEditEnabled) + { + setShowPhysicsCapsule(FALSE); + } +} + +void LLFloaterPathfindingCharacters::showSelectedCharacterCapsules() +{ + // Hide any previous capsule + hideCapsule(); + + // Get the only selected object, or set the selected object to null if we do not have exactly + // one object selected + if (getNumSelectedObjects() == 1) + { + LLPathfindingObjectPtr selectedObjectPtr = getFirstSelectedObject(); + mSelectedCharacterId = selectedObjectPtr->getUUID(); + } + else + { + mSelectedCharacterId.setNull(); + } + + // Show any capsule if enabled + showCapsule(); +} + +void LLFloaterPathfindingCharacters::showCapsule() const +{ + if (mSelectedCharacterId.notNull() && isShowPhysicsCapsule()) + { + LLPathfindingObjectPtr objectPtr = getFirstSelectedObject(); + llassert(objectPtr != NULL); + if (objectPtr != NULL) + { + const LLPathfindingCharacter *character = dynamic_cast<const LLPathfindingCharacter *>(objectPtr.get()); + llassert(mSelectedCharacterId == character->getUUID()); + if (LLPathingLib::getInstance() != NULL) + { + LLPathingLib::getInstance()->createPhysicsCapsuleRep(character->getLength(), character->getRadius(), + character->isHorizontal(), character->getUUID()); + } + } + + gPipeline.hideObject(mSelectedCharacterId); + } +} + +void LLFloaterPathfindingCharacters::hideCapsule() const +{ + if (mSelectedCharacterId.notNull()) + { + gPipeline.restoreHiddenObject(mSelectedCharacterId); + } + if (LLPathingLib::getInstance() != NULL) + { + LLPathingLib::getInstance()->cleanupPhysicsCapsuleRepResiduals(); + } +} + +bool LLFloaterPathfindingCharacters::getCapsuleRenderData(LLVector3& pPosition, LLQuaternion& rot) const +{ + bool result = false; + + // If we have a selected object, find the object on the viewer object list and return its + // position. Else, return false indicating that we either do not have a selected object + // or we cannot find the selected object on the viewer object list + if (mSelectedCharacterId.notNull()) + { + LLViewerObject *viewerObject = gObjectList.findObject(mSelectedCharacterId); + if ( viewerObject != NULL ) + { + rot = viewerObject->getRotation() ; + pPosition = viewerObject->getRenderPosition(); + result = true; + } + } + + return result; +} diff --git a/indra/newview/llfloaterpathfindingcharacters.h b/indra/newview/llfloaterpathfindingcharacters.h new file mode 100644 index 0000000000..4021f4f119 --- /dev/null +++ b/indra/newview/llfloaterpathfindingcharacters.h @@ -0,0 +1,99 @@ +/** +* @file llfloaterpathfindingcharacters.h +* @brief "Pathfinding characters" floater, allowing for identification of pathfinding characters and their cpu usage. +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLFLOATERPATHFINDINGCHARACTERS_H +#define LL_LLFLOATERPATHFINDINGCHARACTERS_H + +#include "llfloaterpathfindingobjects.h" +#include "llhandle.h" +#include "llpathfindingobjectlist.h" +#include "lluuid.h" +#include "v4color.h" + +class LLCheckBoxCtrl; +class LLPathfindingCharacter; +class LLQuaternion; +class LLSD; +class LLVector3; + +class LLFloaterPathfindingCharacters : public LLFloaterPathfindingObjects +{ +public: + virtual void onClose(bool pIsAppQuitting); + + BOOL isShowPhysicsCapsule() const; + void setShowPhysicsCapsule(BOOL pIsShowPhysicsCapsule); + + BOOL isPhysicsCapsuleEnabled(LLUUID& id, LLVector3& pos, LLQuaternion& rot) const; + + static void openCharactersWithSelectedObjects(); + static LLHandle<LLFloaterPathfindingCharacters> getInstanceHandle(); + +protected: + friend class LLFloaterReg; + + LLFloaterPathfindingCharacters(const LLSD& pSeed); + virtual ~LLFloaterPathfindingCharacters(); + + virtual BOOL postBuild(); + + virtual void requestGetObjects(); + + virtual void buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr); + + virtual void updateControlsOnScrollListChange(); + + virtual S32 getNameColumnIndex() const; + virtual S32 getOwnerNameColumnIndex() const; + virtual std::string getOwnerName(const LLPathfindingObject *pObject) const; + virtual const LLColor4 &getBeaconColor() const; + + virtual LLPathfindingObjectListPtr getEmptyObjectList() const; + +private: + void onShowPhysicsCapsuleClicked(); + + LLSD buildCharacterScrollListItemData(const LLPathfindingCharacter *pCharacterPtr) const; + + void updateStateOnDisplayControls(); + void showSelectedCharacterCapsules(); + + void showCapsule() const; + void hideCapsule() const; + + bool getCapsuleRenderData(LLVector3& pPosition, LLQuaternion& rot) const; + + LLCheckBoxCtrl *mShowPhysicsCapsuleCheckBox; + + LLUUID mSelectedCharacterId; + + LLColor4 mBeaconColor; + + LLRootHandle<LLFloaterPathfindingCharacters> mSelfHandle; + static LLHandle<LLFloaterPathfindingCharacters> sInstanceHandle; +}; + +#endif // LL_LLFLOATERPATHFINDINGCHARACTERS_H diff --git a/indra/newview/llfloaterpathfindingconsole.cpp b/indra/newview/llfloaterpathfindingconsole.cpp new file mode 100644 index 0000000000..298454724b --- /dev/null +++ b/indra/newview/llfloaterpathfindingconsole.cpp @@ -0,0 +1,1273 @@ +/** +* @file llfloaterpathfindingconsole.cpp +* @brief "Pathfinding console" floater, allowing for viewing and testing of the pathfinding navmesh through Havok AI utilities. +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llfloaterpathfindingconsole.h" + +#include <vector> + +#include <boost/signals2.hpp> + +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llcontrol.h" +#include "llenvmanager.h" +#include "llfloaterpathfindingcharacters.h" +#include "llfloaterpathfindinglinksets.h" +#include "llfloaterreg.h" +#include "llhandle.h" +#include "llpanel.h" +#include "llpathfindingnavmeshzone.h" +#include "llpathfindingpathtool.h" +#include "llpathinglib.h" +#include "llsliderctrl.h" +#include "llsd.h" +#include "lltabcontainer.h" +#include "lltextbase.h" +#include "lltoolmgr.h" +#include "lltoolfocus.h" +#include "llviewercontrol.h" +#include "llviewerparcelmgr.h" +#include "pipeline.h" + +#define XUI_RENDER_HEATMAP_NONE 0 +#define XUI_RENDER_HEATMAP_A 1 +#define XUI_RENDER_HEATMAP_B 2 +#define XUI_RENDER_HEATMAP_C 3 +#define XUI_RENDER_HEATMAP_D 4 + +#define XUI_CHARACTER_TYPE_NONE 0 +#define XUI_CHARACTER_TYPE_A 1 +#define XUI_CHARACTER_TYPE_B 2 +#define XUI_CHARACTER_TYPE_C 3 +#define XUI_CHARACTER_TYPE_D 4 + +#define XUI_VIEW_TAB_INDEX 0 +#define XUI_TEST_TAB_INDEX 1 + +#define SET_SHAPE_RENDER_FLAG(_flag,_type) _flag |= (1U << _type) + +#define CONTROL_NAME_RETRIEVE_NEIGHBOR "PathfindingRetrieveNeighboringRegion" +#define CONTROL_NAME_WALKABLE_OBJECTS "PathfindingWalkable" +#define CONTROL_NAME_STATIC_OBSTACLE_OBJECTS "PathfindingObstacle" +#define CONTROL_NAME_MATERIAL_VOLUMES "PathfindingMaterial" +#define CONTROL_NAME_EXCLUSION_VOLUMES "PathfindingExclusion" +#define CONTROL_NAME_INTERIOR_EDGE "PathfindingConnectedEdge" +#define CONTROL_NAME_EXTERIOR_EDGE "PathfindingBoundaryEdge" +#define CONTROL_NAME_HEATMAP_MIN "PathfindingHeatColorBase" +#define CONTROL_NAME_HEATMAP_MAX "PathfindingHeatColorMax" +#define CONTROL_NAME_NAVMESH_FACE "PathfindingFaceColor" +#define CONTROL_NAME_TEST_PATH_VALID_END "PathfindingTestPathValidEndColor" +#define CONTROL_NAME_TEST_PATH_INVALID_END "PathfindingTestPathInvalidEndColor" +#define CONTROL_NAME_TEST_PATH "PathfindingTestPathColor" +#define CONTROL_NAME_WATER "PathfindingWaterColor" + +LLHandle<LLFloaterPathfindingConsole> LLFloaterPathfindingConsole::sInstanceHandle; + +//--------------------------------------------------------------------------- +// LLFloaterPathfindingConsole +//--------------------------------------------------------------------------- + +BOOL LLFloaterPathfindingConsole::postBuild() +{ + mViewTestTabContainer = findChild<LLTabContainer>("view_test_tab_container"); + llassert(mViewTestTabContainer != NULL); + mViewTestTabContainer->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onTabSwitch, this)); + + mViewTab = findChild<LLPanel>("view_panel"); + llassert(mViewTab != NULL); + + mShowLabel = findChild<LLTextBase>("show_label"); + llassert(mShowLabel != NULL); + + mShowWorldCheckBox = findChild<LLCheckBoxCtrl>("show_world"); + llassert(mShowWorldCheckBox != NULL); + mShowWorldCheckBox->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onShowWorldSet, this)); + + mShowWorldMovablesOnlyCheckBox = findChild<LLCheckBoxCtrl>("show_world_movables_only"); + llassert(mShowWorldMovablesOnlyCheckBox != NULL); + mShowWorldMovablesOnlyCheckBox->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onShowWorldMovablesOnlySet, this)); + + mShowNavMeshCheckBox = findChild<LLCheckBoxCtrl>("show_navmesh"); + llassert(mShowNavMeshCheckBox != NULL); + mShowNavMeshCheckBox->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onShowNavMeshSet, this)); + + mShowNavMeshWalkabilityLabel = findChild<LLTextBase>("show_walkability_label"); + llassert(mShowNavMeshWalkabilityLabel != NULL); + + mShowNavMeshWalkabilityComboBox = findChild<LLComboBox>("show_heatmap_mode"); + llassert(mShowNavMeshWalkabilityComboBox != NULL); + mShowNavMeshWalkabilityComboBox->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onShowWalkabilitySet, this)); + + mShowWalkablesCheckBox = findChild<LLCheckBoxCtrl>("show_walkables"); + llassert(mShowWalkablesCheckBox != NULL); + + mShowStaticObstaclesCheckBox = findChild<LLCheckBoxCtrl>("show_static_obstacles"); + llassert(mShowStaticObstaclesCheckBox != NULL); + + mShowMaterialVolumesCheckBox = findChild<LLCheckBoxCtrl>("show_material_volumes"); + llassert(mShowMaterialVolumesCheckBox != NULL); + + mShowExclusionVolumesCheckBox = findChild<LLCheckBoxCtrl>("show_exclusion_volumes"); + llassert(mShowExclusionVolumesCheckBox != NULL); + + mShowRenderWaterPlaneCheckBox = findChild<LLCheckBoxCtrl>("show_water_plane"); + llassert(mShowRenderWaterPlaneCheckBox != NULL); + + mShowXRayCheckBox = findChild<LLCheckBoxCtrl>("show_xray"); + llassert(mShowXRayCheckBox != NULL); + + mTestTab = findChild<LLPanel>("test_panel"); + llassert(mTestTab != NULL); + + mPathfindingViewerStatus = findChild<LLTextBase>("pathfinding_viewer_status"); + llassert(mPathfindingViewerStatus != NULL); + + mPathfindingSimulatorStatus = findChild<LLTextBase>("pathfinding_simulator_status"); + llassert(mPathfindingSimulatorStatus != NULL); + + mCtrlClickLabel = findChild<LLTextBase>("ctrl_click_label"); + llassert(mCtrlClickLabel != NULL); + + mShiftClickLabel = findChild<LLTextBase>("shift_click_label"); + llassert(mShiftClickLabel != NULL); + + mCharacterWidthLabel = findChild<LLTextBase>("character_width_label"); + llassert(mCharacterWidthLabel != NULL); + + mCharacterWidthSlider = findChild<LLSliderCtrl>("character_width"); + llassert(mCharacterWidthSlider != NULL); + mCharacterWidthSlider->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onCharacterWidthSet, this)); + + mCharacterWidthUnitLabel = findChild<LLTextBase>("character_width_unit_label"); + llassert(mCharacterWidthUnitLabel != NULL); + + mCharacterTypeLabel = findChild<LLTextBase>("character_type_label"); + llassert(mCharacterTypeLabel != NULL); + + mCharacterTypeComboBox = findChild<LLComboBox>("path_character_type"); + llassert(mCharacterTypeComboBox != NULL); + mCharacterTypeComboBox->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onCharacterTypeSwitch, this)); + + mPathTestingStatus = findChild<LLTextBase>("path_test_status"); + llassert(mPathTestingStatus != NULL); + + mClearPathButton = findChild<LLButton>("clear_path"); + llassert(mClearPathButton != NULL); + mClearPathButton->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onClearPathClicked, this)); + + mErrorColor = LLUIColorTable::instance().getColor("PathfindingErrorColor"); + mWarningColor = LLUIColorTable::instance().getColor("PathfindingWarningColor"); + + if (LLPathingLib::getInstance() != NULL) + { + mPathfindingToolset = new LLToolset(); + mPathfindingToolset->addTool(LLPathfindingPathTool::getInstance()); + mPathfindingToolset->addTool(LLToolCamera::getInstance()); + mPathfindingToolset->setShowFloaterTools(false); + } + + updateCharacterWidth(); + updateCharacterType(); + + return LLFloater::postBuild(); +} + +void LLFloaterPathfindingConsole::onOpen(const LLSD& pKey) +{ + LLFloater::onOpen(pKey); + //make sure we have a pathing system + if ( LLPathingLib::getInstance() == NULL ) + { + setConsoleState(kConsoleStateLibraryNotImplemented); + llwarns <<"Errror: cannot find pathing library implementation."<<llendl; + } + else + { + if (!mNavMeshZoneSlot.connected()) + { + mNavMeshZoneSlot = mNavMeshZone.registerNavMeshZoneListener(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshZoneStatus, this, _1)); + } + + mIsNavMeshUpdating = false; + initializeNavMeshZoneForCurrentRegion(); + registerSavedSettingsListeners(); + fillInColorsForNavMeshVisualization(); + } + + if (!mRegionBoundarySlot.connected()) + { + mRegionBoundarySlot = LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterPathfindingConsole::onRegionBoundaryCross, this)); + } + + if (!mTeleportFailedSlot.connected()) + { + mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLFloaterPathfindingConsole::onRegionBoundaryCross, this)); + } + + if (!mPathEventSlot.connected()) + { + mPathEventSlot = LLPathfindingPathTool::getInstance()->registerPathEventListener(boost::bind(&LLFloaterPathfindingConsole::onPathEvent, this)); + } + + setDefaultInputs(); + updatePathTestStatus(); + + if (mViewTestTabContainer->getCurrentPanelIndex() == XUI_TEST_TAB_INDEX) + { + switchIntoTestPathMode(); + } +} + +void LLFloaterPathfindingConsole::onClose(bool pIsAppQuitting) +{ + switchOutOfTestPathMode(); + + if (mPathEventSlot.connected()) + { + mPathEventSlot.disconnect(); + } + + if (mTeleportFailedSlot.connected()) + { + mTeleportFailedSlot.disconnect(); + } + + if (mRegionBoundarySlot.connected()) + { + mRegionBoundarySlot.disconnect(); + } + + if (mNavMeshZoneSlot.connected()) + { + mNavMeshZoneSlot.disconnect(); + } + + if (LLPathingLib::getInstance() != NULL) + { + mNavMeshZone.disable(); + } + deregisterSavedSettingsListeners(); + + setDefaultInputs(); + setConsoleState(kConsoleStateUnknown); + cleanupRenderableRestoreItems(); + + LLFloater::onClose(pIsAppQuitting); +} + +LLHandle<LLFloaterPathfindingConsole> LLFloaterPathfindingConsole::getInstanceHandle() +{ + if (sInstanceHandle.isDead()) + { + LLFloaterPathfindingConsole *floaterInstance = LLFloaterReg::findTypedInstance<LLFloaterPathfindingConsole>("pathfinding_console"); + if (floaterInstance != NULL) + { + sInstanceHandle = floaterInstance->mSelfHandle; + } + } + + return sInstanceHandle; +} + +BOOL LLFloaterPathfindingConsole::isRenderNavMesh() const +{ + return mShowNavMeshCheckBox->get(); +} + +void LLFloaterPathfindingConsole::setRenderNavMesh(BOOL pIsRenderNavMesh) +{ + mShowNavMeshCheckBox->set(pIsRenderNavMesh); + setNavMeshRenderState(); +} + +BOOL LLFloaterPathfindingConsole::isRenderWalkables() const +{ + return mShowWalkablesCheckBox->get(); +} + +void LLFloaterPathfindingConsole::setRenderWalkables(BOOL pIsRenderWalkables) +{ + mShowWalkablesCheckBox->set(pIsRenderWalkables); +} + +BOOL LLFloaterPathfindingConsole::isRenderStaticObstacles() const +{ + return mShowStaticObstaclesCheckBox->get(); +} + +void LLFloaterPathfindingConsole::setRenderStaticObstacles(BOOL pIsRenderStaticObstacles) +{ + mShowStaticObstaclesCheckBox->set(pIsRenderStaticObstacles); +} + +BOOL LLFloaterPathfindingConsole::isRenderMaterialVolumes() const +{ + return mShowMaterialVolumesCheckBox->get(); +} + +void LLFloaterPathfindingConsole::setRenderMaterialVolumes(BOOL pIsRenderMaterialVolumes) +{ + mShowMaterialVolumesCheckBox->set(pIsRenderMaterialVolumes); +} + +BOOL LLFloaterPathfindingConsole::isRenderExclusionVolumes() const +{ + return mShowExclusionVolumesCheckBox->get(); +} + +void LLFloaterPathfindingConsole::setRenderExclusionVolumes(BOOL pIsRenderExclusionVolumes) +{ + mShowExclusionVolumesCheckBox->set(pIsRenderExclusionVolumes); +} + +BOOL LLFloaterPathfindingConsole::isRenderWorld() const +{ + return mShowWorldCheckBox->get(); +} + +void LLFloaterPathfindingConsole::setRenderWorld(BOOL pIsRenderWorld) +{ + mShowWorldCheckBox->set(pIsRenderWorld); + setWorldRenderState(); +} + +BOOL LLFloaterPathfindingConsole::isRenderWorldMovablesOnly() const +{ + return (mShowWorldCheckBox->get() && mShowWorldMovablesOnlyCheckBox->get()); +} + +void LLFloaterPathfindingConsole::setRenderWorldMovablesOnly(BOOL pIsRenderWorldMovablesOnly) +{ + mShowWorldMovablesOnlyCheckBox->set(pIsRenderWorldMovablesOnly); +} + +BOOL LLFloaterPathfindingConsole::isRenderWaterPlane() const +{ + return mShowRenderWaterPlaneCheckBox->get(); +} + +void LLFloaterPathfindingConsole::setRenderWaterPlane(BOOL pIsRenderWaterPlane) +{ + mShowRenderWaterPlaneCheckBox->set(pIsRenderWaterPlane); +} + +BOOL LLFloaterPathfindingConsole::isRenderXRay() const +{ + return mShowXRayCheckBox->get(); +} + +void LLFloaterPathfindingConsole::setRenderXRay(BOOL pIsRenderXRay) +{ + mShowXRayCheckBox->set(pIsRenderXRay); +} + +LLPathingLib::LLPLCharacterType LLFloaterPathfindingConsole::getRenderHeatmapType() const +{ + LLPathingLib::LLPLCharacterType renderHeatmapType; + + switch (mShowNavMeshWalkabilityComboBox->getValue().asInteger()) + { + case XUI_RENDER_HEATMAP_NONE : + renderHeatmapType = LLPathingLib::LLPL_CHARACTER_TYPE_NONE; + break; + case XUI_RENDER_HEATMAP_A : + renderHeatmapType = LLPathingLib::LLPL_CHARACTER_TYPE_A; + break; + case XUI_RENDER_HEATMAP_B : + renderHeatmapType = LLPathingLib::LLPL_CHARACTER_TYPE_B; + break; + case XUI_RENDER_HEATMAP_C : + renderHeatmapType = LLPathingLib::LLPL_CHARACTER_TYPE_C; + break; + case XUI_RENDER_HEATMAP_D : + renderHeatmapType = LLPathingLib::LLPL_CHARACTER_TYPE_D; + break; + default : + renderHeatmapType = LLPathingLib::LLPL_CHARACTER_TYPE_NONE; + llassert(0); + break; + } + + return renderHeatmapType; +} + +void LLFloaterPathfindingConsole::setRenderHeatmapType(LLPathingLib::LLPLCharacterType pRenderHeatmapType) +{ + LLSD comboBoxValue; + + switch (pRenderHeatmapType) + { + case LLPathingLib::LLPL_CHARACTER_TYPE_NONE : + comboBoxValue = XUI_RENDER_HEATMAP_NONE; + break; + case LLPathingLib::LLPL_CHARACTER_TYPE_A : + comboBoxValue = XUI_RENDER_HEATMAP_A; + break; + case LLPathingLib::LLPL_CHARACTER_TYPE_B : + comboBoxValue = XUI_RENDER_HEATMAP_B; + break; + case LLPathingLib::LLPL_CHARACTER_TYPE_C : + comboBoxValue = XUI_RENDER_HEATMAP_C; + break; + case LLPathingLib::LLPL_CHARACTER_TYPE_D : + comboBoxValue = XUI_RENDER_HEATMAP_D; + break; + default : + comboBoxValue = XUI_RENDER_HEATMAP_NONE; + llassert(0); + break; + } + + mShowNavMeshWalkabilityComboBox->setValue(comboBoxValue); +} + +LLFloaterPathfindingConsole::LLFloaterPathfindingConsole(const LLSD& pSeed) + : LLFloater(pSeed), + mSelfHandle(), + mViewTestTabContainer(NULL), + mViewTab(NULL), + mShowLabel(NULL), + mShowWorldCheckBox(NULL), + mShowWorldMovablesOnlyCheckBox(NULL), + mShowNavMeshCheckBox(NULL), + mShowNavMeshWalkabilityLabel(NULL), + mShowNavMeshWalkabilityComboBox(NULL), + mShowWalkablesCheckBox(NULL), + mShowStaticObstaclesCheckBox(NULL), + mShowMaterialVolumesCheckBox(NULL), + mShowExclusionVolumesCheckBox(NULL), + mShowRenderWaterPlaneCheckBox(NULL), + mShowXRayCheckBox(NULL), + mPathfindingViewerStatus(NULL), + mPathfindingSimulatorStatus(NULL), + mTestTab(NULL), + mCtrlClickLabel(), + mShiftClickLabel(), + mCharacterWidthLabel(), + mCharacterWidthUnitLabel(), + mCharacterWidthSlider(NULL), + mCharacterTypeLabel(), + mCharacterTypeComboBox(NULL), + mPathTestingStatus(NULL), + mClearPathButton(NULL), + mErrorColor(), + mWarningColor(), + mNavMeshZoneSlot(), + mNavMeshZone(), + mIsNavMeshUpdating(false), + mRegionBoundarySlot(), + mTeleportFailedSlot(), + mPathEventSlot(), + mPathfindingToolset(NULL), + mSavedToolset(NULL), + mSavedSettingRetrieveNeighborSlot(), + mSavedSettingWalkableSlot(), + mSavedSettingStaticObstacleSlot(), + mSavedSettingMaterialVolumeSlot(), + mSavedSettingExclusionVolumeSlot(), + mSavedSettingInteriorEdgeSlot(), + mSavedSettingExteriorEdgeSlot(), + mSavedSettingHeatmapMinSlot(), + mSavedSettingHeatmapMaxSlot(), + mSavedSettingNavMeshFaceSlot(), + mSavedSettingTestPathValidEndSlot(), + mSavedSettingTestPathInvalidEndSlot(), + mSavedSettingTestPathSlot(), + mSavedSettingWaterSlot(), + mConsoleState(kConsoleStateUnknown), + mRenderableRestoreList() +{ + mSelfHandle.bind(this); +} + +LLFloaterPathfindingConsole::~LLFloaterPathfindingConsole() +{ +} + +void LLFloaterPathfindingConsole::onTabSwitch() +{ + if (mViewTestTabContainer->getCurrentPanelIndex() == XUI_TEST_TAB_INDEX) + { + switchIntoTestPathMode(); + } + else + { + switchOutOfTestPathMode(); + } +} + +void LLFloaterPathfindingConsole::onShowWorldSet() +{ + setWorldRenderState(); + updateRenderablesObjects(); +} + +void LLFloaterPathfindingConsole::onShowWorldMovablesOnlySet() +{ + updateRenderablesObjects(); +} + +void LLFloaterPathfindingConsole::onShowNavMeshSet() +{ + setNavMeshRenderState(); +} + +void LLFloaterPathfindingConsole::onShowWalkabilitySet() +{ + if (LLPathingLib::getInstance() != NULL) + { + LLPathingLib::getInstance()->setNavMeshMaterialType(getRenderHeatmapType()); + } +} + +void LLFloaterPathfindingConsole::onCharacterWidthSet() +{ + updateCharacterWidth(); +} + +void LLFloaterPathfindingConsole::onCharacterTypeSwitch() +{ + updateCharacterType(); +} + +void LLFloaterPathfindingConsole::onClearPathClicked() +{ + clearPath(); +} + +void LLFloaterPathfindingConsole::handleNavMeshZoneStatus(LLPathfindingNavMeshZone::ENavMeshZoneRequestStatus pNavMeshZoneRequestStatus) +{ + switch (pNavMeshZoneRequestStatus) + { + case LLPathfindingNavMeshZone::kNavMeshZoneRequestUnknown : + setConsoleState(kConsoleStateUnknown); + break; + case LLPathfindingNavMeshZone::kNavMeshZoneRequestWaiting : + setConsoleState(kConsoleStateRegionLoading); + break; + case LLPathfindingNavMeshZone::kNavMeshZoneRequestChecking : + setConsoleState(kConsoleStateCheckingVersion); + break; + case LLPathfindingNavMeshZone::kNavMeshZoneRequestNeedsUpdate : + mIsNavMeshUpdating = true; + mNavMeshZone.refresh(); + break; + case LLPathfindingNavMeshZone::kNavMeshZoneRequestStarted : + setConsoleState(kConsoleStateDownloading); + break; + case LLPathfindingNavMeshZone::kNavMeshZoneRequestCompleted : + mIsNavMeshUpdating = false; + setConsoleState(kConsoleStateHasNavMesh); + break; + case LLPathfindingNavMeshZone::kNavMeshZoneRequestNotEnabled : + setConsoleState(kConsoleStateRegionNotEnabled); + break; + case LLPathfindingNavMeshZone::kNavMeshZoneRequestError : + setConsoleState(kConsoleStateError); + break; + default: + setConsoleState(kConsoleStateUnknown); + llassert(0); + break; + } +} + +void LLFloaterPathfindingConsole::onRegionBoundaryCross() +{ + initializeNavMeshZoneForCurrentRegion(); + setRenderWorld(TRUE); + setRenderWorldMovablesOnly(FALSE); +} + +void LLFloaterPathfindingConsole::onPathEvent() +{ + const LLPathfindingPathTool *pathToolInstance = LLPathfindingPathTool::getInstance(); + + mCharacterWidthSlider->setValue(LLSD(pathToolInstance->getCharacterWidth())); + + LLSD characterType; + switch (pathToolInstance->getCharacterType()) + { + case LLPathfindingPathTool::kCharacterTypeNone : + characterType = XUI_CHARACTER_TYPE_NONE; + break; + case LLPathfindingPathTool::kCharacterTypeA : + characterType = XUI_CHARACTER_TYPE_A; + break; + case LLPathfindingPathTool::kCharacterTypeB : + characterType = XUI_CHARACTER_TYPE_B; + break; + case LLPathfindingPathTool::kCharacterTypeC : + characterType = XUI_CHARACTER_TYPE_C; + break; + case LLPathfindingPathTool::kCharacterTypeD : + characterType = XUI_CHARACTER_TYPE_D; + break; + default : + characterType = XUI_CHARACTER_TYPE_NONE; + llassert(0); + break; + } + mCharacterTypeComboBox->setValue(characterType); + + updatePathTestStatus(); +} + +void LLFloaterPathfindingConsole::setDefaultInputs() +{ + mViewTestTabContainer->selectTab(XUI_VIEW_TAB_INDEX); + setRenderWorld(TRUE); + setRenderWorldMovablesOnly(FALSE); + setRenderNavMesh(FALSE); + setRenderWalkables(FALSE); + setRenderMaterialVolumes(FALSE); + setRenderStaticObstacles(FALSE); + setRenderExclusionVolumes(FALSE); + setRenderWaterPlane(FALSE); + setRenderXRay(FALSE); +} + +void LLFloaterPathfindingConsole::setConsoleState(EConsoleState pConsoleState) +{ + mConsoleState = pConsoleState; + updateControlsOnConsoleState(); + updateViewerStatusOnConsoleState(); + updateSimulatorStatusOnConsoleState(); +} + +void LLFloaterPathfindingConsole::setWorldRenderState() +{ + BOOL renderWorld = isRenderWorld(); + + mShowWorldMovablesOnlyCheckBox->setEnabled(renderWorld && mShowWorldCheckBox->getEnabled()); + if (!renderWorld) + { + mShowWorldMovablesOnlyCheckBox->set(FALSE); + } +} + +void LLFloaterPathfindingConsole::setNavMeshRenderState() +{ + BOOL renderNavMesh = isRenderNavMesh(); + + mShowNavMeshWalkabilityLabel->setEnabled(renderNavMesh); + mShowNavMeshWalkabilityComboBox->setEnabled(renderNavMesh); +} + +void LLFloaterPathfindingConsole::updateRenderablesObjects() +{ + if ( isRenderWorldMovablesOnly() ) + { + gPipeline.hidePermanentObjects( mRenderableRestoreList ); + } + else + { + cleanupRenderableRestoreItems(); + } +} + +void LLFloaterPathfindingConsole::updateControlsOnConsoleState() +{ + switch (mConsoleState) + { + case kConsoleStateUnknown : + case kConsoleStateRegionNotEnabled : + case kConsoleStateRegionLoading : + mViewTestTabContainer->selectTab(XUI_VIEW_TAB_INDEX); + mViewTab->setEnabled(FALSE); + mShowLabel->setEnabled(FALSE); + mShowWorldCheckBox->setEnabled(FALSE); + mShowWorldMovablesOnlyCheckBox->setEnabled(FALSE); + mShowNavMeshCheckBox->setEnabled(FALSE); + mShowNavMeshWalkabilityLabel->setEnabled(FALSE); + mShowNavMeshWalkabilityComboBox->setEnabled(FALSE); + mShowWalkablesCheckBox->setEnabled(FALSE); + mShowStaticObstaclesCheckBox->setEnabled(FALSE); + mShowMaterialVolumesCheckBox->setEnabled(FALSE); + mShowExclusionVolumesCheckBox->setEnabled(FALSE); + mShowRenderWaterPlaneCheckBox->setEnabled(FALSE); + mShowXRayCheckBox->setEnabled(FALSE); + mTestTab->setEnabled(FALSE); + mCtrlClickLabel->setEnabled(FALSE); + mShiftClickLabel->setEnabled(FALSE); + mCharacterWidthLabel->setEnabled(FALSE); + mCharacterWidthUnitLabel->setEnabled(FALSE); + mCharacterWidthSlider->setEnabled(FALSE); + mCharacterTypeLabel->setEnabled(FALSE); + mCharacterTypeComboBox->setEnabled(FALSE); + mClearPathButton->setEnabled(FALSE); + clearPath(); + break; + case kConsoleStateLibraryNotImplemented : + mViewTestTabContainer->selectTab(XUI_VIEW_TAB_INDEX); + mViewTab->setEnabled(FALSE); + mShowLabel->setEnabled(FALSE); + mShowWorldCheckBox->setEnabled(FALSE); + mShowWorldMovablesOnlyCheckBox->setEnabled(FALSE); + mShowNavMeshCheckBox->setEnabled(FALSE); + mShowNavMeshWalkabilityLabel->setEnabled(FALSE); + mShowNavMeshWalkabilityComboBox->setEnabled(FALSE); + mShowWalkablesCheckBox->setEnabled(FALSE); + mShowStaticObstaclesCheckBox->setEnabled(FALSE); + mShowMaterialVolumesCheckBox->setEnabled(FALSE); + mShowExclusionVolumesCheckBox->setEnabled(FALSE); + mShowRenderWaterPlaneCheckBox->setEnabled(FALSE); + mShowXRayCheckBox->setEnabled(FALSE); + mTestTab->setEnabled(FALSE); + mCtrlClickLabel->setEnabled(FALSE); + mShiftClickLabel->setEnabled(FALSE); + mCharacterWidthLabel->setEnabled(FALSE); + mCharacterWidthUnitLabel->setEnabled(FALSE); + mCharacterWidthSlider->setEnabled(FALSE); + mCharacterTypeLabel->setEnabled(FALSE); + mCharacterTypeComboBox->setEnabled(FALSE); + mClearPathButton->setEnabled(FALSE); + clearPath(); + break; + case kConsoleStateCheckingVersion : + case kConsoleStateDownloading : + case kConsoleStateError : + mViewTestTabContainer->selectTab(XUI_VIEW_TAB_INDEX); + mViewTab->setEnabled(FALSE); + mShowLabel->setEnabled(FALSE); + mShowWorldCheckBox->setEnabled(FALSE); + mShowWorldMovablesOnlyCheckBox->setEnabled(FALSE); + mShowNavMeshCheckBox->setEnabled(FALSE); + mShowNavMeshWalkabilityLabel->setEnabled(FALSE); + mShowNavMeshWalkabilityComboBox->setEnabled(FALSE); + mShowWalkablesCheckBox->setEnabled(FALSE); + mShowStaticObstaclesCheckBox->setEnabled(FALSE); + mShowMaterialVolumesCheckBox->setEnabled(FALSE); + mShowExclusionVolumesCheckBox->setEnabled(FALSE); + mShowRenderWaterPlaneCheckBox->setEnabled(FALSE); + mShowXRayCheckBox->setEnabled(FALSE); + mTestTab->setEnabled(FALSE); + mCtrlClickLabel->setEnabled(FALSE); + mShiftClickLabel->setEnabled(FALSE); + mCharacterWidthLabel->setEnabled(FALSE); + mCharacterWidthUnitLabel->setEnabled(FALSE); + mCharacterWidthSlider->setEnabled(FALSE); + mCharacterTypeLabel->setEnabled(FALSE); + mCharacterTypeComboBox->setEnabled(FALSE); + mClearPathButton->setEnabled(FALSE); + clearPath(); + break; + case kConsoleStateHasNavMesh : + mViewTab->setEnabled(TRUE); + mShowLabel->setEnabled(TRUE); + mShowWorldCheckBox->setEnabled(TRUE); + setWorldRenderState(); + mShowNavMeshCheckBox->setEnabled(TRUE); + setNavMeshRenderState(); + mShowWalkablesCheckBox->setEnabled(TRUE); + mShowStaticObstaclesCheckBox->setEnabled(TRUE); + mShowMaterialVolumesCheckBox->setEnabled(TRUE); + mShowExclusionVolumesCheckBox->setEnabled(TRUE); + mShowRenderWaterPlaneCheckBox->setEnabled(TRUE); + mShowXRayCheckBox->setEnabled(TRUE); + mTestTab->setEnabled(TRUE); + mCtrlClickLabel->setEnabled(TRUE); + mShiftClickLabel->setEnabled(TRUE); + mCharacterWidthLabel->setEnabled(TRUE); + mCharacterWidthUnitLabel->setEnabled(TRUE); + mCharacterWidthSlider->setEnabled(TRUE); + mCharacterTypeLabel->setEnabled(TRUE); + mCharacterTypeComboBox->setEnabled(TRUE); + mClearPathButton->setEnabled(TRUE); + break; + default : + llassert(0); + break; + } +} + +void LLFloaterPathfindingConsole::updateViewerStatusOnConsoleState() +{ + std::string viewerStatusText(""); + LLStyle::Params viewerStyleParams; + + switch (mConsoleState) + { + case kConsoleStateUnknown : + viewerStatusText = getString("navmesh_viewer_status_unknown"); + viewerStyleParams.color = mErrorColor; + break; + case kConsoleStateLibraryNotImplemented : + viewerStatusText = getString("navmesh_viewer_status_library_not_implemented"); + viewerStyleParams.color = mErrorColor; + break; + case kConsoleStateRegionNotEnabled : + viewerStatusText = getString("navmesh_viewer_status_region_not_enabled"); + viewerStyleParams.color = mErrorColor; + break; + case kConsoleStateRegionLoading : + viewerStatusText = getString("navmesh_viewer_status_region_loading"); + viewerStyleParams.color = mWarningColor; + break; + case kConsoleStateCheckingVersion : + viewerStatusText = getString("navmesh_viewer_status_checking_version"); + viewerStyleParams.color = mWarningColor; + break; + case kConsoleStateDownloading : + if (mIsNavMeshUpdating) + { + viewerStatusText = getString("navmesh_viewer_status_updating"); + } + else + { + viewerStatusText = getString("navmesh_viewer_status_downloading"); + } + viewerStyleParams.color = mWarningColor; + break; + case kConsoleStateHasNavMesh : + viewerStatusText = getString("navmesh_viewer_status_has_navmesh"); + break; + case kConsoleStateError : + viewerStatusText = getString("navmesh_viewer_status_error"); + viewerStyleParams.color = mErrorColor; + break; + default : + viewerStatusText = getString("navmesh_viewer_status_unknown"); + viewerStyleParams.color = mErrorColor; + llassert(0); + break; + } + + mPathfindingViewerStatus->setText((LLStringExplicit)viewerStatusText, viewerStyleParams); +} + +void LLFloaterPathfindingConsole::updateSimulatorStatusOnConsoleState() +{ + std::string simulatorStatusText(""); + LLStyle::Params simulatorStyleParams; + + switch (mConsoleState) + { + case kConsoleStateUnknown : + case kConsoleStateLibraryNotImplemented : + case kConsoleStateRegionNotEnabled : + case kConsoleStateRegionLoading : + case kConsoleStateCheckingVersion : + case kConsoleStateError : + simulatorStatusText = getString("navmesh_simulator_status_unknown"); + simulatorStyleParams.color = mErrorColor; + break; + case kConsoleStateDownloading : + case kConsoleStateHasNavMesh : + switch (mNavMeshZone.getNavMeshZoneStatus()) + { + case LLPathfindingNavMeshZone::kNavMeshZonePending : + simulatorStatusText = getString("navmesh_simulator_status_pending"); + simulatorStyleParams.color = mWarningColor; + break; + case LLPathfindingNavMeshZone::kNavMeshZoneBuilding : + simulatorStatusText = getString("navmesh_simulator_status_building"); + simulatorStyleParams.color = mWarningColor; + break; + case LLPathfindingNavMeshZone::kNavMeshZoneSomePending : + simulatorStatusText = getString("navmesh_simulator_status_some_pending"); + simulatorStyleParams.color = mWarningColor; + break; + case LLPathfindingNavMeshZone::kNavMeshZoneSomeBuilding : + simulatorStatusText = getString("navmesh_simulator_status_some_building"); + simulatorStyleParams.color = mWarningColor; + break; + case LLPathfindingNavMeshZone::kNavMeshZonePendingAndBuilding : + simulatorStatusText = getString("navmesh_simulator_status_pending_and_building"); + simulatorStyleParams.color = mWarningColor; + break; + case LLPathfindingNavMeshZone::kNavMeshZoneComplete : + simulatorStatusText = getString("navmesh_simulator_status_complete"); + break; + default : + simulatorStatusText = getString("navmesh_simulator_status_unknown"); + simulatorStyleParams.color = mErrorColor; + break; + } + break; + default : + simulatorStatusText = getString("navmesh_simulator_status_unknown"); + simulatorStyleParams.color = mErrorColor; + llassert(0); + break; + } + + mPathfindingSimulatorStatus->setText((LLStringExplicit)simulatorStatusText, simulatorStyleParams); +} + +void LLFloaterPathfindingConsole::initializeNavMeshZoneForCurrentRegion() +{ + mNavMeshZone.disable(); + mNavMeshZone.initialize(); + mNavMeshZone.enable(); + mNavMeshZone.refresh(); + cleanupRenderableRestoreItems(); +} + +void LLFloaterPathfindingConsole::cleanupRenderableRestoreItems() +{ + if ( !mRenderableRestoreList.empty() ) + { + gPipeline.restorePermanentObjects( mRenderableRestoreList ); + mRenderableRestoreList.clear(); + } + else + { + gPipeline.skipRenderingOfTerrain( false ); + } +} + +void LLFloaterPathfindingConsole::switchIntoTestPathMode() +{ + if (LLPathingLib::getInstance() != NULL) + { + llassert(mPathfindingToolset != NULL); + LLToolMgr *toolMgrInstance = LLToolMgr::getInstance(); + if (toolMgrInstance->getCurrentToolset() != mPathfindingToolset) + { + mSavedToolset = toolMgrInstance->getCurrentToolset(); + toolMgrInstance->setCurrentToolset(mPathfindingToolset); + } + } +} + +void LLFloaterPathfindingConsole::switchOutOfTestPathMode() +{ + if (LLPathingLib::getInstance() != NULL) + { + llassert(mPathfindingToolset != NULL); + LLToolMgr *toolMgrInstance = LLToolMgr::getInstance(); + if (toolMgrInstance->getCurrentToolset() == mPathfindingToolset) + { + toolMgrInstance->setCurrentToolset(mSavedToolset); + mSavedToolset = NULL; + } + } +} + +void LLFloaterPathfindingConsole::updateCharacterWidth() +{ + LLPathfindingPathTool::getInstance()->setCharacterWidth(mCharacterWidthSlider->getValueF32()); +} + +void LLFloaterPathfindingConsole::updateCharacterType() +{ + LLPathfindingPathTool::ECharacterType characterType; + + switch (mCharacterTypeComboBox->getValue().asInteger()) + { + case XUI_CHARACTER_TYPE_NONE : + characterType = LLPathfindingPathTool::kCharacterTypeNone; + break; + case XUI_CHARACTER_TYPE_A : + characterType = LLPathfindingPathTool::kCharacterTypeA; + break; + case XUI_CHARACTER_TYPE_B : + characterType = LLPathfindingPathTool::kCharacterTypeB; + break; + case XUI_CHARACTER_TYPE_C : + characterType = LLPathfindingPathTool::kCharacterTypeC; + break; + case XUI_CHARACTER_TYPE_D : + characterType = LLPathfindingPathTool::kCharacterTypeD; + break; + default : + characterType = LLPathfindingPathTool::kCharacterTypeNone; + llassert(0); + break; + } + + LLPathfindingPathTool::getInstance()->setCharacterType(characterType); +} + +void LLFloaterPathfindingConsole::clearPath() +{ + LLPathfindingPathTool::getInstance()->clearPath(); +} + +void LLFloaterPathfindingConsole::updatePathTestStatus() +{ + std::string statusText(""); + LLStyle::Params styleParams; + + switch (LLPathfindingPathTool::getInstance()->getPathStatus()) + { + case LLPathfindingPathTool::kPathStatusUnknown : + statusText = getString("pathing_unknown"); + styleParams.color = mErrorColor; + break; + case LLPathfindingPathTool::kPathStatusChooseStartAndEndPoints : + statusText = getString("pathing_choose_start_and_end_points"); + styleParams.color = mWarningColor; + break; + case LLPathfindingPathTool::kPathStatusChooseStartPoint : + statusText = getString("pathing_choose_start_point"); + styleParams.color = mWarningColor; + break; + case LLPathfindingPathTool::kPathStatusChooseEndPoint : + statusText = getString("pathing_choose_end_point"); + styleParams.color = mWarningColor; + break; + case LLPathfindingPathTool::kPathStatusHasValidPath : + statusText = getString("pathing_path_valid"); + break; + case LLPathfindingPathTool::kPathStatusHasInvalidPath : + statusText = getString("pathing_path_invalid"); + styleParams.color = mErrorColor; + break; + case LLPathfindingPathTool::kPathStatusNotEnabled : + statusText = getString("pathing_region_not_enabled"); + styleParams.color = mErrorColor; + break; + case LLPathfindingPathTool::kPathStatusNotImplemented : + statusText = getString("pathing_library_not_implemented"); + styleParams.color = mErrorColor; + break; + case LLPathfindingPathTool::kPathStatusError : + statusText = getString("pathing_error"); + styleParams.color = mErrorColor; + break; + default : + statusText = getString("pathing_unknown"); + styleParams.color = mErrorColor; + break; + } + + mPathTestingStatus->setText((LLStringExplicit)statusText, styleParams); +} + + +BOOL LLFloaterPathfindingConsole::isRenderAnyShapes() const +{ + return (isRenderWalkables() || isRenderStaticObstacles() || + isRenderMaterialVolumes() || isRenderExclusionVolumes()); +} + +U32 LLFloaterPathfindingConsole::getRenderShapeFlags() +{ + U32 shapeRenderFlag = 0U; + + if (isRenderWalkables()) + { + SET_SHAPE_RENDER_FLAG(shapeRenderFlag, LLPathingLib::LLST_WalkableObjects); + } + if (isRenderStaticObstacles()) + { + SET_SHAPE_RENDER_FLAG(shapeRenderFlag, LLPathingLib::LLST_ObstacleObjects); + } + if (isRenderMaterialVolumes()) + { + SET_SHAPE_RENDER_FLAG(shapeRenderFlag, LLPathingLib::LLST_MaterialPhantoms); + } + if (isRenderExclusionVolumes()) + { + SET_SHAPE_RENDER_FLAG(shapeRenderFlag, LLPathingLib::LLST_ExclusionPhantoms); + } + + return shapeRenderFlag; +} + +void LLFloaterPathfindingConsole::registerSavedSettingsListeners() +{ + if (!mSavedSettingRetrieveNeighborSlot.connected()) + { + mSavedSettingRetrieveNeighborSlot = gSavedSettings.getControl(CONTROL_NAME_RETRIEVE_NEIGHBOR)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleRetrieveNeighborChange, this, _1, _2)); + } + if (!mSavedSettingWalkableSlot.connected()) + { + mSavedSettingWalkableSlot = gSavedSettings.getControl(CONTROL_NAME_WALKABLE_OBJECTS)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2)); + } + if (!mSavedSettingStaticObstacleSlot.connected()) + { + mSavedSettingStaticObstacleSlot = gSavedSettings.getControl(CONTROL_NAME_STATIC_OBSTACLE_OBJECTS)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2)); + } + if (!mSavedSettingMaterialVolumeSlot.connected()) + { + mSavedSettingMaterialVolumeSlot = gSavedSettings.getControl(CONTROL_NAME_MATERIAL_VOLUMES)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2)); + } + if (!mSavedSettingExclusionVolumeSlot.connected()) + { + mSavedSettingExclusionVolumeSlot = gSavedSettings.getControl(CONTROL_NAME_EXCLUSION_VOLUMES)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2)); + } + if (!mSavedSettingInteriorEdgeSlot.connected()) + { + mSavedSettingInteriorEdgeSlot = gSavedSettings.getControl(CONTROL_NAME_INTERIOR_EDGE)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2)); + } + if (!mSavedSettingExteriorEdgeSlot.connected()) + { + mSavedSettingExteriorEdgeSlot = gSavedSettings.getControl(CONTROL_NAME_EXTERIOR_EDGE)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2)); + } + if (!mSavedSettingHeatmapMinSlot.connected()) + { + mSavedSettingHeatmapMinSlot = gSavedSettings.getControl(CONTROL_NAME_HEATMAP_MIN)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2)); + } + if (!mSavedSettingHeatmapMaxSlot.connected()) + { + mSavedSettingHeatmapMaxSlot = gSavedSettings.getControl(CONTROL_NAME_HEATMAP_MAX)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2)); + } + if (!mSavedSettingNavMeshFaceSlot.connected()) + { + mSavedSettingNavMeshFaceSlot = gSavedSettings.getControl(CONTROL_NAME_NAVMESH_FACE)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2)); + } + if (!mSavedSettingTestPathValidEndSlot.connected()) + { + mSavedSettingTestPathValidEndSlot = gSavedSettings.getControl(CONTROL_NAME_TEST_PATH_VALID_END)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2)); + } + if (!mSavedSettingTestPathInvalidEndSlot.connected()) + { + mSavedSettingTestPathInvalidEndSlot = gSavedSettings.getControl(CONTROL_NAME_TEST_PATH_INVALID_END)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2)); + } + if (!mSavedSettingTestPathSlot.connected()) + { + mSavedSettingTestPathSlot = gSavedSettings.getControl(CONTROL_NAME_TEST_PATH)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2)); + } + if (!mSavedSettingWaterSlot.connected()) + { + mSavedSettingWaterSlot = gSavedSettings.getControl(CONTROL_NAME_WATER)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2)); + } +} + +void LLFloaterPathfindingConsole::deregisterSavedSettingsListeners() +{ + if (mSavedSettingRetrieveNeighborSlot.connected()) + { + mSavedSettingRetrieveNeighborSlot.disconnect(); + } + if (mSavedSettingWalkableSlot.connected()) + { + mSavedSettingWalkableSlot.disconnect(); + } + if (mSavedSettingStaticObstacleSlot.connected()) + { + mSavedSettingStaticObstacleSlot.disconnect(); + } + if (mSavedSettingMaterialVolumeSlot.connected()) + { + mSavedSettingMaterialVolumeSlot.disconnect(); + } + if (mSavedSettingExclusionVolumeSlot.connected()) + { + mSavedSettingExclusionVolumeSlot.disconnect(); + } + if (mSavedSettingInteriorEdgeSlot.connected()) + { + mSavedSettingInteriorEdgeSlot.disconnect(); + } + if (mSavedSettingExteriorEdgeSlot.connected()) + { + mSavedSettingExteriorEdgeSlot.disconnect(); + } + if (mSavedSettingHeatmapMinSlot.connected()) + { + mSavedSettingHeatmapMinSlot.disconnect(); + } + if (mSavedSettingHeatmapMaxSlot.connected()) + { + mSavedSettingHeatmapMaxSlot.disconnect(); + } + if (mSavedSettingNavMeshFaceSlot.connected()) + { + mSavedSettingNavMeshFaceSlot.disconnect(); + } + if (mSavedSettingTestPathValidEndSlot.connected()) + { + mSavedSettingTestPathValidEndSlot.disconnect(); + } + if (mSavedSettingTestPathInvalidEndSlot.connected()) + { + mSavedSettingTestPathInvalidEndSlot.disconnect(); + } + if (mSavedSettingTestPathSlot.connected()) + { + mSavedSettingTestPathSlot.disconnect(); + } + if (mSavedSettingWaterSlot.connected()) + { + mSavedSettingWaterSlot.disconnect(); + } +} + +void LLFloaterPathfindingConsole::handleRetrieveNeighborChange(LLControlVariable *pControl, const LLSD &pNewValue) +{ + initializeNavMeshZoneForCurrentRegion(); +} + +void LLFloaterPathfindingConsole::handleNavMeshColorChange(LLControlVariable *pControl, const LLSD &pNewValue) +{ + fillInColorsForNavMeshVisualization(); +} + +void LLFloaterPathfindingConsole::fillInColorsForNavMeshVisualization() +{ + if (LLPathingLib::getInstance() != NULL) + { + LLPathingLib::NavMeshColors navMeshColors; + + LLColor4 in = gSavedSettings.getColor4(CONTROL_NAME_WALKABLE_OBJECTS); + navMeshColors.mWalkable= LLColor4U(in); + + in = gSavedSettings.getColor4(CONTROL_NAME_STATIC_OBSTACLE_OBJECTS); + navMeshColors.mObstacle= LLColor4U(in); + + in = gSavedSettings.getColor4(CONTROL_NAME_MATERIAL_VOLUMES); + navMeshColors.mMaterial= LLColor4U(in); + + in = gSavedSettings.getColor4(CONTROL_NAME_EXCLUSION_VOLUMES); + navMeshColors.mExclusion= LLColor4U(in); + + in = gSavedSettings.getColor4(CONTROL_NAME_INTERIOR_EDGE); + navMeshColors.mConnectedEdge= LLColor4U(in); + + in = gSavedSettings.getColor4(CONTROL_NAME_EXTERIOR_EDGE); + navMeshColors.mBoundaryEdge= LLColor4U(in); + + navMeshColors.mHeatColorBase = gSavedSettings.getColor4(CONTROL_NAME_HEATMAP_MIN); + + navMeshColors.mHeatColorMax = gSavedSettings.getColor4(CONTROL_NAME_HEATMAP_MAX); + + in = gSavedSettings.getColor4(CONTROL_NAME_NAVMESH_FACE); + navMeshColors.mFaceColor= LLColor4U(in); + + in = gSavedSettings.getColor4(CONTROL_NAME_TEST_PATH_VALID_END); + navMeshColors.mStarValid= LLColor4U(in); + + in = gSavedSettings.getColor4(CONTROL_NAME_TEST_PATH_INVALID_END); + navMeshColors.mStarInvalid= LLColor4U(in); + + in = gSavedSettings.getColor4(CONTROL_NAME_TEST_PATH); + navMeshColors.mTestPath= LLColor4U(in); + + in = gSavedSettings.getColor4(CONTROL_NAME_WATER); + navMeshColors.mWaterColor= LLColor4U(in); + + LLPathingLib::getInstance()->setNavMeshColors(navMeshColors); + } +} diff --git a/indra/newview/llfloaterpathfindingconsole.h b/indra/newview/llfloaterpathfindingconsole.h new file mode 100644 index 0000000000..e999e57741 --- /dev/null +++ b/indra/newview/llfloaterpathfindingconsole.h @@ -0,0 +1,220 @@ +/** +* @file llfloaterpathfindingconsole.h +* @brief "Pathfinding console" floater, allowing for viewing and testing of the pathfinding navmesh through Havok AI utilities. +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLFLOATERPATHFINDINGCONSOLE_H +#define LL_LLFLOATERPATHFINDINGCONSOLE_H + +#include <vector> + +#include <boost/signals2.hpp> + +#include "llfloater.h" +#include "llhandle.h" +#include "llpathfindingnavmeshzone.h" +#include "llpathfindingpathtool.h" +#include "llpathinglib.h" +#include "v4color.h" + +class LLButton; +class LLCheckBoxCtrl; +class LLComboBox; +class LLControlVariable; +class LLPanel; +class LLSD; +class LLSliderCtrl; +class LLTabContainer; +class LLTextBase; +class LLToolset; + +class LLFloaterPathfindingConsole +: public LLFloater +{ + friend class LLFloaterReg; + +public: + virtual BOOL postBuild(); + virtual void onOpen(const LLSD& pKey); + virtual void onClose(bool pIsAppQuitting); + + static LLHandle<LLFloaterPathfindingConsole> getInstanceHandle(); + + BOOL isRenderNavMesh() const; + void setRenderNavMesh(BOOL pIsRenderNavMesh); + + BOOL isRenderWalkables() const; + void setRenderWalkables(BOOL pIsRenderWalkables); + + BOOL isRenderStaticObstacles() const; + void setRenderStaticObstacles(BOOL pIsRenderStaticObstacles); + + BOOL isRenderMaterialVolumes() const; + void setRenderMaterialVolumes(BOOL pIsRenderMaterialVolumes); + + BOOL isRenderExclusionVolumes() const; + void setRenderExclusionVolumes(BOOL pIsRenderExclusionVolumes); + + BOOL isRenderWorld() const; + void setRenderWorld(BOOL pIsRenderWorld); + + BOOL isRenderWorldMovablesOnly() const; + void setRenderWorldMovablesOnly(BOOL pIsRenderWorldMovablesOnly); + + BOOL isRenderWaterPlane() const; + void setRenderWaterPlane(BOOL pIsRenderWaterPlane); + + BOOL isRenderXRay() const; + void setRenderXRay(BOOL pIsRenderXRay); + + BOOL isRenderAnyShapes() const; + U32 getRenderShapeFlags(); + + LLPathingLib::LLPLCharacterType getRenderHeatmapType() const; + void setRenderHeatmapType(LLPathingLib::LLPLCharacterType pRenderHeatmapType); + void onRegionBoundaryCross(); +protected: + +private: + typedef enum + { + kConsoleStateUnknown, + kConsoleStateLibraryNotImplemented, + kConsoleStateRegionNotEnabled, + kConsoleStateRegionLoading, + kConsoleStateCheckingVersion, + kConsoleStateDownloading, + kConsoleStateHasNavMesh, + kConsoleStateError + } EConsoleState; + + // Does its own instance management, so clients not allowed + // to allocate or destroy. + LLFloaterPathfindingConsole(const LLSD& pSeed); + virtual ~LLFloaterPathfindingConsole(); + + void onTabSwitch(); + void onShowWorldSet(); + void onShowWorldMovablesOnlySet(); + void onShowNavMeshSet(); + void onShowWalkabilitySet(); + void onCharacterWidthSet(); + void onCharacterTypeSwitch(); + void onClearPathClicked(); + + void handleNavMeshZoneStatus(LLPathfindingNavMeshZone::ENavMeshZoneRequestStatus pNavMeshZoneRequestStatus); + + void onPathEvent(); + + void setDefaultInputs(); + void setConsoleState(EConsoleState pConsoleState); + void setWorldRenderState(); + void setNavMeshRenderState(); + void updateRenderablesObjects(); + + void updateControlsOnConsoleState(); + void updateViewerStatusOnConsoleState(); + void updateSimulatorStatusOnConsoleState(); + + void initializeNavMeshZoneForCurrentRegion(); + + void switchIntoTestPathMode(); + void switchOutOfTestPathMode(); + void updateCharacterWidth(); + void updateCharacterType(); + void clearPath(); + void updatePathTestStatus(); + + void registerSavedSettingsListeners(); + void deregisterSavedSettingsListeners(); + void handleRetrieveNeighborChange(LLControlVariable *pControl, const LLSD &pNewValue); + void handleNavMeshColorChange(LLControlVariable *pControl, const LLSD &pNewValue); + void fillInColorsForNavMeshVisualization(); + void cleanupRenderableRestoreItems(); + + LLRootHandle<LLFloaterPathfindingConsole> mSelfHandle; + LLTabContainer *mViewTestTabContainer; + LLPanel *mViewTab; + LLTextBase *mShowLabel; + LLCheckBoxCtrl *mShowWorldCheckBox; + LLCheckBoxCtrl *mShowWorldMovablesOnlyCheckBox; + LLCheckBoxCtrl *mShowNavMeshCheckBox; + LLTextBase *mShowNavMeshWalkabilityLabel; + LLComboBox *mShowNavMeshWalkabilityComboBox; + LLCheckBoxCtrl *mShowWalkablesCheckBox; + LLCheckBoxCtrl *mShowStaticObstaclesCheckBox; + LLCheckBoxCtrl *mShowMaterialVolumesCheckBox; + LLCheckBoxCtrl *mShowExclusionVolumesCheckBox; + LLCheckBoxCtrl *mShowRenderWaterPlaneCheckBox; + LLCheckBoxCtrl *mShowXRayCheckBox; + LLTextBase *mPathfindingViewerStatus; + LLTextBase *mPathfindingSimulatorStatus; + LLPanel *mTestTab; + LLTextBase *mCtrlClickLabel; + LLTextBase *mShiftClickLabel; + LLTextBase *mCharacterWidthLabel; + LLTextBase *mCharacterWidthUnitLabel; + LLSliderCtrl *mCharacterWidthSlider; + LLTextBase *mCharacterTypeLabel; + LLComboBox *mCharacterTypeComboBox; + LLTextBase *mPathTestingStatus; + LLButton *mClearPathButton; + + LLColor4 mErrorColor; + LLColor4 mWarningColor; + + LLPathfindingNavMeshZone::navmesh_zone_slot_t mNavMeshZoneSlot; + LLPathfindingNavMeshZone mNavMeshZone; + bool mIsNavMeshUpdating; + + boost::signals2::connection mRegionBoundarySlot; + boost::signals2::connection mTeleportFailedSlot; + LLPathfindingPathTool::path_event_slot_t mPathEventSlot; + + LLToolset *mPathfindingToolset; + LLToolset *mSavedToolset; + + boost::signals2::connection mSavedSettingRetrieveNeighborSlot; + boost::signals2::connection mSavedSettingWalkableSlot; + boost::signals2::connection mSavedSettingStaticObstacleSlot; + boost::signals2::connection mSavedSettingMaterialVolumeSlot; + boost::signals2::connection mSavedSettingExclusionVolumeSlot; + boost::signals2::connection mSavedSettingInteriorEdgeSlot; + boost::signals2::connection mSavedSettingExteriorEdgeSlot; + boost::signals2::connection mSavedSettingHeatmapMinSlot; + boost::signals2::connection mSavedSettingHeatmapMaxSlot; + boost::signals2::connection mSavedSettingNavMeshFaceSlot; + boost::signals2::connection mSavedSettingTestPathValidEndSlot; + boost::signals2::connection mSavedSettingTestPathInvalidEndSlot; + boost::signals2::connection mSavedSettingTestPathSlot; + boost::signals2::connection mSavedSettingWaterSlot; + + EConsoleState mConsoleState; + + std::vector<U32> mRenderableRestoreList; + + static LLHandle<LLFloaterPathfindingConsole> sInstanceHandle; +}; + +#endif // LL_LLFLOATERPATHFINDINGCONSOLE_H diff --git a/indra/newview/llfloaterpathfindinglinksets.cpp b/indra/newview/llfloaterpathfindinglinksets.cpp new file mode 100644 index 0000000000..1e46d7a402 --- /dev/null +++ b/indra/newview/llfloaterpathfindinglinksets.cpp @@ -0,0 +1,804 @@ +/** +* @file llfloaterpathfindinglinksets.cpp +* @brief "Pathfinding linksets" floater, allowing manipulation of the linksets on the current region. +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llfloaterpathfindinglinksets.h" + +#include <string> + +#include <boost/bind.hpp> + +#include "llagent.h" +#include "llbutton.h" +#include "llcombobox.h" +#include "llfloaterpathfindingobjects.h" +#include "llfloaterreg.h" +#include "lllineeditor.h" +#include "llnotificationsutil.h" +#include "llpathfindinglinkset.h" +#include "llpathfindinglinksetlist.h" +#include "llpathfindingmanager.h" +#include "llscrolllistitem.h" +#include "llsd.h" +#include "lltextbase.h" +#include "lltextvalidate.h" +#include "lluicolortable.h" +#include "lluictrl.h" +#include "v3math.h" +#include "v4color.h" + +#define XUI_LINKSET_USE_NONE 0 +#define XUI_LINKSET_USE_WALKABLE 1 +#define XUI_LINKSET_USE_STATIC_OBSTACLE 2 +#define XUI_LINKSET_USE_DYNAMIC_OBSTACLE 3 +#define XUI_LINKSET_USE_MATERIAL_VOLUME 4 +#define XUI_LINKSET_USE_EXCLUSION_VOLUME 5 +#define XUI_LINKSET_USE_DYNAMIC_PHANTOM 6 + +//--------------------------------------------------------------------------- +// LLFloaterPathfindingLinksets +//--------------------------------------------------------------------------- + +void LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects() +{ + LLFloaterPathfindingLinksets *linksetsFloater = LLFloaterReg::getTypedInstance<LLFloaterPathfindingLinksets>("pathfinding_linksets"); + linksetsFloater->clearFilters(); + linksetsFloater->showFloaterWithSelectionObjects(); +} + +LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed) + : LLFloaterPathfindingObjects(pSeed), + mFilterByName(NULL), + mFilterByDescription(NULL), + mFilterByLinksetUse(NULL), + mEditLinksetUse(NULL), + mEditLinksetUseWalkable(NULL), + mEditLinksetUseStaticObstacle(NULL), + mEditLinksetUseDynamicObstacle(NULL), + mEditLinksetUseMaterialVolume(NULL), + mEditLinksetUseExclusionVolume(NULL), + mEditLinksetUseDynamicPhantom(NULL), + mLabelWalkabilityCoefficients(NULL), + mLabelEditA(NULL), + mLabelSuggestedUseA(NULL), + mEditA(NULL), + mLabelEditB(NULL), + mLabelSuggestedUseB(NULL), + mEditB(NULL), + mLabelEditC(NULL), + mLabelSuggestedUseC(NULL), + mEditC(NULL), + mLabelEditD(NULL), + mLabelSuggestedUseD(NULL), + mEditD(NULL), + mApplyEditsButton(NULL), + mBeaconColor(), + mPreviousValueA(LLPathfindingLinkset::MAX_WALKABILITY_VALUE), + mPreviousValueB(LLPathfindingLinkset::MAX_WALKABILITY_VALUE), + mPreviousValueC(LLPathfindingLinkset::MAX_WALKABILITY_VALUE), + mPreviousValueD(LLPathfindingLinkset::MAX_WALKABILITY_VALUE) +{ +} + +LLFloaterPathfindingLinksets::~LLFloaterPathfindingLinksets() +{ +} + +BOOL LLFloaterPathfindingLinksets::postBuild() +{ + mBeaconColor = LLUIColorTable::getInstance()->getColor("PathfindingLinksetBeaconColor"); + + mFilterByName = findChild<LLLineEditor>("filter_by_name"); + llassert(mFilterByName != NULL); + mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); + mFilterByName->setSelectAllonFocusReceived(true); + mFilterByName->setCommitOnFocusLost(true); + + mFilterByDescription = findChild<LLLineEditor>("filter_by_description"); + llassert(mFilterByDescription != NULL); + mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); + mFilterByDescription->setSelectAllonFocusReceived(true); + mFilterByDescription->setCommitOnFocusLost(true); + + mFilterByLinksetUse = findChild<LLComboBox>("filter_by_linkset_use"); + llassert(mFilterByLinksetUse != NULL); + mFilterByLinksetUse->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); + + childSetAction("apply_filters", boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); + childSetAction("clear_filters", boost::bind(&LLFloaterPathfindingLinksets::onClearFiltersClicked, this)); + + mEditLinksetUse = findChild<LLComboBox>("edit_linkset_use"); + llassert(mEditLinksetUse != NULL); + mEditLinksetUse->clearRows(); + + mEditLinksetUseUnset = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getString("linkset_choose_use"), XUI_LINKSET_USE_NONE)); + llassert(mEditLinksetUseUnset != NULL); + + mEditLinksetUseWalkable = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kWalkable), XUI_LINKSET_USE_WALKABLE)); + llassert(mEditLinksetUseWalkable != NULL); + + mEditLinksetUseStaticObstacle = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kStaticObstacle), XUI_LINKSET_USE_STATIC_OBSTACLE)); + llassert(mEditLinksetUseStaticObstacle != NULL); + + mEditLinksetUseDynamicObstacle = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kDynamicObstacle), XUI_LINKSET_USE_DYNAMIC_OBSTACLE)); + llassert(mEditLinksetUseDynamicObstacle != NULL); + + mEditLinksetUseMaterialVolume = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kMaterialVolume), XUI_LINKSET_USE_MATERIAL_VOLUME)); + llassert(mEditLinksetUseMaterialVolume != NULL); + + mEditLinksetUseExclusionVolume = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kExclusionVolume), XUI_LINKSET_USE_EXCLUSION_VOLUME)); + llassert(mEditLinksetUseExclusionVolume != NULL); + + mEditLinksetUseDynamicPhantom = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kDynamicPhantom), XUI_LINKSET_USE_DYNAMIC_PHANTOM)); + llassert(mEditLinksetUseDynamicPhantom != NULL); + + mEditLinksetUse->selectFirstItem(); + + mLabelWalkabilityCoefficients = findChild<LLTextBase>("walkability_coefficients_label"); + llassert(mLabelWalkabilityCoefficients != NULL); + + mLabelEditA = findChild<LLTextBase>("edit_a_label"); + llassert(mLabelEditA != NULL); + + mLabelSuggestedUseA = findChild<LLTextBase>("suggested_use_a_label"); + llassert(mLabelSuggestedUseA != NULL); + + mEditA = findChild<LLLineEditor>("edit_a_value"); + llassert(mEditA != NULL); + mEditA->setPrevalidate(LLTextValidate::validateNonNegativeS32); + mEditA->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueA)); + + mLabelEditB = findChild<LLTextBase>("edit_b_label"); + llassert(mLabelEditB != NULL); + + mLabelSuggestedUseB = findChild<LLTextBase>("suggested_use_b_label"); + llassert(mLabelSuggestedUseB != NULL); + + mEditB = findChild<LLLineEditor>("edit_b_value"); + llassert(mEditB != NULL); + mEditB->setPrevalidate(LLTextValidate::validateNonNegativeS32); + mEditB->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueB)); + + mLabelEditC = findChild<LLTextBase>("edit_c_label"); + llassert(mLabelEditC != NULL); + + mLabelSuggestedUseC = findChild<LLTextBase>("suggested_use_c_label"); + llassert(mLabelSuggestedUseC != NULL); + + mEditC = findChild<LLLineEditor>("edit_c_value"); + llassert(mEditC != NULL); + mEditC->setPrevalidate(LLTextValidate::validateNonNegativeS32); + mEditC->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueC)); + + mLabelEditD = findChild<LLTextBase>("edit_d_label"); + llassert(mLabelEditD != NULL); + + mLabelSuggestedUseD = findChild<LLTextBase>("suggested_use_d_label"); + llassert(mLabelSuggestedUseD != NULL); + + mEditD = findChild<LLLineEditor>("edit_d_value"); + llassert(mEditD != NULL); + mEditD->setPrevalidate(LLTextValidate::validateNonNegativeS32); + mEditD->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueD)); + + mApplyEditsButton = findChild<LLButton>("apply_edit_values"); + llassert(mApplyEditsButton != NULL); + mApplyEditsButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyChangesClicked, this)); + + return LLFloaterPathfindingObjects::postBuild(); +} + +void LLFloaterPathfindingLinksets::requestGetObjects() +{ + LLPathfindingManager::getInstance()->requestGetLinksets(getNewRequestId(), boost::bind(&LLFloaterPathfindingLinksets::handleNewObjectList, this, _1, _2, _3)); +} + +void LLFloaterPathfindingLinksets::buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr) +{ + llassert(pObjectListPtr != NULL); + llassert(!pObjectListPtr->isEmpty()); + + std::string nameFilter = mFilterByName->getText(); + std::string descriptionFilter = mFilterByDescription->getText(); + LLPathfindingLinkset::ELinksetUse linksetUseFilter = getFilterLinksetUse(); + bool isFilteringName = !nameFilter.empty(); + bool isFilteringDescription = !descriptionFilter.empty(); + bool isFilteringLinksetUse = (linksetUseFilter != LLPathfindingLinkset::kUnknown); + + const LLVector3& avatarPosition = gAgent.getPositionAgent(); + + if (isFilteringName || isFilteringDescription || isFilteringLinksetUse) + { + LLStringUtil::toUpper(nameFilter); + LLStringUtil::toUpper(descriptionFilter); + for (LLPathfindingObjectList::const_iterator objectIter = pObjectListPtr->begin(); objectIter != pObjectListPtr->end(); ++objectIter) + { + const LLPathfindingObjectPtr objectPtr = objectIter->second; + const LLPathfindingLinkset *linksetPtr = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get()); + llassert(linksetPtr != NULL); + + std::string linksetName = (linksetPtr->isTerrain() ? getString("linkset_terrain_name") : linksetPtr->getName()); + std::string linksetDescription = linksetPtr->getDescription(); + LLStringUtil::toUpper(linksetName); + LLStringUtil::toUpper(linksetDescription); + + if ((!isFilteringName || (linksetName.find(nameFilter) != std::string::npos)) && + (!isFilteringDescription || (linksetDescription.find(descriptionFilter) != std::string::npos)) && + (!isFilteringLinksetUse || (linksetPtr->getLinksetUse() == linksetUseFilter))) + { + LLSD scrollListItemData = buildLinksetScrollListItemData(linksetPtr, avatarPosition); + addObjectToScrollList(objectPtr, scrollListItemData); + } + } + } + else + { + for (LLPathfindingObjectList::const_iterator objectIter = pObjectListPtr->begin(); objectIter != pObjectListPtr->end(); ++objectIter) + { + const LLPathfindingObjectPtr objectPtr = objectIter->second; + const LLPathfindingLinkset *linksetPtr = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get()); + llassert(linksetPtr != NULL); + + LLSD scrollListItemData = buildLinksetScrollListItemData(linksetPtr, avatarPosition); + addObjectToScrollList(objectPtr, scrollListItemData); + } + } +} + +void LLFloaterPathfindingLinksets::updateControlsOnScrollListChange() +{ + LLFloaterPathfindingObjects::updateControlsOnScrollListChange(); + updateEditFieldValues(); + updateStateOnEditFields(); + updateStateOnEditLinksetUse(); +} + +S32 LLFloaterPathfindingLinksets::getNameColumnIndex() const +{ + return 0; +} + +S32 LLFloaterPathfindingLinksets::getOwnerNameColumnIndex() const +{ + return 2; +} + +std::string LLFloaterPathfindingLinksets::getOwnerName(const LLPathfindingObject *pObject) const +{ + return (pObject->hasOwner() + ? (pObject->hasOwnerName() + ? (pObject->isGroupOwned() + ? (pObject->getOwnerName() + " " + getString("linkset_owner_group")) + : pObject->getOwnerName()) + : getString("linkset_owner_loading")) + : getString("linkset_owner_unknown")); +} + +const LLColor4 &LLFloaterPathfindingLinksets::getBeaconColor() const +{ + return mBeaconColor; +} + +LLPathfindingObjectListPtr LLFloaterPathfindingLinksets::getEmptyObjectList() const +{ + LLPathfindingObjectListPtr objectListPtr(new LLPathfindingLinksetList()); + return objectListPtr; +} + +void LLFloaterPathfindingLinksets::requestSetLinksets(LLPathfindingObjectListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) +{ + LLPathfindingManager::getInstance()->requestSetLinksets(getNewRequestId(), pLinksetList, pLinksetUse, pA, pB, pC, pD, boost::bind(&LLFloaterPathfindingLinksets::handleUpdateObjectList, this, _1, _2, _3)); +} + +void LLFloaterPathfindingLinksets::onApplyAllFilters() +{ + rebuildObjectsScrollList(); +} + +void LLFloaterPathfindingLinksets::onClearFiltersClicked() +{ + clearFilters(); + rebuildObjectsScrollList(); +} + +void LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered(LLUICtrl *pUICtrl, LLSD &pPreviousValue) +{ + LLLineEditor *pLineEditor = static_cast<LLLineEditor *>(pUICtrl); + llassert(pLineEditor != NULL); + + const std::string &valueString = pLineEditor->getText(); + + S32 intValue; + LLSD value; + bool doResetValue = false; + + if (valueString.empty()) + { + value = pPreviousValue; + doResetValue = true; + } + else if (LLStringUtil::convertToS32(valueString, intValue)) + { + doResetValue = ((intValue < LLPathfindingLinkset::MIN_WALKABILITY_VALUE) || (intValue > LLPathfindingLinkset::MAX_WALKABILITY_VALUE)); + value = LLSD(llclamp(intValue, LLPathfindingLinkset::MIN_WALKABILITY_VALUE, LLPathfindingLinkset::MAX_WALKABILITY_VALUE)); + } + else + { + value = LLSD(LLPathfindingLinkset::MAX_WALKABILITY_VALUE); + doResetValue = true; + } + + if (doResetValue) + { + pLineEditor->setValue(value); + } + pPreviousValue = value; +} + +void LLFloaterPathfindingLinksets::onApplyChangesClicked() +{ + applyEdit(); +} + +void LLFloaterPathfindingLinksets::clearFilters() +{ + mFilterByName->clear(); + mFilterByDescription->clear(); + setFilterLinksetUse(LLPathfindingLinkset::kUnknown); +} + +void LLFloaterPathfindingLinksets::updateEditFieldValues() +{ + int numSelectedObjects = getNumSelectedObjects(); + if (numSelectedObjects <= 0) + { + mEditLinksetUse->selectFirstItem(); + mEditA->clear(); + mEditB->clear(); + mEditC->clear(); + mEditD->clear(); + } + else + { + LLPathfindingObjectPtr firstSelectedObjectPtr = getFirstSelectedObject(); + llassert(firstSelectedObjectPtr != NULL); + + const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(firstSelectedObjectPtr.get()); + + setEditLinksetUse(linkset->getLinksetUse()); + mPreviousValueA = LLSD(linkset->getWalkabilityCoefficientA()); + mPreviousValueB = LLSD(linkset->getWalkabilityCoefficientB()); + mPreviousValueC = LLSD(linkset->getWalkabilityCoefficientC()); + mPreviousValueD = LLSD(linkset->getWalkabilityCoefficientD()); + mEditA->setValue(mPreviousValueA); + mEditB->setValue(mPreviousValueB); + mEditC->setValue(mPreviousValueC); + mEditD->setValue(mPreviousValueD); + } +} + +LLSD LLFloaterPathfindingLinksets::buildLinksetScrollListItemData(const LLPathfindingLinkset *pLinksetPtr, const LLVector3 &pAvatarPosition) const +{ + llassert(pLinksetPtr != NULL); + LLSD columns = LLSD::emptyArray(); + + if (pLinksetPtr->isTerrain()) + { + columns[0]["column"] = "name"; + columns[0]["value"] = getString("linkset_terrain_name"); + + columns[1]["column"] = "description"; + columns[1]["value"] = getString("linkset_terrain_description"); + + columns[2]["column"] = "owner"; + columns[2]["value"] = getString("linkset_terrain_owner"); + + columns[3]["column"] = "scripted"; + columns[3]["value"] = getString("linkset_terrain_scripted"); + + columns[4]["column"] = "land_impact"; + columns[4]["value"] = getString("linkset_terrain_land_impact"); + + columns[5]["column"] = "dist_from_you"; + columns[5]["value"] = getString("linkset_terrain_dist_from_you"); + } + else + { + columns[0]["column"] = "name"; + columns[0]["value"] = pLinksetPtr->getName(); + + columns[1]["column"] = "description"; + columns[1]["value"] = pLinksetPtr->getDescription(); + + columns[2]["column"] = "owner"; + columns[2]["value"] = getOwnerName(pLinksetPtr); + + columns[3]["column"] = "scripted"; + columns[3]["value"] = (pLinksetPtr->hasIsScripted() + ? (pLinksetPtr->isScripted() + ? getString("linkset_is_scripted") + : getString("linkset_is_not_scripted")) + : getString("linkset_is_unknown_scripted")); + + columns[4]["column"] = "land_impact"; + columns[4]["value"] = llformat("%1d", pLinksetPtr->getLandImpact()); + + columns[5]["column"] = "dist_from_you"; + columns[5]["value"] = llformat("%1.0f m", dist_vec(pAvatarPosition, pLinksetPtr->getLocation())); + } + + columns[6]["column"] = "linkset_use"; + std::string linksetUse = getLinksetUseString(pLinksetPtr->getLinksetUse()); + if (pLinksetPtr->isTerrain()) + { + linksetUse += (" " + getString("linkset_is_terrain")); + } + else if (!pLinksetPtr->isModifiable() && pLinksetPtr->canBeVolume()) + { + linksetUse += (" " + getString("linkset_is_restricted_state")); + } + else if (pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume()) + { + linksetUse += (" " + getString("linkset_is_non_volume_state")); + } + else if (!pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume()) + { + linksetUse += (" " + getString("linkset_is_restricted_non_volume_state")); + } + columns[6]["value"] = linksetUse; + + columns[7]["column"] = "a_percent"; + columns[7]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientA()); + + columns[8]["column"] = "b_percent"; + columns[8]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientB()); + + columns[9]["column"] = "c_percent"; + columns[9]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientC()); + + columns[10]["column"] = "d_percent"; + columns[10]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientD()); + + return columns; +} + +LLSD LLFloaterPathfindingLinksets::buildLinksetUseScrollListData(const std::string &pLabel, S32 pValue) const +{ + LLSD columns; + + columns[0]["column"] = "name"; + columns[0]["value"] = pLabel; + columns[0]["font"] = "SANSSERIF"; + + LLSD element; + element["value"] = pValue; + element["column"] = columns; + + return element; +} + +bool LLFloaterPathfindingLinksets::isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const +{ + bool isShowWarning = false; + + if (pLinksetUse != LLPathfindingLinkset::kUnknown) + { + LLPathfindingObjectListPtr selectedObjects = getSelectedObjects(); + if ((selectedObjects != NULL) && !selectedObjects->isEmpty()) + { + const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get()); + isShowWarning = linksetList->isShowUnmodifiablePhantomWarning(pLinksetUse); + } + } + + return isShowWarning; +} + +bool LLFloaterPathfindingLinksets::isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const +{ + bool isShowWarning = false; + + if (pLinksetUse != LLPathfindingLinkset::kUnknown) + { + LLPathfindingObjectListPtr selectedObjects = getSelectedObjects(); + if ((selectedObjects != NULL) && !selectedObjects->isEmpty()) + { + const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get()); + isShowWarning = linksetList->isShowPhantomToggleWarning(pLinksetUse); + } + } + + return isShowWarning; +} + +bool LLFloaterPathfindingLinksets::isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const +{ + bool isShowWarning = false; + + if (pLinksetUse != LLPathfindingLinkset::kUnknown) + { + LLPathfindingObjectListPtr selectedObjects = getSelectedObjects(); + if ((selectedObjects != NULL) && !selectedObjects->isEmpty()) + { + const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get()); + isShowWarning = linksetList->isShowCannotBeVolumeWarning(pLinksetUse); + } + } + + return isShowWarning; +} + +void LLFloaterPathfindingLinksets::updateStateOnEditFields() +{ + int numSelectedItems = getNumSelectedObjects(); + bool isEditEnabled = (numSelectedItems > 0); + + mEditLinksetUse->setEnabled(isEditEnabled); + + mLabelWalkabilityCoefficients->setEnabled(isEditEnabled); + mLabelEditA->setEnabled(isEditEnabled); + mLabelEditB->setEnabled(isEditEnabled); + mLabelEditC->setEnabled(isEditEnabled); + mLabelEditD->setEnabled(isEditEnabled); + mLabelSuggestedUseA->setEnabled(isEditEnabled); + mLabelSuggestedUseB->setEnabled(isEditEnabled); + mLabelSuggestedUseC->setEnabled(isEditEnabled); + mLabelSuggestedUseD->setEnabled(isEditEnabled); + mEditA->setEnabled(isEditEnabled); + mEditB->setEnabled(isEditEnabled); + mEditC->setEnabled(isEditEnabled); + mEditD->setEnabled(isEditEnabled); + + mApplyEditsButton->setEnabled(isEditEnabled && (getMessagingState() == kMessagingComplete)); +} + +void LLFloaterPathfindingLinksets::updateStateOnEditLinksetUse() +{ + BOOL useWalkable = FALSE; + BOOL useStaticObstacle = FALSE; + BOOL useDynamicObstacle = FALSE; + BOOL useMaterialVolume = FALSE; + BOOL useExclusionVolume = FALSE; + BOOL useDynamicPhantom = FALSE; + + LLPathfindingObjectListPtr selectedObjects = getSelectedObjects(); + if ((selectedObjects != NULL) && !selectedObjects->isEmpty()) + { + const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get()); + linksetList->determinePossibleStates(useWalkable, useStaticObstacle, useDynamicObstacle, useMaterialVolume, useExclusionVolume, useDynamicPhantom); + } + + mEditLinksetUseWalkable->setEnabled(useWalkable); + mEditLinksetUseStaticObstacle->setEnabled(useStaticObstacle); + mEditLinksetUseDynamicObstacle->setEnabled(useDynamicObstacle); + mEditLinksetUseMaterialVolume->setEnabled(useMaterialVolume); + mEditLinksetUseExclusionVolume->setEnabled(useExclusionVolume); + mEditLinksetUseDynamicPhantom->setEnabled(useDynamicPhantom); +} + +void LLFloaterPathfindingLinksets::applyEdit() +{ + LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse(); + + bool showPhantomToggleWarning = isShowPhantomToggleWarning(linksetUse); + bool showUnmodifiablePhantomWarning = isShowUnmodifiablePhantomWarning(linksetUse); + bool showCannotBeVolumeWarning = isShowCannotBeVolumeWarning(linksetUse); + + if (showPhantomToggleWarning || showUnmodifiablePhantomWarning || showCannotBeVolumeWarning) + { + LLPathfindingLinkset::ELinksetUse restrictedLinksetUse = LLPathfindingLinkset::getLinksetUseWithToggledPhantom(linksetUse); + LLSD substitutions; + substitutions["REQUESTED_TYPE"] = getLinksetUseString(linksetUse); + substitutions["RESTRICTED_TYPE"] = getLinksetUseString(restrictedLinksetUse); + + // Build one of the following notifications names + // - PathfindingLinksets_WarnOnPhantom + // - PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted + // - PathfindingLinksets_WarnOnPhantom_MismatchOnVolume + // - PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume + // - PathfindingLinksets_MismatchOnRestricted + // - PathfindingLinksets_MismatchOnVolume + // - PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume + + std::string notificationName = "PathfindingLinksets"; + + if (showPhantomToggleWarning) + { + notificationName += "_WarnOnPhantom"; + } + if (showUnmodifiablePhantomWarning) + { + notificationName += "_MismatchOnRestricted"; + } + if (showCannotBeVolumeWarning) + { + notificationName += "_MismatchOnVolume"; + } + + LLNotificationsUtil::add(notificationName, substitutions, LLSD(), boost::bind(&LLFloaterPathfindingLinksets::handleApplyEdit, this, _1, _2)); + } + else + { + doApplyEdit(); + } +} + +void LLFloaterPathfindingLinksets::handleApplyEdit(const LLSD &pNotification, const LLSD &pResponse) +{ + if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0) + { + doApplyEdit(); + } +} + +void LLFloaterPathfindingLinksets::doApplyEdit() +{ + LLPathfindingObjectListPtr selectedObjects = getSelectedObjects(); + if ((selectedObjects != NULL) && !selectedObjects->isEmpty()) + { + LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse(); + const std::string &aString = mEditA->getText(); + const std::string &bString = mEditB->getText(); + const std::string &cString = mEditC->getText(); + const std::string &dString = mEditD->getText(); + S32 aValue = static_cast<S32>(atoi(aString.c_str())); + S32 bValue = static_cast<S32>(atoi(bString.c_str())); + S32 cValue = static_cast<S32>(atoi(cString.c_str())); + S32 dValue = static_cast<S32>(atoi(dString.c_str())); + + + requestSetLinksets(selectedObjects, linksetUse, aValue, bValue, cValue, dValue); + } +} + +std::string LLFloaterPathfindingLinksets::getLinksetUseString(LLPathfindingLinkset::ELinksetUse pLinksetUse) const +{ + std::string linksetUse; + + switch (pLinksetUse) + { + case LLPathfindingLinkset::kWalkable : + linksetUse = getString("linkset_use_walkable"); + break; + case LLPathfindingLinkset::kStaticObstacle : + linksetUse = getString("linkset_use_static_obstacle"); + break; + case LLPathfindingLinkset::kDynamicObstacle : + linksetUse = getString("linkset_use_dynamic_obstacle"); + break; + case LLPathfindingLinkset::kMaterialVolume : + linksetUse = getString("linkset_use_material_volume"); + break; + case LLPathfindingLinkset::kExclusionVolume : + linksetUse = getString("linkset_use_exclusion_volume"); + break; + case LLPathfindingLinkset::kDynamicPhantom : + linksetUse = getString("linkset_use_dynamic_phantom"); + break; + case LLPathfindingLinkset::kUnknown : + default : + linksetUse = getString("linkset_use_dynamic_obstacle"); + llassert(0); + break; + } + + return linksetUse; +} + +LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getFilterLinksetUse() const +{ + return convertToLinksetUse(mFilterByLinksetUse->getValue()); +} + +void LLFloaterPathfindingLinksets::setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse) +{ + mFilterByLinksetUse->setValue(convertToXuiValue(pLinksetUse)); +} + +LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getEditLinksetUse() const +{ + return convertToLinksetUse(mEditLinksetUse->getValue()); +} + +void LLFloaterPathfindingLinksets::setEditLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse) +{ + mEditLinksetUse->setValue(convertToXuiValue(pLinksetUse)); +} + +LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::convertToLinksetUse(LLSD pXuiValue) const +{ + LLPathfindingLinkset::ELinksetUse linkUse; + + switch (pXuiValue.asInteger()) + { + case XUI_LINKSET_USE_NONE : + linkUse = LLPathfindingLinkset::kUnknown; + break; + case XUI_LINKSET_USE_WALKABLE : + linkUse = LLPathfindingLinkset::kWalkable; + break; + case XUI_LINKSET_USE_STATIC_OBSTACLE : + linkUse = LLPathfindingLinkset::kStaticObstacle; + break; + case XUI_LINKSET_USE_DYNAMIC_OBSTACLE : + linkUse = LLPathfindingLinkset::kDynamicObstacle; + break; + case XUI_LINKSET_USE_MATERIAL_VOLUME : + linkUse = LLPathfindingLinkset::kMaterialVolume; + break; + case XUI_LINKSET_USE_EXCLUSION_VOLUME : + linkUse = LLPathfindingLinkset::kExclusionVolume; + break; + case XUI_LINKSET_USE_DYNAMIC_PHANTOM : + linkUse = LLPathfindingLinkset::kDynamicPhantom; + break; + default : + linkUse = LLPathfindingLinkset::kUnknown; + llassert(0); + break; + } + + return linkUse; +} + +LLSD LLFloaterPathfindingLinksets::convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const +{ + LLSD xuiValue; + + switch (pLinksetUse) + { + case LLPathfindingLinkset::kUnknown : + xuiValue = XUI_LINKSET_USE_NONE; + break; + case LLPathfindingLinkset::kWalkable : + xuiValue = XUI_LINKSET_USE_WALKABLE; + break; + case LLPathfindingLinkset::kStaticObstacle : + xuiValue = XUI_LINKSET_USE_STATIC_OBSTACLE; + break; + case LLPathfindingLinkset::kDynamicObstacle : + xuiValue = XUI_LINKSET_USE_DYNAMIC_OBSTACLE; + break; + case LLPathfindingLinkset::kMaterialVolume : + xuiValue = XUI_LINKSET_USE_MATERIAL_VOLUME; + break; + case LLPathfindingLinkset::kExclusionVolume : + xuiValue = XUI_LINKSET_USE_EXCLUSION_VOLUME; + break; + case LLPathfindingLinkset::kDynamicPhantom : + xuiValue = XUI_LINKSET_USE_DYNAMIC_PHANTOM; + break; + default : + xuiValue = XUI_LINKSET_USE_NONE; + llassert(0); + break; + } + + return xuiValue; +} diff --git a/indra/newview/llfloaterpathfindinglinksets.h b/indra/newview/llfloaterpathfindinglinksets.h new file mode 100644 index 0000000000..7149da9215 --- /dev/null +++ b/indra/newview/llfloaterpathfindinglinksets.h @@ -0,0 +1,142 @@ +/** +* @file llfloaterpathfindinglinksets.h +* @brief "Pathfinding linksets" floater, allowing manipulation of the linksets on the current region. +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLFLOATERPATHFINDINGLINKSETS_H +#define LL_LLFLOATERPATHFINDINGLINKSETS_H + +#include <string> + +#include "llfloaterpathfindingobjects.h" +#include "llpathfindinglinkset.h" +#include "llpathfindingobjectlist.h" +#include "v4color.h" + +class LLButton; +class LLComboBox; +class LLLineEditor; +class LLScrollListItem; +class LLSD; +class LLTextBase; +class LLUICtrl; +class LLVector3; + +class LLFloaterPathfindingLinksets : public LLFloaterPathfindingObjects +{ +public: + static void openLinksetsWithSelectedObjects(); + +protected: + friend class LLFloaterReg; + + LLFloaterPathfindingLinksets(const LLSD& pSeed); + virtual ~LLFloaterPathfindingLinksets(); + + virtual BOOL postBuild(); + + virtual void requestGetObjects(); + + virtual void buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr); + + virtual void updateControlsOnScrollListChange(); + + virtual S32 getNameColumnIndex() const; + virtual S32 getOwnerNameColumnIndex() const; + virtual std::string getOwnerName(const LLPathfindingObject *pObject) const; + virtual const LLColor4 &getBeaconColor() const; + + virtual LLPathfindingObjectListPtr getEmptyObjectList() const; + +private: + void requestSetLinksets(LLPathfindingObjectListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD); + + void onApplyAllFilters(); + void onClearFiltersClicked(); + void onWalkabilityCoefficientEntered(LLUICtrl *pUICtrl, LLSD &pPreviousValue); + void onApplyChangesClicked(); + + void clearFilters(); + + void updateEditFieldValues(); + LLSD buildLinksetScrollListItemData(const LLPathfindingLinkset *pLinksetPtr, const LLVector3 &pAvatarPosition) const; + LLSD buildLinksetUseScrollListData(const std::string &pLabel, S32 pValue) const; + + bool isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; + bool isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; + bool isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; + + void updateStateOnEditFields(); + void updateStateOnEditLinksetUse(); + + void applyEdit(); + void handleApplyEdit(const LLSD &pNotification, const LLSD &pResponse); + void doApplyEdit(); + + std::string getLinksetUseString(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; + + LLPathfindingLinkset::ELinksetUse getFilterLinksetUse() const; + void setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse); + + LLPathfindingLinkset::ELinksetUse getEditLinksetUse() const; + void setEditLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse); + + LLPathfindingLinkset::ELinksetUse convertToLinksetUse(LLSD pXuiValue) const; + LLSD convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; + + LLLineEditor *mFilterByName; + LLLineEditor *mFilterByDescription; + LLComboBox *mFilterByLinksetUse; + LLComboBox *mEditLinksetUse; + LLScrollListItem *mEditLinksetUseUnset; + LLScrollListItem *mEditLinksetUseWalkable; + LLScrollListItem *mEditLinksetUseStaticObstacle; + LLScrollListItem *mEditLinksetUseDynamicObstacle; + LLScrollListItem *mEditLinksetUseMaterialVolume; + LLScrollListItem *mEditLinksetUseExclusionVolume; + LLScrollListItem *mEditLinksetUseDynamicPhantom; + LLTextBase *mLabelWalkabilityCoefficients; + LLTextBase *mLabelEditA; + LLTextBase *mLabelSuggestedUseA; + LLLineEditor *mEditA; + LLTextBase *mLabelEditB; + LLTextBase *mLabelSuggestedUseB; + LLLineEditor *mEditB; + LLTextBase *mLabelEditC; + LLTextBase *mLabelSuggestedUseC; + LLLineEditor *mEditC; + LLTextBase *mLabelEditD; + LLTextBase *mLabelSuggestedUseD; + LLLineEditor *mEditD; + LLButton *mApplyEditsButton; + + LLColor4 mBeaconColor; + + LLSD mPreviousValueA; + LLSD mPreviousValueB; + LLSD mPreviousValueC; + LLSD mPreviousValueD; +}; + +#endif // LL_LLFLOATERPATHFINDINGLINKSETS_H diff --git a/indra/newview/llfloaterpathfindingobjects.cpp b/indra/newview/llfloaterpathfindingobjects.cpp new file mode 100644 index 0000000000..20c1215bcb --- /dev/null +++ b/indra/newview/llfloaterpathfindingobjects.cpp @@ -0,0 +1,884 @@ +/** +* @file llfloaterpathfindingobjects.cpp +* @brief Base class for both the pathfinding linksets and characters floater. +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llfloaterpathfindingobjects.h" + +#include <string> +#include <map> +#include <vector> + +#include <boost/bind.hpp> +#include <boost/signals2.hpp> + +#include "llagent.h" +#include "llavatarname.h" +#include "llavatarnamecache.h" +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llenvmanager.h" +#include "llfloater.h" +#include "llfontgl.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "llpathfindingmanager.h" +#include "llresmgr.h" +#include "llscrolllistcell.h" +#include "llscrolllistctrl.h" +#include "llscrolllistitem.h" +#include "llselectmgr.h" +#include "llsd.h" +#include "llstring.h" +#include "llstyle.h" +#include "lltextbase.h" +#include "lluicolortable.h" +#include "llviewermenu.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "v3dmath.h" +#include "v3math.h" +#include "v4color.h" + +#define DEFAULT_BEACON_WIDTH 6 + +//--------------------------------------------------------------------------- +// LLFloaterPathfindingObjects +//--------------------------------------------------------------------------- + +void LLFloaterPathfindingObjects::onOpen(const LLSD &pKey) +{ + LLFloater::onOpen(pKey); + + selectNoneObjects(); + mObjectsScrollList->setCommitOnSelectionChange(TRUE); + + if (!mSelectionUpdateSlot.connected()) + { + mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterPathfindingObjects::onInWorldSelectionListChanged, this)); + } + + if (!mRegionBoundaryCrossingSlot.connected()) + { + mRegionBoundaryCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLFloaterPathfindingObjects::onRegionBoundaryCrossed, this)); + } + + if (!mGodLevelChangeSlot.connected()) + { + mGodLevelChangeSlot = gAgent.registerGodLevelChanageListener(boost::bind(&LLFloaterPathfindingObjects::onGodLevelChange, this, _1)); + } + + requestGetObjects(); +} + +void LLFloaterPathfindingObjects::onClose(bool pIsAppQuitting) +{ + if (mGodLevelChangeSlot.connected()) + { + mGodLevelChangeSlot.disconnect(); + } + + if (mRegionBoundaryCrossingSlot.connected()) + { + mRegionBoundaryCrossingSlot.disconnect(); + } + + if (mSelectionUpdateSlot.connected()) + { + mSelectionUpdateSlot.disconnect(); + } + + mObjectsScrollList->setCommitOnSelectionChange(FALSE); + selectNoneObjects(); + + if (mObjectsSelection.notNull()) + { + mObjectsSelection.clear(); + } + + if (pIsAppQuitting) + { + clearAllObjects(); + } +} + +void LLFloaterPathfindingObjects::draw() +{ + LLFloater::draw(); + + if (isShowBeacons()) + { + std::vector<LLScrollListItem *> selectedItems = mObjectsScrollList->getAllSelected(); + if (!selectedItems.empty()) + { + int numSelectedItems = selectedItems.size(); + S32 nameColumnIndex = getNameColumnIndex(); + const LLColor4 &beaconColor = getBeaconColor(); + const LLColor4 &beaconTextColor = getBeaconTextColor(); + S32 beaconWidth = getBeaconWidth(); + + std::vector<LLViewerObject *> viewerObjects; + viewerObjects.reserve(numSelectedItems); + + for (std::vector<LLScrollListItem *>::const_iterator selectedItemIter = selectedItems.begin(); + selectedItemIter != selectedItems.end(); ++selectedItemIter) + { + const LLScrollListItem *selectedItem = *selectedItemIter; + + LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID()); + if (viewerObject != NULL) + { + const std::string &objectName = selectedItem->getColumn(nameColumnIndex)->getValue().asString(); + gObjectList.addDebugBeacon(viewerObject->getPositionAgent(), objectName, beaconColor, beaconTextColor, beaconWidth); + } + } + } + } +} + +LLFloaterPathfindingObjects::LLFloaterPathfindingObjects(const LLSD &pSeed) + : LLFloater(pSeed), + mObjectsScrollList(NULL), + mMessagingStatus(NULL), + mRefreshListButton(NULL), + mSelectAllButton(NULL), + mSelectNoneButton(NULL), + mShowBeaconCheckBox(NULL), + mTakeButton(NULL), + mTakeCopyButton(NULL), + mReturnButton(NULL), + mDeleteButton(NULL), + mTeleportButton(NULL), + mDefaultBeaconColor(), + mDefaultBeaconTextColor(), + mErrorTextColor(), + mWarningTextColor(), + mMessagingState(kMessagingUnknown), + mMessagingRequestId(0U), + mMissingNameObjectsScrollListItems(), + mObjectList(), + mObjectsSelection(), + mHasObjectsToBeSelected(false), + mObjectsToBeSelected(), + mSelectionUpdateSlot(), + mRegionBoundaryCrossingSlot() +{ +} + +LLFloaterPathfindingObjects::~LLFloaterPathfindingObjects() +{ + clearAllObjects(); +} + +BOOL LLFloaterPathfindingObjects::postBuild() +{ + mDefaultBeaconColor = LLUIColorTable::getInstance()->getColor("PathfindingDefaultBeaconColor"); + mDefaultBeaconTextColor = LLUIColorTable::getInstance()->getColor("PathfindingDefaultBeaconTextColor"); + mErrorTextColor = LLUIColorTable::getInstance()->getColor("PathfindingErrorColor"); + mWarningTextColor = LLUIColorTable::getInstance()->getColor("PathfindingWarningColor"); + + mObjectsScrollList = findChild<LLScrollListCtrl>("objects_scroll_list"); + llassert(mObjectsScrollList != NULL); + mObjectsScrollList->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onScrollListSelectionChanged, this)); + mObjectsScrollList->sortByColumnIndex(static_cast<U32>(getNameColumnIndex()), TRUE); + + mMessagingStatus = findChild<LLTextBase>("messaging_status"); + llassert(mMessagingStatus != NULL); + + mRefreshListButton = findChild<LLButton>("refresh_objects_list"); + llassert(mRefreshListButton != NULL); + mRefreshListButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onRefreshObjectsClicked, this)); + + mSelectAllButton = findChild<LLButton>("select_all_objects"); + llassert(mSelectAllButton != NULL); + mSelectAllButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onSelectAllObjectsClicked, this)); + + mSelectNoneButton = findChild<LLButton>("select_none_objects"); + llassert(mSelectNoneButton != NULL); + mSelectNoneButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onSelectNoneObjectsClicked, this)); + + mShowBeaconCheckBox = findChild<LLCheckBoxCtrl>("show_beacon"); + llassert(mShowBeaconCheckBox != NULL); + + mTakeButton = findChild<LLButton>("take_objects"); + llassert(mTakeButton != NULL); + mTakeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onTakeClicked, this)); + + mTakeCopyButton = findChild<LLButton>("take_copy_objects"); + llassert(mTakeCopyButton != NULL); + mTakeCopyButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onTakeCopyClicked, this)); + + mReturnButton = findChild<LLButton>("return_objects"); + llassert(mReturnButton != NULL); + mReturnButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onReturnClicked, this)); + + mDeleteButton = findChild<LLButton>("delete_objects"); + llassert(mDeleteButton != NULL); + mDeleteButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onDeleteClicked, this)); + + mTeleportButton = findChild<LLButton>("teleport_me_to_object"); + llassert(mTeleportButton != NULL); + mTeleportButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onTeleportClicked, this)); + + return LLFloater::postBuild(); +} + +void LLFloaterPathfindingObjects::requestGetObjects() +{ + llassert(0); +} + +LLPathfindingManager::request_id_t LLFloaterPathfindingObjects::getNewRequestId() +{ + return ++mMessagingRequestId; +} + +void LLFloaterPathfindingObjects::handleNewObjectList(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pRequestStatus, LLPathfindingObjectListPtr pObjectList) +{ + llassert(pRequestId <= mMessagingRequestId); + if (pRequestId == mMessagingRequestId) + { + switch (pRequestStatus) + { + case LLPathfindingManager::kRequestStarted : + setMessagingState(kMessagingGetRequestSent); + break; + case LLPathfindingManager::kRequestCompleted : + mObjectList = pObjectList; + rebuildObjectsScrollList(); + setMessagingState(kMessagingComplete); + break; + case LLPathfindingManager::kRequestNotEnabled : + clearAllObjects(); + setMessagingState(kMessagingNotEnabled); + break; + case LLPathfindingManager::kRequestError : + clearAllObjects(); + setMessagingState(kMessagingGetError); + break; + default : + clearAllObjects(); + setMessagingState(kMessagingGetError); + llassert(0); + break; + } + } +} + +void LLFloaterPathfindingObjects::handleUpdateObjectList(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pRequestStatus, LLPathfindingObjectListPtr pObjectList) +{ + // We current assume that handleUpdateObjectList is called only when objects are being SET + llassert(pRequestId <= mMessagingRequestId); + if (pRequestId == mMessagingRequestId) + { + switch (pRequestStatus) + { + case LLPathfindingManager::kRequestStarted : + setMessagingState(kMessagingSetRequestSent); + break; + case LLPathfindingManager::kRequestCompleted : + if (mObjectList == NULL) + { + mObjectList = pObjectList; + } + else + { + mObjectList->update(pObjectList); + } + rebuildObjectsScrollList(); + setMessagingState(kMessagingComplete); + break; + case LLPathfindingManager::kRequestNotEnabled : + clearAllObjects(); + setMessagingState(kMessagingNotEnabled); + break; + case LLPathfindingManager::kRequestError : + clearAllObjects(); + setMessagingState(kMessagingSetError); + break; + default : + clearAllObjects(); + setMessagingState(kMessagingSetError); + llassert(0); + break; + } + } +} + +void LLFloaterPathfindingObjects::rebuildObjectsScrollList() +{ + if (!mHasObjectsToBeSelected) + { + std::vector<LLScrollListItem*> selectedItems = mObjectsScrollList->getAllSelected(); + int numSelectedItems = selectedItems.size(); + if (numSelectedItems > 0) + { + mObjectsToBeSelected.reserve(selectedItems.size()); + for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin(); + itemIter != selectedItems.end(); ++itemIter) + { + const LLScrollListItem *listItem = *itemIter; + mObjectsToBeSelected.push_back(listItem->getUUID()); + } + } + } + + S32 origScrollPosition = mObjectsScrollList->getScrollPos(); + mObjectsScrollList->deleteAllItems(); + mMissingNameObjectsScrollListItems.clear(); + + if ((mObjectList != NULL) && !mObjectList->isEmpty()) + { + buildObjectsScrollList(mObjectList); + + mObjectsScrollList->selectMultiple(mObjectsToBeSelected); + if (mHasObjectsToBeSelected) + { + mObjectsScrollList->scrollToShowSelected(); + } + else + { + mObjectsScrollList->setScrollPos(origScrollPosition); + } + } + + mObjectsToBeSelected.clear(); + mHasObjectsToBeSelected = false; + + updateControlsOnScrollListChange(); +} + +void LLFloaterPathfindingObjects::buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr) +{ + llassert(0); +} + +void LLFloaterPathfindingObjects::addObjectToScrollList(const LLPathfindingObjectPtr pObjectPtr, const LLSD &pScrollListItemData) +{ + LLScrollListCell::Params cellParams; + cellParams.font = LLFontGL::getFontSansSerif(); + + LLScrollListItem::Params rowParams; + rowParams.value = pObjectPtr->getUUID().asString(); + + llassert(pScrollListItemData.isArray()); + for (LLSD::array_const_iterator cellIter = pScrollListItemData.beginArray(); + cellIter != pScrollListItemData.endArray(); ++cellIter) + { + const LLSD &cellElement = *cellIter; + + llassert(cellElement.has("column")); + llassert(cellElement.get("column").isString()); + cellParams.column = cellElement.get("column").asString(); + + llassert(cellElement.has("value")); + llassert(cellElement.get("value").isString()); + cellParams.value = cellElement.get("value").asString(); + + rowParams.columns.add(cellParams); + } + + LLScrollListItem *scrollListItem = mObjectsScrollList->addRow(rowParams); + + if (pObjectPtr->hasOwner() && !pObjectPtr->hasOwnerName()) + { + mMissingNameObjectsScrollListItems.insert(std::make_pair<std::string, LLScrollListItem *>(pObjectPtr->getUUID().asString(), scrollListItem)); + pObjectPtr->registerOwnerNameListener(boost::bind(&LLFloaterPathfindingObjects::handleObjectNameResponse, this, _1)); + } +} + +void LLFloaterPathfindingObjects::updateControlsOnScrollListChange() +{ + updateMessagingStatus(); + updateStateOnListControls(); + selectScrollListItemsInWorld(); + updateStateOnActionControls(); +} + +void LLFloaterPathfindingObjects::updateControlsOnInWorldSelectionChange() +{ + updateStateOnActionControls(); +} + +S32 LLFloaterPathfindingObjects::getNameColumnIndex() const +{ + return 0; +} + +S32 LLFloaterPathfindingObjects::getOwnerNameColumnIndex() const +{ + return 2; +} + +std::string LLFloaterPathfindingObjects::getOwnerName(const LLPathfindingObject *pObject) const +{ + llassert(0); + std::string returnVal; + return returnVal; +} + +const LLColor4 &LLFloaterPathfindingObjects::getBeaconColor() const +{ + return mDefaultBeaconColor; +} + +const LLColor4 &LLFloaterPathfindingObjects::getBeaconTextColor() const +{ + return mDefaultBeaconTextColor; +} + +S32 LLFloaterPathfindingObjects::getBeaconWidth() const +{ + return DEFAULT_BEACON_WIDTH; +} + +void LLFloaterPathfindingObjects::showFloaterWithSelectionObjects() +{ + mObjectsToBeSelected.clear(); + + LLObjectSelectionHandle selectedObjectsHandle = LLSelectMgr::getInstance()->getSelection(); + if (selectedObjectsHandle.notNull()) + { + LLObjectSelection *selectedObjects = selectedObjectsHandle.get(); + if (!selectedObjects->isEmpty()) + { + for (LLObjectSelection::valid_iterator objectIter = selectedObjects->valid_begin(); + objectIter != selectedObjects->valid_end(); ++objectIter) + { + LLSelectNode *object = *objectIter; + LLViewerObject *viewerObject = object->getObject(); + mObjectsToBeSelected.push_back(viewerObject->getID()); + } + } + } + mHasObjectsToBeSelected = true; + + if (!isShown()) + { + openFloater(); + setVisibleAndFrontmost(); + } + else + { + rebuildObjectsScrollList(); + if (isMinimized()) + { + setMinimized(FALSE); + } + setVisibleAndFrontmost(); + } + setFocus(TRUE); +} + +BOOL LLFloaterPathfindingObjects::isShowBeacons() const +{ + return mShowBeaconCheckBox->get(); +} + +void LLFloaterPathfindingObjects::clearAllObjects() +{ + selectNoneObjects(); + mObjectsScrollList->deleteAllItems(); + mMissingNameObjectsScrollListItems.clear(); + mObjectList.reset(); +} + +void LLFloaterPathfindingObjects::selectAllObjects() +{ + mObjectsScrollList->selectAll(); +} + +void LLFloaterPathfindingObjects::selectNoneObjects() +{ + mObjectsScrollList->deselectAllItems(); +} + +void LLFloaterPathfindingObjects::teleportToSelectedObject() +{ + std::vector<LLScrollListItem*> selectedItems = mObjectsScrollList->getAllSelected(); + llassert(selectedItems.size() == 1); + if (selectedItems.size() == 1) + { + std::vector<LLScrollListItem*>::const_reference selectedItemRef = selectedItems.front(); + const LLScrollListItem *selectedItem = selectedItemRef; + llassert(mObjectList != NULL); + LLVector3d teleportLocation; + LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID()); + if (viewerObject == NULL) + { + // If we cannot find the object in the viewer list, teleport to the last reported position + const LLPathfindingObjectPtr objectPtr = mObjectList->find(selectedItem->getUUID().asString()); + teleportLocation = gAgent.getPosGlobalFromAgent(objectPtr->getLocation()); + } + else + { + // If we can find the object in the viewer list, teleport to the known current position + teleportLocation = viewerObject->getPositionGlobal(); + } + gAgent.teleportViaLocationLookAt(teleportLocation); + } +} + +LLPathfindingObjectListPtr LLFloaterPathfindingObjects::getEmptyObjectList() const +{ + llassert(0); + LLPathfindingObjectListPtr objectListPtr(new LLPathfindingObjectList()); + return objectListPtr; +} + +int LLFloaterPathfindingObjects::getNumSelectedObjects() const +{ + return mObjectsScrollList->getNumSelected(); +} + +LLPathfindingObjectListPtr LLFloaterPathfindingObjects::getSelectedObjects() const +{ + LLPathfindingObjectListPtr selectedObjects = getEmptyObjectList(); + + std::vector<LLScrollListItem*> selectedItems = mObjectsScrollList->getAllSelected(); + if (!selectedItems.empty()) + { + for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin(); + itemIter != selectedItems.end(); ++itemIter) + { + LLPathfindingObjectPtr objectPtr = findObject(*itemIter); + if (objectPtr != NULL) + { + selectedObjects->update(objectPtr); + } + } + } + + return selectedObjects; +} + +LLPathfindingObjectPtr LLFloaterPathfindingObjects::getFirstSelectedObject() const +{ + LLPathfindingObjectPtr objectPtr; + + std::vector<LLScrollListItem*> selectedItems = mObjectsScrollList->getAllSelected(); + if (!selectedItems.empty()) + { + objectPtr = findObject(selectedItems.front()); + } + + return objectPtr; +} + +LLFloaterPathfindingObjects::EMessagingState LLFloaterPathfindingObjects::getMessagingState() const +{ + return mMessagingState; +} + +void LLFloaterPathfindingObjects::setMessagingState(EMessagingState pMessagingState) +{ + mMessagingState = pMessagingState; + updateControlsOnScrollListChange(); +} + +void LLFloaterPathfindingObjects::onRefreshObjectsClicked() +{ + requestGetObjects(); +} + +void LLFloaterPathfindingObjects::onSelectAllObjectsClicked() +{ + selectAllObjects(); +} + +void LLFloaterPathfindingObjects::onSelectNoneObjectsClicked() +{ + selectNoneObjects(); +} + +void LLFloaterPathfindingObjects::onTakeClicked() +{ + handle_take(); + requestGetObjects(); +} + +void LLFloaterPathfindingObjects::onTakeCopyClicked() +{ + handle_take_copy(); +} + +void LLFloaterPathfindingObjects::onReturnClicked() +{ + LLNotification::Params params("PathfindingReturnMultipleItems"); + params.functor.function(boost::bind(&LLFloaterPathfindingObjects::handleReturnItemsResponse, this, _1, _2)); + + LLSD substitutions; + int numItems = getNumSelectedObjects(); + substitutions["NUM_ITEMS"] = static_cast<LLSD::Integer>(numItems); + params.substitutions = substitutions; + + if (numItems == 1) + { + LLNotifications::getInstance()->forceResponse(params, 0); + } + else if (numItems > 1) + { + LLNotifications::getInstance()->add(params); + } +} + +void LLFloaterPathfindingObjects::onDeleteClicked() +{ + LLNotification::Params params("PathfindingDeleteMultipleItems"); + params.functor.function(boost::bind(&LLFloaterPathfindingObjects::handleDeleteItemsResponse, this, _1, _2)); + + LLSD substitutions; + int numItems = getNumSelectedObjects(); + substitutions["NUM_ITEMS"] = static_cast<LLSD::Integer>(numItems); + params.substitutions = substitutions; + + if (numItems == 1) + { + LLNotifications::getInstance()->forceResponse(params, 0); + } + else if (numItems > 1) + { + LLNotifications::getInstance()->add(params); + } +} + +void LLFloaterPathfindingObjects::onTeleportClicked() +{ + teleportToSelectedObject(); +} + +void LLFloaterPathfindingObjects::onScrollListSelectionChanged() +{ + updateControlsOnScrollListChange(); +} + +void LLFloaterPathfindingObjects::onInWorldSelectionListChanged() +{ + updateControlsOnInWorldSelectionChange(); +} + +void LLFloaterPathfindingObjects::onRegionBoundaryCrossed() +{ + requestGetObjects(); +} + +void LLFloaterPathfindingObjects::onGodLevelChange(U8 pGodLevel) +{ + requestGetObjects(); +} + +void LLFloaterPathfindingObjects::handleObjectNameResponse(const LLPathfindingObject *pObject) +{ + llassert(pObject != NULL); + const std::string uuid = pObject->getUUID().asString(); + scroll_list_item_map::iterator scrollListItemIter = mMissingNameObjectsScrollListItems.find(uuid); + if (scrollListItemIter != mMissingNameObjectsScrollListItems.end()) + { + LLScrollListItem *scrollListItem = scrollListItemIter->second; + llassert(scrollListItem != NULL); + + LLScrollListCell *scrollListCell = scrollListItem->getColumn(getOwnerNameColumnIndex()); + LLSD ownerName = getOwnerName(pObject); + + scrollListCell->setValue(ownerName); + + mMissingNameObjectsScrollListItems.erase(scrollListItemIter); + } +} + +void LLFloaterPathfindingObjects::updateMessagingStatus() +{ + std::string statusText(""); + LLStyle::Params styleParams; + + switch (getMessagingState()) + { + case kMessagingUnknown: + statusText = getString("messaging_initial"); + styleParams.color = mErrorTextColor; + break; + case kMessagingGetRequestSent : + statusText = getString("messaging_get_inprogress"); + styleParams.color = mWarningTextColor; + break; + case kMessagingGetError : + statusText = getString("messaging_get_error"); + styleParams.color = mErrorTextColor; + break; + case kMessagingSetRequestSent : + statusText = getString("messaging_set_inprogress"); + styleParams.color = mWarningTextColor; + break; + case kMessagingSetError : + statusText = getString("messaging_set_error"); + styleParams.color = mErrorTextColor; + break; + case kMessagingComplete : + if (mObjectsScrollList->isEmpty()) + { + statusText = getString("messaging_complete_none_found"); + } + else + { + S32 numItems = mObjectsScrollList->getItemCount(); + S32 numSelectedItems = mObjectsScrollList->getNumSelected(); + + LLLocale locale(LLStringUtil::getLocale()); + std::string numItemsString; + LLResMgr::getInstance()->getIntegerString(numItemsString, numItems); + + std::string numSelectedItemsString; + LLResMgr::getInstance()->getIntegerString(numSelectedItemsString, numSelectedItems); + + LLStringUtil::format_map_t string_args; + string_args["[NUM_SELECTED]"] = numSelectedItemsString; + string_args["[NUM_TOTAL]"] = numItemsString; + statusText = getString("messaging_complete_available", string_args); + } + break; + case kMessagingNotEnabled : + statusText = getString("messaging_not_enabled"); + styleParams.color = mErrorTextColor; + break; + default: + statusText = getString("messaging_initial"); + styleParams.color = mErrorTextColor; + llassert(0); + break; + } + + mMessagingStatus->setText((LLStringExplicit)statusText, styleParams); +} + +void LLFloaterPathfindingObjects::updateStateOnListControls() +{ + switch (getMessagingState()) + { + case kMessagingUnknown: + case kMessagingGetRequestSent : + case kMessagingSetRequestSent : + mRefreshListButton->setEnabled(FALSE); + mSelectAllButton->setEnabled(FALSE); + mSelectNoneButton->setEnabled(FALSE); + break; + case kMessagingGetError : + case kMessagingSetError : + case kMessagingNotEnabled : + mRefreshListButton->setEnabled(TRUE); + mSelectAllButton->setEnabled(FALSE); + mSelectNoneButton->setEnabled(FALSE); + break; + case kMessagingComplete : + { + int numItems = mObjectsScrollList->getItemCount(); + int numSelectedItems = mObjectsScrollList->getNumSelected(); + mRefreshListButton->setEnabled(TRUE); + mSelectAllButton->setEnabled(numSelectedItems < numItems); + mSelectNoneButton->setEnabled(numSelectedItems > 0); + } + break; + default: + llassert(0); + break; + } +} + +void LLFloaterPathfindingObjects::updateStateOnActionControls() +{ + int numSelectedItems = mObjectsScrollList->getNumSelected(); + bool isEditEnabled = (numSelectedItems > 0); + + mShowBeaconCheckBox->setEnabled(isEditEnabled); + mTakeButton->setEnabled(isEditEnabled && visible_take_object()); + mTakeCopyButton->setEnabled(isEditEnabled && enable_object_take_copy()); + mReturnButton->setEnabled(isEditEnabled && enable_object_return()); + mDeleteButton->setEnabled(isEditEnabled && enable_object_delete()); + mTeleportButton->setEnabled(numSelectedItems == 1); +} + +void LLFloaterPathfindingObjects::selectScrollListItemsInWorld() +{ + mObjectsSelection.clear(); + LLSelectMgr::getInstance()->deselectAll(); + + std::vector<LLScrollListItem *> selectedItems = mObjectsScrollList->getAllSelected(); + if (!selectedItems.empty()) + { + int numSelectedItems = selectedItems.size(); + + std::vector<LLViewerObject *>viewerObjects; + viewerObjects.reserve(numSelectedItems); + + for (std::vector<LLScrollListItem *>::const_iterator selectedItemIter = selectedItems.begin(); + selectedItemIter != selectedItems.end(); ++selectedItemIter) + { + const LLScrollListItem *selectedItem = *selectedItemIter; + + LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID()); + if (viewerObject != NULL) + { + viewerObjects.push_back(viewerObject); + } + } + + if (!viewerObjects.empty()) + { + mObjectsSelection = LLSelectMgr::getInstance()->selectObjectAndFamily(viewerObjects); + } + } +} + +void LLFloaterPathfindingObjects::handleReturnItemsResponse(const LLSD &pNotification, const LLSD &pResponse) +{ + if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0) + { + handle_object_return(); + requestGetObjects(); + } +} + +void LLFloaterPathfindingObjects::handleDeleteItemsResponse(const LLSD &pNotification, const LLSD &pResponse) +{ + if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0) + { + handle_object_delete(); + requestGetObjects(); + } +} + +LLPathfindingObjectPtr LLFloaterPathfindingObjects::findObject(const LLScrollListItem *pListItem) const +{ + LLPathfindingObjectPtr objectPtr; + + LLUUID uuid = pListItem->getUUID(); + const std::string &uuidString = uuid.asString(); + llassert(mObjectList != NULL); + objectPtr = mObjectList->find(uuidString); + + return objectPtr; +} diff --git a/indra/newview/llfloaterpathfindingobjects.h b/indra/newview/llfloaterpathfindingobjects.h new file mode 100644 index 0000000000..4024e15fd6 --- /dev/null +++ b/indra/newview/llfloaterpathfindingobjects.h @@ -0,0 +1,179 @@ +/** +* @file llfloaterpathfindingobjects.h +* @brief Base class for both the pathfinding linksets and characters floater. +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLFLOATERPATHFINDINGOBJECTS_H +#define LL_LLFLOATERPATHFINDINGOBJECTS_H + +#include <string> +#include <map> + +#include <boost/signals2.hpp> + +#include "llagent.h" +#include "llfloater.h" +#include "llpathfindingmanager.h" +#include "llpathfindingobject.h" +#include "llpathfindingobjectlist.h" +#include "llselectmgr.h" +#include "lluuid.h" +#include "v4color.h" + +class LLAvatarName; +class LLButton; +class LLCheckBoxCtrl; +class LLScrollListCtrl; +class LLScrollListItem; +class LLSD; +class LLTextBase; + +class LLFloaterPathfindingObjects : public LLFloater +{ +public: + virtual void onOpen(const LLSD &pKey); + virtual void onClose(bool pIsAppQuitting); + virtual void draw(); + +protected: + friend class LLFloaterReg; + + typedef enum + { + kMessagingUnknown, + kMessagingGetRequestSent, + kMessagingGetError, + kMessagingSetRequestSent, + kMessagingSetError, + kMessagingComplete, + kMessagingNotEnabled + } EMessagingState; + + LLFloaterPathfindingObjects(const LLSD &pSeed); + virtual ~LLFloaterPathfindingObjects(); + + virtual BOOL postBuild(); + + virtual void requestGetObjects(); + LLPathfindingManager::request_id_t getNewRequestId(); + void handleNewObjectList(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pRequestStatus, LLPathfindingObjectListPtr pObjectList); + void handleUpdateObjectList(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pRequestStatus, LLPathfindingObjectListPtr pObjectList); + + void rebuildObjectsScrollList(); + virtual void buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr); + void addObjectToScrollList(const LLPathfindingObjectPtr pObjectPr, const LLSD &pScrollListItemData); + + virtual void updateControlsOnScrollListChange(); + virtual void updateControlsOnInWorldSelectionChange(); + + virtual S32 getNameColumnIndex() const; + virtual S32 getOwnerNameColumnIndex() const; + virtual std::string getOwnerName(const LLPathfindingObject *pObject) const; + virtual const LLColor4 &getBeaconColor() const; + virtual const LLColor4 &getBeaconTextColor() const; + virtual S32 getBeaconWidth() const; + + void showFloaterWithSelectionObjects(); + + BOOL isShowBeacons() const; + void clearAllObjects(); + void selectAllObjects(); + void selectNoneObjects(); + void teleportToSelectedObject(); + + virtual LLPathfindingObjectListPtr getEmptyObjectList() const; + int getNumSelectedObjects() const; + LLPathfindingObjectListPtr getSelectedObjects() const; + LLPathfindingObjectPtr getFirstSelectedObject() const; + + EMessagingState getMessagingState() const; + +private: + LLFloaterPathfindingObjects(const LLFloaterPathfindingObjects &pOther); + + void setMessagingState(EMessagingState pMessagingState); + + void onRefreshObjectsClicked(); + void onSelectAllObjectsClicked(); + void onSelectNoneObjectsClicked(); + void onTakeClicked(); + void onTakeCopyClicked(); + void onReturnClicked(); + void onDeleteClicked(); + void onTeleportClicked(); + + void onScrollListSelectionChanged(); + void onInWorldSelectionListChanged(); + void onRegionBoundaryCrossed(); + void onGodLevelChange(U8 pGodLevel); + + void handleObjectNameResponse(const LLPathfindingObject *pObject); + + void updateMessagingStatus(); + void updateStateOnListControls(); + void updateStateOnActionControls(); + void selectScrollListItemsInWorld(); + + void handleReturnItemsResponse(const LLSD &pNotification, const LLSD &pResponse); + void handleDeleteItemsResponse(const LLSD &pNotification, const LLSD &pResponse); + + LLPathfindingObjectPtr findObject(const LLScrollListItem *pListItem) const; + + LLScrollListCtrl *mObjectsScrollList; + LLTextBase *mMessagingStatus; + LLButton *mRefreshListButton; + LLButton *mSelectAllButton; + LLButton *mSelectNoneButton; + LLCheckBoxCtrl *mShowBeaconCheckBox; + + LLButton *mTakeButton; + LLButton *mTakeCopyButton; + LLButton *mReturnButton; + LLButton *mDeleteButton; + LLButton *mTeleportButton; + + LLColor4 mDefaultBeaconColor; + LLColor4 mDefaultBeaconTextColor; + LLColor4 mErrorTextColor; + LLColor4 mWarningTextColor; + + EMessagingState mMessagingState; + LLPathfindingManager::request_id_t mMessagingRequestId; + + typedef std::map<std::string, LLScrollListItem *> scroll_list_item_map; + scroll_list_item_map mMissingNameObjectsScrollListItems; + + LLPathfindingObjectListPtr mObjectList; + + LLObjectSelectionHandle mObjectsSelection; + + bool mHasObjectsToBeSelected; + uuid_vec_t mObjectsToBeSelected; + + boost::signals2::connection mSelectionUpdateSlot; + boost::signals2::connection mRegionBoundaryCrossingSlot; + LLAgent::god_level_change_slot_t mGodLevelChangeSlot; +}; + +#endif // LL_LLFLOATERPATHFINDINGOBJECTS_H diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index a333989e7e..b308a820b2 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -35,7 +35,7 @@ #include "llfloaterpreference.h" #include "message.h" - +#include "llfloaterautoreplacesettings.h" #include "llagent.h" #include "llavatarconstants.h" #include "llcheckboxctrl.h" @@ -51,11 +51,11 @@ #include "llfloaterabout.h" #include "llfloaterhardwaresettings.h" #include "llfloatersidepanelcontainer.h" -#include "llimfloater.h" +#include "llfloaterimsession.h" #include "llkeyboard.h" #include "llmodaldialog.h" #include "llnavigationbar.h" -#include "llnearbychat.h" +#include "llfloaterimnearbychat.h" #include "llnotifications.h" #include "llnotificationsutil.h" #include "llnotificationtemplate.h" @@ -77,7 +77,7 @@ #include "llviewerthrottle.h" #include "llvotree.h" #include "llvosky.h" - +#include "llfloaterpathfindingconsole.h" // linden library includes #include "llavatarnamecache.h" #include "llerror.h" @@ -306,7 +306,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mAvatarDataInitialized(false), mClickActionDirty(false) { - + LLConversationLog::instance().addObserver(this); + //Build Floater is now Called from LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>); static bool registered_dialog = false; @@ -329,8 +330,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.VoiceSetKey", boost::bind(&LLFloaterPreference::onClickSetKey, this)); mCommitCallbackRegistrar.add("Pref.VoiceSetMiddleMouse", boost::bind(&LLFloaterPreference::onClickSetMiddleMouse, this)); mCommitCallbackRegistrar.add("Pref.SetSounds", boost::bind(&LLFloaterPreference::onClickSetSounds, this)); -// mCommitCallbackRegistrar.add("Pref.ClickSkipDialogs", boost::bind(&LLFloaterPreference::onClickSkipDialogs, this)); -// mCommitCallbackRegistrar.add("Pref.ClickResetDialogs", boost::bind(&LLFloaterPreference::onClickResetDialogs, this)); mCommitCallbackRegistrar.add("Pref.ClickEnablePopup", boost::bind(&LLFloaterPreference::onClickEnablePopup, this)); mCommitCallbackRegistrar.add("Pref.ClickDisablePopup", boost::bind(&LLFloaterPreference::onClickDisablePopup, this)); mCommitCallbackRegistrar.add("Pref.LogPath", boost::bind(&LLFloaterPreference::onClickLogPath, this)); @@ -346,16 +345,21 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.BlockList", boost::bind(&LLFloaterPreference::onClickBlockList, this)); mCommitCallbackRegistrar.add("Pref.Proxy", boost::bind(&LLFloaterPreference::onClickProxySettings, this)); mCommitCallbackRegistrar.add("Pref.TranslationSettings", boost::bind(&LLFloaterPreference::onClickTranslationSettings, this)); - + mCommitCallbackRegistrar.add("Pref.AutoReplace", boost::bind(&LLFloaterPreference::onClickAutoReplace, this)); + mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this)); + sSkin = gSavedSettings.getString("SkinCurrent"); - mCommitCallbackRegistrar.add("Pref.ClickActionChange", boost::bind(&LLFloaterPreference::onClickActionChange, this)); + mCommitCallbackRegistrar.add("Pref.ClickActionChange", boost::bind(&LLFloaterPreference::onClickActionChange, this)); gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2)); gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2)); gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged, _2)); - + LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this ); + + mCommitCallbackRegistrar.add("Pref.ClearLog", boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance())); + mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this)); } void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type ) @@ -423,18 +427,14 @@ void LLFloaterPreference::saveAvatarProperties( void ) BOOL LLFloaterPreference::postBuild() { - gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2)); - - gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2)); - - gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2)); - - gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2)); + gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false)); gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged)); gSavedSettings.getControl("ChatBubbleOpacity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onNameTagOpacityChange, this, _2)); + gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeMaturity, this)); + LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core"); if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab"))) tabcontainer->selectFirstTab(); @@ -445,26 +445,41 @@ BOOL LLFloaterPreference::postBuild() getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this)); - // if floater is opened before login set default localized busy message + getChild<LLComboBox>("FriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"FriendIMOptions")); + getChild<LLComboBox>("NonFriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NonFriendIMOptions")); + getChild<LLComboBox>("ConferenceIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ConferenceIMOptions")); + getChild<LLComboBox>("GroupChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"GroupChatOptions")); + getChild<LLComboBox>("NearbyChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NearbyChatOptions")); + + // if floater is opened before login set default localized do not disturb message if (LLStartUp::getStartupState() < STATE_STARTED) { - gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault")); + gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault")); } + // set 'enable' property for 'Clear log...' button + changed(); + + LLLogChat::setSaveHistorySignal(boost::bind(&LLFloaterPreference::onLogChatHistorySaved, this)); + return TRUE; } -void LLFloaterPreference::onBusyResponseChanged() +void LLFloaterPreference::updateDeleteTranscriptsButton() { - // set "BusyResponseChanged" TRUE if user edited message differs from default, FALSE otherwise - if (LLTrans::getString("BusyModeResponseDefault") != getChild<LLUICtrl>("busy_response")->getValue().asString()) - { - gSavedPerAccountSettings.setBOOL("BusyResponseChanged", TRUE ); - } - else - { - gSavedPerAccountSettings.setBOOL("BusyResponseChanged", FALSE ); - } + std::vector<std::string> list_of_transcriptions_file_names; + LLLogChat::getListOfTranscriptFiles(list_of_transcriptions_file_names); + getChild<LLButton>("delete_transcripts")->setEnabled(list_of_transcriptions_file_names.size() > 0); +} + +void LLFloaterPreference::onDoNotDisturbResponseChanged() +{ + // set "DoNotDisturbResponseChanged" TRUE if user edited message differs from default, FALSE otherwise + bool response_changed_flag = + LLTrans::getString("DoNotDisturbModeResponseDefault") + != getChild<LLUICtrl>("do_not_disturb_response")->getValue().asString(); + + gSavedPerAccountSettings.setBOOL("DoNotDisturbResponseChanged", response_changed_flag ); } LLFloaterPreference::~LLFloaterPreference() @@ -475,6 +490,8 @@ LLFloaterPreference::~LLFloaterPreference() { ctrl_window_size->setCurrentByIndex(i); } + + LLConversationLog::instance().removeObserver(this); } void LLFloaterPreference::draw() @@ -547,14 +564,8 @@ void LLFloaterPreference::apply() LLViewerMedia::setProxyConfig(proxy_enable, proxy_address, proxy_port); } -// LLWString busy_response = utf8str_to_wstring(getChild<LLUICtrl>("busy_response")->getValue().asString()); -// LLWStringUtil::replaceTabsWithSpaces(busy_response, 4); - - gSavedSettings.setBOOL("PlainTextChatHistory", getChild<LLUICtrl>("plain_text_chat_history")->getValue().asBoolean()); - if (mGotPersonalInfo) { -// gSavedSettings.setString("BusyModeResponse2", std::string(wstring_to_utf8str(busy_response))); bool new_im_via_email = getChild<LLUICtrl>("send_im_to_email")->getValue().asBoolean(); bool new_hide_online = getChild<LLUICtrl>("online_visibility")->getValue().asBoolean(); @@ -604,6 +615,9 @@ void LLFloaterPreference::cancel() // hide translation settings floater LLFloaterReg::hideInstance("prefs_translation"); + // hide translation settings floater + LLFloaterReg::hideInstance("prefs_autoreplace"); + // cancel hardware menu LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::getTypedInstance<LLFloaterHardwareSettings>("prefs_hardware_settings"); if (hardware_settings) @@ -625,26 +639,33 @@ void LLFloaterPreference::cancel() { advanced_proxy_settings->cancel(); } + //Need to reload the navmesh if the pathing console is up + LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle(); + if ( !pathfindingConsoleHandle.isDead() ) + { + LLFloaterPathfindingConsole* pPathfindingConsole = pathfindingConsoleHandle.get(); + pPathfindingConsole->onRegionBoundaryCross(); + } } void LLFloaterPreference::onOpen(const LLSD& key) { - // this variable and if that follows it are used to properly handle busy mode response message + // this variable and if that follows it are used to properly handle do not disturb mode response message static bool initialized = FALSE; - // if user is logged in and we haven't initialized busy_response yet, do it + // if user is logged in and we haven't initialized do not disturb mode response yet, do it if (!initialized && LLStartUp::getStartupState() == STATE_STARTED) { - // Special approach is used for busy response localization, because "BusyModeResponse" is + // Special approach is used for do not disturb response localization, because "DoNotDisturbModeResponse" is // in non-localizable xml, and also because it may be changed by user and in this case it shouldn't be localized. - // To keep track of whether busy response is default or changed by user additional setting BusyResponseChanged + // To keep track of whether do not disturb response is default or changed by user additional setting DoNotDisturbResponseChanged // was added into per account settings. // initialization should happen once,so setting variable to TRUE initialized = TRUE; - // this connection is needed to properly set "BusyResponseChanged" setting when user makes changes in - // busy response message. - gSavedPerAccountSettings.getControl("BusyModeResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onBusyResponseChanged, this)); + // this connection is needed to properly set "DoNotDisturbResponseChanged" setting when user makes changes in + // do not disturb response message. + gSavedPerAccountSettings.getControl("DoNotDisturbModeResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onDoNotDisturbResponseChanged, this)); } gAgent.sendAgentUserInfoRequest(); @@ -691,6 +712,14 @@ void LLFloaterPreference::onOpen(const LLSD& key) // while preferences floater was closed. buildPopupLists(); + + //get the options that were checked + onNotificationsChange("FriendIMOptions"); + onNotificationsChange("NonFriendIMOptions"); + onNotificationsChange("ConferenceIMOptions"); + onNotificationsChange("GroupChatOptions"); + onNotificationsChange("NearbyChatOptions"); + LLPanelLogin::setAlwaysRefresh(true); refresh(); @@ -706,12 +735,12 @@ void LLFloaterPreference::onVertexShaderEnable() } //static -void LLFloaterPreference::initBusyResponse() +void LLFloaterPreference::initDoNotDisturbResponse() { - if (!gSavedPerAccountSettings.getBOOL("BusyResponseChanged")) + if (!gSavedPerAccountSettings.getBOOL("DoNotDisturbResponseChanged")) { - //LLTrans::getString("BusyModeResponseDefault") is used here for localization (EXT-5885) - gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault")); + //LLTrans::getString("DoNotDisturbModeResponseDefault") is used here for localization (EXT-5885) + gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault")); } } @@ -736,12 +765,16 @@ void LLFloaterPreference::onClose(bool app_quitting) { gSavedSettings.setS32("LastPrefTab", getChild<LLTabContainer>("pref core")->getCurrentPanelIndex()); LLPanelLogin::setAlwaysRefresh(false); - cancel(); + if (!app_quitting) + { + cancel(); + } } void LLFloaterPreference::onOpenHardwareSettings() { - LLFloaterReg::showInstance("prefs_hardware_settings"); + LLFloater* floater = LLFloaterReg::showInstance("prefs_hardware_settings"); + addDependentFloater(floater, FALSE); } // static void LLFloaterPreference::onBtnOK() @@ -762,8 +795,31 @@ void LLFloaterPreference::onBtnOK() apply(); closeFloater(false); + //Conversation transcript and log path changed so reload conversations based on new location + if(mPriorInstantMessageLogPath.length()) + { + if(moveTranscriptsAndLog()) + { + //When floaters are empty but have a chat history files, reload chat history into them + LLFloaterIMSessionTab::reloadEmptyFloaters(); + } + //Couldn't move files so restore the old path and show a notification + else + { + gSavedPerAccountSettings.setString("InstantMessageLogPath", mPriorInstantMessageLogPath); + LLNotificationsUtil::add("PreferenceChatPathChanged"); + } + mPriorInstantMessageLogPath.clear(); + } + LLUIColorTable::instance().saveUserSettings(); gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); + + //Only save once logged in and loaded per account settings + if(mGotPersonalInfo) + { + gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE); + } } else { @@ -771,7 +827,15 @@ void LLFloaterPreference::onBtnOK() llinfos << "Can't close preferences!" << llendl; } - LLPanelLogin::updateLocationCombo( false ); + LLPanelLogin::updateLocationSelectorsVisibility(); + //Need to reload the navmesh if the pathing console is up + LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle(); + if ( !pathfindingConsoleHandle.isDead() ) + { + LLFloaterPathfindingConsole* pPathfindingConsole = pathfindingConsoleHandle.get(); + pPathfindingConsole->onRegionBoundaryCross(); + } + } // static @@ -788,7 +852,7 @@ void LLFloaterPreference::onBtnApply( ) apply(); saveSettings(); - LLPanelLogin::updateLocationCombo( false ); + LLPanelLogin::updateLocationSelectorsVisibility(); } // static @@ -808,12 +872,12 @@ void LLFloaterPreference::onBtnCancel() } // static -void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email) +void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email) { LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); if (instance) { - instance->setPersonalInfo(visibility, im_via_email, email); + instance->setPersonalInfo(visibility, im_via_email); } } @@ -855,6 +919,23 @@ void LLFloaterPreference::onLanguageChange() } } +void LLFloaterPreference::onNotificationsChange(const std::string& OptionName) +{ + mNotificationOptions[OptionName] = getChild<LLComboBox>(OptionName)->getSelectedItemLabel(); + + bool show_notifications_alert = true; + for (notifications_map::iterator it_notification = mNotificationOptions.begin(); it_notification != mNotificationOptions.end(); it_notification++) + { + if(it_notification->second != "None") + { + show_notifications_alert = false; + break; + } + } + + getChild<LLTextBox>("notifications_alert")->setVisible(show_notifications_alert); +} + void LLFloaterPreference::onNameTagOpacityChange(const LLSD& newvalue) { LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("background"); @@ -930,7 +1011,6 @@ void LLFloaterPreference::refreshSkin(void* data) self->getChild<LLRadioGroup>("skin_selection", true)->setValue(sSkin); } - void LLFloaterPreference::buildPopupLists() { LLScrollListCtrl& disabled_popups = @@ -1377,17 +1457,94 @@ void LLFloaterPreference::setAllIgnored() void LLFloaterPreference::onClickLogPath() { std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath")); + mPriorInstantMessageLogPath.clear(); LLDirPicker& picker = LLDirPicker::instance(); + //Launches a directory picker and waits for feedback if (!picker.getDir(&proposed_name ) ) { return; //Canceled! } - gSavedPerAccountSettings.setString("InstantMessageLogPath", picker.getDirName()); + //Gets the path from the directory picker + std::string dir_name = picker.getDirName(); + + //Path changed + if(proposed_name != dir_name) + { + gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name); + mPriorInstantMessageLogPath = proposed_name; + + // enable/disable 'Delete transcripts button + updateDeleteTranscriptsButton(); +} } -void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email) +bool LLFloaterPreference::moveTranscriptsAndLog() +{ + std::string instantMessageLogPath(gSavedPerAccountSettings.getString("InstantMessageLogPath")); + std::string chatLogPath = gDirUtilp->add(instantMessageLogPath, gDirUtilp->getUserName()); + + bool madeDirectory = false; + + //Does the directory really exist, if not then make it + if(!LLFile::isdir(chatLogPath)) + { + //mkdir success is defined as zero + if(LLFile::mkdir(chatLogPath) != 0) + { + return false; + } + madeDirectory = true; + } + + std::string originalConversationLogDir = LLConversationLog::instance().getFileName(); + std::string targetConversationLogDir = gDirUtilp->add(chatLogPath, "conversation.log"); + //Try to move the conversation log + if(!LLConversationLog::instance().moveLog(originalConversationLogDir, targetConversationLogDir)) + { + //Couldn't move the log and created a new directory so remove the new directory + if(madeDirectory) + { + LLFile::rmdir(chatLogPath); + } + return false; + } + + //Attempt to move transcripts + std::vector<std::string> listOfTranscripts; + std::vector<std::string> listOfFilesMoved; + + LLLogChat::getListOfTranscriptFiles(listOfTranscripts); + + if(!LLLogChat::moveTranscripts(gDirUtilp->getChatLogsDir(), + instantMessageLogPath, + listOfTranscripts, + listOfFilesMoved)) + { + //Couldn't move all the transcripts so restore those that moved back to their old location + LLLogChat::moveTranscripts(instantMessageLogPath, + gDirUtilp->getChatLogsDir(), + listOfFilesMoved); + + //Move the conversation log back + LLConversationLog::instance().moveLog(targetConversationLogDir, originalConversationLogDir); + + if(madeDirectory) + { + LLFile::rmdir(chatLogPath); + } + + return false; + } + + gDirUtilp->setChatLogsDir(instantMessageLogPath); + gDirUtilp->updatePerAccountChatLogsDir(); + + return true; +} + +void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email) { mGotPersonalInfo = true; mOriginalIMViaEmail = im_via_email; @@ -1409,37 +1566,15 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im } getChild<LLUICtrl>("online_searchresults")->setEnabled(TRUE); - - getChildView("include_im_in_chat_history")->setEnabled(TRUE); - getChildView("show_timestamps_check_im")->setEnabled(TRUE); getChildView("friends_online_notify_checkbox")->setEnabled(TRUE); - getChild<LLUICtrl>("online_visibility")->setValue(mOriginalHideOnlineStatus); getChild<LLUICtrl>("online_visibility")->setLabelArg("[DIR_VIS]", mDirectoryVisibility); getChildView("send_im_to_email")->setEnabled(TRUE); getChild<LLUICtrl>("send_im_to_email")->setValue(im_via_email); - getChildView("plain_text_chat_history")->setEnabled(TRUE); - getChild<LLUICtrl>("plain_text_chat_history")->setValue(gSavedSettings.getBOOL("PlainTextChatHistory")); - getChildView("log_instant_messages")->setEnabled(TRUE); -// getChildView("log_chat")->setEnabled(TRUE); -// getChildView("busy_response")->setEnabled(TRUE); -// getChildView("log_instant_messages_timestamp")->setEnabled(TRUE); -// getChildView("log_chat_timestamp")->setEnabled(TRUE); - getChildView("log_chat_IM")->setEnabled(TRUE); - getChildView("log_date_timestamp")->setEnabled(TRUE); - -// getChild<LLUICtrl>("busy_response")->setValue(gSavedSettings.getString("BusyModeResponse2")); - getChildView("favorites_on_login_check")->setEnabled(TRUE); - getChildView("log_nearby_chat")->setEnabled(TRUE); - getChildView("log_instant_messages")->setEnabled(TRUE); - getChildView("show_timestamps_check_im")->setEnabled(TRUE); getChildView("log_path_string")->setEnabled(FALSE);// LineEditor becomes readonly in this case. getChildView("log_path_button")->setEnabled(TRUE); - childEnable("logfile_name_datestamp"); - std::string display_email(email); - getChild<LLUICtrl>("email_address")->setValue(display_email); - + getChildView("chat_font_size")->setEnabled(TRUE); } void LLFloaterPreference::onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name) @@ -1501,7 +1636,8 @@ void LLFloaterPreference::onChangeMaturity() // but the UI for this will still be enabled void LLFloaterPreference::onClickBlockList() { - LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD()); + LLFloaterSidePanelContainer::showPanel("people", "panel_people", + LLSD().with("people_panel_tab_name", "blocked_panel")); } void LLFloaterPreference::onClickProxySettings() @@ -1514,11 +1650,48 @@ void LLFloaterPreference::onClickTranslationSettings() LLFloaterReg::showInstance("prefs_translation"); } +void LLFloaterPreference::onClickAutoReplace() +{ + LLFloaterReg::showInstance("prefs_autoreplace"); +} + +void LLFloaterPreference::onClickSpellChecker() +{ + LLFloaterReg::showInstance("prefs_spellchecker"); +} + void LLFloaterPreference::onClickActionChange() { mClickActionDirty = true; } +void LLFloaterPreference::onDeleteTranscripts() +{ + LLSD args; + args["FOLDER"] = gDirUtilp->getUserName(); + + LLNotificationsUtil::add("PreferenceChatDeleteTranscripts", args, LLSD(), boost::bind(&LLFloaterPreference::onDeleteTranscriptsResponse, this, _1, _2)); +} + +void LLFloaterPreference::onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response) +{ + if (0 == LLNotificationsUtil::getSelectedOption(notification, response)) + { + LLLogChat::deleteTranscripts(); + updateDeleteTranscriptsButton(); + } +} + +void LLFloaterPreference::onLogChatHistorySaved() +{ + LLButton * delete_transcripts_buttonp = getChild<LLButton>("delete_transcripts"); + + if (!delete_transcripts_buttonp->getEnabled()) + { + delete_transcripts_buttonp->setEnabled(true); + } +} + void LLFloaterPreference::updateClickActionSettings() { const int single_clk_action = getChild<LLComboBox>("single_click_action_combo")->getValue().asInteger(); @@ -1557,6 +1730,35 @@ void LLFloaterPreference::setCacheLocation(const LLStringExplicit& location) cache_location_editor->setToolTip(location); } +void LLFloaterPreference::selectPanel(const LLSD& name) +{ + LLTabContainer * tab_containerp = getChild<LLTabContainer>("pref core"); + LLPanel * panel = tab_containerp->getPanelByName(name); + if (NULL != panel) + { + tab_containerp->selectTabPanel(panel); + } +} + +void LLFloaterPreference::selectPrivacyPanel() +{ + selectPanel("im"); +} + +void LLFloaterPreference::selectChatPanel() +{ + selectPanel("chat"); +} + +void LLFloaterPreference::changed() +{ + getChild<LLButton>("clear_log")->setEnabled(LLConversationLog::instance().getConversations().size() > 0); + + // set 'enable' property for 'Delete transcripts...' button + updateDeleteTranscriptsButton(); + +} + //------------------------------Updater--------------------------------------- static bool handleBandwidthChanged(const LLSD& newvalue) @@ -1615,6 +1817,17 @@ LLPanelPreference::LLPanelPreference() //virtual BOOL LLPanelPreference::postBuild() { + ////////////////////// PanelGeneral /////////////////// + if (hasChild("display_names_check")) + { + BOOL use_people_api = gSavedSettings.getBOOL("UsePeopleAPI"); + LLCheckBoxCtrl* ctrl_display_name = getChild<LLCheckBoxCtrl>("display_names_check"); + ctrl_display_name->setEnabled(use_people_api); + if (!use_people_api) + { + ctrl_display_name->setValue(FALSE); + } + } ////////////////////// PanelVoice /////////////////// if (hasChild("voice_unavailable")) @@ -1639,12 +1852,6 @@ BOOL LLPanelPreference::postBuild() } - if (hasChild("online_visibility") && hasChild("send_im_to_email")) - { - getChild<LLUICtrl>("email_address")->setValue(getString("log_in_to_change") ); -// getChild<LLUICtrl>("busy_response")->setValue(getString("log_in_to_change")); - } - //////////////////////PanelPrivacy /////////////////// if (hasChild("media_enabled")) { @@ -1666,7 +1873,7 @@ BOOL LLPanelPreference::postBuild() getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setCommitCallback(boost::bind(&showFavoritesOnLoginWarning, _1, _2)); } - // Panel Advanced + //////////////////////PanelAdvanced /////////////////// if (hasChild("modifier_combo")) { //localizing if push2talk button is set to middle mouse @@ -1800,7 +2007,46 @@ void LLPanelPreference::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl) } } +class LLPanelPreferencePrivacy : public LLPanelPreference +{ +public: + LLPanelPreferencePrivacy() + { + mAccountIndependentSettings.push_back("VoiceCallsFriendsOnly"); + mAccountIndependentSettings.push_back("AutoDisengageMic"); + } + + /*virtual*/ void saveSettings() + { + LLPanelPreference::saveSettings(); + + // Don't save (=erase from the saved values map) per-account privacy settings + // if we're not logged in, otherwise they will be reset to defaults on log off. + if (LLStartUp::getStartupState() != STATE_STARTED) + { + // Erase only common settings, assuming there are no color settings on Privacy page. + for (control_values_map_t::iterator it = mSavedValues.begin(); it != mSavedValues.end(); ) + { + const std::string setting = it->first->getName(); + if (find(mAccountIndependentSettings.begin(), + mAccountIndependentSettings.end(), setting) == mAccountIndependentSettings.end()) + { + mSavedValues.erase(it++); + } + else + { + ++it; + } + } + } + } + +private: + std::list<std::string> mAccountIndependentSettings; +}; + static LLRegisterPanelClassWrapper<LLPanelPreferenceGraphics> t_pref_graph("panel_preference_graphics"); +static LLRegisterPanelClassWrapper<LLPanelPreferencePrivacy> t_pref_privacy("panel_preference_privacy"); BOOL LLPanelPreferenceGraphics::postBuild() { @@ -2071,4 +2317,4 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings() otherHttpProxy->selectFirstItem(); } -}; +} diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 7ee3294478..22e80a21cb 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -35,7 +35,9 @@ #include "llfloater.h" #include "llavatarpropertiesprocessor.h" +#include "llconversationlog.h" +class LLConversationLogObserver; class LLPanelPreference; class LLPanelLCD; class LLPanelDebug; @@ -45,6 +47,8 @@ class LLSliderCtrl; class LLSD; class LLTextBox; +typedef std::map<std::string, std::string> notifications_map; + typedef enum { GS_LOW_GRAPHICS, @@ -56,7 +60,7 @@ typedef enum // Floater to control preferences (display, audio, bandwidth, general. -class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver +class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver, public LLConversationLogObserver { public: LLFloaterPreference(const LLSD& key); @@ -68,20 +72,24 @@ public: /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ void onClose(bool app_quitting); + /*virtual*/ void changed(); + /*virtual*/ void changed(const LLUUID& session_id, U32 mask) {}; // static data update, called from message handler - static void updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email); + static void updateUserInfo(const std::string& visibility, bool im_via_email); // refresh all the graphics preferences menus static void refreshEnabledGraphics(); - // translate user's busy response message according to current locale if message is default, otherwise do nothing - static void initBusyResponse(); + // translate user's do not disturb response message according to current locale if message is default, otherwise do nothing + static void initDoNotDisturbResponse(); void processProperties( void* pData, EAvatarProcessorType type ); void processProfileProperties(const LLAvatarData* pAvatarData ); void storeAvatarProperties( const LLAvatarData* pAvatarData ); void saveAvatarProperties( void ); + void selectPrivacyPanel(); + void selectChatPanel(); protected: void onBtnOK(); @@ -91,11 +99,12 @@ protected: void onClickClearCache(); // Clear viewer texture cache, vfs, and VO cache on next startup void onClickBrowserClearCache(); // Clear web history and caches as well as viewer caches above void onLanguageChange(); + void onNotificationsChange(const std::string& OptionName); void onNameTagOpacityChange(const LLSD& newvalue); - // set value of "BusyResponseChanged" in account settings depending on whether busy response + // set value of "DoNotDisturbResponseChanged" in account settings depending on whether do not disturb response // string differs from default after user changes. - void onBusyResponseChanged(); + void onDoNotDisturbResponseChanged(); // if the custom settings box is clicked void onChangeCustom(); void updateMeterText(LLUICtrl* ctrl); @@ -129,15 +138,14 @@ public: void setKey(KEY key); void onClickSetMiddleMouse(); void onClickSetSounds(); -// void onClickSkipDialogs(); -// void onClickResetDialogs(); void onClickEnablePopup(); void onClickDisablePopup(); void resetAllIgnored(); void setAllIgnored(); - void onClickLogPath(); + void onClickLogPath(); + bool moveTranscriptsAndLog(); void enableHistory(); - void setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email); + void setPersonalInfo(const std::string& visibility, bool im_via_email); void refreshEnabledState(); void disableUnavailableSettings(); void onCommitWindowedMode(); @@ -157,18 +165,29 @@ public: void onClickBlockList(); void onClickProxySettings(); void onClickTranslationSettings(); + void onClickAutoReplace(); + void onClickSpellChecker(); void applyUIColor(LLUICtrl* ctrl, const LLSD& param); void getUIColor(LLUICtrl* ctrl, const LLSD& param); - + void onLogChatHistorySaved(); void buildPopupLists(); static void refreshSkin(void* data); + void selectPanel(const LLSD& name); + private: + + void onDeleteTranscripts(); + void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response); + void updateDeleteTranscriptsButton(); + static std::string sSkin; + notifications_map mNotificationOptions; bool mClickActionDirty; ///< Set to true when the click/double-click options get changed by user. bool mGotPersonalInfo; bool mOriginalIMViaEmail; bool mLanguageChanged; bool mAvatarDataInitialized; + std::string mPriorInstantMessageLogPath; bool mOriginalHideOnlineStatus; std::string mDirectoryVisibility; @@ -198,15 +217,17 @@ public: virtual void saveSettings(); class Updater; + +protected: + typedef std::map<LLControlVariable*, LLSD> control_values_map_t; + control_values_map_t mSavedValues; + private: //for "Only friends and groups can call or IM me" static void showFriendsOnlyWarning(LLUICtrl*, const LLSD&); //for "Show my Favorite Landmarks at Login" static void showFavoritesOnLoginWarning(LLUICtrl* checkbox, const LLSD& value); - typedef std::map<LLControlVariable*, LLSD> control_values_map_t; - control_values_map_t mSavedValues; - typedef std::map<std::string, LLColor4> string_color_map_t; string_color_map_t mSavedColors; diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 676059779c..e6b76159a1 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -287,8 +287,7 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) //dispatch the message dispatch.dispatch(request, invoice, strings); - LLViewerRegion* region = gAgent.getRegion(); - panel->updateControls(region); + panel->updateControls(gAgent.getRegion()); } @@ -648,9 +647,14 @@ void LLPanelRegionGeneralInfo::onClickKick() // this depends on the grandparent view being a floater // in order to set up floater dependency + LLView * button = findChild<LLButton>("kick_btn"); LLFloater* parent_floater = gFloaterView->getParentFloater(this); - LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), FALSE, TRUE); - parent_floater->addDependentFloater(child_floater); + LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), + FALSE, TRUE, FALSE, parent_floater->getName(), button); + if (child_floater) + { + parent_floater->addDependentFloater(child_floater); + } } void LLPanelRegionGeneralInfo::onKickCommit(const uuid_vec_t& ids) @@ -922,7 +926,14 @@ BOOL LLPanelRegionDebugInfo::sendUpdate() void LLPanelRegionDebugInfo::onClickChooseAvatar() { - LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2), FALSE, TRUE); + LLView * button = findChild<LLButton>("choose_avatar_btn"); + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + LLFloater * child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2), + FALSE, TRUE, FALSE, parent_floater->getName(), button); + if (child_floater) + { + parent_floater->addDependentFloater(child_floater); + } } @@ -1468,9 +1479,14 @@ void LLPanelEstateInfo::onClickKickUser() { // this depends on the grandparent view being a floater // in order to set up floater dependency + LLView * button = findChild<LLButton>("kick_user_from_estate_btn"); LLFloater* parent_floater = gFloaterView->getParentFloater(this); - LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), FALSE, TRUE); - parent_floater->addDependentFloater(child_floater); + LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), + FALSE, TRUE, FALSE, parent_floater->getName(), button); + if (child_floater) + { + parent_floater->addDependentFloater(child_floater); + } } void LLPanelEstateInfo::onKickUserCommit(const uuid_vec_t& ids) @@ -1641,8 +1657,39 @@ bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& res } LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]); + //Get parent floater name + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + LLFloater* parent_floater = panel ? gFloaterView->getParentFloater(panel) : NULL; + const std::string& parent_floater_name = parent_floater ? parent_floater->getName() : ""; + + //Determine the button that triggered opening of the avatar picker + //(so that a shadow frustum from the button to the avatar picker can be created) + LLView * button = NULL; + switch(change_info->mOperationFlag) + { + case ESTATE_ACCESS_ALLOWED_AGENT_ADD: + button = panel->findChild<LLButton>("add_allowed_avatar_btn"); + break; + + case ESTATE_ACCESS_BANNED_AGENT_ADD: + button = panel->findChild<LLButton>("add_banned_avatar_btn"); + break; + + case ESTATE_ACCESS_MANAGER_ADD: + button = panel->findChild<LLButton>("add_estate_manager_btn"); + break; + } + // avatar picker yes multi-select, yes close-on-select - LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, (void*)change_info), TRUE, TRUE); + LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, (void*)change_info), + TRUE, TRUE, FALSE, parent_floater_name, button); + + //Allows the closed parent floater to close the child floater (avatar picker) + if (child_floater) + { + parent_floater->addDependentFloater(child_floater); + } + return false; } @@ -1891,6 +1938,26 @@ void LLPanelEstateInfo::sendEstateAccessDelta(U32 flags, const LLUUID& agent_or_ gAgent.sendReliableMessage(); } +// static +void LLPanelEstateInfo::updateEstateOwnerName(const std::string& name) +{ + LLPanelEstateInfo* panelp = LLFloaterRegionInfo::getPanelEstate(); + if (panelp) + { + panelp->setOwnerName(name); + } +} + +// static +void LLPanelEstateInfo::updateEstateName(const std::string& name) +{ + LLPanelEstateInfo* panelp = LLFloaterRegionInfo::getPanelEstate(); + if (panelp) + { + panelp->getChildRef<LLTextBox>("estate_name").setText(name); + } +} + void LLPanelEstateInfo::updateControls(LLViewerRegion* region) { BOOL god = gAgent.isGodlike(); @@ -1898,10 +1965,18 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region) BOOL manager = (region && region->isEstateManager()); setCtrlsEnabled(god || owner || manager); + BOOL has_allowed_avatar = getChild<LLNameListCtrl>("allowed_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_allowed_group = getChild<LLNameListCtrl>("allowed_group_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_banned_agent = getChild<LLNameListCtrl>("banned_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_estate_manager = getChild<LLNameListCtrl>("estate_manager_name_list")->getFirstSelected() ? TRUE : FALSE; + getChildView("add_allowed_avatar_btn")->setEnabled(god || owner || manager); - getChildView("remove_allowed_avatar_btn")->setEnabled(god || owner || manager); + getChildView("remove_allowed_avatar_btn")->setEnabled(has_allowed_avatar && (god || owner || manager)); + getChildView("allowed_avatar_name_list")->setEnabled(god || owner || manager); + getChildView("add_allowed_group_btn")->setEnabled(god || owner || manager); - getChildView("remove_allowed_group_btn")->setEnabled(god || owner || manager); + getChildView("remove_allowed_group_btn")->setEnabled(has_allowed_group && (god || owner || manager) ); + getChildView("allowed_group_name_list")->setEnabled(god || owner || manager); // Can't ban people from mainland, orientation islands, etc. because this // creates much network traffic and server load. @@ -1909,14 +1984,15 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region) bool linden_estate = isLindenEstate(); bool enable_ban = (god || owner || manager) && !linden_estate; getChildView("add_banned_avatar_btn")->setEnabled(enable_ban); - getChildView("remove_banned_avatar_btn")->setEnabled(enable_ban); + getChildView("remove_banned_avatar_btn")->setEnabled(has_banned_agent && enable_ban); + getChildView("banned_avatar_name_list")->setEnabled(god || owner || manager); getChildView("message_estate_btn")->setEnabled(god || owner || manager); getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager); // estate managers can't add estate managers getChildView("add_estate_manager_btn")->setEnabled(god || owner); - getChildView("remove_estate_manager_btn")->setEnabled(god || owner); + getChildView("remove_estate_manager_btn")->setEnabled(has_estate_manager && (god || owner)); getChildView("estate_manager_name_list")->setEnabled(god || owner); refresh(); @@ -1953,10 +2029,8 @@ bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region) void LLPanelEstateInfo::updateChild(LLUICtrl* child_ctrl) { - if (checkRemovalButton(child_ctrl->getName())) - { - // do nothing - } + // Ensure appropriate state of the management ui. + updateControls(gAgent.getRegion()); } bool LLPanelEstateInfo::estateUpdate(LLMessageSystem* msg) @@ -2054,23 +2128,8 @@ void LLPanelEstateInfo::refreshFromEstate() getChild<LLUICtrl>("limit_payment")->setValue(estate_info.getDenyAnonymous()); getChild<LLUICtrl>("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified()); - // If visible from mainland, disable the access allowed - // UI, as anyone can teleport there. - // However, gods need to be able to edit the access list for - // linden estates, regardless of visibility, to allow object - // and L$ transfers. - { - bool visible_from_mainland = estate_info.getIsExternallyVisible(); - bool god = gAgent.isGodlike(); - bool linden_estate = isLindenEstate(); - - bool enable_agent = (!visible_from_mainland || (god && linden_estate)); - bool enable_group = enable_agent; - bool enable_ban = !linden_estate; - - setAccessAllowedEnabled(enable_agent, enable_group, enable_ban); - } - + // Ensure appriopriate state of the management UI + updateControls(gAgent.getRegion()); refresh(); } @@ -2199,47 +2258,6 @@ void LLPanelEstateInfo::setOwnerName(const std::string& name) getChild<LLUICtrl>("estate_owner")->setValue(LLSD(name)); } -void LLPanelEstateInfo::setAccessAllowedEnabled(bool enable_agent, - bool enable_group, - bool enable_ban) -{ - getChildView("allow_resident_label")->setEnabled(enable_agent); - getChildView("allowed_avatar_name_list")->setEnabled(enable_agent); - getChildView("allowed_avatar_name_list")->setVisible( enable_agent); - getChildView("add_allowed_avatar_btn")->setEnabled(enable_agent); - getChildView("remove_allowed_avatar_btn")->setEnabled(enable_agent); - - // Groups - getChildView("allow_group_label")->setEnabled(enable_group); - getChildView("allowed_group_name_list")->setEnabled(enable_group); - getChildView("allowed_group_name_list")->setVisible( enable_group); - getChildView("add_allowed_group_btn")->setEnabled(enable_group); - getChildView("remove_allowed_group_btn")->setEnabled(enable_group); - - // Ban - getChildView("ban_resident_label")->setEnabled(enable_ban); - getChildView("banned_avatar_name_list")->setEnabled(enable_ban); - getChildView("banned_avatar_name_list")->setVisible( enable_ban); - getChildView("add_banned_avatar_btn")->setEnabled(enable_ban); - getChildView("remove_banned_avatar_btn")->setEnabled(enable_ban); - - // Update removal buttons if needed - if (enable_agent) - { - checkRemovalButton("allowed_avatar_name_list"); - } - - if (enable_group) - { - checkRemovalButton("allowed_group_name_list"); - } - - if (enable_ban) - { - checkRemovalButton("banned_avatar_name_list"); - } -} - void LLPanelEstateInfo::clearAccessLists() { LLNameListCtrl* name_list = getChild<LLNameListCtrl>("allowed_avatar_name_list"); @@ -2253,39 +2271,7 @@ void LLPanelEstateInfo::clearAccessLists() { name_list->deleteAllItems(); } -} - -// enables/disables the "remove" button for the various allow/ban lists -BOOL LLPanelEstateInfo::checkRemovalButton(std::string name) -{ - std::string btn_name = ""; - if (name == "allowed_avatar_name_list") - { - btn_name = "remove_allowed_avatar_btn"; - } - else if (name == "allowed_group_name_list") - { - btn_name = "remove_allowed_group_btn"; - } - else if (name == "banned_avatar_name_list") - { - btn_name = "remove_banned_avatar_btn"; - } - else if (name == "estate_manager_name_list") - { - //ONLY OWNER CAN ADD /DELET ESTATE MANAGER - LLViewerRegion* region = gAgent.getRegion(); - if (region && (region->getOwner() == gAgent.getID())) - { - btn_name = "remove_estate_manager_btn"; - } - } - - // enable the remove button if something is selected - LLNameListCtrl* name_list = getChild<LLNameListCtrl>(name); - getChildView(btn_name)->setEnabled(name_list && name_list->getFirstSelected() ? TRUE : FALSE); - - return (btn_name != ""); + updateControls(gAgent.getRegion()); } // static @@ -2766,15 +2752,15 @@ bool LLDispatchSetEstateAccess::operator()( if (allowed_agent_name_list) { - //allowed_agent_name_list->deleteAllItems(); + // Don't sort these as we add them, sort them when we are done. + allowed_agent_name_list->clearSortOrder(); for (S32 i = 0; i < num_allowed_agents && i < ESTATE_MAX_ACCESS_IDS; i++) { LLUUID id; memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ allowed_agent_name_list->addNameItem(id); } - panel->getChildView("remove_allowed_avatar_btn")->setEnabled(allowed_agent_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_agent_name_list->sortByColumnIndex(0, TRUE); + allowed_agent_name_list->sortByName(TRUE); } } @@ -2791,6 +2777,8 @@ bool LLDispatchSetEstateAccess::operator()( if (allowed_group_name_list) { + // Don't sort these as we add them, sort them when we are done. + allowed_group_name_list->clearSortOrder(); allowed_group_name_list->deleteAllItems(); for (S32 i = 0; i < num_allowed_groups && i < ESTATE_MAX_GROUP_IDS; i++) { @@ -2798,8 +2786,7 @@ bool LLDispatchSetEstateAccess::operator()( memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ allowed_group_name_list->addGroupNameItem(id); } - panel->getChildView("remove_allowed_group_btn")->setEnabled(allowed_group_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_group_name_list->sortByColumnIndex(0, TRUE); + allowed_group_name_list->sortByName(TRUE); } } @@ -2823,15 +2810,16 @@ bool LLDispatchSetEstateAccess::operator()( if (banned_agent_name_list) { - //banned_agent_name_list->deleteAllItems(); + // Don't sort these as we add them, sort them when we are done. + banned_agent_name_list->clearSortOrder(); + for (S32 i = 0; i < num_banned_agents && i < ESTATE_MAX_ACCESS_IDS; i++) { LLUUID id; memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ banned_agent_name_list->addNameItem(id); } - panel->getChildView("remove_banned_avatar_btn")->setEnabled(banned_agent_name_list->getFirstSelected() ? TRUE : FALSE); - banned_agent_name_list->sortByColumnIndex(0, TRUE); + banned_agent_name_list->sortByName(TRUE); } } @@ -2846,6 +2834,9 @@ bool LLDispatchSetEstateAccess::operator()( panel->getChild<LLNameListCtrl>("estate_manager_name_list"); if (estate_manager_name_list) { + // Don't sort these as we add them, sort them when we are done. + estate_manager_name_list->clearSortOrder(); + estate_manager_name_list->deleteAllItems(); // Clear existing entries // There should be only ESTATE_MAX_MANAGERS people in the list, but if the database gets more (SL-46107) don't @@ -2857,11 +2848,13 @@ bool LLDispatchSetEstateAccess::operator()( memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ estate_manager_name_list->addNameItem(id); } - panel->getChildView("remove_estate_manager_btn")->setEnabled(estate_manager_name_list->getFirstSelected() ? TRUE : FALSE); - estate_manager_name_list->sortByColumnIndex(0, TRUE); + estate_manager_name_list->sortByName(TRUE); } } + // Update the buttons which may change based on the list contents but also needs to account for general access features. + panel->updateControls(gAgent.getRegion()); + return true; } diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index c402de66e8..f0499f1903 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -33,6 +33,7 @@ #include "llfloater.h" #include "llhost.h" #include "llpanel.h" +#include "llextendedstatus.h" #include "llenvmanager.h" // for LLEnvironmentSettings @@ -293,6 +294,9 @@ public: void updateControls(LLViewerRegion* region); + static void updateEstateName(const std::string& name); + static void updateEstateOwnerName(const std::string& name); + virtual bool refreshFromRegion(LLViewerRegion* region); virtual bool estateUpdate(LLMessageSystem* msg); @@ -308,9 +312,6 @@ public: const std::string getOwnerName() const; void setOwnerName(const std::string& name); - // If visible from mainland, allowed agent and allowed groups - // are ignored, so must disable UI. - void setAccessAllowedEnabled(bool enable_agent, bool enable_group, bool enable_ban); protected: virtual BOOL sendUpdate(); // confirmation dialog callback @@ -320,7 +321,6 @@ protected: void commitEstateManagers(); void clearAccessLists(); - BOOL checkRemovalButton(std::string name); BOOL checkSunHourSlider(LLUICtrl* child_ctrl); U32 mEstateID; diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index c08848b1ea..0e4c7406c5 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -103,7 +103,8 @@ LLFloaterReporter::LLFloaterReporter(const LLSD& key) mPicking( FALSE), mPosition(), mCopyrightWarningSeen( FALSE ), - mResourceDatap(new LLResourceData()) + mResourceDatap(new LLResourceData()), + mAvatarNameCacheConnection() { } @@ -187,6 +188,11 @@ BOOL LLFloaterReporter::postBuild() // virtual LLFloaterReporter::~LLFloaterReporter() { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + // child views automatically deleted mObjectID = LLUUID::null; @@ -285,7 +291,14 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id) void LLFloaterReporter::onClickSelectAbuser() { - gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE )); + LLView * button = findChild<LLButton>("select_abuser", TRUE); + + LLFloater * root_floater = gFloaterView->getParentFloater(this); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE, FALSE, root_floater->getName(), button); + if (picker) + { + root_floater->addDependentFloater(picker); + } } void LLFloaterReporter::callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName> names) @@ -306,11 +319,17 @@ void LLFloaterReporter::setFromAvatarID(const LLUUID& avatar_id) std::string avatar_link = LLSLURL("agent", mObjectID, "inspect").getSLURLString(); getChild<LLUICtrl>("owner_name")->setValue(avatar_link); - LLAvatarNameCache::get(avatar_id, boost::bind(&LLFloaterReporter::onAvatarNameCache, this, _1, _2)); + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(avatar_id, boost::bind(&LLFloaterReporter::onAvatarNameCache, this, _1, _2)); } void LLFloaterReporter::onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name) { + mAvatarNameCacheConnection.disconnect(); + if (mObjectID == avatar_id) { mOwnerName = av_name.getCompleteName(); diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index cd98f7be57..d54e7f6ab0 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -31,6 +31,7 @@ #include "llfloater.h" #include "lluuid.h" #include "v3math.h" +#include "llextendedstatus.h" class LLAvatarName; class LLMessageSystem; @@ -136,6 +137,7 @@ private: std::list<LLMeanCollisionData*> mMCDList; std::string mDefaultSummary; LLResourceData* mResourceDatap; + boost::signals2::connection mAvatarNameCacheConnection; }; #endif diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp index a0d1a32e12..b691db1049 100644 --- a/indra/newview/llfloaterscriptdebug.cpp +++ b/indra/newview/llfloaterscriptdebug.cpp @@ -106,7 +106,11 @@ void LLFloaterScriptDebug::addScriptLine(const std::string &utf8mesg, const std: if (objectp) { objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", TRUE, LLViewerTexture::BOOST_UI)); - floater_label = llformat("%s(%.2f, %.2f)", user_name.c_str(), objectp->getPositionRegion().mV[VX], objectp->getPositionRegion().mV[VY]); + floater_label = llformat("%s(%.0f, %.0f, %.0f)", + user_name.c_str(), + objectp->getPositionRegion().mV[VX], + objectp->getPositionRegion().mV[VY], + objectp->getPositionRegion().mV[VZ]); } else { diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index a50907601c..8d8bba7b17 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -602,15 +602,7 @@ void LLPanelScriptLimitsRegionMemory::onNameCache( return; } - std::string name; - if (LLAvatarNameCache::useDisplayNames()) - { - name = LLCacheName::buildUsername(full_name); - } - else - { - name = full_name; - } + std::string name = LLCacheName::buildUsername(full_name); std::vector<LLSD>::iterator id_itor; for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor) @@ -713,10 +705,7 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) else { name_is_cached = gCacheName->getFullName(owner_id, owner_buf); // username - if (LLAvatarNameCache::useDisplayNames()) - { - owner_buf = LLCacheName::buildUsername(owner_buf); - } + owner_buf = LLCacheName::buildUsername(owner_buf); } if(!name_is_cached) { diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp index 3434841d09..0cb37dabe7 100644 --- a/indra/newview/llfloatersellland.cpp +++ b/indra/newview/llfloatersellland.cpp @@ -81,6 +81,7 @@ private: LLUUID mAuthorizedBuyer; bool mParcelSoldWithObjects; SelectionObserver mParcelSelectionObserver; + boost::signals2::connection mAvatarNameCacheConnection; void updateParcelInfo(); void refreshUI(); @@ -129,13 +130,18 @@ LLFloater* LLFloaterSellLand::buildFloater(const LLSD& key) LLFloaterSellLandUI::LLFloaterSellLandUI(const LLSD& key) : LLFloater(key), mParcelSelectionObserver(this), - mRegion(0) + mRegion(0), + mAvatarNameCacheConnection() { LLViewerParcelMgr::getInstance()->addObserver(&mParcelSelectionObserver); } LLFloaterSellLandUI::~LLFloaterSellLandUI() { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } LLViewerParcelMgr::getInstance()->removeObserver(&mParcelSelectionObserver); } @@ -230,15 +236,20 @@ void LLFloaterSellLandUI::updateParcelInfo() if(mSellToBuyer) { - LLAvatarNameCache::get(mAuthorizedBuyer, - boost::bind(&LLFloaterSellLandUI::onBuyerNameCache, this, _2)); + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(mAuthorizedBuyer, boost::bind(&LLFloaterSellLandUI::onBuyerNameCache, this, _2)); } } void LLFloaterSellLandUI::onBuyerNameCache(const LLAvatarName& av_name) { + mAvatarNameCacheConnection.disconnect(); + getChild<LLUICtrl>("sell_to_agent")->setValue(av_name.getCompleteName()); - getChild<LLUICtrl>("sell_to_agent")->setToolTip(av_name.mUsername); + getChild<LLUICtrl>("sell_to_agent")->setToolTip(av_name.getUserName()); } void LLFloaterSellLandUI::setBadge(const char* id, Badge badge) @@ -392,8 +403,13 @@ void LLFloaterSellLandUI::onChangeValue(LLUICtrl *ctrl, void *userdata) void LLFloaterSellLandUI::doSelectAgent() { + LLView * button = findChild<LLView>("sell_to_select_agent"); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterSellLandUI::callbackAvatarPick, this, _1, _2), FALSE, TRUE, FALSE, this->getName(), button); // grandparent is a floater, in order to set up dependency - addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLFloaterSellLandUI::callbackAvatarPick, this, _1, _2), FALSE, TRUE)); + if (picker) + { + addDependentFloater(picker); + } } void LLFloaterSellLandUI::callbackAvatarPick(const uuid_vec_t& ids, const std::vector<LLAvatarName> names) diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp index be7a53491d..96b5c6b09b 100644 --- a/indra/newview/llfloatersidepanelcontainer.cpp +++ b/indra/newview/llfloatersidepanelcontainer.cpp @@ -59,17 +59,17 @@ LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_na LLView* view = findChildView(panel_name, true); if (!view) return NULL; + if (!getVisible()) + { openFloater(); + } LLPanel* panel = NULL; LLSideTrayPanelContainer* container = dynamic_cast<LLSideTrayPanelContainer*>(view->getParent()); if (container) { - LLSD new_params = params; - new_params[LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME] = panel_name; - container->onOpen(new_params); - + container->openPanel(panel_name, params); panel = container->getCurrentPanel(); } else if ((panel = dynamic_cast<LLPanel*>(view)) != NULL) diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index cfa35fa561..d8d62e5bbb 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -100,9 +100,6 @@ S32 BORDER_WIDTH = 6; const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512 -static std::string lastSnapshotWidthName(S32 shot_type); -static std::string lastSnapshotHeightName(S32 shot_type); - static LLDefaultChildRegistry::Register<LLSnapshotFloaterView> r("snapshot_floater_view"); ///---------------------------------------------------------------------------- @@ -138,7 +135,11 @@ public: /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent); void setSize(S32 w, S32 h); + void setWidth(S32 w) { mWidth[mCurImageIndex] = w; } + void setHeight(S32 h) { mHeight[mCurImageIndex] = h; } void getSize(S32& w, S32& h) const; + S32 getWidth() const { return mWidth[mCurImageIndex]; } + S32 getHeight() const { return mHeight[mCurImageIndex]; } S32 getDataSize() const { return mDataSize; } void setMaxImageSize(S32 size) ; S32 getMaxImageSize() {return mMaxImageSize ;} @@ -155,8 +156,9 @@ public: LLViewerTexture* getCurrentImage(); F32 getImageAspect(); F32 getAspect() ; - LLRect getImageRect(); - BOOL isImageScaled(); + const LLRect& getImageRect() const { return mImageRect[mCurImageIndex]; } + BOOL isImageScaled() const { return mImageScaled[mCurImageIndex]; } + void setImageScaled(BOOL scaled) { mImageScaled[mCurImageIndex] = scaled; } const LLVector3d& getPosTakenGlobal() const { return mPosTakenGlobal; } void setSnapshotType(ESnapshotType type) { mSnapshotType = type; } @@ -171,6 +173,7 @@ public: LLPointer<LLImageFormatted> getFormattedImage() const { return mFormattedImage; } LLPointer<LLImageRaw> getEncodedImage() const { return mPreviewImageEncoded; } + /// Sets size of preview thumbnail image and thhe surrounding rect. BOOL setThumbnailImageSize() ; void generateThumbnailImage(BOOL force_update = FALSE) ; void resetThumbnailImage() { mThumbnailImage = NULL ; } @@ -299,7 +302,7 @@ LLViewerTexture* LLSnapshotLivePreview::getCurrentImage() F32 LLSnapshotLivePreview::getAspect() { - F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]); + F32 image_aspect_ratio = ((F32)getWidth()) / ((F32)getHeight()); F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight()); if (!mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot")) @@ -314,7 +317,7 @@ F32 LLSnapshotLivePreview::getAspect() F32 LLSnapshotLivePreview::getImageAspect() { - if (!mViewerImage[mCurImageIndex]) + if (!getCurrentImage()) { return 0.f; } @@ -322,33 +325,24 @@ F32 LLSnapshotLivePreview::getImageAspect() return getAspect() ; } -LLRect LLSnapshotLivePreview::getImageRect() -{ - return mImageRect[mCurImageIndex]; -} - -BOOL LLSnapshotLivePreview::isImageScaled() -{ - return mImageScaled[mCurImageIndex]; -} - void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail, F32 delay) { - lldebugs << "updateSnapshot: mSnapshotUpToDate = " << mSnapshotUpToDate << llendl; - if (mSnapshotUpToDate) + // Invalidate current image. + lldebugs << "updateSnapshot: mSnapshotUpToDate = " << getSnapshotUpToDate() << llendl; + if (getSnapshotUpToDate()) { S32 old_image_index = mCurImageIndex; mCurImageIndex = (mCurImageIndex + 1) % 2; - mWidth[mCurImageIndex] = mWidth[old_image_index]; - mHeight[mCurImageIndex] = mHeight[old_image_index]; + setSize(mWidth[old_image_index], mHeight[old_image_index]); mFallAnimTimer.start(); } mSnapshotUpToDate = FALSE; + // Update snapshot source rect depending on whether we keep the aspect ratio. LLRect& rect = mImageRect[mCurImageIndex]; rect.set(0, getRect().getHeight(), getRect().getWidth(), 0); - F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]); + F32 image_aspect_ratio = ((F32)getWidth()) / ((F32)getHeight()); F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight()); if (mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot")) @@ -369,13 +363,18 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail } } + // Stop shining animation. mShineAnimTimer.stop(); + + // Update snapshot if requested. if (new_snapshot) { mSnapshotDelayTimer.start(); mSnapshotDelayTimer.setTimerExpirySec(delay); LLFloaterSnapshot::preUpdate(); } + + // Update thumbnail if requested. if(new_thumbnail) { mThumbnailUpToDate = FALSE ; @@ -435,23 +434,23 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y) //called when the frame is frozen. void LLSnapshotLivePreview::draw() { - if (mViewerImage[mCurImageIndex].notNull() && + if (getCurrentImage() && mPreviewImageEncoded.notNull() && - mSnapshotUpToDate) + getSnapshotUpToDate()) { LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f); gl_rect_2d(getRect(), bg_color); - LLRect &rect = mImageRect[mCurImageIndex]; - LLRect shadow_rect = mImageRect[mCurImageIndex]; + const LLRect& rect = getImageRect(); + LLRect shadow_rect = rect; shadow_rect.stretch(BORDER_WIDTH); gl_drop_shadow(shadow_rect.mLeft, shadow_rect.mTop, shadow_rect.mRight, shadow_rect.mBottom, LLColor4(0.f, 0.f, 0.f, mNeedsFlash ? 0.f :0.5f), 10); LLColor4 image_color(1.f, 1.f, 1.f, 1.f); gGL.color4fv(image_color.mV); - gGL.getTexUnit(0)->bind(mViewerImage[mCurImageIndex]); + gGL.getTexUnit(0)->bind(getCurrentImage()); // calculate UV scale - F32 uv_width = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mWidth[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f); - F32 uv_height = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mHeight[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f); + F32 uv_width = isImageScaled() ? 1.f : llmin((F32)getWidth() / (F32)getCurrentImage()->getWidth(), 1.f); + F32 uv_height = isImageScaled() ? 1.f : llmin((F32)getHeight() / (F32)getCurrentImage()->getHeight(), 1.f); gGL.pushMatrix(); { gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f); @@ -491,6 +490,7 @@ void LLSnapshotLivePreview::draw() mFlashAlpha = lerp(mFlashAlpha, 0.f, LLCriticalDamp::getInterpolant(0.15f)); } + // Draw shining animation if appropriate. if (mShineCountdown > 0) { mShineCountdown--; @@ -501,6 +501,7 @@ void LLSnapshotLivePreview::draw() } else if (mShineAnimTimer.getStarted()) { + lldebugs << "Drawing shining animation" << llendl; F32 shine_interp = llmin(1.f, mShineAnimTimer.getElapsedTimeF32() / SHINE_TIME); // draw "shine" effect @@ -545,7 +546,7 @@ void LLSnapshotLivePreview::draw() { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.color4f(1.f, 1.f, 1.f, 1.f); - LLRect outline_rect = mImageRect[mCurImageIndex]; + const LLRect& outline_rect = getImageRect(); gGL.begin(LLRender::QUADS); { gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); @@ -577,6 +578,7 @@ void LLSnapshotLivePreview::draw() S32 old_image_index = (mCurImageIndex + 1) % 2; if (mViewerImage[old_image_index].notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME) { + lldebugs << "Drawing fall animation" << llendl; F32 fall_interp = mFallAnimTimer.getElapsedTimeF32() / FALL_TIME; F32 alpha = clamp_rescale(fall_interp, 0.f, 1.f, 0.8f, 0.4f); LLColor4 image_color(1.f, 1.f, 1.f, alpha); @@ -620,13 +622,14 @@ void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_pare LLView::reshape(width, height, called_from_parent); if (old_rect.getWidth() != width || old_rect.getHeight() != height) { + lldebugs << "window reshaped, updating thumbnail" << llendl; updateSnapshot(FALSE, TRUE); } } BOOL LLSnapshotLivePreview::setThumbnailImageSize() { - if(mWidth[mCurImageIndex] < 10 || mHeight[mCurImageIndex] < 10) + if(getWidth() < 10 || getHeight() < 10) { return FALSE ; } @@ -662,11 +665,11 @@ BOOL LLSnapshotLivePreview::setThumbnailImageSize() S32 left = 0 , top = mThumbnailHeight, right = mThumbnailWidth, bottom = 0 ; if(!mKeepAspectRatio) { - F32 ratio_x = (F32)mWidth[mCurImageIndex] / window_width ; - F32 ratio_y = (F32)mHeight[mCurImageIndex] / window_height ; + F32 ratio_x = (F32)getWidth() / window_width ; + F32 ratio_y = (F32)getHeight() / window_height ; - //if(mWidth[mCurImageIndex] > window_width || - // mHeight[mCurImageIndex] > window_height ) + //if(getWidth() > window_width || + // getHeight() > window_height ) { if(ratio_x > ratio_y) { @@ -698,11 +701,11 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update) { return ; } - if(mThumbnailUpToDate && !force_update)//already updated + if(getThumbnailUpToDate() && !force_update)//already updated { return ; } - if(mWidth[mCurImageIndex] < 10 || mHeight[mCurImageIndex] < 10) + if(getWidth() < 10 || getHeight() < 10) { return ; } @@ -750,15 +753,13 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update) BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) { LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)snapshot_preview; - -#if 1 // XXX tmp - if (previewp->mWidth[previewp->mCurImageIndex] == 0 || previewp->mHeight[previewp->mCurImageIndex] == 0) + if (previewp->getWidth() == 0 || previewp->getHeight() == 0) { - llwarns << "Incorrect dimensions: " << previewp->mWidth[previewp->mCurImageIndex] << "x" << previewp->mHeight[previewp->mCurImageIndex] << llendl; + llwarns << "Incorrect dimensions: " << previewp->getWidth() << "x" << previewp->getHeight() << llendl; return FALSE; } -#endif + // If we're in freeze-frame mode and camera has moved, update snapshot. LLVector3 new_camera_pos = LLViewerCamera::getInstance()->getOrigin(); LLQuaternion new_camera_rot = LLViewerCamera::getInstance()->getQuaternion(); if (gSavedSettings.getBOOL("FreezeTime") && @@ -768,6 +769,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) previewp->mCameraRot = new_camera_rot; // request a new snapshot whenever the camera moves, with a time delay BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot"); + lldebugs << "camera moved, updating thumbnail" << llendl; previewp->updateSnapshot( autosnap, // whether a new snapshot is needed or merely invalidate the existing one FALSE, // or if 1st arg is false, whether to produce a new thumbnail image. @@ -801,13 +803,13 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) previewp->setEnabled(FALSE); previewp->getWindow()->incBusyCount(); - previewp->mImageScaled[previewp->mCurImageIndex] = FALSE; + previewp->setImageScaled(FALSE); // grab the raw image and encode it into desired format if(gViewerWindow->rawSnapshot( previewp->mPreviewImage, - previewp->mWidth[previewp->mCurImageIndex], - previewp->mHeight[previewp->mCurImageIndex], + previewp->getWidth(), + previewp->getHeight(), previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"), previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE, gSavedSettings.getBOOL("RenderUIInSnapshot"), @@ -830,8 +832,8 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) previewp->mPreviewImage->getHeight(), previewp->mPreviewImage->getComponents()); - scaled->biasedScaleToPowerOfTwo(512); - previewp->mImageScaled[previewp->mCurImageIndex] = TRUE; + scaled->biasedScaleToPowerOfTwo(MAX_TEXTURE_SIZE); + previewp->setImageScaled(TRUE); if (formatted->encode(scaled, 0.f)) { previewp->mDataSize = formatted->getDataSize(); @@ -886,7 +888,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) { // go ahead and shrink image to appropriate power of 2 for display scaled->biasedScaleToPowerOfTwo(1024); - previewp->mImageScaled[previewp->mCurImageIndex] = TRUE; + previewp->setImageScaled(TRUE); } else { @@ -933,14 +935,14 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) void LLSnapshotLivePreview::setSize(S32 w, S32 h) { lldebugs << "setSize(" << w << ", " << h << ")" << llendl; - mWidth[mCurImageIndex] = w; - mHeight[mCurImageIndex] = h; + setWidth(w); + setHeight(h); } void LLSnapshotLivePreview::getSize(S32& w, S32& h) const { - w = mWidth[mCurImageIndex]; - h = mHeight[mCurImageIndex]; + w = getWidth(); + h = getHeight(); } void LLSnapshotLivePreview::saveTexture() @@ -957,9 +959,9 @@ void LLSnapshotLivePreview::saveTexture() mPreviewImage->getHeight(), mPreviewImage->getComponents()); - scaled->biasedScaleToPowerOfTwo(512); + scaled->biasedScaleToPowerOfTwo(MAX_TEXTURE_SIZE); lldebugs << "scaled texture to " << scaled->getWidth() << "x" << scaled->getHeight() << llendl; - + if (formatted->encode(scaled, 0.0f)) { LLVFile::writeFile(formatted->getData(), formatted->getDataSize(), gVFS, new_asset_id, LLAssetType::AT_TEXTURE); @@ -1068,24 +1070,18 @@ public: static void onClickMore(void* data) ; static void onClickUICheck(LLUICtrl *ctrl, void* data); static void onClickHUDCheck(LLUICtrl *ctrl, void* data); -#if 0 - static void onClickKeepAspectCheck(LLUICtrl *ctrl, void* data); -#endif static void applyKeepAspectCheck(LLFloaterSnapshot* view, BOOL checked); static void updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update = TRUE); static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data); static void onCommitLayerTypes(LLUICtrl* ctrl, void*data); static void onImageQualityChange(LLFloaterSnapshot* view, S32 quality_val); static void onImageFormatChange(LLFloaterSnapshot* view); -#if 0 - static void onCommitSnapshotType(LLUICtrl* ctrl, void* data); - static void onCommitCustomResolution(LLUICtrl *ctrl, void* data); -#endif static void applyCustomResolution(LLFloaterSnapshot* view, S32 w, S32 h); static void onSnapshotUploadFinished(bool status); static void onSendingPostcardFinished(bool status); - static void resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height) ; static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value); + static void setImageSizeSpinnersValues(LLFloaterSnapshot *view, S32 width, S32 height) ; + static void updateSpinners(LLFloaterSnapshot* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed); static LLPanelSnapshot* getActivePanel(LLFloaterSnapshot* floater, bool ok_if_not_found = true); static LLSnapshotLivePreview::ESnapshotType getActiveSnapshotType(LLFloaterSnapshot* floater); @@ -1256,16 +1252,9 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) previewp->mKeepAspectRatio = TRUE; floaterp->getChild<LLComboBox>("profile_size_combo")->setCurrentByIndex(0); - gSavedSettings.setS32("SnapshotProfileLastResolution", 0); - floaterp->getChild<LLComboBox>("postcard_size_combo")->setCurrentByIndex(0); - gSavedSettings.setS32("SnapshotPostcardLastResolution", 0); - floaterp->getChild<LLComboBox>("texture_size_combo")->setCurrentByIndex(0); - gSavedSettings.setS32("SnapshotTextureLastResolution", 0); - floaterp->getChild<LLComboBox>("local_size_combo")->setCurrentByIndex(0); - gSavedSettings.setS32("SnapshotLocalLastResolution", 0); LLSnapshotLivePreview* previewp = getPreviewView(floaterp); previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw()); @@ -1349,19 +1338,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) floater->getChildView("share_to_web")->setVisible( gSavedSettings.getBOOL("SnapshotSharingEnabled")); #endif -#if 0 - floater->getChildView("postcard_size_combo")->setVisible( FALSE); - floater->getChildView("texture_size_combo")->setVisible( FALSE); - floater->getChildView("local_size_combo")->setVisible( FALSE); -#endif - - floater->getChild<LLComboBox>("profile_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotProfileLastResolution")); - floater->getChild<LLComboBox>("postcard_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastResolution")); - floater->getChild<LLComboBox>("texture_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution")); - floater->getChild<LLComboBox>("local_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution")); floater->getChild<LLComboBox>("local_format_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFormat")); - - // *TODO: Separate settings for Web images from postcards enableAspectRatioCheckbox(floater, !floater->impl.mAspectRatioCheckOff); setAspectRatioCheckboxValue(floater, gSavedSettings.getBOOL("KeepAspectForSnapshot")); floater->getChildView("layer_types")->setEnabled(shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL); @@ -1375,19 +1352,20 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) // Initialize spinners. if (width_ctrl->getValue().asInteger() == 0) { - S32 w = gSavedSettings.getS32(lastSnapshotWidthName(shot_type)); + S32 w = gViewerWindow->getWindowWidthRaw(); lldebugs << "Initializing width spinner (" << width_ctrl->getName() << "): " << w << llendl; width_ctrl->setValue(w); } if (height_ctrl->getValue().asInteger() == 0) { - S32 h = gSavedSettings.getS32(lastSnapshotHeightName(shot_type)); + S32 h = gViewerWindow->getWindowHeightRaw(); lldebugs << "Initializing height spinner (" << height_ctrl->getName() << "): " << h << llendl; height_ctrl->setValue(h); } + // Сlamp snapshot resolution to window size when showing UI or HUD in snapshot. if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot")) - { //clamp snapshot resolution to window size when showing UI or HUD in snapshot + { S32 width = gViewerWindow->getWindowWidthRaw(); S32 height = gViewerWindow->getWindowHeightRaw(); @@ -1416,7 +1394,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) BOOL got_snap = previewp && previewp->getSnapshotUpToDate(); // *TODO: Separate maximum size for Web images from postcards - //lldebugs << "Is snapshot up-to-date? " << got_snap << llendl; + lldebugs << "Is snapshot up-to-date? " << got_snap << llendl; LLLocale locale(LLLocale::USER_LOCALE); std::string bytes_string; @@ -1441,6 +1419,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) && got_bytes && previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" )); + // Update the width and height spinners based on the corresponding resolution combos. (?) switch(shot_type) { case LLSnapshotLivePreview::SNAPSHOT_WEB: @@ -1467,7 +1446,6 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) if (previewp) { - lldebugs << "Setting snapshot type (" << shot_type << "), format (" << shot_format << ")" << llendl; previewp->setSnapshotType(shot_type); previewp->setSnapshotFormat(shot_format); previewp->setSnapshotBufferType(layer_type); @@ -1480,6 +1458,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) info["have-snapshot"] = got_snap; current_panel->updateControls(info); } + lldebugs << "finished updating controls" << llendl; } // static @@ -1510,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; } @@ -1520,6 +1505,7 @@ void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, if (previewp) { BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot"); + lldebugs << "updating " << (autosnap ? "snapshot" : "thumbnail") << llendl; previewp->updateSnapshot(autosnap, update_thumbnail, autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f); } } @@ -1532,6 +1518,7 @@ void LLFloaterSnapshot::Impl::onClickNewSnapshot(void* data) if (previewp && view) { view->impl.setStatus(Impl::STATUS_READY); + lldebugs << "updating snapshot" << llendl; previewp->updateSnapshot(TRUE); } } @@ -1559,17 +1546,8 @@ void LLFloaterSnapshot::Impl::onClickMore(void* data) { view->impl.setStatus(Impl::STATUS_READY); gSavedSettings.setBOOL("AdvanceSnapshot", !visible); -#if 0 - view->translate( 0, view->getUIWinHeightShort() - view->getUIWinHeightLong() ); - view->reshape(view->getRect().getWidth(), view->getUIWinHeightLong()); -#endif updateControls(view) ; updateLayout(view) ; - // *TODO: redundant? - if(getPreviewView(view)) - { - getPreviewView(view)->setThumbnailImageSize() ; - } } } @@ -1601,16 +1579,6 @@ void LLFloaterSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data) } } -#if 0 -// static -void LLFloaterSnapshot::Impl::onClickKeepAspectCheck(LLUICtrl* ctrl, void* data) -{ - LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - applyKeepAspectCheck(view, check->get()); -} -#endif - // static void LLFloaterSnapshot::Impl::applyKeepAspectCheck(LLFloaterSnapshot* view, BOOL checked) { @@ -1625,11 +1593,9 @@ void LLFloaterSnapshot::Impl::applyKeepAspectCheck(LLFloaterSnapshot* view, BOOL S32 w, h ; previewp->getSize(w, h) ; - if(checkImageSize(previewp, w, h, TRUE, previewp->getMaxImageSize())) - { - resetSnapshotSizeOnUI(view, w, h) ; - } + updateSpinners(view, previewp, w, h, TRUE); // may change w and h + lldebugs << "updating thumbnail" << llendl; previewp->setSize(w, h) ; previewp->updateSnapshot(FALSE, TRUE); checkAutoSnapshot(previewp, TRUE); @@ -1664,39 +1630,31 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde previewp->mKeepAspectRatio = FALSE ; return ; } - - if(0 == index) //current window size - { - view->impl.mAspectRatioCheckOff = true ; - enableAspectRatioCheckbox(view, FALSE); - if(previewp) - { - previewp->mKeepAspectRatio = TRUE ; - } + BOOL keep_aspect = FALSE, enable_cb = FALSE; + + if (0 == index) // current window size + { + enable_cb = FALSE; + keep_aspect = TRUE; } - else if(-1 == index) //custom + else if (-1 == index) // custom { - view->impl.mAspectRatioCheckOff = false ; - enableAspectRatioCheckbox(view, TRUE); - - if(previewp) - { - previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ; - } + enable_cb = TRUE; + keep_aspect = gSavedSettings.getBOOL("KeepAspectForSnapshot"); } - else + else // predefined resolution { - view->impl.mAspectRatioCheckOff = true ; - enableAspectRatioCheckbox(view, FALSE); - - if(previewp) - { - previewp->mKeepAspectRatio = FALSE ; - } + enable_cb = FALSE; + keep_aspect = FALSE; } - return ; + view->impl.mAspectRatioCheckOff = !enable_cb; + enableAspectRatioCheckbox(view, enable_cb); + if (previewp) + { + previewp->mKeepAspectRatio = keep_aspect; + } } // Show/hide upload progress indicators. @@ -1743,27 +1701,7 @@ void LLFloaterSnapshot::Impl::setFinished(LLFloaterSnapshot* floater, bool finis } } -static std::string lastSnapshotWidthName(S32 shot_type) -{ - switch (shot_type) - { - case LLSnapshotLivePreview::SNAPSHOT_WEB: return "LastSnapshotToProfileWidth"; - case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: return "LastSnapshotToEmailWidth"; - case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: return "LastSnapshotToInventoryWidth"; - default: return "LastSnapshotToDiskWidth"; - } -} -static std::string lastSnapshotHeightName(S32 shot_type) -{ - switch (shot_type) - { - case LLSnapshotLivePreview::SNAPSHOT_WEB: return "LastSnapshotToProfileHeight"; - case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: return "LastSnapshotToEmailHeight"; - case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: return "LastSnapshotToInventoryHeight"; - default: return "LastSnapshotToDiskHeight"; - } -} - +// Apply a new resolution selected from the given combobox. // static void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update) { @@ -1776,12 +1714,6 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL return; } - // save off all selected resolution values - gSavedSettings.setS32("SnapshotProfileLastResolution", view->getChild<LLComboBox>("profile_size_combo")->getCurrentIndex()); - gSavedSettings.setS32("SnapshotPostcardLastResolution", view->getChild<LLComboBox>("postcard_size_combo")->getCurrentIndex()); - gSavedSettings.setS32("SnapshotTextureLastResolution", view->getChild<LLComboBox>("texture_size_combo")->getCurrentIndex()); - gSavedSettings.setS32("SnapshotLocalLastResolution", view->getChild<LLComboBox>("local_size_combo")->getCurrentIndex()); - std::string sdstring = combobox->getSelectedValue(); LLSD sdres; std::stringstream sstream(sdstring); @@ -1805,7 +1737,6 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL else if (width == -1 || height == -1) { // load last custom value -#if 1 S32 new_width = 0, new_height = 0; LLPanelSnapshot* spanel = getActivePanel(view); if (spanel) @@ -1813,26 +1744,24 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL lldebugs << "Loading typed res from panel " << spanel->getName() << llendl; new_width = spanel->getTypedPreviewWidth(); new_height = spanel->getTypedPreviewHeight(); + + // Limit custom size for inventory snapshots to 512x512 px. + if (getActiveSnapshotType(view) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE) + { + new_width = llmin(new_width, MAX_TEXTURE_SIZE); + new_height = llmin(new_height, MAX_TEXTURE_SIZE); + } } else { - const S32 shot_type = getActiveSnapshotType(view); - lldebugs << "Loading saved res for shot_type " << shot_type << llendl; - new_width = gSavedSettings.getS32(lastSnapshotWidthName(shot_type)); - new_height = gSavedSettings.getS32(lastSnapshotHeightName(shot_type)); + lldebugs << "No custom res chosen, setting preview res from window: " + << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << llendl; + new_width = gViewerWindow->getWindowWidthRaw(); + new_height = gViewerWindow->getWindowHeightRaw(); } llassert(new_width > 0 && new_height > 0); previewp->setSize(new_width, new_height); -#else - LLPanelSnapshot* spanel = getActivePanel(view); - if (spanel) - { - lldebugs << "Setting custom preview res : " << spanel->getTypedPreviewWidth() << "x" << spanel->getTypedPreviewHeight() << llendl; - previewp->setSize(spanel->getTypedPreviewWidth(), spanel->getTypedPreviewHeight()); - } - //previewp->setSize(gSavedSettings.getS32(lastSnapshotWidthName()), gSavedSettings.getS32(lastSnapshotHeightName())); -#endif } else { @@ -1851,11 +1780,7 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL height = llmin(height, gViewerWindow->getWindowHeightRaw()); } - - if(checkImageSize(previewp, width, height, TRUE, previewp->getMaxImageSize())) - { - resetSnapshotSizeOnUI(view, width, height) ; - } + updateSpinners(view, previewp, width, height, TRUE); // may change width and height if(getWidthSpinner(view)->getValue().asInteger() != width || getHeightSpinner(view)->getValue().asInteger() != height) { @@ -1869,9 +1794,11 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL // hide old preview as the aspect ratio could be wrong checkAutoSnapshot(previewp, FALSE); + lldebugs << "updating thumbnail" << llendl; getPreviewView(view)->updateSnapshot(FALSE, TRUE); if(do_update) { + lldebugs << "Will update controls" << llendl; updateControls(view); setNeedRefresh(view, true); } @@ -1914,93 +1841,29 @@ void LLFloaterSnapshot::Impl::onImageFormatChange(LLFloaterSnapshot* view) if (view) { gSavedSettings.setS32("SnapshotFormat", getImageFormat(view)); + lldebugs << "image format changed, updating snapshot" << llendl; getPreviewView(view)->updateSnapshot(TRUE); updateControls(view); setNeedRefresh(view, false); // we're refreshing } } -#if 0 -//static -void LLFloaterSnapshot::Impl::onCommitSnapshotType(LLUICtrl* ctrl, void* data) -{ - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - if (view) - { - gSavedSettings.setS32("LastSnapshotType", getTypeIndex(view)); - getPreviewView(view)->updateSnapshot(TRUE); - updateControls(view); - } -} -#endif - // Sets the named size combo to "custom" mode. // static void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const std::string& comboname) { LLComboBox* combo = floater->getChild<LLComboBox>(comboname); - combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index - - if(comboname == "postcard_size_combo") - { - gSavedSettings.setS32("SnapshotPostcardLastResolution", combo->getCurrentIndex()); - } - else if(comboname == "profile_size_combo") - { - gSavedSettings.setS32("SnapshotProfileLastResolution", combo->getCurrentIndex()); - } - else if(comboname == "texture_size_combo") - { - gSavedSettings.setS32("SnapshotTextureLastResolution", combo->getCurrentIndex()); - } - else if(comboname == "local_size_combo") - { - gSavedSettings.setS32("SnapshotLocalLastResolution", combo->getCurrentIndex()); - } - checkAspectRatio(floater, -1); // -1 means custom } - - +// Update supplied width and height according to the constrain proportions flag; limit them by max_val. //static BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value) { S32 w = width ; S32 h = height ; - //if texture, ignore aspect ratio setting, round image size to power of 2. -#if 0 // Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here - if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == gSavedSettings.getS32("LastSnapshotType")) - { - if(width > max_value) - { - width = max_value ; - } - if(height > max_value) - { - height = max_value ; - } - - //round to nearest power of 2 based on the direction of movement - // i.e. higher power of two if increasing texture resolution - if(gSavedSettings.getS32("LastSnapshotToInventoryWidth") < width || - gSavedSettings.getS32("LastSnapshotToInventoryHeight") < height) - { - // Up arrow pressed - width = get_next_power_two(width, MAX_TEXTURE_SIZE) ; - height = get_next_power_two(height, MAX_TEXTURE_SIZE) ; - } - else - { - // Down or no change - width = get_lower_power_two(width, MAX_TEXTURE_SIZE) ; - height = get_lower_power_two(height, MAX_TEXTURE_SIZE) ; - } - } - else -#endif if(previewp && previewp->mKeepAspectRatio) { if(gViewerWindow->getWindowWidthRaw() < 1 || gViewerWindow->getWindowHeightRaw() < 1) @@ -2014,11 +1877,11 @@ BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S3 //change another value proportionally if(isWidthChanged) { - height = (S32)(width / aspect_ratio) ; + height = llround(width / aspect_ratio) ; } else { - width = (S32)(height * aspect_ratio) ; + width = llround(height * aspect_ratio) ; } //bound w/h by the max_value @@ -2036,32 +1899,25 @@ BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S3 } } } - else - { - } return (w != width || h != height) ; } //static -void LLFloaterSnapshot::Impl::resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height) +void LLFloaterSnapshot::Impl::setImageSizeSpinnersValues(LLFloaterSnapshot *view, S32 width, S32 height) { getWidthSpinner(view)->forceSetValue(width); getHeightSpinner(view)->forceSetValue(height); - gSavedSettings.setS32(lastSnapshotWidthName(getActiveSnapshotType(view)), width); - gSavedSettings.setS32(lastSnapshotHeightName(getActiveSnapshotType(view)), height); } -#if 0 -//static -void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* data) +// static +void LLFloaterSnapshot::Impl::updateSpinners(LLFloaterSnapshot* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed) { - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - S32 w = llfloor((F32)getWidthSpinner(view)->getValue().asReal()); - S32 h = llfloor((F32)getHeightSpinner(view)->getValue().asReal()); - applyCustomResolution(view, w, h); + if (checkImageSize(previewp, width, height, is_width_changed, previewp->getMaxImageSize())) + { + setImageSizeSpinnersValues(view, width, height); + } } -#endif // static void LLFloaterSnapshot::Impl::applyCustomResolution(LLFloaterSnapshot* view, S32 w, S32 h) @@ -2069,68 +1925,38 @@ void LLFloaterSnapshot::Impl::applyCustomResolution(LLFloaterSnapshot* view, S32 bool need_refresh = false; lldebugs << "applyCustomResolution(" << w << ", " << h << ")" << llendl; - if (view) + if (!view) return; + + LLSnapshotLivePreview* previewp = getPreviewView(view); + if (previewp) { - LLSnapshotLivePreview* previewp = getPreviewView(view); - if (previewp) - { - S32 curw,curh; - previewp->getSize(curw, curh); - - if (w != curw || h != curh) - { - BOOL update_ = FALSE ; - //if to upload a snapshot, process spinner input in a special way. -#if 0 // Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here - if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == gSavedSettings.getS32("LastSnapshotType")) - { - S32 spinner_increment = (S32)((LLSpinCtrl*)ctrl)->getIncrement() ; - S32 dw = w - curw ; - S32 dh = h - curh ; - dw = (dw == spinner_increment) ? 1 : ((dw == -spinner_increment) ? -1 : 0) ; - dh = (dh == spinner_increment) ? 1 : ((dh == -spinner_increment) ? -1 : 0) ; - - if(dw) - { - w = (dw > 0) ? curw << dw : curw >> -dw ; - update_ = TRUE ; - } - if(dh) - { - h = (dh > 0) ? curh << dh : curh >> -dh ; - update_ = TRUE ; - } - } -#endif - previewp->setMaxImageSize((S32) getWidthSpinner(view)->getMaxValue()) ; - - // Check image size changes the value of height and width - if(checkImageSize(previewp, w, h, w != curw, previewp->getMaxImageSize()) - || update_) - { - resetSnapshotSizeOnUI(view, w, h) ; - } + S32 curw,curh; + previewp->getSize(curw, curh); - previewp->setSize(w,h); - checkAutoSnapshot(previewp, FALSE); - previewp->updateSnapshot(FALSE, TRUE); - comboSetCustom(view, "profile_size_combo"); - comboSetCustom(view, "postcard_size_combo"); - comboSetCustom(view, "texture_size_combo"); - comboSetCustom(view, "local_size_combo"); - need_refresh = true; - } - } + if (w != curw || h != curh) + { + //if to upload a snapshot, process spinner input in a special way. + previewp->setMaxImageSize((S32) getWidthSpinner(view)->getMaxValue()) ; - gSavedSettings.setS32(lastSnapshotWidthName(getActiveSnapshotType(view)), w); - gSavedSettings.setS32(lastSnapshotHeightName(getActiveSnapshotType(view)), h); + updateSpinners(view, previewp, w, h, w != curw); // may change w and h - updateControls(view); - if (need_refresh) - { - setNeedRefresh(view, true); // need to do this after updateControls() + previewp->setSize(w,h); + checkAutoSnapshot(previewp, FALSE); + lldebugs << "applied custom resolution, updating thumbnail" << llendl; + previewp->updateSnapshot(FALSE, TRUE); + comboSetCustom(view, "profile_size_combo"); + comboSetCustom(view, "postcard_size_combo"); + comboSetCustom(view, "texture_size_combo"); + comboSetCustom(view, "local_size_combo"); + need_refresh = true; } } + + updateControls(view); + if (need_refresh) + { + setNeedRefresh(view, true); // need to do this after updateControls() + } } // static @@ -2164,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); @@ -2186,10 +2012,6 @@ BOOL LLFloaterSnapshot::postBuild() LLWebSharing::instance().init(); } -#if 0 - childSetCommitCallback("snapshot_type_radio", Impl::onCommitSnapshotType, this); -#endif - mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn"); childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this); mRefreshLabel = getChild<LLUICtrl>("refresh_lbl"); @@ -2198,31 +2020,18 @@ BOOL LLFloaterSnapshot::postBuild() childSetAction("advanced_options_btn", Impl::onClickMore, this); -#if 0 - childSetCommitCallback("snapshot_width", Impl::onCommitCustomResolution, this); - childSetCommitCallback("snapshot_height", Impl::onCommitCustomResolution, this); -#endif - childSetCommitCallback("ui_check", Impl::onClickUICheck, this); getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot")); childSetCommitCallback("hud_check", Impl::onClickHUDCheck, this); getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot")); -#if 0 - childSetCommitCallback("keep_aspect_check", Impl::onClickKeepAspectCheck, this); -#endif impl.setAspectRatioCheckboxValue(this, gSavedSettings.getBOOL("KeepAspectForSnapshot")); childSetCommitCallback("layer_types", Impl::onCommitLayerTypes, this); getChild<LLUICtrl>("layer_types")->setValue("colors"); getChildView("layer_types")->setEnabled(FALSE); -#if 0 // leads to crash later if one of the settings values is 0 - impl.getWidthSpinner(this)->setValue(gSavedSettings.getS32(lastSnapshotWidthName())); - impl.getHeightSpinner(this)->setValue(gSavedSettings.getS32(lastSnapshotHeightName())); -#endif - getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame")); childSetCommitCallback("freeze_frame_check", Impl::onCommitFreezeFrame, this); @@ -2250,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); @@ -2341,6 +2157,7 @@ void LLFloaterSnapshot::onOpen(const LLSD& key) LLSnapshotLivePreview* preview = LLFloaterSnapshot::Impl::getPreviewView(this); if(preview) { + lldebugs << "opened, updating snapshot" << llendl; preview->updateSnapshot(TRUE); } focusFirstItem(FALSE); @@ -2422,6 +2239,7 @@ void LLFloaterSnapshot::update() return; BOOL changed = FALSE; + lldebugs << "npreviews: " << LLSnapshotLivePreview::sList.size() << llendl; for (std::set<LLSnapshotLivePreview*>::iterator iter = LLSnapshotLivePreview::sList.begin(); iter != LLSnapshotLivePreview::sList.end(); ++iter) { @@ -2429,6 +2247,7 @@ void LLFloaterSnapshot::update() } if(changed) { + lldebugs << "changed" << llendl; inst->impl.updateControls(inst); } } diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp new file mode 100644 index 0000000000..5ecdd11918 --- /dev/null +++ b/indra/newview/llfloaterspellchecksettings.cpp @@ -0,0 +1,491 @@ +/** + * @file llfloaterspellchecksettings.h + * @brief Spell checker settings floater + * +* $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 "llcombobox.h" +#include "llfilepicker.h" +#include "llfloaterreg.h" +#include "llfloaterspellchecksettings.h" +#include "llscrolllistctrl.h" +#include "llsdserialize.h" +#include "llspellcheck.h" +#include "lltrans.h" +#include "llviewercontrol.h" +#include "llnotificationsutil.h" + +#include <boost/algorithm/string.hpp> + +///---------------------------------------------------------------------------- +/// Class LLFloaterSpellCheckerSettings +///---------------------------------------------------------------------------- +LLFloaterSpellCheckerSettings::LLFloaterSpellCheckerSettings(const LLSD& key) + : LLFloater(key) +{ +} + +void LLFloaterSpellCheckerSettings::draw() +{ + LLFloater::draw(); + + std::vector<LLScrollListItem*> sel_items = getChild<LLScrollListCtrl>("spellcheck_available_list")->getAllSelected(); + bool enable_remove = !sel_items.empty(); + for (std::vector<LLScrollListItem*>::const_iterator sel_it = sel_items.begin(); sel_it != sel_items.end(); ++sel_it) + { + enable_remove &= LLSpellChecker::canRemoveDictionary((*sel_it)->getValue().asString()); + } + getChild<LLUICtrl>("spellcheck_remove_btn")->setEnabled(enable_remove); +} + +BOOL LLFloaterSpellCheckerSettings::postBuild(void) +{ + gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&LLFloaterSpellCheckerSettings::refreshDictionaries, this, false)); + LLSpellChecker::setSettingsChangeCallback(boost::bind(&LLFloaterSpellCheckerSettings::onSpellCheckSettingsChange, this)); + getChild<LLUICtrl>("spellcheck_remove_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnRemove, this)); + getChild<LLUICtrl>("spellcheck_import_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnImport, this)); + getChild<LLUICtrl>("spellcheck_main_combo")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::refreshDictionaries, this, false)); + getChild<LLUICtrl>("spellcheck_moveleft_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnMove, this, "spellcheck_active_list", "spellcheck_available_list")); + getChild<LLUICtrl>("spellcheck_moveright_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnMove, this, "spellcheck_available_list", "spellcheck_active_list")); + center(); + return true; +} + +void LLFloaterSpellCheckerSettings::onBtnImport() +{ + LLFloaterReg::showInstance("prefs_spellchecker_import"); +} + +void LLFloaterSpellCheckerSettings::onBtnMove(const std::string& from, const std::string& to) +{ + LLScrollListCtrl* from_ctrl = findChild<LLScrollListCtrl>(from); + LLScrollListCtrl* to_ctrl = findChild<LLScrollListCtrl>(to); + + LLSD row; + row["columns"][0]["column"] = "name"; + + std::vector<LLScrollListItem*> sel_items = from_ctrl->getAllSelected(); + std::vector<LLScrollListItem*>::const_iterator sel_it; + for ( sel_it = sel_items.begin(); sel_it != sel_items.end(); ++sel_it) + { + row["value"] = (*sel_it)->getValue(); + row["columns"][0]["value"] = (*sel_it)->getColumn(0)->getValue(); + to_ctrl->addElement(row); + to_ctrl->setSelectedByValue( (*sel_it)->getValue(), true ); + } + from_ctrl->deleteSelectedItems(); +} + +void LLFloaterSpellCheckerSettings::onClose(bool app_quitting) +{ + if (app_quitting) + { + // don't save anything + return; + } + LLFloaterReg::hideInstance("prefs_spellchecker_import"); + + std::list<std::string> list_dict; + + LLComboBox* dict_combo = findChild<LLComboBox>("spellcheck_main_combo"); + const std::string dict_name = dict_combo->getSelectedItemLabel(); + if (!dict_name.empty()) + { + list_dict.push_back(dict_name); + + LLScrollListCtrl* list_ctrl = findChild<LLScrollListCtrl>("spellcheck_active_list"); + std::vector<LLScrollListItem*> list_items = list_ctrl->getAllData(); + for (std::vector<LLScrollListItem*>::const_iterator item_it = list_items.begin(); item_it != list_items.end(); ++item_it) + { + const std::string language = (*item_it)->getValue().asString(); + if (LLSpellChecker::hasDictionary(language, true)) + { + list_dict.push_back(language); + } + } + } + gSavedSettings.setString("SpellCheckDictionary", boost::join(list_dict, ",")); +} + +void LLFloaterSpellCheckerSettings::onOpen(const LLSD& key) +{ + refreshDictionaries(true); +} + +void LLFloaterSpellCheckerSettings::onBtnRemove() +{ + std::vector<LLScrollListItem*> sel_items = getChild<LLScrollListCtrl>("spellcheck_available_list")->getAllSelected(); + for (std::vector<LLScrollListItem*>::const_iterator sel_it = sel_items.begin(); sel_it != sel_items.end(); ++sel_it) + { + LLSpellChecker::instance().removeDictionary((*sel_it)->getValue().asString()); + } +} + +void LLFloaterSpellCheckerSettings::onSpellCheckSettingsChange() +{ + refreshDictionaries(true); +} + +void LLFloaterSpellCheckerSettings::refreshDictionaries(bool from_settings) +{ + bool enabled = gSavedSettings.getBOOL("SpellCheck"); + getChild<LLUICtrl>("spellcheck_moveleft_btn")->setEnabled(enabled); + getChild<LLUICtrl>("spellcheck_moveright_btn")->setEnabled(enabled); + + // Populate the dictionary combobox + LLComboBox* dict_combo = findChild<LLComboBox>("spellcheck_main_combo"); + std::string dict_cur = dict_combo->getSelectedItemLabel(); + if ((dict_cur.empty() || from_settings) && (LLSpellChecker::getUseSpellCheck())) + { + dict_cur = LLSpellChecker::instance().getPrimaryDictionary(); + } + dict_combo->clearRows(); + + const LLSD& dict_map = LLSpellChecker::getDictionaryMap(); + if (dict_map.size()) + { + for (LLSD::array_const_iterator dict_it = dict_map.beginArray(); dict_it != dict_map.endArray(); ++dict_it) + { + const LLSD& dict = *dict_it; + if ( (dict["installed"].asBoolean()) && (dict["is_primary"].asBoolean()) && (dict.has("language")) ) + { + dict_combo->add(dict["language"].asString()); + } + } + if (!dict_combo->selectByValue(dict_cur)) + { + dict_combo->clear(); + } + } + dict_combo->sortByName(); + dict_combo->setEnabled(enabled); + + // Populate the available and active dictionary list + LLScrollListCtrl* avail_ctrl = findChild<LLScrollListCtrl>("spellcheck_available_list"); + LLScrollListCtrl* active_ctrl = findChild<LLScrollListCtrl>("spellcheck_active_list"); + + LLSpellChecker::dict_list_t active_list; + if ( ((!avail_ctrl->getItemCount()) && (!active_ctrl->getItemCount())) || (from_settings) ) + { + if (LLSpellChecker::getUseSpellCheck()) + { + active_list = LLSpellChecker::instance().getSecondaryDictionaries(); + } + } + else + { + std::vector<LLScrollListItem*> active_items = active_ctrl->getAllData(); + for (std::vector<LLScrollListItem*>::const_iterator item_it = active_items.begin(); item_it != active_items.end(); ++item_it) + { + std::string dict = (*item_it)->getValue().asString(); + if (dict_cur != dict) + { + active_list.push_back(dict); + } + } + } + + LLSD row; + row["columns"][0]["column"] = "name"; + + active_ctrl->clearRows(); + active_ctrl->setEnabled(enabled); + for (LLSpellChecker::dict_list_t::const_iterator it = active_list.begin(); it != active_list.end(); ++it) + { + const std::string language = *it; + const LLSD dict = LLSpellChecker::getDictionaryData(language); + row["value"] = language; + row["columns"][0]["value"] = (!dict["user_installed"].asBoolean()) ? language : language + " " + LLTrans::getString("UserDictionary"); + active_ctrl->addElement(row); + } + active_ctrl->sortByColumnIndex(0, true); + active_list.push_back(dict_cur); + + avail_ctrl->clearRows(); + avail_ctrl->setEnabled(enabled); + for (LLSD::array_const_iterator dict_it = dict_map.beginArray(); dict_it != dict_map.endArray(); ++dict_it) + { + const LLSD& dict = *dict_it; + const std::string language = dict["language"].asString(); + if ( (dict["installed"].asBoolean()) && (active_list.end() == std::find(active_list.begin(), active_list.end(), language)) ) + { + row["value"] = language; + row["columns"][0]["value"] = (!dict["user_installed"].asBoolean()) ? language : language + " " + LLTrans::getString("UserDictionary"); + avail_ctrl->addElement(row); + } + } + avail_ctrl->sortByColumnIndex(0, true); +} + +///---------------------------------------------------------------------------- +/// Class LLFloaterSpellCheckerImport +///---------------------------------------------------------------------------- +LLFloaterSpellCheckerImport::LLFloaterSpellCheckerImport(const LLSD& key) + : LLFloater(key) +{ +} + +BOOL LLFloaterSpellCheckerImport::postBuild(void) +{ + getChild<LLUICtrl>("dictionary_path_browse")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerImport::onBtnBrowse, this)); + getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerImport::onBtnOK, this)); + getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerImport::onBtnCancel, this)); + center(); + return true; +} + +void LLFloaterSpellCheckerImport::onBtnBrowse() +{ + LLFilePicker& file_picker = LLFilePicker::instance(); + if (!file_picker.getOpenFile(LLFilePicker::FFLOAD_DICTIONARY)) + { + return; + } + + std::string filepath = file_picker.getFirstFile(); + + const std::string extension = gDirUtilp->getExtension(filepath); + if ("xcu" == extension) + { + filepath = parseXcuFile(filepath); + if (filepath.empty()) + { + return; + } + } + + getChild<LLUICtrl>("dictionary_path")->setValue(filepath); + + mDictionaryDir = gDirUtilp->getDirName(filepath); + mDictionaryBasename = gDirUtilp->getBaseFileName(filepath, true); + getChild<LLUICtrl>("dictionary_name")->setValue(mDictionaryBasename); +} + +void LLFloaterSpellCheckerImport::onBtnCancel() +{ + closeFloater(false); +} + +void LLFloaterSpellCheckerImport::onBtnOK() +{ + const std::string dict_dic = mDictionaryDir + gDirUtilp->getDirDelimiter() + mDictionaryBasename + ".dic"; + const std::string dict_aff = mDictionaryDir + gDirUtilp->getDirDelimiter() + mDictionaryBasename + ".aff"; + std::string dict_language = getChild<LLUICtrl>("dictionary_language")->getValue().asString(); + LLStringUtil::trim(dict_language); + + bool imported = false; + if ( dict_language.empty() + || mDictionaryDir.empty() + || mDictionaryBasename.empty() + || ! gDirUtilp->fileExists(dict_dic) + ) + { + LLNotificationsUtil::add("SpellingDictImportRequired"); + } + else + { + std::string settings_dic = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".dic"; + if ( copyFile( dict_dic, settings_dic ) ) + { + if (gDirUtilp->fileExists(dict_aff)) + { + std::string settings_aff = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".aff"; + if (copyFile( dict_aff, settings_aff )) + { + imported = true; + } + else + { + LLSD args = LLSD::emptyMap(); + args["FROM_NAME"] = dict_aff; + args["TO_NAME"] = settings_aff; + LLNotificationsUtil::add("SpellingDictImportFailed", args); + } + } + else + { + LLSD args = LLSD::emptyMap(); + args["DIC_NAME"] = dict_dic; + LLNotificationsUtil::add("SpellingDictIsSecondary", args); + + imported = true; + } + } + else + { + LLSD args = LLSD::emptyMap(); + args["FROM_NAME"] = dict_dic; + args["TO_NAME"] = settings_dic; + LLNotificationsUtil::add("SpellingDictImportFailed", args); + } + } + + if ( imported ) + { + LLSD custom_dict_info; + custom_dict_info["is_primary"] = (bool)gDirUtilp->fileExists(dict_aff); + custom_dict_info["name"] = mDictionaryBasename; + custom_dict_info["language"] = dict_language; + + LLSD custom_dict_map; + llifstream custom_file_in(LLSpellChecker::getDictionaryUserPath() + "user_dictionaries.xml"); + if (custom_file_in.is_open()) + { + LLSDSerialize::fromXMLDocument(custom_dict_map, custom_file_in); + custom_file_in.close(); + } + + LLSD::array_iterator it = custom_dict_map.beginArray(); + for (; it != custom_dict_map.endArray(); ++it) + { + LLSD& dict_info = *it; + if (dict_info["name"].asString() == mDictionaryBasename) + { + dict_info = custom_dict_info; + break; + } + } + if (custom_dict_map.endArray() == it) + { + custom_dict_map.append(custom_dict_info); + } + + llofstream custom_file_out(LLSpellChecker::getDictionaryUserPath() + "user_dictionaries.xml", std::ios::trunc); + if (custom_file_out.is_open()) + { + LLSDSerialize::toPrettyXML(custom_dict_map, custom_file_out); + custom_file_out.close(); + } + + LLSpellChecker::refreshDictionaryMap(); + } + + closeFloater(false); +} + +bool LLFloaterSpellCheckerImport::copyFile(const std::string from, const std::string to) +{ + bool copied = false; + LLFILE* in = LLFile::fopen(from, "rb"); /* Flawfinder: ignore */ + if (in) + { + LLFILE* out = LLFile::fopen(to, "wb"); /* Flawfinder: ignore */ + if (out) + { + char buf[16384]; /* Flawfinder: ignore */ + size_t readbytes; + bool write_ok = true; + while(write_ok && (readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */ + { + if (fwrite(buf, 1, readbytes, out) != readbytes) + { + LL_WARNS("SpellCheck") << "Short write" << LL_ENDL; + write_ok = false; + } + } + if ( write_ok ) + { + copied = true; + } + fclose(out); + } + } + fclose(in); + return copied; +} + +std::string LLFloaterSpellCheckerImport::parseXcuFile(const std::string& file_path) const +{ + LLXMLNodePtr xml_root; + if ( (!LLUICtrlFactory::getLayeredXMLNode(file_path, xml_root)) || (xml_root.isNull()) ) + { + return LLStringUtil::null; + } + + // Bury down to the "Dictionaries" parent node + LLXMLNode* dict_node = NULL; + for (LLXMLNode* outer_node = xml_root->getFirstChild(); outer_node && !dict_node; outer_node = outer_node->getNextSibling()) + { + std::string temp; + if ( (outer_node->getAttributeString("oor:name", temp)) && ("ServiceManager" == temp) ) + { + for (LLXMLNode* inner_node = outer_node->getFirstChild(); inner_node && !dict_node; inner_node = inner_node->getNextSibling()) + { + if ( (inner_node->getAttributeString("oor:name", temp)) && ("Dictionaries" == temp) ) + { + dict_node = inner_node; + break; + } + } + } + } + + if (dict_node) + { + // Iterate over all child nodes until we find one that has a <value>DICT_SPELL</value> node + for (LLXMLNode* outer_node = dict_node->getFirstChild(); outer_node; outer_node = outer_node->getNextSibling()) + { + std::string temp; + LLXMLNodePtr location_node, format_node; + for (LLXMLNode* inner_node = outer_node->getFirstChild(); inner_node; inner_node = inner_node->getNextSibling()) + { + if (inner_node->getAttributeString("oor:name", temp)) + { + if ("Locations" == temp) + { + inner_node->getChild("value", location_node, false); + } + else if ("Format" == temp) + { + inner_node->getChild("value", format_node, false); + } + } + } + if ( (format_node.isNull()) || ("DICT_SPELL" != format_node->getValue()) || (location_node.isNull()) ) + { + continue; + } + + // Found a list of file locations, return the .dic (if present) + std::list<std::string> location_list; + boost::split(location_list, location_node->getValue(), boost::is_any_of(std::string(" "))); + for (std::list<std::string>::iterator it = location_list.begin(); it != location_list.end(); ++it) + { + std::string& location = *it; + if ("\\" != gDirUtilp->getDirDelimiter()) + LLStringUtil::replaceString(location, "\\", gDirUtilp->getDirDelimiter()); + else + LLStringUtil::replaceString(location, "/", gDirUtilp->getDirDelimiter()); + LLStringUtil::replaceString(location, "%origin%", gDirUtilp->getDirName(file_path)); + if ("dic" == gDirUtilp->getExtension(location)) + { + return location; + } + } + } + } + + return LLStringUtil::null; +} diff --git a/indra/newview/llfloaterspellchecksettings.h b/indra/newview/llfloaterspellchecksettings.h new file mode 100644 index 0000000000..eded3a9133 --- /dev/null +++ b/indra/newview/llfloaterspellchecksettings.h @@ -0,0 +1,68 @@ +/** + * @file llfloaterspellchecksettings.h + * @brief Spell checker settings floater + * +* $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 LLFLOATERSPELLCHECKERSETTINGS_H +#define LLFLOATERSPELLCHECKERSETTINGS_H + +#include "llfloater.h" + +class LLFloaterSpellCheckerSettings : public LLFloater +{ +public: + LLFloaterSpellCheckerSettings(const LLSD& key); + + /*virtual*/ void draw(); + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void onClose(bool app_quitting); + +protected: + void onBtnImport(); + void onBtnMove(const std::string& from, const std::string& to); + void onBtnRemove(); + void onSpellCheckSettingsChange(); + void refreshDictionaries(bool from_settings); +}; + +class LLFloaterSpellCheckerImport : public LLFloater +{ +public: + LLFloaterSpellCheckerImport(const LLSD& key); + + /*virtual*/ BOOL postBuild(); + +protected: + void onBtnBrowse(); + void onBtnCancel(); + void onBtnOK(); + bool copyFile(const std::string from, const std::string to); + std::string parseXcuFile(const std::string& file_path) const; + + std::string mDictionaryDir; + std::string mDictionaryBasename; +}; + +#endif // LLFLOATERSPELLCHECKERSETTINGS_H diff --git a/indra/newview/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp new file mode 100644 index 0000000000..9a23d99802 --- /dev/null +++ b/indra/newview/llfloatertexturefetchdebugger.cpp @@ -0,0 +1,472 @@ +/** + * @file llfloatertexturefetchdebugger.cpp + * @brief LLFloaterTextureFetchDebugger class definition + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "llfloatertexturefetchdebugger.h" + +#include "lluictrlfactory.h" +#include "llbutton.h" +#include "llspinctrl.h" +#include "llresmgr.h" + +#include "llmath.h" +#include "llviewerwindow.h" +#include "llappviewer.h" +#include "lltexturefetch.h" +#include "llviewercontrol.h" + +LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key) + : LLFloater(key), + mDebugger(NULL) +{ + setTitle("Texture Fetching Debugger Floater"); + + mCommitCallbackRegistrar.add("TexFetchDebugger.ChangeTexelPixelRatio", boost::bind(&LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio, this)); + + mCommitCallbackRegistrar.add("TexFetchDebugger.Start", boost::bind(&LLFloaterTextureFetchDebugger::onClickStart, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.Clear", boost::bind(&LLFloaterTextureFetchDebugger::onClickClear, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.Close", boost::bind(&LLFloaterTextureFetchDebugger::onClickClose, this)); + + mCommitCallbackRegistrar.add("TexFetchDebugger.CacheRead", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheRead, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.CacheWrite", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheWrite, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.HTTPLoad", boost::bind(&LLFloaterTextureFetchDebugger::onClickHTTPLoad, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.Decode", boost::bind(&LLFloaterTextureFetchDebugger::onClickDecode, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.GLTexture", boost::bind(&LLFloaterTextureFetchDebugger::onClickGLTexture, this)); + + mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllCache, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP, this)); +} +//---------------------------------------------- + +BOOL LLFloaterTextureFetchDebugger::postBuild(void) +{ + mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger(); + mStartStatus = (S32)LLTextureFetchDebugger::IDLE; + + //set states for buttons + mButtonStateMap["start_btn"] = true; + mButtonStateMap["close_btn"] = true; + mButtonStateMap["clear_btn"] = true; + mButtonStateMap["cacheread_btn"] = false; + mButtonStateMap["cachewrite_btn"] = false; + mButtonStateMap["http_btn"] = false; + mButtonStateMap["decode_btn"] = false; + mButtonStateMap["gl_btn"] = false; + + mButtonStateMap["refetchviscache_btn"] = false; + mButtonStateMap["refetchvishttp_btn"] = false; + mButtonStateMap["refetchallcache_btn"] = false; + mButtonStateMap["refetchallhttp_btn"] = false; + + updateButtons(); + + getChild<LLUICtrl>("texel_pixel_ratio")->setValue(gSavedSettings.getF32("TexelPixelRatio")); + + return TRUE ; +} + +LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger() +{ + //stop everything + mDebugger->setStopDebug(); +} + +void LLFloaterTextureFetchDebugger::updateButtons() +{ + for(std::map<std::string, bool>::iterator iter = mButtonStateMap.begin(); iter != mButtonStateMap.end(); ++iter) + { + if(iter->second) + { + childEnable(iter->first.c_str()); + } + else + { + childDisable(iter->first.c_str()); + } + } +} + +void LLFloaterTextureFetchDebugger::disableButtons() +{ + childDisable("start_btn"); + childDisable("clear_btn"); + childDisable("cacheread_btn"); + childDisable("cachewrite_btn"); + childDisable("http_btn"); + childDisable("decode_btn"); + childDisable("gl_btn"); + childDisable("refetchviscache_btn"); + childDisable("refetchvishttp_btn"); + childDisable("refetchallcache_btn"); + childDisable("refetchallhttp_btn"); +} +void LLFloaterTextureFetchDebugger::setStartStatus(S32 status) +{ + llassert_always(LLTextureFetchDebugger::IDLE == (LLTextureFetchDebugger::e_debug_state)mStartStatus) ; + mStartStatus = status; +} + +bool LLFloaterTextureFetchDebugger::idleStart() +{ + if(mStartStatus != (S32)LLTextureFetchDebugger::IDLE) + { + mDebugger->startWork((LLTextureFetchDebugger::e_debug_state)mStartStatus); + mStartStatus = (S32)LLTextureFetchDebugger::IDLE; + return true; + } + + return false; +} + +void LLFloaterTextureFetchDebugger::idle() +{ + if(idleStart()) + { + return; + } + + const F32 max_time = 0.005f; //5ms + LLTextureFetchDebugger::e_debug_state state = mDebugger->getState(); + if(mDebugger->update(max_time)) + { + switch(state) + { + case LLTextureFetchDebugger::IDLE: + break; + case LLTextureFetchDebugger::START_DEBUG: + mButtonStateMap["cacheread_btn"] = true; + mButtonStateMap["http_btn"] = true; + mButtonStateMap["refetchviscache_btn"] = true; + mButtonStateMap["refetchvishttp_btn"] = true; + mButtonStateMap["refetchallcache_btn"] = true; + mButtonStateMap["refetchallhttp_btn"] = true; + break; + case LLTextureFetchDebugger::READ_CACHE: + mButtonStateMap["decode_btn"] = true; + break; + case LLTextureFetchDebugger::WRITE_CACHE: + break; + case LLTextureFetchDebugger::DECODING: + mButtonStateMap["gl_btn"] = true; + break; + case LLTextureFetchDebugger::HTTP_FETCHING: + mButtonStateMap["cacheread_btn"] = true; + mButtonStateMap["cachewrite_btn"] = true; + mButtonStateMap["decode_btn"] = true; + break; + case LLTextureFetchDebugger::GL_TEX: + break; + case LLTextureFetchDebugger::REFETCH_VIS_CACHE: + break; + case LLTextureFetchDebugger::REFETCH_VIS_HTTP: + break; + case LLTextureFetchDebugger::REFETCH_ALL_CACHE: + break; + case LLTextureFetchDebugger::REFETCH_ALL_HTTP: + break; + default: + break; + } + + if(state != LLTextureFetchDebugger::IDLE) + { + updateButtons(); + } + } +} + +//---------------------- +void LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio() +{ + gSavedSettings.setF32("TexelPixelRatio", getChild<LLUICtrl>("texel_pixel_ratio")->getValue().asReal()); +} + +void LLFloaterTextureFetchDebugger::onClickStart() +{ + disableButtons(); + + setStartStatus((S32)LLTextureFetchDebugger::START_DEBUG); + + mButtonStateMap["start_btn"] = false; + + updateButtons(); +} + +void LLFloaterTextureFetchDebugger::onClickClose() +{ + setVisible(FALSE); + + //stop everything + mDebugger->setStopDebug(); + + delete this; +} + +void LLFloaterTextureFetchDebugger::onClickClear() +{ + mButtonStateMap["start_btn"] = true; + mButtonStateMap["close_btn"] = true; + mButtonStateMap["clear_btn"] = true; + mButtonStateMap["cacheread_btn"] = false; + mButtonStateMap["cachewrite_btn"] = false; + mButtonStateMap["http_btn"] = false; + mButtonStateMap["decode_btn"] = false; + mButtonStateMap["gl_btn"] = false; + mButtonStateMap["refetchviscache_btn"] = true; + mButtonStateMap["refetchvishttp_btn"] = true; + updateButtons(); + + //stop everything + mDebugger->setStopDebug(); + mDebugger->clearHistory(); +} + +void LLFloaterTextureFetchDebugger::onClickCacheRead() +{ + disableButtons(); + + setStartStatus((S32)LLTextureFetchDebugger::READ_CACHE); +} + +void LLFloaterTextureFetchDebugger::onClickCacheWrite() +{ + disableButtons(); + + setStartStatus((S32)LLTextureFetchDebugger::WRITE_CACHE); +} + +void LLFloaterTextureFetchDebugger::onClickHTTPLoad() +{ + disableButtons(); + + setStartStatus((S32)LLTextureFetchDebugger::HTTP_FETCHING); +} + +void LLFloaterTextureFetchDebugger::onClickDecode() +{ + disableButtons(); + + setStartStatus((S32)LLTextureFetchDebugger::DECODING); +} + +void LLFloaterTextureFetchDebugger::onClickGLTexture() +{ + disableButtons(); + + setStartStatus((S32)LLTextureFetchDebugger::GL_TEX); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchVisCache() +{ + disableButtons(); + + setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_CACHE); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP() +{ + disableButtons(); + + setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_HTTP); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchAllCache() +{ + disableButtons(); + + setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_CACHE); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP() +{ + disableButtons(); + + setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_HTTP); +} + +void LLFloaterTextureFetchDebugger::draw() +{ + //total number of fetched textures + { + getChild<LLUICtrl>("total_num_fetched_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchedTextures())); + } + + //total number of fetching requests + { + getChild<LLUICtrl>("total_num_fetching_requests_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchingRequests())); + } + + //total number of cache hits + { + getChild<LLUICtrl>("total_num_cache_hits_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumCacheHits())); + } + + //total number of visible textures + { + getChild<LLUICtrl>("total_num_visible_tex_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchedTextures())); + } + + //total number of visible texture fetching requests + { + getChild<LLUICtrl>("total_num_visible_tex_fetch_req_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchingRequests())); + } + + //total number of fetched data + { + getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getFetchedData() >> 10)); + getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getDecodedData() >> 10)); + getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getFetchedPixels() / 1000000.f)); + } + + //total number of visible fetched data + { + getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getVisibleFetchedData() >> 10)); + getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getVisibleDecodedData() >> 10)); + } + + //total number of rendered fetched data + { + getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getRenderedData() >> 10)); + getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getRenderedDecodedData() >> 10)); + getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRenderedPixels() / 1000000.f)); + } + + //total time on cache readings + if(mDebugger->getCacheReadTime() < 0.f) + { + getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheReadTime())); + } + + //total time on cache writings + if(mDebugger->getCacheWriteTime() < 0.f) + { + getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheWriteTime())); + } + + //total time on decoding + if(mDebugger->getDecodeTime() < 0.f) + { + getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getDecodeTime())); + } + + //total time on gl texture creation + if(mDebugger->getGLCreationTime() < 0.f) + { + getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getGLCreationTime())); + } + + //total time on HTTP fetching + if(mDebugger->getHTTPTime() < 0.f) + { + getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getHTTPTime())); + } + + //total time on entire fetching + { + getChild<LLUICtrl>("total_time_fetch_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getTotalFetchingTime())); + } + + //total time on refetching visible textures from cache + if(mDebugger->getRefetchVisCacheTime() < 0.f) + { + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisCacheTime())); + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10)); + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f)); + } + + //total time on refetching all textures from cache + if(mDebugger->getRefetchAllCacheTime() < 0.f) + { + getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllCacheTime())); + getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10)); + getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f)); + } + + //total time on refetching visible textures from http + if(mDebugger->getRefetchVisHTTPTime() < 0.f) + { + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisHTTPTime())); + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10)); + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f)); + } + + //total time on refetching all textures from http + if(mDebugger->getRefetchAllHTTPTime() < 0.f) + { + getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllHTTPTime())); + getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10)); + getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f)); + } + + LLFloater::draw(); +} diff --git a/indra/newview/llfloatertexturefetchdebugger.h b/indra/newview/llfloatertexturefetchdebugger.h new file mode 100644 index 0000000000..096ad88e07 --- /dev/null +++ b/indra/newview/llfloatertexturefetchdebugger.h @@ -0,0 +1,76 @@ +/** + * @file llfloatertexturefetchdebugger.h + * @brief texture fetching debugger window, debug use only + * + * $LicenseInfo:firstyear=2004&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_FLOATER_TEXTURE_FETCH_DEBUGGER__H +#define LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H + +#include "llfloater.h" +class LLTextureFetchDebugger; + +class LLFloaterTextureFetchDebugger : public LLFloater +{ + friend class LLFloaterReg; +public: + /// initialize all the callbacks for the menu + + virtual BOOL postBuild() ; + virtual void draw() ; + + void onChangeTexelPixelRatio(); + + void onClickStart(); + void onClickClear(); + void onClickClose(); + + void onClickCacheRead(); + void onClickCacheWrite(); + void onClickHTTPLoad(); + void onClickDecode(); + void onClickGLTexture(); + + void onClickRefetchVisCache(); + void onClickRefetchVisHTTP(); + void onClickRefetchAllCache(); + void onClickRefetchAllHTTP(); +public: + void idle() ; + +private: + LLFloaterTextureFetchDebugger(const LLSD& key); + virtual ~LLFloaterTextureFetchDebugger(); + + void updateButtons(); + void disableButtons(); + + void setStartStatus(S32 status); + bool idleStart(); +private: + LLTextureFetchDebugger* mDebugger; + std::map<std::string, bool> mButtonStateMap; + S32 mStartStatus; +}; + +#endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 1008b4a6e4..14923eec3c 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -36,6 +36,7 @@ #include "llagentcamera.h" #include "llbutton.h" #include "llcheckboxctrl.h" +#include "llcombobox.h" #include "lldraghandle.h" #include "llerror.h" #include "llfloaterbuildoptions.h" @@ -103,14 +104,12 @@ const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] = // Local prototypes +void commit_grid_mode(LLUICtrl *ctrl); void commit_select_component(void *data); void click_show_more(void*); void click_popup_info(void*); void click_popup_done(void*); void click_popup_minimize(void*); -void click_popup_rotate_left(void*); -void click_popup_rotate_reset(void*); -void click_popup_rotate_right(void*); void commit_slider_dozer_force(LLUICtrl *); void click_apply_to_selection(void*); void commit_radio_group_focus(LLUICtrl* ctrl); @@ -252,6 +251,7 @@ BOOL LLFloaterTools::postBuild() getChild<LLUICtrl>("checkbox uniform")->setValue((BOOL)gSavedSettings.getBOOL("ScaleUniform")); mCheckStretchTexture = getChild<LLCheckBoxCtrl>("checkbox stretch textures"); getChild<LLUICtrl>("checkbox stretch textures")->setValue((BOOL)gSavedSettings.getBOOL("ScaleStretchTextures")); + mComboGridMode = getChild<LLComboBox>("combobox grid mode"); mCheckStretchUniformLabel = getChild<LLTextBox>("checkbox uniform label"); // @@ -330,6 +330,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key) mCheckSnapToGrid(NULL), mBtnGridOptions(NULL), mTitleMedia(NULL), + mComboGridMode(NULL), mCheckStretchUniform(NULL), mCheckStretchTexture(NULL), mCheckStretchUniformLabel(NULL), @@ -386,6 +387,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key) mCommitCallbackRegistrar.add("BuildTool.commitRadioMove", boost::bind(&commit_radio_group_move,_1)); mCommitCallbackRegistrar.add("BuildTool.commitRadioEdit", boost::bind(&commit_radio_group_edit,_1)); + mCommitCallbackRegistrar.add("BuildTool.gridMode", boost::bind(&commit_grid_mode,_1)); mCommitCallbackRegistrar.add("BuildTool.selectComponent", boost::bind(&commit_select_component, this)); mCommitCallbackRegistrar.add("BuildTool.gridOptions", boost::bind(&LLFloaterTools::onClickGridOptions,this)); mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this)); @@ -529,7 +531,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(); @@ -655,8 +657,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mBtnEdit ->setToggleState( edit_visible ); mRadioGroupEdit->setVisible( edit_visible ); - bool linked_parts = gSavedSettings.getBOOL("EditLinkedParts"); - getChildView("RenderingCost")->setVisible( !linked_parts && (edit_visible || focus_visible || move_visible) && sShowObjectCost); + //bool linked_parts = gSavedSettings.getBOOL("EditLinkedParts"); + //getChildView("RenderingCost")->setVisible( !linked_parts && (edit_visible || focus_visible || move_visible) && sShowObjectCost); mBtnLink->setVisible(edit_visible); mBtnUnlink->setVisible(edit_visible); @@ -687,6 +689,33 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mRadioGroupEdit->setValue("radio select face"); } + if (mComboGridMode) + { + mComboGridMode->setVisible( edit_visible ); + S32 index = mComboGridMode->getCurrentIndex(); + mComboGridMode->removeall(); + + switch (mObjectSelection->getSelectType()) + { + case SELECT_TYPE_HUD: + mComboGridMode->add(getString("grid_screen_text")); + mComboGridMode->add(getString("grid_local_text")); + break; + case SELECT_TYPE_WORLD: + mComboGridMode->add(getString("grid_world_text")); + mComboGridMode->add(getString("grid_local_text")); + mComboGridMode->add(getString("grid_reference_text")); + break; + case SELECT_TYPE_ATTACHMENT: + mComboGridMode->add(getString("grid_attachment_text")); + mComboGridMode->add(getString("grid_local_text")); + mComboGridMode->add(getString("grid_reference_text")); + break; + } + + mComboGridMode->setCurrentByIndex(index); + } + // Snap to grid disabled for grab tool - very confusing if (mCheckSnapToGrid) mCheckSnapToGrid->setVisible( edit_visible /* || tool == LLToolGrab::getInstance() */ ); if (mBtnGridOptions) mBtnGridOptions->setVisible( edit_visible /* || tool == LLToolGrab::getInstance() */ ); @@ -922,24 +951,6 @@ void commit_slider_zoom(LLUICtrl *ctrl) gAgentCamera.setCameraZoomFraction(zoom_level); } -void click_popup_rotate_left(void*) -{ - LLSelectMgr::getInstance()->selectionRotateAroundZ( 45.f ); - dialog_refresh_all(); -} - -void click_popup_rotate_reset(void*) -{ - LLSelectMgr::getInstance()->selectionResetRotation(); - dialog_refresh_all(); -} - -void click_popup_rotate_right(void*) -{ - LLSelectMgr::getInstance()->selectionRotateAroundZ( -45.f ); - dialog_refresh_all(); -} - void commit_slider_dozer_force(LLUICtrl *ctrl) { // the slider is logarithmic, so we exponentiate to get the actual force multiplier @@ -1037,6 +1048,24 @@ void LLFloaterTools::setObjectType( LLPCode pcode ) gFocusMgr.setMouseCapture(NULL); } +void commit_grid_mode(LLUICtrl *ctrl) +{ + LLComboBox* combo = (LLComboBox*)ctrl; + + LLSelectMgr::getInstance()->setGridMode((EGridMode)combo->getCurrentIndex()); +} + +// static +void LLFloaterTools::setGridMode(S32 mode) +{ + LLFloaterTools* tools_floater = LLFloaterReg::getTypedInstance<LLFloaterTools>("build"); + if (!tools_floater || !tools_floater->mComboGridMode) + { + return; + } + + tools_floater->mComboGridMode->setCurrentByIndex(mode); +} void LLFloaterTools::onClickGridOptions() { @@ -1144,7 +1173,7 @@ void LLFloaterTools::updateLandImpacts() childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", remaining_capacity_str); // Update land impacts info in the 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->updateLandImpacts(parcel); @@ -1179,7 +1208,10 @@ void LLFloaterTools::getMediaState() return; } - bool editable = (first_object->permModify() || selectedMediaEditable()); + BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode() + && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced()) + || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced(); + bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable()); // Check modify permissions and whether any selected objects are in // the process of being fetched. If they are, then we're not editable @@ -1234,6 +1266,7 @@ void LLFloaterTools::getMediaState() } } func; + // check if all faces have media(or, all dont have media) LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media ); @@ -1409,9 +1442,7 @@ bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& re // void LLFloaterTools::clearMediaSettings() { - LLFloaterMediaSettings::getInstance(); LLFloaterMediaSettings::clearValues(false); - } ////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index 63ed9dc82b..ecb0092a6f 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -33,6 +33,7 @@ class LLButton; class LLCheckBoxCtrl; +class LLComboBox; class LLPanelPermissions; class LLPanelObject; class LLPanelVolume; @@ -106,6 +107,8 @@ public: bool selectedMediaEditable(); void updateLandImpacts(); + static void setGridMode(S32 mode); + private: void refresh(); void refreshMedia(); @@ -140,6 +143,7 @@ public: LLCheckBoxCtrl* mCheckSnapToGrid; LLButton* mBtnGridOptions; + LLComboBox* mComboGridMode; LLCheckBoxCtrl* mCheckStretchUniform; LLCheckBoxCtrl* mCheckStretchTexture; diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index 87d048c15b..7530c72dd2 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -82,6 +82,7 @@ LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key) mCommitCallbackRegistrar.add("TopObjects.Refresh", boost::bind(&LLFloaterTopObjects::onRefresh, this)); mCommitCallbackRegistrar.add("TopObjects.GetByObjectName", boost::bind(&LLFloaterTopObjects::onGetByObjectName, this)); mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName", boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this)); + mCommitCallbackRegistrar.add("TopObjects.GetByParcelName", boost::bind(&LLFloaterTopObjects::onGetByParcelName, this)); mCommitCallbackRegistrar.add("TopObjects.CommitObjectsList",boost::bind(&LLFloaterTopObjects::onCommitObjectsList, this)); } @@ -99,21 +100,6 @@ BOOL LLFloaterTopObjects::postBuild() setDefaultBtn("show_beacon_btn"); - /* - LLLineEditor* line_editor = getChild<LLLineEditor>("owner_name_editor"); - if (line_editor) - { - line_editor->setCommitOnFocusLost(FALSE); - line_editor->setCommitCallback(onGetByOwnerName, this); - } - - line_editor = getChild<LLLineEditor>("object_name_editor"); - if (line_editor) - { - line_editor->setCommitOnFocusLost(FALSE); - line_editor->setCommitCallback(onGetByObjectName, this); - }*/ - mCurrentMode = STAT_REPORT_TOP_SCRIPTS; mFlags = 0; mFilter.clear(); @@ -168,9 +154,11 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) F32 score; std::string name_buf; std::string owner_buf; + std::string parcel_buf("unknown"); F32 mono_score = 0.f; bool have_extended_data = false; S32 public_urls = 0; + F32 script_memory = 0.f; msg->getU32Fast(_PREHASH_ReportData, _PREHASH_TaskLocalID, task_local_id, block); msg->getUUIDFast(_PREHASH_ReportData, _PREHASH_TaskID, task_id, block); @@ -180,12 +168,18 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) msg->getF32Fast(_PREHASH_ReportData, _PREHASH_Score, score, block); msg->getStringFast(_PREHASH_ReportData, _PREHASH_TaskName, name_buf, block); msg->getStringFast(_PREHASH_ReportData, _PREHASH_OwnerName, owner_buf, block); + if(msg->has("DataExtended")) { have_extended_data = true; msg->getU32("DataExtended", "TimeStamp", time_stamp, block); msg->getF32("DataExtended", "MonoScore", mono_score, block); msg->getS32("DataExtended", "PublicURLs", public_urls, block); + if (msg->getSize("DataExtended", "ParcelName") > 0) + { + msg->getString("DataExtended", "ParcelName", parcel_buf, block); + msg->getF32("DataExtended", "Size", script_memory, block); + } } LLSD element; @@ -193,50 +187,48 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) element["id"] = task_id; LLSD columns; - columns[0]["column"] = "score"; - columns[0]["value"] = llformat("%0.3f", score); - columns[0]["font"] = "SANSSERIF"; + S32 column_num = 0; + columns[column_num]["column"] = "score"; + columns[column_num]["value"] = llformat("%0.3f", score); + columns[column_num++]["font"] = "SANSSERIF"; - columns[1]["column"] = "name"; - columns[1]["value"] = name_buf; - columns[1]["font"] = "SANSSERIF"; + columns[column_num]["column"] = "name"; + columns[column_num]["value"] = name_buf; + columns[column_num++]["font"] = "SANSSERIF"; // Owner names can have trailing spaces sent from server LLStringUtil::trim(owner_buf); - if (LLAvatarNameCache::useDisplayNames()) - { - // ...convert hard-coded name from server to a username - // *TODO: Send owner_id from server and look up display name - owner_buf = LLCacheName::buildUsername(owner_buf); - } - else - { - // ...just strip out legacy "Resident" name - owner_buf = LLCacheName::cleanFullName(owner_buf); - } - columns[2]["column"] = "owner"; - columns[2]["value"] = owner_buf; - columns[2]["font"] = "SANSSERIF"; - - columns[3]["column"] = "location"; - columns[3]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z); - columns[3]["font"] = "SANSSERIF"; - columns[4]["column"] = "time"; - columns[4]["type"] = "date"; - columns[4]["value"] = LLDate((time_t)time_stamp); - columns[4]["font"] = "SANSSERIF"; + // *TODO: Send owner_id from server and look up display name + owner_buf = LLCacheName::buildUsername(owner_buf); + + columns[column_num]["column"] = "owner"; + columns[column_num]["value"] = owner_buf; + columns[column_num++]["font"] = "SANSSERIF"; + + columns[column_num]["column"] = "location"; + columns[column_num]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z); + columns[column_num++]["font"] = "SANSSERIF"; + + columns[column_num]["column"] = "parcel"; + columns[column_num]["value"] = parcel_buf; + columns[column_num++]["font"] = "SANSSERIF"; + + columns[column_num]["column"] = "time"; + columns[column_num]["type"] = "date"; + columns[column_num]["value"] = LLDate((time_t)time_stamp); + columns[column_num++]["font"] = "SANSSERIF"; if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS && have_extended_data) { - columns[5]["column"] = "mono_time"; - columns[5]["value"] = llformat("%0.3f", mono_score); - columns[5]["font"] = "SANSSERIF"; + columns[column_num]["column"] = "memory"; + columns[column_num]["value"] = llformat("%0.0f", (script_memory / 1000.f)); + columns[column_num++]["font"] = "SANSSERIF"; - columns[6]["column"] = "URLs"; - columns[6]["value"] = llformat("%d", public_urls); - columns[6]["font"] = "SANSSERIF"; + columns[column_num]["column"] = "URLs"; + columns[column_num]["value"] = llformat("%d", public_urls); + columns[column_num++]["font"] = "SANSSERIF"; } element["columns"] = columns; list->addElement(element); @@ -260,18 +252,18 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) { setTitle(getString("top_scripts_title")); list->setColumnLabel("score", getString("scripts_score_label")); - list->setColumnLabel("mono_time", getString("scripts_mono_time_label")); LLUIString format = getString("top_scripts_text"); format.setArg("[COUNT]", llformat("%d", total_count)); - format.setArg("[TIME]", llformat("%0.1f", mtotalScore)); + format.setArg("[TIME]", llformat("%0.3f", mtotalScore)); getChild<LLUICtrl>("title_text")->setValue(LLSD(format)); } else { setTitle(getString("top_colliders_title")); list->setColumnLabel("score", getString("colliders_score_label")); - list->setColumnLabel("mono_time", ""); + list->setColumnLabel("URLs", ""); + list->setColumnLabel("memory", ""); LLUIString format = getString("top_colliders_text"); format.setArg("[COUNT]", llformat("%d", total_count)); getChild<LLUICtrl>("title_text")->setValue(LLSD(format)); @@ -301,6 +293,7 @@ void LLFloaterTopObjects::updateSelectionInfo() { getChild<LLUICtrl>("object_name_editor")->setValue(sli->getColumn(1)->getValue().asString()); getChild<LLUICtrl>("owner_name_editor")->setValue(sli->getColumn(2)->getValue().asString()); + getChild<LLUICtrl>("parcel_name_editor")->setValue(sli->getColumn(4)->getValue().asString()); } } @@ -480,6 +473,15 @@ void LLFloaterTopObjects::onGetByOwnerName() onRefresh(); } + +void LLFloaterTopObjects::onGetByParcelName() +{ + mFlags = STAT_FILTER_BY_PARCEL_NAME; + mFilter = getChild<LLUICtrl>("parcel_name_editor")->getValue().asString(); + onRefresh(); +} + + void LLFloaterTopObjects::showBeacon() { LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list"); diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h index a608ca20f1..6edc46cf79 100644 --- a/indra/newview/llfloatertopobjects.h +++ b/indra/newview/llfloatertopobjects.h @@ -73,9 +73,7 @@ private: void onGetByOwnerName(); void onGetByObjectName(); - -// static void onGetByOwnerNameClicked(void* data) { onGetByOwnerName(NULL, data); }; -// static void onGetByObjectNameClicked(void* data) { onGetByObjectName(NULL, data); }; + void onGetByParcelName(); void showBeacon(); diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index c5df7e16e9..a242b224cd 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -71,9 +71,9 @@ class LLIamHere : public LLHTTPClient::Responder public: - static boost::intrusive_ptr< LLIamHere > build( LLFloaterTOS* parent ) + static LLIamHere* build( LLFloaterTOS* parent ) { - return boost::intrusive_ptr< LLIamHere >( new LLIamHere( parent ) ); + return new LLIamHere( parent ); }; virtual void setParent( LLFloaterTOS* parentIn ) @@ -102,7 +102,7 @@ class LLIamHere : public LLHTTPClient::Responder // this is global and not a class member to keep crud out of the header file namespace { - boost::intrusive_ptr< LLIamHere > gResponsePtr = 0; + LLPointer< LLIamHere > gResponsePtr = 0; }; BOOL LLFloaterTOS::postBuild() diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp index 959edff713..33f2c35239 100644 --- a/indra/newview/llfloatertranslationsettings.cpp +++ b/indra/newview/llfloatertranslationsettings.cpp @@ -29,6 +29,7 @@ #include "llfloatertranslationsettings.h" // Viewer includes +#include "llfloaterimnearbychat.h" #include "lltranslate.h" #include "llviewercontrol.h" // for gSavedSettings @@ -224,11 +225,10 @@ void LLFloaterTranslationSettings::updateControlsEnabledState() mGoogleVerifyBtn->setEnabled(on && google_selected && !mGoogleKeyVerified && !getEnteredGoogleKey().empty()); - mOKBtn->setEnabled( - !on || ( - (bing_selected && mBingKeyVerified) || - (google_selected && mGoogleKeyVerified) - )); + bool service_verified = (bing_selected && mBingKeyVerified) || (google_selected && mGoogleKeyVerified); + gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified); + + mOKBtn->setEnabled(!on || service_verified); } void LLFloaterTranslationSettings::verifyKey(int service, const std::string& key, bool alert) @@ -284,7 +284,16 @@ void LLFloaterTranslationSettings::onBtnGoogleVerify() verifyKey(LLTranslate::SERVICE_GOOGLE, key); } } +void LLFloaterTranslationSettings::onClose(bool app_quitting) +{ + std::string service = gSavedSettings.getString("TranslationService"); + bool bing_selected = service == "bing"; + bool google_selected = service == "google"; + + bool service_verified = (bing_selected && mBingKeyVerified) || (google_selected && mGoogleKeyVerified); + gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified); +} void LLFloaterTranslationSettings::onBtnOK() { gSavedSettings.setBOOL("TranslateChat", mMachineTranslationCB->getValue().asBoolean()); @@ -292,5 +301,7 @@ void LLFloaterTranslationSettings::onBtnOK() gSavedSettings.setString("TranslationService", getSelectedService()); gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey()); gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey()); + (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))-> + showTranslationCheckbox(LLTranslate::isTranslationConfigured()); closeFloater(false); } diff --git a/indra/newview/llfloatertranslationsettings.h b/indra/newview/llfloatertranslationsettings.h index 9b47ad72ed..b9bfd6265a 100644 --- a/indra/newview/llfloatertranslationsettings.h +++ b/indra/newview/llfloatertranslationsettings.h @@ -44,6 +44,7 @@ public: void setBingVerified(bool ok, bool alert); void setGoogleVerified(bool ok, bool alert); + void onClose(bool app_quitting); private: std::string getSelectedService() const; diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 4c9c4cb154..15e0b89f6c 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -137,7 +137,7 @@ public: virtual ~LLFloaterUIPreview(); std::string getLocStr(S32 ID); // fetches the localization string based on what is selected in the drop-down menu - void displayFloater(BOOL click, S32 ID, bool save = false); // needs to be public so live file can call it when it finds an update + void displayFloater(BOOL click, S32 ID); // needs to be public so live file can call it when it finds an update /*virtual*/ BOOL postBuild(); /*virtual*/ void onClose(bool app_quitting); @@ -291,7 +291,8 @@ LLLocalizationResetForcer::LLLocalizationResetForcer(LLFloaterUIPreview* floater { mSavedLocalization = LLUI::sSettingGroups["config"]->getString("Language"); // save current localization setting LLUI::sSettingGroups["config"]->setString("Language", floater->getLocStr(ID));// hack language to be the one we want to preview floaters in - LLUI::setupPaths(); // forcibly reset XUI paths with this new language + // forcibly reset XUI paths with this new language + gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), floater->getLocStr(ID)); } // Actually reset in destructor @@ -299,7 +300,8 @@ LLLocalizationResetForcer::LLLocalizationResetForcer(LLFloaterUIPreview* floater LLLocalizationResetForcer::~LLLocalizationResetForcer() { LLUI::sSettingGroups["config"]->setString("Language", mSavedLocalization); // reset language to what it was before we changed it - LLUI::setupPaths(); // forcibly reset XUI paths with this new language + // forcibly reset XUI paths with this new language + gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), mSavedLocalization); } // Live file constructor @@ -488,7 +490,7 @@ BOOL LLFloaterUIPreview::postBuild() { if((found = iter.next(language_directory))) // get next directory { - std::string full_path = xui_dir + language_directory; + std::string full_path = gDirUtilp->add(xui_dir, language_directory); if(LLFile::isfile(full_path.c_str())) // if it's not a directory, skip it { continue; @@ -773,7 +775,8 @@ void LLFloaterUIPreview::onClickDisplayFloater(S32 caller_id) // Saves the current floater/panel void LLFloaterUIPreview::onClickSaveFloater(S32 caller_id) { - displayFloater(TRUE, caller_id, true); + displayFloater(TRUE, caller_id); + popupAndPrintWarning("Save-floater functionality removed, use XML schema to clean up XUI files"); } // Saves all floater/panels @@ -784,25 +787,15 @@ void LLFloaterUIPreview::onClickSaveAll(S32 caller_id) for (int index = 0; index < listSize; index++) { mFileList->selectNthItem(index); - displayFloater(TRUE, caller_id, true); + displayFloater(TRUE, caller_id); } -} - -// Given path to floater or panel XML file "filename.xml", -// returns "filename_new.xml" -static std::string append_new_to_xml_filename(const std::string& path) -{ - std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), path); - std::string::size_type extension_pos = full_filename.rfind(".xml"); - full_filename.resize(extension_pos); - full_filename += "_new.xml"; - return full_filename; + popupAndPrintWarning("Save-floater functionality removed, use XML schema to clean up XUI files"); } // Actually display the floater // Only set up a new live file if this came from a click (at which point there should be no existing live file), rather than from the live file's update itself; // otherwise, we get an infinite loop as the live file keeps recreating itself. That means this function is generally called twice. -void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) +void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID) { // Convince UI that we're in a different language (the one selected on the drop-down menu) LLLocalizationResetForcer reset_forcer(this, ID); // save old language in reset forcer object (to be reset upon destruction when it falls out of scope) @@ -843,48 +836,13 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) if(!strncmp(path.c_str(),"floater_",8) || !strncmp(path.c_str(), "inspect_", 8)) // if it's a floater { - if (save) - { - LLXMLNodePtr floater_write = new LLXMLNode(); - (*floaterp)->buildFromFile(path, floater_write); // just build it - - if (!floater_write->isNull()) - { - std::string full_filename = append_new_to_xml_filename(path); - LLFILE* floater_temp = LLFile::fopen(full_filename.c_str(), "w"); - LLXMLNode::writeHeaderToFile(floater_temp); - const bool use_type_decorations = false; - floater_write->writeToFile(floater_temp, std::string(), use_type_decorations); - fclose(floater_temp); - } - } - else - { - (*floaterp)->buildFromFile(path); // just build it - (*floaterp)->openFloater((*floaterp)->getKey()); - (*floaterp)->setCanResize((*floaterp)->isResizable()); - } - + (*floaterp)->buildFromFile(path); // just build it + (*floaterp)->openFloater((*floaterp)->getKey()); + (*floaterp)->setCanResize((*floaterp)->isResizable()); } else if (!strncmp(path.c_str(),"menu_",5)) // if it's a menu { - if (save) - { - LLXMLNodePtr menu_write = new LLXMLNode(); - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(path, gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance(), menu_write); - - if (!menu_write->isNull()) - { - std::string full_filename = append_new_to_xml_filename(path); - LLFILE* menu_temp = LLFile::fopen(full_filename.c_str(), "w"); - LLXMLNode::writeHeaderToFile(menu_temp); - const bool use_type_decorations = false; - menu_write->writeToFile(menu_temp, std::string(), use_type_decorations); - fclose(menu_temp); - } - - delete menu; - } + // former 'save' processing excised } else // if it is a panel... { @@ -896,37 +854,21 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) LLPanel::Params panel_params; LLPanel* panel = LLUICtrlFactory::create<LLPanel>(panel_params); // create a new panel - if (save) - { - LLXMLNodePtr panel_write = new LLXMLNode(); - panel->buildFromFile(path, panel_write); // build it - - if (!panel_write->isNull()) - { - std::string full_filename = append_new_to_xml_filename(path); - LLFILE* panel_temp = LLFile::fopen(full_filename.c_str(), "w"); - LLXMLNode::writeHeaderToFile(panel_temp); - const bool use_type_decorations = false; - panel_write->writeToFile(panel_temp, std::string(), use_type_decorations); - fclose(panel_temp); - } - } - else - { - 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 - (*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 - 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?) - } + panel->buildFromFile(path); // build it + LLRect new_size = panel->getRect(); // get its rectangle + 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 + 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?) } if(ID == 1) @@ -962,7 +904,7 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) (*floaterp)->center(); addDependentFloater(*floaterp); - if(click && ID == 1 && !save) + if(click && ID == 1) { // set up live file to track it if(mLiveFile) diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp index 151cd2a1cd..e85d849c9a 100644 --- a/indra/newview/llfloaterurlentry.cpp +++ b/indra/newview/llfloaterurlentry.cpp @@ -219,7 +219,8 @@ void LLFloaterURLEntry::onBtnOK( void* userdata ) } // Discover the MIME type only for "http" scheme. - if(scheme == "http" || scheme == "https") + if(!media_url.empty() && + (scheme == "http" || scheme == "https")) { LLHTTPClient::getHeaderOnly( media_url, new LLMediaTypeResponder(self->getHandle())); diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp index 030fed0575..227720bee3 100644 --- a/indra/newview/llfloatervoiceeffect.cpp +++ b/indra/newview/llfloatervoiceeffect.cpp @@ -145,7 +145,9 @@ void LLFloaterVoiceEffect::refreshEffectList() for (voice_effect_list_t::const_iterator it = template_list.begin(); it != template_list.end(); ++it) { const LLUUID& effect_id = it->second; - std::string effect_name = getString("effect_" + it->first); // will throw an error if the effect is not listed in the XML + + std::string localized_effect = "effect_" + it->first; + std::string effect_name = hasString(localized_effect) ? getString(localized_effect) : it->first; // XML contains localized effects names LLSD effect_properties = effect_interface->getVoiceEffectProperties(effect_id); diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp new file mode 100644 index 0000000000..38446e46df --- /dev/null +++ b/indra/newview/llfloatervoicevolume.cpp @@ -0,0 +1,220 @@ +/** + * @file llfloatervoicevolume.cpp + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "llfloatervoicevolume.h" + +// Linden libraries +#include "llavatarname.h" +#include "llavatarnamecache.h" +#include "llfloater.h" +#include "llfloaterreg.h" +#include "lltextbox.h" + +// viewer files +#include "llagent.h" +#include "llavataractions.h" +#include "llinspect.h" +#include "lltransientfloatermgr.h" +#include "llvoiceclient.h" + +class LLAvatarName; + +////////////////////////////////////////////////////////////////////////////// +// LLFloaterVoiceVolume +////////////////////////////////////////////////////////////////////////////// + +// Avatar Inspector, a small information window used when clicking +// on avatar names in the 2D UI and in the ambient inspector widget for +// the 3D world. +class LLFloaterVoiceVolume : public LLInspect, LLTransientFloater +{ + friend class LLFloaterReg; + +public: + // avatar_id - Avatar ID for which to show information + // Inspector will be positioned relative to current mouse position + LLFloaterVoiceVolume(const LLSD& avatar_id); + virtual ~LLFloaterVoiceVolume(); + + /*virtual*/ BOOL postBuild(void); + + // Because floater is single instance, need to re-parse data on each spawn + // (for example, inspector about same avatar but in different position) + /*virtual*/ void onOpen(const LLSD& avatar_id); + + /*virtual*/ LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; } + +private: + // Set the volume slider to this user's current client-side volume setting, + // hiding/disabling if the user is not nearby. + void updateVolumeControls(); + + void onClickMuteVolume(); + void onVolumeChange(const LLSD& data); + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + +private: + LLUUID mAvatarID; + // Need avatar name information to spawn friend add request + LLAvatarName mAvatarName; + boost::signals2::connection mAvatarNameCacheConnection; +}; + +LLFloaterVoiceVolume::LLFloaterVoiceVolume(const LLSD& sd) +: LLInspect(LLSD()) // single_instance, doesn't really need key +, mAvatarID() // set in onOpen() *Note: we used to show partner's name but we dont anymore --angela 3rd Dec* +, mAvatarName() +, mAvatarNameCacheConnection() +{ + LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this); + LLTransientFloater::init(this); +} + +LLFloaterVoiceVolume::~LLFloaterVoiceVolume() +{ + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + LLTransientFloaterMgr::getInstance()->removeControlView(this); +} + +/*virtual*/ +BOOL LLFloaterVoiceVolume::postBuild(void) +{ + getChild<LLUICtrl>("mute_btn")->setCommitCallback( + boost::bind(&LLFloaterVoiceVolume::onClickMuteVolume, this) ); + + getChild<LLUICtrl>("volume_slider")->setCommitCallback( + boost::bind(&LLFloaterVoiceVolume::onVolumeChange, this, _2)); + + return TRUE; +} + + +// Multiple calls to showInstance("floater_voice_volume", foo) will provide different +// LLSD for foo, which we will catch here. +//virtual +void LLFloaterVoiceVolume::onOpen(const LLSD& data) +{ + // Start open animation + LLInspect::onOpen(data); + + // Extract appropriate avatar id + mAvatarID = data["avatar_id"]; + + LLUI::positionViewNearMouse(this); + + getChild<LLUICtrl>("avatar_name")->setValue(""); + updateVolumeControls(); + + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID, boost::bind(&LLFloaterVoiceVolume::onAvatarNameCache, this, _1, _2)); +} + +void LLFloaterVoiceVolume::updateVolumeControls() +{ + bool voice_enabled = LLVoiceClient::getInstance()->getVoiceEnabled(mAvatarID); + + LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn"); + LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider"); + + // Do not display volume slider and mute button if it + // is ourself or we are not in a voice channel together + if (!voice_enabled || (mAvatarID == gAgent.getID())) + { + mute_btn->setVisible(false); + volume_slider->setVisible(false); + } + else + { + mute_btn->setVisible(true); + volume_slider->setVisible(true); + + // By convention, we only display and toggle voice mutes, not all mutes + bool is_muted = LLAvatarActions::isVoiceMuted(mAvatarID); + bool is_linden = LLStringUtil::endsWith(mAvatarName.getUserName(), " Linden"); + + mute_btn->setEnabled(!is_linden); + mute_btn->setValue(is_muted); + + volume_slider->setEnabled(!is_muted); + + F32 volume; + if (is_muted) + { + // it's clearer to display their volume as zero + volume = 0.f; + } + else + { + // actual volume + volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID); + } + volume_slider->setValue((F64)volume); + } + +} + +void LLFloaterVoiceVolume::onClickMuteVolume() +{ + LLAvatarActions::toggleMuteVoice(mAvatarID); + updateVolumeControls(); +} + +void LLFloaterVoiceVolume::onVolumeChange(const LLSD& data) +{ + F32 volume = (F32)data.asReal(); + LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume); +} + +void LLFloaterVoiceVolume::onAvatarNameCache( + const LLUUID& agent_id, + const LLAvatarName& av_name) +{ + mAvatarNameCacheConnection.disconnect(); + + if (agent_id != mAvatarID) + { + return; + } + + getChild<LLUICtrl>("avatar_name")->setValue(av_name.getCompleteName()); + mAvatarName = av_name; +} + +////////////////////////////////////////////////////////////////////////////// +// LLFloaterVoiceVolumeUtil +////////////////////////////////////////////////////////////////////////////// +void LLFloaterVoiceVolumeUtil::registerFloater() +{ + LLFloaterReg::add("floater_voice_volume", "floater_voice_volume.xml", + &LLFloaterReg::build<LLFloaterVoiceVolume>); +} diff --git a/indra/newview/llfloatervoicevolume.h b/indra/newview/llfloatervoicevolume.h new file mode 100644 index 0000000000..8fcf7f250b --- /dev/null +++ b/indra/newview/llfloatervoicevolume.h @@ -0,0 +1,35 @@ +/** + * @file llfloatervoicevolume.h + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLFLOATERVOICEVOLUME_H +#define LL_LLFLOATERVOICEVOLUME_H + +namespace LLFloaterVoiceVolumeUtil +{ + // Register with LLFloaterReg + void registerFloater(); +} + +#endif // LL_LLFLOATERVOICEVOLUME_H diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp index f410c31f44..3fe2518de6 100644 --- a/indra/newview/llfloaterwebcontent.cpp +++ b/indra/newview/llfloaterwebcontent.cpp @@ -55,6 +55,15 @@ LLFloaterWebContent::_Params::_Params() LLFloaterWebContent::LLFloaterWebContent( const Params& params ) : LLFloater( params ), LLInstanceTracker<LLFloaterWebContent, std::string>(params.id()), + mWebBrowser(NULL), + mAddressCombo(NULL), + mSecureLockIcon(NULL), + mStatusBarText(NULL), + mStatusBarProgress(NULL), + mBtnBack(NULL), + mBtnForward(NULL), + mBtnReload(NULL), + mBtnStop(NULL), mUUID(params.id()), mShowPageTitle(params.show_page_title) { @@ -74,11 +83,16 @@ BOOL LLFloaterWebContent::postBuild() mStatusBarText = getChild< LLTextBox >( "statusbartext" ); mStatusBarProgress = getChild<LLProgressBar>("statusbarprogress" ); + mBtnBack = getChildView( "back" ); + mBtnForward = getChildView( "forward" ); + mBtnReload = getChildView( "reload" ); + mBtnStop = getChildView( "stop" ); + // observe browser events mWebBrowser->addObserver( this ); // these buttons are always enabled - getChildView("reload")->setEnabled( true ); + mBtnReload->setEnabled( true ); getChildView("popexternal")->setEnabled( true ); // cache image for secure browsing @@ -128,46 +142,14 @@ bool LLFloaterWebContent::matchesKey(const LLSD& key) //static LLFloater* LLFloaterWebContent::create( Params p) { - lldebugs << "url = " << p.url() << ", target = " << p.target() << ", uuid = " << p.id() << llendl; - - if (!p.id.isProvided()) - { - p.id = LLUUID::generateNewID().asString(); - } - - if(p.target().empty() || p.target() == "_blank") - { - p.target = p.id(); - } - - S32 browser_window_limit = gSavedSettings.getS32("WebContentWindowLimit"); - if(browser_window_limit != 0) - { - // showInstance will open a new window. Figure out how many web browsers are already open, - // and close the least recently opened one if this will put us over the limit. - - LLFloaterReg::const_instance_list_t &instances = LLFloaterReg::getFloaterList(p.window_class); - lldebugs << "total instance count is " << instances.size() << llendl; - - for(LLFloaterReg::const_instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); iter++) - { - lldebugs << " " << (*iter)->getKey()["target"] << llendl; - } - - if(instances.size() >= (size_t)browser_window_limit) - { - // Destroy the least recently opened instance - (*instances.begin())->closeFloater(); - } - } - + preCreate(p); return new LLFloaterWebContent(p); } //static void LLFloaterWebContent::closeRequest(const std::string &uuid) { - LLFloaterWebContent* floaterp = getInstance(uuid); + LLFloaterWebContent* floaterp = instance_tracker_t::getInstance(uuid); if (floaterp) { floaterp->closeFloater(false); @@ -177,7 +159,7 @@ void LLFloaterWebContent::closeRequest(const std::string &uuid) //static void LLFloaterWebContent::geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height) { - LLFloaterWebContent* floaterp = getInstance(uuid); + LLFloaterWebContent* floaterp = instance_tracker_t::getInstance(uuid); if (floaterp) { floaterp->geometryChanged(x, y, width, height); @@ -187,7 +169,7 @@ void LLFloaterWebContent::geometryChanged(const std::string &uuid, S32 x, S32 y, void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height) { // Make sure the layout of the browser control is updated, so this calculation is correct. - LLLayoutStack::updateClass(); + getChild<LLLayoutStack>("stack1")->updateLayout(); // TODO: need to adjust size and constrain position to make sure floaters aren't moved outside the window view, etc. LLCoordWindow window_size; @@ -211,6 +193,43 @@ void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height) setShape(new_rect); } +// static +void LLFloaterWebContent::preCreate(LLFloaterWebContent::Params& p) +{ + lldebugs << "url = " << p.url() << ", target = " << p.target() << ", uuid = " << p.id() << llendl; + + if (!p.id.isProvided()) + { + p.id = LLUUID::generateNewID().asString(); + } + + if(p.target().empty() || p.target() == "_blank") + { + p.target = p.id(); + } + + S32 browser_window_limit = gSavedSettings.getS32("WebContentWindowLimit"); + if(browser_window_limit != 0) + { + // showInstance will open a new window. Figure out how many web browsers are already open, + // and close the least recently opened one if this will put us over the limit. + + LLFloaterReg::const_instance_list_t &instances = LLFloaterReg::getFloaterList(p.window_class); + lldebugs << "total instance count is " << instances.size() << llendl; + + for(LLFloaterReg::const_instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); iter++) + { + lldebugs << " " << (*iter)->getKey()["target"] << llendl; + } + + if(instances.size() >= (size_t)browser_window_limit) + { + // Destroy the least recently opened instance + (*instances.begin())->closeFloater(); + } + } +} + void LLFloaterWebContent::open_media(const Params& p) { // Specifying a mime type of text/html here causes the plugin system to skip the MIME type probe and just open a browser plugin. @@ -239,7 +258,7 @@ void LLFloaterWebContent::open_media(const Params& p) if (!p.preferred_media_size().isEmpty()) { - LLLayoutStack::updateClass(); + getChild<LLLayoutStack>("stack1")->updateLayout(); LLRect browser_rect = mWebBrowser->calcScreenRect(); LLCoordWindow window_size; getWindow()->getSize(&window_size); @@ -276,8 +295,8 @@ void LLFloaterWebContent::onClose(bool app_quitting) void LLFloaterWebContent::draw() { // this is asynchronous so we need to keep checking - getChildView( "back" )->setEnabled( mWebBrowser->canNavigateBack() ); - getChildView( "forward" )->setEnabled( mWebBrowser->canNavigateForward() ); + mBtnBack->setEnabled( mWebBrowser->canNavigateBack() ); + mBtnForward->setEnabled( mWebBrowser->canNavigateForward() ); LLFloater::draw(); } @@ -297,12 +316,12 @@ void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent else if(event == MEDIA_EVENT_NAVIGATE_BEGIN) { // flags are sent with this event - getChildView("back")->setEnabled( self->getHistoryBackAvailable() ); - getChildView("forward")->setEnabled( self->getHistoryForwardAvailable() ); + mBtnBack->setEnabled( self->getHistoryBackAvailable() ); + mBtnForward->setEnabled( self->getHistoryForwardAvailable() ); // toggle visibility of these buttons based on browser state - getChildView("reload")->setVisible( false ); - getChildView("stop")->setVisible( true ); + mBtnReload->setVisible( false ); + mBtnStop->setVisible( true ); // turn "on" progress bar now we're about to start loading mStatusBarProgress->setVisible( true ); @@ -310,12 +329,12 @@ void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE) { // flags are sent with this event - getChildView("back")->setEnabled( self->getHistoryBackAvailable() ); - getChildView("forward")->setEnabled( self->getHistoryForwardAvailable() ); + mBtnBack->setEnabled( self->getHistoryBackAvailable() ); + mBtnForward->setEnabled( self->getHistoryForwardAvailable() ); // toggle visibility of these buttons based on browser state - getChildView("reload")->setVisible( true ); - getChildView("stop")->setVisible( false ); + mBtnReload->setVisible( true ); + mBtnStop->setVisible( false ); // turn "off" progress bar now we're loaded mStatusBarProgress->setVisible( false ); @@ -421,8 +440,8 @@ void LLFloaterWebContent::onClickStop() // still should happen when we catch the navigate complete event // but sometimes (don't know why) that event isn't sent from Qt // and we ghetto a point where the stop button stays active. - getChildView("reload")->setVisible( true ); - getChildView("stop")->setVisible( false ); + mBtnReload->setVisible( true ); + mBtnStop->setVisible( false ); } void LLFloaterWebContent::onEnterAddress() diff --git a/indra/newview/llfloaterwebcontent.h b/indra/newview/llfloaterwebcontent.h index 6fc66d1ad8..cfc87e9015 100644 --- a/indra/newview/llfloaterwebcontent.h +++ b/indra/newview/llfloaterwebcontent.h @@ -43,6 +43,7 @@ class LLFloaterWebContent : public LLInstanceTracker<LLFloaterWebContent, std::string> { public: + typedef LLInstanceTracker<LLFloaterWebContent, std::string> instance_tracker_t; LOG_CLASS(LLFloaterWebContent); struct _Params : public LLInitParam::Block<_Params> @@ -89,6 +90,7 @@ protected: void onEnterAddress(); void onPopExternal(); + static void preCreate(Params& p); void open_media(const Params& ); void set_current_url(const std::string& url); @@ -97,6 +99,12 @@ protected: LLIconCtrl* mSecureLockIcon; LLTextBox* mStatusBarText; LLProgressBar* mStatusBarProgress; + + LLView* mBtnBack; + LLView* mBtnForward; + LLView* mBtnReload; + LLView* mBtnStop; + std::string mCurrentURL; std::string mUUID; bool mShowPageTitle; diff --git a/indra/newview/llfloaterwebprofile.cpp b/indra/newview/llfloaterwebprofile.cpp new file mode 100644 index 0000000000..c41f6f148f --- /dev/null +++ b/indra/newview/llfloaterwebprofile.cpp @@ -0,0 +1,79 @@ +/** + * @file llfloaterwebprofile.cpp + * @brief Avatar profile floater. + * + * $LicenseInfo:firstyear=2009&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 "llfloaterwebprofile.h" + +#include "llviewercontrol.h" + +LLFloaterWebProfile::LLFloaterWebProfile(const Params& key) : + LLFloaterWebContent(key) +{ +} + +void LLFloaterWebProfile::onOpen(const LLSD& key) +{ + Params p(key); + p.show_chrome(false). + window_class("profile"); + LLFloaterWebContent::onOpen(p); + applyPreferredRect(); +} + +// virtual +void LLFloaterWebProfile::handleReshape(const LLRect& new_rect, bool by_user) +{ + lldebugs << "handleReshape: " << new_rect << llendl; + + if (by_user && !isMinimized()) + { + lldebugs << "Storing new rect" << llendl; + gSavedSettings.setRect("WebProfileFloaterRect", new_rect); + } + + LLFloaterWebContent::handleReshape(new_rect, by_user); +} + +LLFloater* LLFloaterWebProfile::create(const LLSD& key) +{ + LLFloaterWebContent::Params p(key); + preCreate(p); + return new LLFloaterWebProfile(p); +} + +void LLFloaterWebProfile::applyPreferredRect() +{ + const LLRect preferred_rect = gSavedSettings.getRect("WebProfileFloaterRect"); + lldebugs << "Applying preferred rect: " << preferred_rect << llendl; + + // Don't override position that may have been set by floater stacking code. + LLRect new_rect = getRect(); + new_rect.setLeftTopAndSize( + new_rect.mLeft, new_rect.mTop, + preferred_rect.getWidth(), preferred_rect.getHeight()); + setShape(new_rect); +} diff --git a/indra/newview/llmemoryview.h b/indra/newview/llfloaterwebprofile.h index dc4849a9c4..4c355e401b 100644 --- a/indra/newview/llmemoryview.h +++ b/indra/newview/llfloaterwebprofile.h @@ -1,8 +1,8 @@ /** - * @file llmemoryview.h - * @brief LLMemoryView class definition + * @file llfloaterwebprofile.h + * @brief Avatar profile floater. * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. * @@ -24,39 +24,36 @@ * $/LicenseInfo$ */ -#ifndef LL_LLMEMORYVIEW_H -#define LL_LLMEMORYVIEW_H +#ifndef LL_LLFLOATERWEBPROFILE_H +#define LL_LLFLOATERWEBPROFILE_H -#include "llview.h" +#include "llfloaterwebcontent.h" +#include "llviewermediaobserver.h" -class LLAllocator; +#include <string> -class LLMemoryView : public LLView +class LLMediaCtrl; + +/** + * Displays avatar profile web page. + */ +class LLFloaterWebProfile +: public LLFloaterWebContent { + LOG_CLASS(LLFloaterWebProfile); public: - struct Params : public LLInitParam::Block<Params, LLView::Params> - { - Params() - { - changeDefault(mouse_opaque, true); - changeDefault(visible, false); - } - }; - LLMemoryView(const LLMemoryView::Params&); - virtual ~LLMemoryView(); - - virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); - virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); - virtual BOOL handleHover(S32 x, S32 y, MASK mask); - virtual void draw(); - - void refreshProfile(); + typedef LLFloaterWebContent::Params Params; -private: - std::vector<LLWString> mLines; - LLAllocator* mAlloc; - BOOL mPaused ; + LLFloaterWebProfile(const Params& key); + + /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false); + static LLFloater* create(const LLSD& key); + +private: + void applyPreferredRect(); }; -#endif +#endif // LL_LLFLOATERWEBPROFILE_H + diff --git a/indra/newview/llfloaterwindowsize.cpp b/indra/newview/llfloaterwindowsize.cpp index a70f2af11a..ec161018b8 100644 --- a/indra/newview/llfloaterwindowsize.cpp +++ b/indra/newview/llfloaterwindowsize.cpp @@ -58,33 +58,12 @@ bool extractWindowSizeFromString(const std::string& instr, U32 *width, U32 *heig } -///---------------------------------------------------------------------------- -/// Class LLFloaterWindowSize -///---------------------------------------------------------------------------- -class LLFloaterWindowSize -: public LLFloater -{ - friend class LLFloaterReg; -private: - LLFloaterWindowSize(const LLSD& key); - virtual ~LLFloaterWindowSize(); - -public: - /*virtual*/ BOOL postBuild(); - void initWindowSizeControls(); - void onClickSet(); - void onClickCancel(); -}; - - LLFloaterWindowSize::LLFloaterWindowSize(const LLSD& key) : LLFloater(key) -{ -} +{} LLFloaterWindowSize::~LLFloaterWindowSize() -{ -} +{} BOOL LLFloaterWindowSize::postBuild() { @@ -145,13 +124,3 @@ void LLFloaterWindowSize::onClickCancel() { closeFloater(); } - -///---------------------------------------------------------------------------- -/// LLFloaterWindowSizeUtil -///---------------------------------------------------------------------------- -void LLFloaterWindowSizeUtil::registerFloater() -{ - LLFloaterReg::add("window_size", "floater_window_size.xml", - &LLFloaterReg::build<LLFloaterWindowSize>); - -} diff --git a/indra/newview/llfloaterwindowsize.h b/indra/newview/llfloaterwindowsize.h index 40f1a25bb3..a71e5e273c 100644 --- a/indra/newview/llfloaterwindowsize.h +++ b/indra/newview/llfloaterwindowsize.h @@ -26,10 +26,24 @@ #ifndef LLFLOATERWINDOWSIZE_H #define LLFLOATERWINDOWSIZE_H -// Allow user to set the window size for filming tutorials, machinima, etc -namespace LLFloaterWindowSizeUtil +#include "llfloater.h" + +///---------------------------------------------------------------------------- +/// Class LLFloaterWindowSize +///---------------------------------------------------------------------------- +class LLFloaterWindowSize + : public LLFloater { - void registerFloater(); -} + friend class LLFloaterReg; +private: + LLFloaterWindowSize(const LLSD& key); + virtual ~LLFloaterWindowSize(); + +public: + /*virtual*/ BOOL postBuild(); + void initWindowSizeControls(); + void onClickSet(); + void onClickCancel(); +}; #endif diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp deleted file mode 100644 index 6ec2598e44..0000000000 --- a/indra/newview/llfolderview.cpp +++ /dev/null @@ -1,2591 +0,0 @@ -/** - * @file llfolderview.cpp - * @brief Implementation of the folder view collection of classes. - * - * $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 "llfolderview.h" - -#include "llcallbacklist.h" -#include "llinventorybridge.h" -#include "llinventoryclipboard.h" // *TODO: remove this once hack below gone. -#include "llinventoryfilter.h" -#include "llinventoryfunctions.h" -#include "llinventorymodelbackgroundfetch.h" -#include "llinventorypanel.h" -#include "llfoldertype.h" -#include "llfloaterinventory.h"// hacked in for the bonus context menu items. -#include "llkeyboard.h" -#include "lllineeditor.h" -#include "llmenugl.h" -#include "llpanel.h" -#include "llpreview.h" -#include "llscrollcontainer.h" // hack to allow scrolling -#include "lltooldraganddrop.h" -#include "lltrans.h" -#include "llui.h" -#include "llviewertexture.h" -#include "llviewertexturelist.h" -#include "llviewerjointattachment.h" -#include "llviewermenu.h" -#include "lluictrlfactory.h" -#include "llviewercontrol.h" -#include "llviewerfoldertype.h" -#include "llviewerwindow.h" -#include "llvoavatar.h" -#include "llfloaterproperties.h" -#include "llnotificationsutil.h" - -// Linden library includes -#include "lldbstrings.h" -#include "llfocusmgr.h" -#include "llfontgl.h" -#include "llgl.h" -#include "llrender.h" -#include "llinventory.h" - -// Third-party library includes -#include <algorithm> - -///---------------------------------------------------------------------------- -/// Local function declarations, constants, enums, and typedefs -///---------------------------------------------------------------------------- - -const S32 RENAME_WIDTH_PAD = 4; -const S32 RENAME_HEIGHT_PAD = 1; -const S32 AUTO_OPEN_STACK_DEPTH = 16; -const S32 MIN_ITEM_WIDTH_VISIBLE = LLFolderViewItem::ICON_WIDTH - + LLFolderViewItem::ICON_PAD - + LLFolderViewItem::ARROW_SIZE - + LLFolderViewItem::TEXT_PAD - + /*first few characters*/ 40; -const S32 MINIMUM_RENAMER_WIDTH = 80; - -// *TODO: move in params in xml if necessary. Requires modification of LLFolderView & LLInventoryPanel Params. -const S32 STATUS_TEXT_HPAD = 6; -const S32 STATUS_TEXT_VPAD = 8; - -enum { - SIGNAL_NO_KEYBOARD_FOCUS = 1, - SIGNAL_KEYBOARD_FOCUS = 2 -}; - -F32 LLFolderView::sAutoOpenTime = 1.f; - -void delete_selected_item(void* user_data); -void copy_selected_item(void* user_data); -void open_selected_items(void* user_data); -void properties_selected_items(void* user_data); -void paste_items(void* user_data); - - -//--------------------------------------------------------------------------- - -// Tells all folders in a folderview to sort their items -// (and only their items, not folders) by a certain function. -class LLSetItemSortFunction : public LLFolderViewFunctor -{ -public: - LLSetItemSortFunction(U32 ordering) - : mSortOrder(ordering) {} - virtual ~LLSetItemSortFunction() {} - virtual void doFolder(LLFolderViewFolder* folder); - virtual void doItem(LLFolderViewItem* item); - - U32 mSortOrder; -}; - - -// Set the sort order. -void LLSetItemSortFunction::doFolder(LLFolderViewFolder* folder) -{ - folder->setItemSortOrder(mSortOrder); -} - -// Do nothing. -void LLSetItemSortFunction::doItem(LLFolderViewItem* item) -{ - return; -} - -//--------------------------------------------------------------------------- - -// Tells all folders in a folderview to close themselves -// For efficiency, calls setOpenArrangeRecursively(). -// The calling function must then call: -// LLFolderView* root = getRoot(); -// if( root ) -// { -// root->arrange( NULL, NULL ); -// root->scrollToShowSelection(); -// } -// to patch things up. -class LLCloseAllFoldersFunctor : public LLFolderViewFunctor -{ -public: - LLCloseAllFoldersFunctor(BOOL close) { mOpen = !close; } - virtual ~LLCloseAllFoldersFunctor() {} - virtual void doFolder(LLFolderViewFolder* folder); - virtual void doItem(LLFolderViewItem* item); - - BOOL mOpen; -}; - - -// Set the sort order. -void LLCloseAllFoldersFunctor::doFolder(LLFolderViewFolder* folder) -{ - folder->setOpenArrangeRecursively(mOpen); -} - -// Do nothing. -void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item) -{ } - -///---------------------------------------------------------------------------- -/// Class LLFolderView -///---------------------------------------------------------------------------- -LLFolderView::Params::Params() -: task_id("task_id"), - title("title"), - use_label_suffix("use_label_suffix"), - allow_multiselect("allow_multiselect", true), - show_load_status("show_load_status", true), - use_ellipses("use_ellipses", false) -{ -} - - -// Default constructor -LLFolderView::LLFolderView(const Params& p) -: LLFolderViewFolder(p), - mRunningHeight(0), - mScrollContainer( NULL ), - mPopupMenuHandle(), - mAllowMultiSelect(p.allow_multiselect), - mShowFolderHierarchy(FALSE), - mSourceID(p.task_id), - mRenameItem( NULL ), - mNeedsScroll( FALSE ), - mUseLabelSuffix(p.use_label_suffix), - mPinningSelectedItem(FALSE), - mNeedsAutoSelect( FALSE ), - mAutoSelectOverride(FALSE), - mNeedsAutoRename(FALSE), - mDebugFilters(FALSE), - mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME), // This gets overridden by a pref immediately - mFilter( new LLInventoryFilter(p.title) ), - mShowSelectionContext(FALSE), - mShowSingleSelection(FALSE), - mArrangeGeneration(0), - mSignalSelectCallback(0), - mMinWidth(0), - mDragAndDropThisFrame(FALSE), - mCallbackRegistrar(NULL), - mParentPanel(p.parent_panel), - mUseEllipses(p.use_ellipses), - mDraggingOverItem(NULL), - mStatusTextBox(NULL) -{ - mRoot = this; - - mShowLoadStatus = p.show_load_status(); - - LLRect rect = p.rect; - LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom); - setRect( rect ); - reshape(rect.getWidth(), rect.getHeight()); - mIsOpen = TRUE; // this view is always open. - mAutoOpenItems.setDepth(AUTO_OPEN_STACK_DEPTH); - mAutoOpenCandidate = NULL; - mAutoOpenTimer.stop(); - mKeyboardSelection = FALSE; - const LLFolderViewItem::Params& item_params = - LLUICtrlFactory::getDefaultParams<LLFolderViewItem>(); - S32 indentation = item_params.folder_indentation(); - mIndentation = -indentation; // children start at indentation 0 - gIdleCallbacks.addFunction(idle, this); - - //clear label - // go ahead and render root folder as usual - // just make sure the label ("Inventory Folder") never shows up - mLabel = LLStringUtil::null; - - //mRenamer->setWriteableBgColor(LLColor4::white); - // Escape is handled by reverting the rename, not commiting it (default behavior) - LLLineEditor::Params params; - params.name("ren"); - params.rect(rect); - params.font(getLabelFontForStyle(LLFontGL::NORMAL)); - params.max_length.bytes(DB_INV_ITEM_NAME_STR_LEN); - params.commit_callback.function(boost::bind(&LLFolderView::commitRename, this, _2)); - params.prevalidate_callback(&LLTextValidate::validateASCIIPrintableNoPipe); - params.commit_on_focus_lost(true); - params.visible(false); - mRenamer = LLUICtrlFactory::create<LLLineEditor> (params); - addChild(mRenamer); - - // Textbox - LLTextBox::Params text_p; - LLFontGL* font = getLabelFontForStyle(mLabelStyle); - LLRect new_r = LLRect(rect.mLeft + ICON_PAD, - rect.mTop - TEXT_PAD, - rect.mRight, - rect.mTop - TEXT_PAD - llfloor(font->getLineHeight())); - text_p.rect(new_r); - text_p.name(std::string(p.name)); - text_p.font(font); - text_p.visible(false); - text_p.parse_urls(true); - text_p.wrap(true); // allow multiline text. See EXT-7564, EXT-7047 - // set text padding the same as in People panel. EXT-7047, EXT-4837 - text_p.h_pad(STATUS_TEXT_HPAD); - text_p.v_pad(STATUS_TEXT_VPAD); - mStatusTextBox = LLUICtrlFactory::create<LLTextBox> (text_p); - mStatusTextBox->setFollowsLeft(); - mStatusTextBox->setFollowsTop(); - //addChild(mStatusTextBox); - - - // make the popup menu available - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if (!menu) - { - menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu"); - } - menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor")); - mPopupMenuHandle = menu->getHandle(); - - mListener->openItem(); -} - -// Destroys the object -LLFolderView::~LLFolderView( void ) -{ - closeRenamer(); - - // The release focus call can potentially call the - // scrollcontainer, which can potentially be called with a partly - // destroyed scollcontainer. Just null it out here, and no worries - // about calling into the invalid scroll container. - // Same with the renamer. - mScrollContainer = NULL; - mRenameItem = NULL; - mRenamer = NULL; - mStatusTextBox = NULL; - - mAutoOpenItems.removeAllNodes(); - gIdleCallbacks.deleteFunction(idle, this); - - delete mPopupMenuHandle.get(); - - mAutoOpenItems.removeAllNodes(); - clearSelection(); - mItems.clear(); - mFolders.clear(); - - mItemMap.clear(); - - delete mFilter; - mFilter = NULL; -} - -BOOL LLFolderView::canFocusChildren() const -{ - return FALSE; -} - -static LLFastTimer::DeclareTimer FTM_SORT("Sort Inventory"); - -void LLFolderView::setSortOrder(U32 order) -{ - if (order != mSortOrder) - { - LLFastTimer t(FTM_SORT); - - mSortOrder = order; - - sortBy(order); - arrangeAll(); - } -} - - -U32 LLFolderView::getSortOrder() const -{ - return mSortOrder; -} - -BOOL LLFolderView::addFolder( LLFolderViewFolder* folder) -{ - // enforce sort order of My Inventory followed by Library - if (folder->getListener()->getUUID() == gInventory.getLibraryRootFolderID()) - { - mFolders.push_back(folder); - } - else - { - mFolders.insert(mFolders.begin(), folder); - } - if (folder->numSelected()) - { - recursiveIncrementNumDescendantsSelected(folder->numSelected()); - } - folder->setShowLoadStatus(mShowLoadStatus); - folder->setOrigin(0, 0); - folder->reshape(getRect().getWidth(), 0); - folder->setVisible(FALSE); - addChild( folder ); - folder->dirtyFilter(); - folder->requestArrange(); - return TRUE; -} - -void LLFolderView::closeAllFolders() -{ - // Close all the folders - setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN); - arrangeAll(); -} - -void LLFolderView::openTopLevelFolders() -{ - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->setOpen(TRUE); - } -} - -void LLFolderView::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse) -{ - // call base class to do proper recursion - LLFolderViewFolder::setOpenArrangeRecursively(openitem, recurse); - // make sure root folder is always open - mIsOpen = TRUE; -} - -static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange"); - -// This view grows and shinks to enclose all of its children items and folders. -S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_generation ) -{ - if (getListener()->getUUID().notNull()) - { - if (mNeedsSort) - { - mFolders.sort(mSortFunction); - mItems.sort(mSortFunction); - mNeedsSort = false; - } - } - - LLFastTimer t2(FTM_ARRANGE); - - filter_generation = mFilter->getMinRequiredGeneration(); - mMinWidth = 0; - - mHasVisibleChildren = hasFilteredDescendants(filter_generation); - // arrange always finishes, so optimistically set the arrange generation to the most current - mLastArrangeGeneration = getRoot()->getArrangeGeneration(); - - LLInventoryFilter::EFolderShow show_folder_state = - getRoot()->getFilter()->getShowFolderState(); - - S32 total_width = LEFT_PAD; - S32 running_height = mDebugFilters ? llceil(LLFontGL::getFontMonospace()->getLineHeight()) : 0; - S32 target_height = running_height; - S32 parent_item_height = getRect().getHeight(); - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - LLFolderViewFolder* folderp = (*fit); - if (getDebugFilters()) - { - folderp->setVisible(TRUE); - } - else - { - folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders? - (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter - } - - if (folderp->getVisible()) - { - S32 child_height = 0; - S32 child_width = 0; - S32 child_top = parent_item_height - running_height; - - target_height += folderp->arrange( &child_width, &child_height, filter_generation ); - - mMinWidth = llmax(mMinWidth, child_width); - total_width = llmax( total_width, child_width ); - running_height += child_height; - folderp->setOrigin( ICON_PAD, child_top - (*fit)->getRect().getHeight() ); - } - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - LLFolderViewItem* itemp = (*iit); - itemp->setVisible(itemp->getFiltered(filter_generation)); - - if (itemp->getVisible()) - { - S32 child_width = 0; - S32 child_height = 0; - S32 child_top = parent_item_height - running_height; - - target_height += itemp->arrange( &child_width, &child_height, filter_generation ); - itemp->reshape(itemp->getRect().getWidth(), child_height); - - mMinWidth = llmax(mMinWidth, child_width); - total_width = llmax( total_width, child_width ); - running_height += child_height; - itemp->setOrigin( ICON_PAD, child_top - itemp->getRect().getHeight() ); - } - } - - if(!mHasVisibleChildren)// is there any filtered items ? - { - //Nope. We need to display status textbox, let's reserve some place for it - running_height = mStatusTextBox->getTextPixelHeight(); - target_height = running_height; - } - - mRunningHeight = running_height; - LLRect scroll_rect = mScrollContainer->getContentWindowRect(); - reshape( llmax(scroll_rect.getWidth(), total_width), running_height ); - - LLRect new_scroll_rect = mScrollContainer->getContentWindowRect(); - if (new_scroll_rect.getWidth() != scroll_rect.getWidth()) - { - reshape( llmax(scroll_rect.getWidth(), total_width), running_height ); - } - - // move item renamer text field to item's new position - updateRenamerPosition(); - - mTargetHeight = (F32)target_height; - return llround(mTargetHeight); -} - -const std::string LLFolderView::getFilterSubString(BOOL trim) -{ - return mFilter->getFilterSubString(trim); -} - -static LLFastTimer::DeclareTimer FTM_FILTER("Filter Inventory"); - -void LLFolderView::filter( LLInventoryFilter& filter ) -{ - LLFastTimer t2(FTM_FILTER); - filter.setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000)); - - if (getCompletedFilterGeneration() < filter.getCurrentGeneration()) - { - mPassedFilter = FALSE; - mMinWidth = 0; - LLFolderViewFolder::filter(filter); - } - else - { - mPassedFilter = TRUE; - } -} - -void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - LLRect scroll_rect; - if (mScrollContainer) - { - LLView::reshape(width, height, called_from_parent); - scroll_rect = mScrollContainer->getContentWindowRect(); - } - width = llmax(mMinWidth, scroll_rect.getWidth()); - height = llmax(mRunningHeight, scroll_rect.getHeight()); - - // restrict width with scroll container's width - if (mUseEllipses) - width = scroll_rect.getWidth(); - - LLView::reshape(width, height, called_from_parent); - - mReshapeSignal(mSelectedItems, FALSE); -} - -void LLFolderView::addToSelectionList(LLFolderViewItem* item) -{ - if (item->isSelected()) - { - removeFromSelectionList(item); - } - if (mSelectedItems.size()) - { - mSelectedItems.back()->setIsCurSelection(FALSE); - } - item->setIsCurSelection(TRUE); - mSelectedItems.push_back(item); -} - -void LLFolderView::removeFromSelectionList(LLFolderViewItem* item) -{ - if (mSelectedItems.size()) - { - mSelectedItems.back()->setIsCurSelection(FALSE); - } - - selected_items_t::iterator item_iter; - for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end();) - { - if (*item_iter == item) - { - item_iter = mSelectedItems.erase(item_iter); - } - else - { - ++item_iter; - } - } - if (mSelectedItems.size()) - { - mSelectedItems.back()->setIsCurSelection(TRUE); - } -} - -LLFolderViewItem* LLFolderView::getCurSelectedItem( void ) -{ - if(mSelectedItems.size()) - { - LLFolderViewItem* itemp = mSelectedItems.back(); - llassert(itemp->getIsCurSelection()); - return itemp; - } - return NULL; -} - - -// Record the selected item and pass it down the hierachy. -BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus) -{ - mSignalSelectCallback = take_keyboard_focus ? SIGNAL_KEYBOARD_FOCUS : SIGNAL_NO_KEYBOARD_FOCUS; - - if( selection == this ) - { - return FALSE; - } - - if( selection && take_keyboard_focus) - { - mParentPanel->setFocus(TRUE); - } - - // clear selection down here because change of keyboard focus can potentially - // affect selection - clearSelection(); - - if(selection) - { - addToSelectionList(selection); - } - - BOOL rv = LLFolderViewFolder::setSelection(selection, openitem, take_keyboard_focus); - if(openitem && selection) - { - selection->getParentFolder()->requestArrange(); - } - - llassert(mSelectedItems.size() <= 1); - - return rv; -} - -void LLFolderView::setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus) -{ - LLFolderViewItem* itemp = getItemByID(obj_id); - if(itemp && itemp->getListener()) - { - itemp->arrangeAndSet(TRUE, take_keyboard_focus); - mSelectThisID.setNull(); - return; - } - else - { - // save the desired item to be selected later (if/when ready) - mSelectThisID = obj_id; - } -} - -void LLFolderView::updateSelection() -{ - if (mSelectThisID.notNull()) - { - setSelectionByID(mSelectThisID, false); - } -} - -BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected) -{ - BOOL rv = FALSE; - - // can't select root folder - if(!selection || selection == this) - { - return FALSE; - } - - if (!mAllowMultiSelect) - { - clearSelection(); - } - - selected_items_t::iterator item_iter; - for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter) - { - if (*item_iter == selection) - { - break; - } - } - - BOOL on_list = (item_iter != mSelectedItems.end()); - - if(selected && !on_list) - { - addToSelectionList(selection); - } - if(!selected && on_list) - { - removeFromSelectionList(selection); - } - - rv = LLFolderViewFolder::changeSelection(selection, selected); - - mSignalSelectCallback = SIGNAL_KEYBOARD_FOCUS; - - 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() -{ - LLFastTimer _(FTM_SANITIZE_SELECTION); - // store off current item in case it is automatically deselected - // and we want to preserve context - LLFolderViewItem* original_selected_item = getCurSelectedItem(); - - // Cache "Show all folders" filter setting - BOOL show_all_folders = (getRoot()->getFilter()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS); - - std::vector<LLFolderViewItem*> items_to_remove; - selected_items_t::iterator item_iter; - for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter) - { - LLFolderViewItem* item = *item_iter; - - // ensure that each ancestor is open and potentially passes filtering - BOOL visible = item->potentiallyVisible(); // initialize from filter state for this item - // modify with parent open and filters states - LLFolderViewFolder* parent_folder = item->getParentFolder(); - if ( parent_folder ) - { - if ( show_all_folders ) - { // "Show all folders" is on, so this folder is visible - visible = TRUE; - } - else - { // Move up through parent folders and see what's visible - while(parent_folder) - { - visible = visible && parent_folder->isOpen() && parent_folder->potentiallyVisible(); - parent_folder = parent_folder->getParentFolder(); - } - } - } - - // deselect item if any ancestor is closed or didn't pass filter requirements. - if (!visible) - { - items_to_remove.push_back(item); - } - - // disallow nested selections (i.e. folder items plus one or more ancestors) - // could check cached mum selections count and only iterate if there are any - // but that may be a premature optimization. - selected_items_t::iterator other_item_iter; - for (other_item_iter = mSelectedItems.begin(); other_item_iter != mSelectedItems.end(); ++other_item_iter) - { - LLFolderViewItem* other_item = *other_item_iter; - for( parent_folder = other_item->getParentFolder(); parent_folder; parent_folder = parent_folder->getParentFolder()) - { - if (parent_folder == item) - { - // this is a descendent of the current folder, remove from list - items_to_remove.push_back(other_item); - break; - } - } - } - - // Don't allow invisible items (such as root folders) to be selected. - if (item == getRoot()) - { - items_to_remove.push_back(item); - } - } - - std::vector<LLFolderViewItem*>::iterator item_it; - for (item_it = items_to_remove.begin(); item_it != items_to_remove.end(); ++item_it ) - { - changeSelection(*item_it, FALSE); // toggle selection (also removes from list) - } - - // if nothing selected after prior constraints... - if (mSelectedItems.empty()) - { - // ...select first available parent of original selection, or "My Inventory" otherwise - LLFolderViewItem* new_selection = NULL; - if (original_selected_item) - { - for(LLFolderViewFolder* parent_folder = original_selected_item->getParentFolder(); - parent_folder; - parent_folder = parent_folder->getParentFolder()) - { - if (parent_folder->potentiallyVisible()) - { - // give initial selection to first ancestor folder that potentially passes the filter - if (!new_selection) - { - new_selection = parent_folder; - } - - // if any ancestor folder of original item is closed, move the selection up - // to the highest closed - if (!parent_folder->isOpen()) - { - new_selection = parent_folder; - } - } - } - } - else - { - new_selection = NULL; - } - - if (new_selection) - { - setSelection(new_selection, FALSE, FALSE); - } - } -} - -void LLFolderView::clearSelection() -{ - for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); - item_it != mSelectedItems.end(); - ++item_it) - { - (*item_it)->setUnselected(); - } - - mSelectedItems.clear(); - mSelectThisID.setNull(); -} - -std::set<LLUUID> LLFolderView::getSelectionList() const -{ - std::set<LLUUID> selection; - for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); - item_it != mSelectedItems.end(); - ++item_it) - { - selection.insert((*item_it)->getListener()->getUUID()); - } - return selection; -} - -BOOL LLFolderView::startDrag(LLToolDragAndDrop::ESource source) -{ - std::vector<EDragAndDropType> types; - uuid_vec_t cargo_ids; - selected_items_t::iterator item_it; - BOOL can_drag = TRUE; - if (!mSelectedItems.empty()) - { - for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) - { - EDragAndDropType type = DAD_NONE; - LLUUID id = LLUUID::null; - can_drag = can_drag && (*item_it)->getListener()->startDrag(&type, &id); - - types.push_back(type); - cargo_ids.push_back(id); - } - - LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, source, mSourceID); - } - return can_drag; -} - -void LLFolderView::commitRename( const LLSD& data ) -{ - finishRenamingItem(); -} - -void LLFolderView::draw() -{ - static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", LLColor4::white); - if (mDebugFilters) - { - std::string current_filter_string = llformat("Current Filter: %d, Least Filter: %d, Auto-accept Filter: %d", - mFilter->getCurrentGeneration(), mFilter->getMinRequiredGeneration(), mFilter->getMustPassGeneration()); - LLFontGL::getFontMonospace()->renderUTF8(current_filter_string, 0, 2, - getRect().getHeight() - LLFontGL::getFontMonospace()->getLineHeight(), LLColor4(0.5f, 0.5f, 0.8f, 1.f), - LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE ); - } - - //LLFontGL* font = getLabelFontForStyle(mLabelStyle); - - // if cursor has moved off of me during drag and drop - // close all auto opened folders - if (!mDragAndDropThisFrame) - { - closeAutoOpenedFolders(); - } - - // while dragging, update selection rendering to reflect single/multi drag status - if (LLToolDragAndDrop::getInstance()->hasMouseCapture()) - { - EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept(); - if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE) - { - setShowSingleSelection(TRUE); - } - else - { - setShowSingleSelection(FALSE); - } - } - else - { - setShowSingleSelection(FALSE); - } - - - if (mSearchTimer.getElapsedTimeF32() > gSavedSettings.getF32("TypeAheadTimeout") || !mSearchString.size()) - { - mSearchString.clear(); - } - - if (hasVisibleChildren() - || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) - { - mStatusText.clear(); - mStatusTextBox->setVisible( FALSE ); - } - else - { - if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration()) - { - mStatusText = LLTrans::getString("Searching"); - } - else - { - if (getFilter()) - { - LLStringUtil::format_map_t args; - args["[SEARCH_TERM]"] = LLURI::escape(getFilter()->getFilterSubStringOrig()); - mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage(), args); - } - } - mStatusTextBox->setValue(mStatusText); - mStatusTextBox->setVisible( TRUE ); - - // firstly reshape message textbox with current size. This is necessary to - // LLTextBox::getTextPixelHeight works properly - const LLRect local_rect = getLocalRect(); - mStatusTextBox->setShape(local_rect); - - // get preferable text height... - S32 pixel_height = mStatusTextBox->getTextPixelHeight(); - bool height_changed = local_rect.getHeight() != pixel_height; - if (height_changed) - { - // ... if it does not match current height, lets rearrange current view. - // This will indirectly call ::arrange and reshape of the status textbox. - // We should call this method to also notify parent about required rect. - // See EXT-7564, EXT-7047. - arrangeFromRoot(); - } - - } - - // skip over LLFolderViewFolder::draw since we don't want the folder icon, label, - // and arrow for the root folder - LLView::draw(); - - mDragAndDropThisFrame = FALSE; -} - -void LLFolderView::finishRenamingItem( void ) -{ - if(!mRenamer) - { - return; - } - if( mRenameItem ) - { - mRenameItem->rename( mRenamer->getText() ); - } - - closeRenamer(); - - // List is re-sorted alphabeticly, so scroll to make sure the selected item is visible. - scrollToShowSelection(); -} - -void LLFolderView::closeRenamer( void ) -{ - if (mRenamer && mRenamer->getVisible()) - { - // Triggers onRenamerLost() that actually closes the renamer. - gViewerWindow->removePopup(mRenamer); - } -} - -void LLFolderView::removeSelectedItems( void ) -{ - if (mSelectedItems.empty()) return; - LLSD args; - args["QUESTION"] = LLTrans::getString(mSelectedItems.size() > 1 ? "DeleteItems" : "DeleteItem"); - LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLFolderView::onItemsRemovalConfirmation, this, _1, _2)); -} - -bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector<LLFolderViewItem*>& selectedItems) -{ - LLFolderViewItem* item_parent = dynamic_cast<LLFolderViewItem*>(item->getParent()); - - if (item_parent) - { - for(std::vector<LLFolderViewItem*>::const_iterator it = selectedItems.begin(); it != selectedItems.end(); ++it) - { - const LLFolderViewItem* const selected_item = (*it); - - LLFolderViewItem* parent = item_parent; - - while (parent) - { - if (selected_item == parent) - { - return true; - } - - parent = dynamic_cast<LLFolderViewItem*>(parent->getParent()); - } - } - } - - return false; -} - -void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) return; // canceled - - if(getVisible() && getEnabled()) - { - // just in case we're removing the renaming item. - mRenameItem = NULL; - - // create a temporary structure which we will use to remove - // items, since the removal will futz with internal data - // structures. - std::vector<LLFolderViewItem*> items; - S32 count = mSelectedItems.size(); - if(count == 0) return; - LLFolderViewItem* item = NULL; - selected_items_t::iterator item_it; - for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) - { - item = *item_it; - if(item->isRemovable()) - { - items.push_back(item); - } - else - { - llinfos << "Cannot delete " << item->getName() << llendl; - return; - } - } - - // iterate through the new container. - count = items.size(); - LLUUID new_selection_id; - if(count == 1) - { - LLFolderViewItem* item_to_delete = items[0]; - LLFolderViewFolder* parent = item_to_delete->getParentFolder(); - LLFolderViewItem* new_selection = item_to_delete->getNextOpenNode(FALSE); - if (!new_selection) - { - new_selection = item_to_delete->getPreviousOpenNode(FALSE); - } - if(parent) - { - if (parent->removeItem(item_to_delete)) - { - // change selection on successful delete - if (new_selection) - { - setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus()); - } - else - { - setSelectionFromRoot(NULL, mParentPanel->hasFocus()); - } - } - } - arrangeAll(); - } - else if (count > 1) - { - LLDynamicArray<LLFolderViewEventListener*> listeners; - LLFolderViewEventListener* listener; - LLFolderViewItem* last_item = items[count - 1]; - LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE); - while(new_selection && new_selection->isSelected()) - { - new_selection = new_selection->getNextOpenNode(FALSE); - } - if (!new_selection) - { - new_selection = last_item->getPreviousOpenNode(FALSE); - while (new_selection && (new_selection->isSelected() || isDescendantOfASelectedItem(new_selection, items))) - { - new_selection = new_selection->getPreviousOpenNode(FALSE); - } - } - if (new_selection) - { - setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus()); - } - else - { - setSelectionFromRoot(NULL, mParentPanel->hasFocus()); - } - - for(S32 i = 0; i < count; ++i) - { - listener = items[i]->getListener(); - if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewEventListener*>::FAIL)) - { - listeners.put(listener); - } - } - listener = listeners.get(0); - if(listener) - { - listener->removeBatch(listeners); - } - } - arrangeAll(); - scrollToShowSelection(); - } -} - -// open the selected item. -void LLFolderView::openSelectedItems( void ) -{ - if(getVisible() && getEnabled()) - { - if (mSelectedItems.size() == 1) - { - mSelectedItems.front()->openItem(); - } - else - { - LLMultiPreview* multi_previewp = new LLMultiPreview(); - LLMultiProperties* multi_propertiesp = new LLMultiProperties(); - - selected_items_t::iterator item_it; - for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) - { - // IT_{OBJECT,ATTACHMENT} creates LLProperties - // floaters; others create LLPreviews. Put - // each one in the right type of container. - LLFolderViewEventListener* listener = (*item_it)->getListener(); - bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT); - if (is_prop) - LLFloater::setFloaterHost(multi_propertiesp); - else - LLFloater::setFloaterHost(multi_previewp); - (*item_it)->openItem(); - } - - LLFloater::setFloaterHost(NULL); - // *NOTE: LLMulti* will safely auto-delete when open'd - // without any children. - multi_previewp->openFloater(LLSD()); - multi_propertiesp->openFloater(LLSD()); - } - } -} - -void LLFolderView::propertiesSelectedItems( void ) -{ - if(getVisible() && getEnabled()) - { - if (mSelectedItems.size() == 1) - { - LLFolderViewItem* folder_item = mSelectedItems.front(); - if(!folder_item) return; - folder_item->getListener()->showProperties(); - } - else - { - LLMultiProperties* multi_propertiesp = new LLMultiProperties(); - - LLFloater::setFloaterHost(multi_propertiesp); - - selected_items_t::iterator item_it; - for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) - { - (*item_it)->getListener()->showProperties(); - } - - LLFloater::setFloaterHost(NULL); - multi_propertiesp->openFloater(LLSD()); - } - } -} - -void LLFolderView::changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type) -{ - LLFolderBridge *folder_bridge = LLFolderBridge::sSelf.get(); - - if (!folder_bridge) return; - LLViewerInventoryCategory *cat = folder_bridge->getCategory(); - if (!cat) return; - cat->changeType(new_folder_type); -} - -void LLFolderView::autoOpenItem( LLFolderViewFolder* item ) -{ - if (mAutoOpenItems.check() == item || mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH) - { - return; - } - - // close auto-opened folders - LLFolderViewFolder* close_item = mAutoOpenItems.check(); - while (close_item && close_item != item->getParentFolder()) - { - mAutoOpenItems.pop(); - close_item->setOpenArrangeRecursively(FALSE); - close_item = mAutoOpenItems.check(); - } - - item->requestArrange(); - - mAutoOpenItems.push(item); - - item->setOpen(TRUE); - LLRect content_rect = mScrollContainer->getContentWindowRect(); - LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0); - scrollToShowItem(item, constraint_rect); -} - -void LLFolderView::closeAutoOpenedFolders() -{ - while (mAutoOpenItems.check()) - { - LLFolderViewFolder* close_item = mAutoOpenItems.pop(); - close_item->setOpen(FALSE); - } - - if (mAutoOpenCandidate) - { - mAutoOpenCandidate->setAutoOpenCountdown(0.f); - } - mAutoOpenCandidate = NULL; - mAutoOpenTimer.stop(); -} - -BOOL LLFolderView::autoOpenTest(LLFolderViewFolder* folder) -{ - if (folder && mAutoOpenCandidate == folder) - { - if (mAutoOpenTimer.getStarted()) - { - if (!mAutoOpenCandidate->isOpen()) - { - mAutoOpenCandidate->setAutoOpenCountdown(clamp_rescale(mAutoOpenTimer.getElapsedTimeF32(), 0.f, sAutoOpenTime, 0.f, 1.f)); - } - if (mAutoOpenTimer.getElapsedTimeF32() > sAutoOpenTime) - { - autoOpenItem(folder); - mAutoOpenTimer.stop(); - return TRUE; - } - } - return FALSE; - } - - // otherwise new candidate, restart timer - if (mAutoOpenCandidate) - { - mAutoOpenCandidate->setAutoOpenCountdown(0.f); - } - mAutoOpenCandidate = folder; - mAutoOpenTimer.start(); - return FALSE; -} - -BOOL LLFolderView::canCopy() const -{ - if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0))) - { - return FALSE; - } - - for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it) - { - const LLFolderViewItem* item = *selected_it; - if (!item->getListener()->isItemCopyable()) - { - return FALSE; - } - } - return TRUE; -} - -// copy selected item -void LLFolderView::copy() -{ - // *NOTE: total hack to clear the inventory clipboard - LLInventoryClipboard::instance().reset(); - S32 count = mSelectedItems.size(); - if(getVisible() && getEnabled() && (count > 0)) - { - LLFolderViewEventListener* listener = NULL; - selected_items_t::iterator item_it; - for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) - { - listener = (*item_it)->getListener(); - if(listener) - { - listener->copyToClipboard(); - } - } - } - mSearchString.clear(); -} - -BOOL LLFolderView::canCut() const -{ - if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0))) - { - return FALSE; - } - - for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it) - { - const LLFolderViewItem* item = *selected_it; - const LLFolderViewEventListener* listener = item->getListener(); - - if (!listener || !listener->isItemRemovable()) - { - return FALSE; - } - } - return TRUE; -} - -void LLFolderView::cut() -{ - // clear the inventory clipboard - LLInventoryClipboard::instance().reset(); - S32 count = mSelectedItems.size(); - if(getVisible() && getEnabled() && (count > 0)) - { - LLFolderViewEventListener* listener = NULL; - selected_items_t::iterator item_it; - for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) - { - listener = (*item_it)->getListener(); - if(listener) - { - listener->cutToClipboard(); - } - } - } - mSearchString.clear(); -} - -BOOL LLFolderView::canPaste() const -{ - if (mSelectedItems.empty()) - { - return FALSE; - } - - if(getVisible() && getEnabled()) - { - for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); - item_it != mSelectedItems.end(); ++item_it) - { - // *TODO: only check folders and parent folders of items - const LLFolderViewItem* item = (*item_it); - const LLFolderViewEventListener* listener = item->getListener(); - if(!listener || !listener->isClipboardPasteable()) - { - const LLFolderViewFolder* folderp = item->getParentFolder(); - listener = folderp->getListener(); - if (!listener || !listener->isClipboardPasteable()) - { - return FALSE; - } - } - } - return TRUE; - } - return FALSE; -} - -// paste selected item -void LLFolderView::paste() -{ - if(getVisible() && getEnabled()) - { - // find set of unique folders to paste into - std::set<LLFolderViewItem*> folder_set; - - selected_items_t::iterator selected_it; - for (selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it) - { - LLFolderViewItem* item = *selected_it; - LLFolderViewEventListener* listener = item->getListener(); - if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY) - { - item = item->getParentFolder(); - } - folder_set.insert(item); - } - - std::set<LLFolderViewItem*>::iterator set_iter; - for(set_iter = folder_set.begin(); set_iter != folder_set.end(); ++set_iter) - { - LLFolderViewEventListener* listener = (*set_iter)->getListener(); - if(listener && listener->isClipboardPasteable()) - { - listener->pasteFromClipboard(); - } - } - } - mSearchString.clear(); -} - -// public rename functionality - can only start the process -void LLFolderView::startRenamingSelectedItem( void ) -{ - // make sure selection is visible - scrollToShowSelection(); - - S32 count = mSelectedItems.size(); - LLFolderViewItem* item = NULL; - if(count > 0) - { - item = mSelectedItems.front(); - } - if(getVisible() && getEnabled() && (count == 1) && item && item->getListener() && - item->getListener()->isItemRenameable()) - { - mRenameItem = item; - - updateRenamerPosition(); - - - mRenamer->setText(item->getName()); - mRenamer->selectAll(); - mRenamer->setVisible( TRUE ); - // set focus will fail unless item is visible - mRenamer->setFocus( TRUE ); - mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this)); - gViewerWindow->addPopup(mRenamer); - } -} - -BOOL LLFolderView::handleKeyHere( KEY key, MASK mask ) -{ - BOOL handled = FALSE; - - // SL-51858: Key presses are not being passed to the Popup menu. - // A proper fix is non-trivial so instead just close the menu. - LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); - if (menu && menu->isOpen()) - { - LLMenuGL::sMenuContainer->hideMenus(); - } - - LLView *item = NULL; - if (getChildCount() > 0) - { - item = *(getChildList()->begin()); - } - - switch( key ) - { - case KEY_F2: - mSearchString.clear(); - startRenamingSelectedItem(); - handled = TRUE; - break; - - case KEY_RETURN: - if (mask == MASK_NONE) - { - if( mRenameItem && mRenamer->getVisible() ) - { - finishRenamingItem(); - mSearchString.clear(); - handled = TRUE; - } - else - { - LLFolderView::openSelectedItems(); - handled = TRUE; - } - } - break; - - case KEY_ESCAPE: - if( mRenameItem && mRenamer->getVisible() ) - { - closeRenamer(); - handled = TRUE; - } - mSearchString.clear(); - break; - - case KEY_PAGE_UP: - mSearchString.clear(); - mScrollContainer->pageUp(30); - handled = TRUE; - break; - - case KEY_PAGE_DOWN: - mSearchString.clear(); - mScrollContainer->pageDown(30); - handled = TRUE; - break; - - case KEY_HOME: - mSearchString.clear(); - mScrollContainer->goToTop(); - handled = TRUE; - break; - - case KEY_END: - mSearchString.clear(); - mScrollContainer->goToBottom(); - break; - - case KEY_DOWN: - if((mSelectedItems.size() > 0) && mScrollContainer) - { - LLFolderViewItem* last_selected = getCurSelectedItem(); - - if (!mKeyboardSelection) - { - setSelection(last_selected, FALSE, TRUE); - mKeyboardSelection = TRUE; - } - - LLFolderViewItem* next = NULL; - if (mask & MASK_SHIFT) - { - // don't shift select down to children of folders (they are implicitly selected through parent) - next = last_selected->getNextOpenNode(FALSE); - if (next) - { - if (next->isSelected()) - { - // shrink selection - changeSelectionFromRoot(last_selected, FALSE); - } - else if (last_selected->getParentFolder() == next->getParentFolder()) - { - // grow selection - changeSelectionFromRoot(next, TRUE); - } - } - } - else - { - next = last_selected->getNextOpenNode(); - if( next ) - { - if (next == last_selected) - { - //special case for LLAccordionCtrl - if(notifyParent(LLSD().with("action","select_next")) > 0 )//message was processed - { - clearSelection(); - return TRUE; - } - return FALSE; - } - setSelection( next, FALSE, TRUE ); - } - else - { - //special case for LLAccordionCtrl - if(notifyParent(LLSD().with("action","select_next")) > 0 )//message was processed - { - clearSelection(); - return TRUE; - } - return FALSE; - } - } - scrollToShowSelection(); - mSearchString.clear(); - handled = TRUE; - } - break; - - case KEY_UP: - if((mSelectedItems.size() > 0) && mScrollContainer) - { - LLFolderViewItem* last_selected = mSelectedItems.back(); - - if (!mKeyboardSelection) - { - setSelection(last_selected, FALSE, TRUE); - mKeyboardSelection = TRUE; - } - - LLFolderViewItem* prev = NULL; - if (mask & MASK_SHIFT) - { - // don't shift select down to children of folders (they are implicitly selected through parent) - prev = last_selected->getPreviousOpenNode(FALSE); - if (prev) - { - if (prev->isSelected()) - { - // shrink selection - changeSelectionFromRoot(last_selected, FALSE); - } - else if (last_selected->getParentFolder() == prev->getParentFolder()) - { - // grow selection - changeSelectionFromRoot(prev, TRUE); - } - } - } - else - { - prev = last_selected->getPreviousOpenNode(); - if( prev ) - { - if (prev == this) - { - // If case we are in accordion tab notify parent to go to the previous accordion - if(notifyParent(LLSD().with("action","select_prev")) > 0 )//message was processed - { - clearSelection(); - return TRUE; - } - - return FALSE; - } - setSelection( prev, FALSE, TRUE ); - } - } - scrollToShowSelection(); - mSearchString.clear(); - - handled = TRUE; - } - break; - - case KEY_RIGHT: - if(mSelectedItems.size()) - { - LLFolderViewItem* last_selected = getCurSelectedItem(); - last_selected->setOpen( TRUE ); - mSearchString.clear(); - handled = TRUE; - } - break; - - case KEY_LEFT: - if(mSelectedItems.size()) - { - LLFolderViewItem* last_selected = getCurSelectedItem(); - LLFolderViewItem* parent_folder = last_selected->getParentFolder(); - if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder()) - { - setSelection(parent_folder, FALSE, TRUE); - } - else - { - last_selected->setOpen( FALSE ); - } - mSearchString.clear(); - scrollToShowSelection(); - handled = TRUE; - } - break; - } - - if (!handled && mParentPanel->hasFocus()) - { - if (key == KEY_BACKSPACE) - { - mSearchTimer.reset(); - if (mSearchString.size()) - { - mSearchString.erase(mSearchString.size() - 1, 1); - } - search(getCurSelectedItem(), mSearchString, FALSE); - handled = TRUE; - } - } - - return handled; -} - - -BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char) -{ - if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL - { - return FALSE; - } - - if (uni_char > 0x7f) - { - llwarns << "LLFolderView::handleUnicodeCharHere - Don't handle non-ascii yet, aborting" << llendl; - return FALSE; - } - - BOOL handled = FALSE; - if (mParentPanel->hasFocus()) - { - // SL-51858: Key presses are not being passed to the Popup menu. - // A proper fix is non-trivial so instead just close the menu. - LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); - if (menu && menu->isOpen()) - { - LLMenuGL::sMenuContainer->hideMenus(); - } - - //do text search - if (mSearchTimer.getElapsedTimeF32() > gSavedSettings.getF32("TypeAheadTimeout")) - { - mSearchString.clear(); - } - mSearchTimer.reset(); - if (mSearchString.size() < 128) - { - mSearchString += uni_char; - } - search(getCurSelectedItem(), mSearchString, FALSE); - - handled = TRUE; - } - - return handled; -} - - -BOOL LLFolderView::canDoDelete() const -{ - if (mSelectedItems.size() == 0) return FALSE; - - for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) - { - if (!(*item_it)->getListener()->isItemRemovable()) - { - return FALSE; - } - } - return TRUE; -} - -void LLFolderView::doDelete() -{ - if(mSelectedItems.size() > 0) - { - removeSelectedItems(); - } -} - - -BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - mKeyboardSelection = FALSE; - mSearchString.clear(); - - mParentPanel->setFocus(TRUE); - - LLEditMenuHandler::gEditMenuHandler = this; - - return LLView::handleMouseDown( x, y, mask ); -} - -BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward) -{ - // get first selected item - LLFolderViewItem* search_item = first_item; - - // make sure search string is upper case - std::string upper_case_string = search_string; - LLStringUtil::toUpper(upper_case_string); - - // if nothing selected, select first item in folder - if (!search_item) - { - // start from first item - search_item = getNextFromChild(NULL); - } - - // search over all open nodes for first substring match (with wrapping) - BOOL found = FALSE; - LLFolderViewItem* original_search_item = search_item; - do - { - // wrap at end - if (!search_item) - { - if (backward) - { - search_item = getPreviousFromChild(NULL); - } - else - { - search_item = getNextFromChild(NULL); - } - if (!search_item || search_item == original_search_item) - { - break; - } - } - - const std::string current_item_label(search_item->getSearchableLabel()); - S32 search_string_length = llmin(upper_case_string.size(), current_item_label.size()); - if (!current_item_label.compare(0, search_string_length, upper_case_string)) - { - found = TRUE; - break; - } - if (backward) - { - search_item = search_item->getPreviousOpenNode(); - } - else - { - search_item = search_item->getNextOpenNode(); - } - - } while(search_item != original_search_item); - - - if (found) - { - setSelection(search_item, FALSE, TRUE); - scrollToShowSelection(); - } - - return found; -} - -BOOL LLFolderView::handleDoubleClick( S32 x, S32 y, MASK mask ) -{ - // skip LLFolderViewFolder::handleDoubleClick() - return LLView::handleDoubleClick( x, y, mask ); -} - -BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask ) -{ - // all user operations move keyboard focus to inventory - // this way, we know when to stop auto-updating a search - mParentPanel->setFocus(TRUE); - - BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL; - S32 count = mSelectedItems.size(); - LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); - if ( handled - && ( count > 0 && (hasVisibleChildren() || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) ) // show menu only if selected items are visible - && menu ) - { - if (mCallbackRegistrar) - mCallbackRegistrar->pushScope(); - - updateMenuOptions(menu); - - menu->updateParent(LLMenuGL::sMenuContainer); - LLMenuGL::showPopup(this, menu, x, y); - if (mCallbackRegistrar) - mCallbackRegistrar->popScope(); - } - else - { - if (menu && menu->getVisible()) - { - menu->setVisible(FALSE); - } - setSelection(NULL, FALSE, TRUE); - } - return handled; -} - -// Add "--no options--" if the menu is completely blank. -BOOL LLFolderView::addNoOptions(LLMenuGL* menu) const -{ - const std::string nooptions_str = "--no options--"; - LLView *nooptions_item = NULL; - - const LLView::child_list_t *list = menu->getChildList(); - for (LLView::child_list_t::const_iterator itor = list->begin(); - itor != list->end(); - ++itor) - { - LLView *menu_item = (*itor); - if (menu_item->getVisible()) - { - return FALSE; - } - std::string name = menu_item->getName(); - if (menu_item->getName() == nooptions_str) - { - nooptions_item = menu_item; - } - } - if (nooptions_item) - { - nooptions_item->setVisible(TRUE); - nooptions_item->setEnabled(FALSE); - return TRUE; - } - return FALSE; -} - -BOOL LLFolderView::handleHover( S32 x, S32 y, MASK mask ) -{ - return LLView::handleHover( x, y, mask ); -} - -BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - mDragAndDropThisFrame = TRUE; - // have children handle it first - BOOL handled = LLView::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, - accept, tooltip_msg); - - // when drop is not handled by child, it should be handled - // by the folder which is the hierarchy root. - if (!handled) - { - if (getListener()->getUUID().notNull()) - { - handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); - } - else - { - if (!mFolders.empty()) - { - // dispatch to last folder as a hack to support "Contents" folder in object inventory - handled = mFolders.back()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg); - } - } - } - - if (handled) - { - lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderView" << llendl; - } - - return handled; -} - -void LLFolderView::deleteAllChildren() -{ - closeRenamer(); - delete mPopupMenuHandle.get(); - mPopupMenuHandle = LLHandle<LLView>(); - mScrollContainer = NULL; - mRenameItem = NULL; - mRenamer = NULL; - mStatusTextBox = NULL; - - clearSelection(); - LLView::deleteAllChildren(); -} - -void LLFolderView::scrollToShowSelection() -{ - // If items are filtered while background fetch is in progress - // scrollbar resets to the first filtered item. See EXT-3981. - // However we allow scrolling for folder views with mAutoSelectOverride - // (used in Places SP) as an exception because the selection in them - // is not reset during items filtering. See STORM-133. - if ( (!LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mAutoSelectOverride) - && mSelectedItems.size() ) - { - mNeedsScroll = TRUE; - } -} - -// If the parent is scroll containter, scroll it to make the selection -// is maximally visible. -void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect) -{ - if (!mScrollContainer) return; - - // don't scroll to items when mouse is being used to scroll/drag and drop - if (gFocusMgr.childHasMouseCapture(mScrollContainer)) - { - mNeedsScroll = FALSE; - return; - } - - // if item exists and is in visible portion of parent folder... - if(item) - { - LLRect local_rect = item->getLocalRect(); - LLRect item_scrolled_rect; // item position relative to display area of scroller - LLRect visible_doc_rect = mScrollContainer->getVisibleContentRect(); - - S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight(); - S32 label_height = llround(getLabelFontForStyle(mLabelStyle)->getLineHeight()); - // when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder - S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + ICON_PAD) : local_rect.getHeight(); - - // get portion of item that we want to see... - LLRect item_local_rect = LLRect(item->getIndentation(), - local_rect.getHeight(), - llmin(MIN_ITEM_WIDTH_VISIBLE, local_rect.getWidth()), - llmax(0, local_rect.getHeight() - max_height_to_show)); - - LLRect item_doc_rect; - - item->localRectToOtherView(item_local_rect, &item_doc_rect, this); - - mScrollContainer->scrollToShowRect( item_doc_rect, constraint_rect ); - - } -} - -LLRect LLFolderView::getVisibleRect() -{ - S32 visible_height = mScrollContainer->getRect().getHeight(); - S32 visible_width = mScrollContainer->getRect().getWidth(); - LLRect visible_rect; - visible_rect.setLeftTopAndSize(-getRect().mLeft, visible_height - getRect().mBottom, visible_width, visible_height); - return visible_rect; -} - -BOOL LLFolderView::getShowSelectionContext() -{ - if (mShowSelectionContext) - { - return TRUE; - } - LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); - if (menu && menu->getVisible()) - { - return TRUE; - } - return FALSE; -} - -void LLFolderView::setShowSingleSelection(BOOL show) -{ - if (show != mShowSingleSelection) - { - mMultiSelectionFadeTimer.reset(); - mShowSingleSelection = show; - } -} - -void LLFolderView::addItemID(const LLUUID& id, LLFolderViewItem* itemp) -{ - mItemMap[id] = itemp; -} - -void LLFolderView::removeItemID(const LLUUID& id) -{ - mItemMap.erase(id); -} - -LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID"); -LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id) -{ - LLFastTimer _(FTM_GET_ITEM_BY_ID); - if (id == getListener()->getUUID()) - { - return this; - } - - std::map<LLUUID, LLFolderViewItem*>::iterator map_it; - map_it = mItemMap.find(id); - if (map_it != mItemMap.end()) - { - return map_it->second; - } - - return NULL; -} - -LLFolderViewFolder* LLFolderView::getFolderByID(const LLUUID& id) -{ - if (id == getListener()->getUUID()) - { - return this; - } - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end(); - ++iter) - { - LLFolderViewFolder *folder = (*iter); - if (folder->getListener()->getUUID() == id) - { - return folder; - } - } - return NULL; -} - -bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata) -{ - std::string action = userdata.asString(); - - if ("rename" == action) - { - startRenamingSelectedItem(); - return true; - } - if ("delete" == action) - { - removeSelectedItems(); - return true; - } - - if ("copy" == action) - { - LLInventoryClipboard::instance().reset(); - } - - static const std::string change_folder_string = "change_folder_type_"; - if (action.length() > change_folder_string.length() && - (action.compare(0,change_folder_string.length(),"change_folder_type_") == 0)) - { - LLFolderType::EType new_folder_type = LLViewerFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length())); - changeType(model, new_folder_type); - return true; - } - - - std::set<LLUUID> selected_items = getSelectionList(); - - LLMultiPreview* multi_previewp = NULL; - LLMultiProperties* multi_propertiesp = NULL; - - if (("task_open" == action || "open" == action) && selected_items.size() > 1) - { - multi_previewp = new LLMultiPreview(); - gFloaterView->addChild(multi_previewp); - - LLFloater::setFloaterHost(multi_previewp); - - } - else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1) - { - multi_propertiesp = new LLMultiProperties(); - gFloaterView->addChild(multi_propertiesp); - - LLFloater::setFloaterHost(multi_propertiesp); - } - - std::set<LLUUID>::iterator set_iter; - - for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter) - { - LLFolderViewItem* folder_item = getItemByID(*set_iter); - if(!folder_item) continue; - LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener(); - if(!bridge) continue; - bridge->performAction(model, action); - } - - LLFloater::setFloaterHost(NULL); - if (multi_previewp) - { - multi_previewp->openFloater(LLSD()); - } - else if (multi_propertiesp) - { - multi_propertiesp->openFloater(LLSD()); - } - - return true; -} - -static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select"); -static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory"); - -// Main idle routine -void LLFolderView::doIdle() -{ - // If this is associated with the user's inventory, don't do anything - // until that inventory is loaded up. - const LLInventoryPanel *inventory_panel = dynamic_cast<LLInventoryPanel*>(mParentPanel); - if (inventory_panel && !inventory_panel->getIsViewsInitialized()) - { - return; - } - - LLFastTimer t2(FTM_INVENTORY); - - BOOL debug_filters = gSavedSettings.getBOOL("DebugInventoryFilters"); - if (debug_filters != getDebugFilters()) - { - mDebugFilters = debug_filters; - arrangeAll(); - } - - mFilter->clearModified(); - BOOL filter_modified_and_active = mCompletedFilterGeneration < mFilter->getCurrentGeneration() && - mFilter->isNotDefault(); - mNeedsAutoSelect = filter_modified_and_active && - !(gFocusMgr.childHasKeyboardFocus(this) || gFocusMgr.getMouseCapture()); - - // filter to determine visiblity before arranging - filterFromRoot(); - - // automatically show matching items, and select first one if we had a selection - // do this every frame until user puts keyboard focus into the inventory window - // signaling the end of the automatic update - // only do this when mNeedsFilter is set, meaning filtered items have - // potentially changed - if (mNeedsAutoSelect) - { - LLFastTimer t3(FTM_AUTO_SELECT); - // select new item only if a filtered item not currently selected - LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back(); - if ((selected_itemp && !selected_itemp->getFiltered()) && !mAutoSelectOverride) - { - // select first filtered item - LLSelectFirstFilteredItem filter; - applyFunctorRecursively(filter); - } - - // Open filtered folders for folder views with mAutoSelectOverride=TRUE. - // Used by LLPlacesFolderView. - if (mAutoSelectOverride && !mFilter->getFilterSubString().empty()) - { - LLOpenFilteredFolders filter; - applyFunctorRecursively(filter); - } - - scrollToShowSelection(); - } - - // during filtering process, try to pin selected item's location on screen - // this will happen when searching your inventory and when new items arrive - if (filter_modified_and_active) - { - // calculate rectangle to pin item to at start of animated rearrange - if (!mPinningSelectedItem && !mSelectedItems.empty()) - { - // lets pin it! - mPinningSelectedItem = TRUE; - - LLRect visible_content_rect = mScrollContainer->getVisibleContentRect(); - LLFolderViewItem* selected_item = mSelectedItems.back(); - - LLRect item_rect; - selected_item->localRectToOtherView(selected_item->getLocalRect(), &item_rect, this); - // if item is visible in scrolled region - if (visible_content_rect.overlaps(item_rect)) - { - // then attempt to keep it in same place on screen - mScrollConstraintRect = item_rect; - mScrollConstraintRect.translate(-visible_content_rect.mLeft, -visible_content_rect.mBottom); - } - else - { - // otherwise we just want it onscreen somewhere - LLRect content_rect = mScrollContainer->getContentWindowRect(); - mScrollConstraintRect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight()); - } - } - } - else - { - // stop pinning selected item after folders stop rearranging - if (!needsArrange()) - { - mPinningSelectedItem = FALSE; - } - } - - LLRect constraint_rect; - if (mPinningSelectedItem) - { - // use last known constraint rect for pinned item - constraint_rect = mScrollConstraintRect; - } - else - { - // during normal use (page up/page down, etc), just try to fit item on screen - LLRect content_rect = mScrollContainer->getContentWindowRect(); - constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight()); - } - - - BOOL is_visible = isInVisibleChain(); - - if ( is_visible ) - { - sanitizeSelection(); - if( needsArrange() ) - { - arrangeFromRoot(); - } - } - - if (mSelectedItems.size() && mNeedsScroll) - { - scrollToShowItem(mSelectedItems.back(), constraint_rect); - // continue scrolling until animated layout change is done - if (!filter_modified_and_active - && (!needsArrange() || !is_visible)) - { - mNeedsScroll = FALSE; - } - } - - if (mSignalSelectCallback) - { - //RN: we use keyboard focus as a proxy for user-explicit actions - BOOL take_keyboard_focus = (mSignalSelectCallback == SIGNAL_KEYBOARD_FOCUS); - mSelectSignal(mSelectedItems, take_keyboard_focus); - } - mSignalSelectCallback = FALSE; -} - - -//static -void LLFolderView::idle(void* user_data) -{ - LLFolderView* self = (LLFolderView*)user_data; - if ( self ) - { // Do the real idle - self->doIdle(); - } -} - -void LLFolderView::dumpSelectionInformation() -{ - llinfos << "LLFolderView::dumpSelectionInformation()" << llendl; - llinfos << "****************************************" << llendl; - selected_items_t::iterator item_it; - for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) - { - llinfos << " " << (*item_it)->getName() << llendl; - } - llinfos << "****************************************" << llendl; -} - -void LLFolderView::updateRenamerPosition() -{ - if(mRenameItem) - { - // See also LLFolderViewItem::draw() - S32 x = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mRenameItem->getIndentation(); - S32 y = mRenameItem->getRect().getHeight() - mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD; - mRenameItem->localPointToScreen( x, y, &x, &y ); - screenPointToLocal( x, y, &x, &y ); - mRenamer->setOrigin( x, y ); - - LLRect scroller_rect(0, 0, gViewerWindow->getWindowWidthScaled(), 0); - if (mScrollContainer) - { - scroller_rect = mScrollContainer->getContentWindowRect(); - } - - S32 width = llmax(llmin(mRenameItem->getRect().getWidth() - x, scroller_rect.getWidth() - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH); - S32 height = mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD; - mRenamer->reshape( width, height, TRUE ); - } -} - -// Update visibility and availability (i.e. enabled/disabled) of context menu items. -void LLFolderView::updateMenuOptions(LLMenuGL* menu) -{ - const LLView::child_list_t *list = menu->getChildList(); - - LLView::child_list_t::const_iterator menu_itor; - for (menu_itor = list->begin(); menu_itor != list->end(); ++menu_itor) - { - (*menu_itor)->setVisible(FALSE); - (*menu_itor)->pushVisible(TRUE); - (*menu_itor)->setEnabled(TRUE); - } - - // Successively filter out invalid options - - U32 flags = FIRST_SELECTED_ITEM; - for (selected_items_t::iterator item_itor = mSelectedItems.begin(); - item_itor != mSelectedItems.end(); - ++item_itor) - { - LLFolderViewItem* selected_item = (*item_itor); - selected_item->buildContextMenu(*menu, flags); - flags = 0x0; - } - - addNoOptions(menu); -} - -// Refresh the context menu (that is already shown). -void LLFolderView::updateMenu() -{ - LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); - if (menu && menu->getVisible()) - { - updateMenuOptions(menu); - menu->needsArrange(); // update menu height if needed - } -} - -bool LLFolderView::selectFirstItem() -{ - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();++iter) - { - LLFolderViewFolder* folder = (*iter ); - if (folder->getVisible()) - { - LLFolderViewItem* itemp = folder->getNextFromChild(0,true); - if(itemp) - setSelection(itemp,FALSE,TRUE); - return true; - } - - } - for(items_t::iterator iit = mItems.begin(); - iit != mItems.end(); ++iit) - { - LLFolderViewItem* itemp = (*iit); - if (itemp->getVisible()) - { - setSelection(itemp,FALSE,TRUE); - return true; - } - } - return false; -} -bool LLFolderView::selectLastItem() -{ - for(items_t::reverse_iterator iit = mItems.rbegin(); - iit != mItems.rend(); ++iit) - { - LLFolderViewItem* itemp = (*iit); - if (itemp->getVisible()) - { - setSelection(itemp,FALSE,TRUE); - return true; - } - } - for (folders_t::reverse_iterator iter = mFolders.rbegin(); - iter != mFolders.rend();++iter) - { - LLFolderViewFolder* folder = (*iter); - if (folder->getVisible()) - { - LLFolderViewItem* itemp = folder->getPreviousFromChild(0,true); - if(itemp) - setSelection(itemp,FALSE,TRUE); - return true; - } - } - return false; -} - - -S32 LLFolderView::notify(const LLSD& info) -{ - if(info.has("action")) - { - std::string str_action = info["action"]; - if(str_action == "select_first") - { - setFocus(true); - selectFirstItem(); - scrollToShowSelection(); - return 1; - - } - else if(str_action == "select_last") - { - setFocus(true); - selectLastItem(); - scrollToShowSelection(); - return 1; - } - } - return 0; -} - - -///---------------------------------------------------------------------------- -/// Local function definitions -///---------------------------------------------------------------------------- - -void LLFolderView::onRenamerLost() -{ - if (mRenamer && mRenamer->getVisible()) - { - mRenamer->setVisible(FALSE); - - // will commit current name (which could be same as original name) - mRenamer->setFocus(FALSE); - } - - if( mRenameItem ) - { - setSelectionFromRoot( mRenameItem, TRUE ); - mRenameItem = NULL; - } -} - -LLInventoryFilter* LLFolderView::getFilter() -{ - return mFilter; -} - -void LLFolderView::setFilterPermMask( PermissionMask filter_perm_mask ) -{ - mFilter->setFilterPermissions(filter_perm_mask); -} - -U32 LLFolderView::getFilterObjectTypes() const -{ - return mFilter->getFilterObjectTypes(); -} - -PermissionMask LLFolderView::getFilterPermissions() const -{ - return mFilter->getFilterPermissions(); -} - -BOOL LLFolderView::isFilterModified() -{ - return mFilter->isNotDefault(); -} - -void delete_selected_item(void* user_data) -{ - if(user_data) - { - LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data); - fv->removeSelectedItems(); - } -} - -void copy_selected_item(void* user_data) -{ - if(user_data) - { - LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data); - fv->copy(); - } -} - -void paste_items(void* user_data) -{ - if(user_data) - { - LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data); - fv->paste(); - } -} - -void open_selected_items(void* user_data) -{ - if(user_data) - { - LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data); - fv->openSelectedItems(); - } -} - -void properties_selected_items(void* user_data) -{ - if(user_data) - { - LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data); - fv->propertiesSelectedItems(); - } -} diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h deleted file mode 100644 index 8af01e9102..0000000000 --- a/indra/newview/llfolderview.h +++ /dev/null @@ -1,351 +0,0 @@ -/** - * @file llfolderview.h - * @brief Definition of the folder view collection of classes. - * - * $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$ - */ - -/** - * - * The folder view collection of classes provides an interface for - * making a 'folder view' similar to the way the a single pane file - * folder interface works. - * - */ - -#ifndef LL_LLFOLDERVIEW_H -#define LL_LLFOLDERVIEW_H - -#include "llfolderviewitem.h" // because LLFolderView is-a LLFolderViewFolder - -#include "lluictrl.h" -#include "v4color.h" -#include "lldarray.h" -#include "stdenums.h" -#include "lldepthstack.h" -#include "lleditmenuhandler.h" -#include "llfontgl.h" -#include "lltooldraganddrop.h" -#include "llviewertexture.h" - -class LLFolderViewEventListener; -class LLFolderViewFolder; -class LLFolderViewItem; -class LLInventoryModel; -class LLPanel; -class LLLineEditor; -class LLMenuGL; -class LLScrollContainer; -class LLUICtrl; -class LLTextBox; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderView -// -// Th LLFolderView represents the root level folder view object. It -// manages the screen region of the folder view. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler -{ -public: - struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params> - { - Mandatory<LLPanel*> parent_panel; - Optional<LLUUID> task_id; - Optional<std::string> title; - Optional<bool> use_label_suffix, - allow_multiselect, - show_load_status, - use_ellipses; - - Params(); - }; - LLFolderView(const Params&); - virtual ~LLFolderView( void ); - - virtual BOOL canFocusChildren() const; - - virtual LLFolderView* getRoot() { return this; } - - // FolderViews default to sort by name. This will change that, - // and resort the items if necessary. - void setSortOrder(U32 order); - void setFilterPermMask(PermissionMask filter_perm_mask); - - typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t; - void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); } - void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); } - - // filter is never null - LLInventoryFilter* getFilter(); - const std::string getFilterSubString(BOOL trim = FALSE); - U32 getFilterObjectTypes() const; - PermissionMask getFilterPermissions() const; - // *NOTE: use getFilter()->getShowFolderState(); - //LLInventoryFilter::EFolderShow getShowFolderState(); - U32 getSortOrder() const; - BOOL isFilterModified(); - - // Close all folders in the view - void closeAllFolders(); - void openTopLevelFolders(); - - virtual void toggleOpen() {}; - virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse); - virtual BOOL addFolder( LLFolderViewFolder* folder); - - // Finds width and height of this object and it's children. Also - // makes sure that this view and it's children are the right size. - virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); - - void arrangeAll() { mArrangeGeneration++; } - S32 getArrangeGeneration() { return mArrangeGeneration; } - - // applies filters to control visibility of inventory items - virtual void filter( LLInventoryFilter& filter); - - // get the last selected item - virtual LLFolderViewItem* getCurSelectedItem( void ); - - // Record the selected item and pass it down the hierachy. - virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus); - - // Used by menu callbacks - void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus); - - // Called once a frame to update the selection if mSelectThisID has been set - void updateSelection(); - - // This method is used to toggle the selection of an item. Walks - // 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 - void sanitizeSelection(); - void clearSelection(); - void addToSelectionList(LLFolderViewItem* item); - void removeFromSelectionList(LLFolderViewItem* item); - - BOOL startDrag(LLToolDragAndDrop::ESource source); - void setDragAndDropThisFrame() { mDragAndDropThisFrame = TRUE; } - void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; } - LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; } - - - // deletion functionality - void removeSelectedItems(); - - // open the selected item. - void openSelectedItems( void ); - void propertiesSelectedItems( void ); - - // change the folder type - void changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type); - - void autoOpenItem(LLFolderViewFolder* item); - void closeAutoOpenedFolders(); - BOOL autoOpenTest(LLFolderViewFolder* item); - - // copy & paste - virtual void copy(); - virtual BOOL canCopy() const; - - virtual void cut(); - virtual BOOL canCut() const; - - virtual void paste(); - virtual BOOL canPaste() const; - - virtual void doDelete(); - virtual BOOL canDoDelete() const; - - // public rename functionality - can only start the process - void startRenamingSelectedItem( void ); - - // These functions were used when there was only one folderview, - // and relied on that concept. This functionality is now handled - // by the listeners and the lldraganddroptool. - //LLFolderViewItem* getMovingItem() { return mMovingItem; } - //void setMovingItem( LLFolderViewItem* item ) { mMovingItem = item; } - //void dragItemIntoFolder( LLFolderViewItem* moving_item, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept ); - //void dragFolderIntoFolder( LLFolderViewFolder* moving_folder, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept ); - - // LLView functionality - ///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent ); - /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask ); - /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char); - /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); - /*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); - /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); - /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask ); - /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg); - /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); - /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) { setShowSelectionContext(FALSE); } - virtual void draw(); - virtual void deleteAllChildren(); - - void scrollToShowSelection(); - void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect); - void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; } - LLRect getVisibleRect(); - - BOOL search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward); - void setShowSelectionContext(BOOL show) { mShowSelectionContext = show; } - BOOL getShowSelectionContext(); - void setShowSingleSelection(BOOL show); - BOOL getShowSingleSelection() { return mShowSingleSelection; } - F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); } - bool getUseEllipses() { return mUseEllipses; } - - void addItemID(const LLUUID& id, LLFolderViewItem* itemp); - void removeItemID(const LLUUID& id); - LLFolderViewItem* getItemByID(const LLUUID& id); - LLFolderViewFolder* getFolderByID(const LLUUID& id); - - bool doToSelected(LLInventoryModel* model, const LLSD& userdata); - - void doIdle(); // Real idle routine - static void idle(void* user_data); // static glue to doIdle() - - BOOL needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; } - BOOL needsAutoRename() { return mNeedsAutoRename; } - void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; } - void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; } - void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; } - - void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; } - - BOOL getDebugFilters() { return mDebugFilters; } - - LLPanel* getParentPanel() { return mParentPanel; } - // DEBUG only - void dumpSelectionInformation(); - - virtual S32 notify(const LLSD& info) ; - - bool useLabelSuffix() { return mUseLabelSuffix; } - void updateMenu(); - -private: - void updateMenuOptions(LLMenuGL* menu); - void updateRenamerPosition(); - -protected: - LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container. - - void commitRename( const LLSD& data ); - void onRenamerLost(); - - void finishRenamingItem( void ); - void closeRenamer( void ); - - bool selectFirstItem(); - bool selectLastItem(); - - BOOL addNoOptions(LLMenuGL* menu) const; - - void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response); - -protected: - LLHandle<LLView> mPopupMenuHandle; - - typedef std::deque<LLFolderViewItem*> selected_items_t; - selected_items_t mSelectedItems; - BOOL mKeyboardSelection; - BOOL mAllowMultiSelect; - BOOL mShowFolderHierarchy; - LLUUID mSourceID; - - // Renaming variables and methods - LLFolderViewItem* mRenameItem; // The item currently being renamed - LLLineEditor* mRenamer; - - BOOL mNeedsScroll; - BOOL mPinningSelectedItem; - LLRect mScrollConstraintRect; - BOOL mNeedsAutoSelect; - BOOL mAutoSelectOverride; - BOOL mNeedsAutoRename; - bool mUseLabelSuffix; - - BOOL mDebugFilters; - U32 mSortOrder; - LLDepthStack<LLFolderViewFolder> mAutoOpenItems; - LLFolderViewFolder* mAutoOpenCandidate; - LLFrameTimer mAutoOpenTimer; - LLFrameTimer mSearchTimer; - std::string mSearchString; - LLInventoryFilter* mFilter; - BOOL mShowSelectionContext; - BOOL mShowSingleSelection; - LLFrameTimer mMultiSelectionFadeTimer; - S32 mArrangeGeneration; - - signal_t mSelectSignal; - signal_t mReshapeSignal; - S32 mSignalSelectCallback; - S32 mMinWidth; - S32 mRunningHeight; - std::map<LLUUID, LLFolderViewItem*> mItemMap; - BOOL mDragAndDropThisFrame; - - LLUUID mSelectThisID; // if non null, select this item - - LLPanel* mParentPanel; - - /** - * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll. - * NOTE: For now it uses only to cut LLFolderViewItem::mLabel text to be used for Landmarks in Places Panel. - */ - bool mUseEllipses; // See EXT-719 - - /** - * Contains item under mouse pointer while dragging - */ - LLFolderViewItem* mDraggingOverItem; // See EXT-719 - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar; - -public: - static F32 sAutoOpenTime; - LLTextBox* mStatusTextBox; - -}; - -bool sort_item_name(LLFolderViewItem* a, LLFolderViewItem* b); -bool sort_item_date(LLFolderViewItem* a, LLFolderViewItem* b); - -// Flags for buildContextMenu() -const U32 SUPPRESS_OPEN_ITEM = 0x1; -const U32 FIRST_SELECTED_ITEM = 0x2; - -#endif // LL_LLFOLDERVIEW_H diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h deleted file mode 100644 index aee31ca033..0000000000 --- a/indra/newview/llfoldervieweventlistener.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file llfoldervieweventlistener.h - * - * $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$ - */ -#ifndef LLFOLDERVIEWEVENTLISTENER_H -#define LLFOLDERVIEWEVENTLISTENER_H - -#include "lldarray.h" // *TODO: convert to std::vector -#include "llfoldertype.h" -#include "llfontgl.h" // just for StyleFlags enum -#include "llinventorytype.h" -#include "llpermissionsflags.h" -#include "llpointer.h" -#include "llwearabletype.h" - - -class LLFolderViewItem; -class LLFolderView; -class LLFontGL; -class LLInventoryModel; -class LLMenuGL; -class LLScrollContainer; -class LLUIImage; -class LLUUID; - -// This is an abstract base class that users of the folderview classes -// would use to catch the useful events emitted from the folder -// views. -class LLFolderViewEventListener -{ -public: - virtual ~LLFolderViewEventListener( void ) {} - virtual const std::string& getName() const = 0; - virtual const std::string& getDisplayName() const = 0; - virtual const LLUUID& getUUID() const = 0; - virtual time_t getCreationDate() const = 0; // UTC seconds - virtual PermissionMask getPermissionMask() const = 0; - virtual LLFolderType::EType getPreferredType() const = 0; - virtual LLPointer<LLUIImage> getIcon() const = 0; - virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); } - virtual LLFontGL::StyleFlags getLabelStyle() const = 0; - virtual std::string getLabelSuffix() const = 0; - virtual void openItem( void ) = 0; - virtual void closeItem( void ) = 0; - virtual void previewItem( void ) = 0; - virtual void selectItem(void) = 0; - virtual void showProperties(void) = 0; - virtual BOOL isItemRenameable() const = 0; - virtual BOOL renameItem(const std::string& new_name) = 0; - virtual BOOL isItemMovable( void ) const = 0; // Can be moved to another folder - virtual BOOL isItemRemovable( void ) const = 0; // Can be destroyed - virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual. - virtual BOOL removeItem() = 0; - virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0; - virtual void move( LLFolderViewEventListener* parent_listener ) = 0; - virtual BOOL isItemCopyable() const = 0; - virtual BOOL copyToClipboard() const = 0; - virtual void cutToClipboard() = 0; - virtual BOOL isClipboardPasteable() const = 0; - virtual void pasteFromClipboard() = 0; - virtual void pasteLinkFromClipboard() = 0; - virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0; - virtual BOOL isUpToDate() const = 0; - virtual BOOL hasChildren() const = 0; - virtual LLInventoryType::EType getInventoryType() const = 0; - virtual void performAction(LLInventoryModel* model, std::string action) = 0; - virtual LLWearableType::EType getWearableType() const = 0; - - // This method should be called when a drag begins. returns TRUE - // if the drag can begin, otherwise FALSE. - virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0; - - // This method will be called to determine if a drop can be - // performed, and will set drop to TRUE if a drop is - // requested. Returns TRUE if a drop is possible/happened, - // otherwise FALSE. - virtual BOOL dragOrDrop(MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - std::string& tooltip_msg) = 0; -}; - -#endif diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp deleted file mode 100644 index 02222e430f..0000000000 --- a/indra/newview/llfolderviewitem.cpp +++ /dev/null @@ -1,2775 +0,0 @@ -/** -* @file llfolderviewitem.cpp -* @brief Items and folders that can appear in a hierarchical folder view -* -* $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 "llfolderviewitem.h" - -// viewer includes -#include "llfolderview.h" // Items depend extensively on LLFolderViews -#include "llfoldervieweventlistener.h" -#include "llviewerfoldertype.h" -#include "llinventorybridge.h" // for LLItemBridge in LLInventorySort::operator() -#include "llinventoryfilter.h" -#include "llinventoryfunctions.h" -#include "llinventorymodelbackgroundfetch.h" -#include "llpanel.h" -#include "llviewercontrol.h" // gSavedSettings -#include "llviewerwindow.h" // Argh, only for setCursor() - -// linden library includes -#include "llfocusmgr.h" // gFocusMgr -#include "lltrans.h" - -///---------------------------------------------------------------------------- -/// Class LLFolderViewItem -///---------------------------------------------------------------------------- - -static LLDefaultChildRegistry::Register<LLFolderViewItem> r("folder_view_item"); - -// statics -std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts - -// only integers can be initialized in header -const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f; -const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f; - -const LLColor4U DEFAULT_WHITE(255, 255, 255); - - -//static -LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style) -{ - LLFontGL* rtn = sFonts[style]; - if (!rtn) // grab label font with this style, lazily - { - LLFontDescriptor labelfontdesc("SansSerif", "Small", style); - rtn = LLFontGL::getFont(labelfontdesc); - if (!rtn) - { - rtn = LLFontGL::getFontDefault(); - } - sFonts[style] = rtn; - } - return rtn; -} - -//static -void LLFolderViewItem::initClass() -{ -} - -//static -void LLFolderViewItem::cleanupClass() -{ - sFonts.clear(); -} - - -// NOTE: Optimize this, we call it a *lot* when opening a large inventory -LLFolderViewItem::Params::Params() -: icon(), - icon_open(), - icon_overlay(), - root(), - listener(), - folder_arrow_image("folder_arrow_image"), - folder_indentation("folder_indentation"), - selection_image("selection_image"), - item_height("item_height"), - item_top_pad("item_top_pad"), - creation_date() -{} - -// Default constructor -LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p) -: LLView(p), - mLabelWidth(0), - mLabelWidthDirty(false), - mParentFolder( NULL ), - mIsSelected( FALSE ), - mIsCurSelection( FALSE ), - mSelectPending(FALSE), - mLabelStyle( LLFontGL::NORMAL ), - mHasVisibleChildren(FALSE), - mIndentation(0), - mItemHeight(p.item_height), - mPassedFilter(FALSE), - mLastFilterGeneration(-1), - mStringMatchOffset(std::string::npos), - mControlLabelRotation(0.f), - mDragAndDropTarget(FALSE), - mIsLoading(FALSE), - mLabel(p.name), - mRoot(p.root), - mCreationDate(p.creation_date), - mIcon(p.icon), - mIconOpen(p.icon_open), - mIconOverlay(p.icon_overlay), - mListener(p.listener), - mShowLoadStatus(false), - mIsMouseOverTitle(false) -{ -} - -BOOL LLFolderViewItem::postBuild() -{ - refresh(); - return TRUE; -} - -// Destroys the object -LLFolderViewItem::~LLFolderViewItem( void ) -{ - delete mListener; - mListener = NULL; -} - -LLFolderView* LLFolderViewItem::getRoot() -{ - return mRoot; -} - -// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor. -BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor ) -{ - LLFolderViewItem* root = this; - while( root->mParentFolder ) - { - if( root->mParentFolder == potential_ancestor ) - { - return TRUE; - } - root = root->mParentFolder; - } - return FALSE; -} - -LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children) -{ - if (!mParentFolder) - { - return NULL; - } - - LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children ); - while(itemp && !itemp->getVisible()) - { - LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children ); - if (itemp == next_itemp) - { - // hit last item - return itemp->getVisible() ? itemp : this; - } - itemp = next_itemp; - } - - return itemp; -} - -LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children) -{ - if (!mParentFolder) - { - return NULL; - } - - LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children ); - - // Skip over items that are invisible or are hidden from the UI. - while(itemp && !itemp->getVisible()) - { - LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children ); - if (itemp == next_itemp) - { - // hit first item - return itemp->getVisible() ? itemp : this; - } - itemp = next_itemp; - } - - return itemp; -} - -// is this item something we think we should be showing? -// for example, if we haven't gotten around to filtering it yet, then the answer is yes -// until we find out otherwise -BOOL LLFolderViewItem::potentiallyVisible() -{ - // we haven't been checked against min required filter - // or we have and we passed - return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered(); -} - -BOOL LLFolderViewItem::getFiltered() -{ - return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration(); -} - -BOOL LLFolderViewItem::getFiltered(S32 filter_generation) -{ - return mPassedFilter && mLastFilterGeneration >= filter_generation; -} - -void LLFolderViewItem::setFiltered(BOOL filtered, S32 filter_generation) -{ - mPassedFilter = filtered; - mLastFilterGeneration = filter_generation; -} - -void LLFolderViewItem::setIcon(LLUIImagePtr icon) -{ - mIcon = icon; -} - -// refresh information from the listener -void LLFolderViewItem::refreshFromListener() -{ - if(mListener) - { - mLabel = mListener->getDisplayName(); - LLFolderType::EType preferred_type = mListener->getPreferredType(); - - // *TODO: to be removed when database supports multi language. This is a - // temporary attempt to display the inventory folder in the user locale. - // mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID - // it uses the same way to find localized string - - // HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder) - // Translation of Accessories folder in Library inventory folder - bool accessories = false; - if(mLabel == std::string("Accessories")) - { - //To ensure that Accessories folder is in Library we have to check its parent folder. - //Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model - LLInventoryCategory* cat = gInventory.getCategory(mListener->getUUID()); - if(cat) - { - const LLUUID& parent_folder_id = cat->getParentUUID(); - accessories = (parent_folder_id == gInventory.getLibraryRootFolderID()); - } - } - - //"Accessories" inventory category has folder type FT_NONE. So, this folder - //can not be detected as protected with LLFolderType::lookupIsProtectedType - if (accessories || LLFolderType::lookupIsProtectedType(preferred_type)) - { - LLTrans::findString(mLabel, "InvFolder " + mLabel); - }; - - setToolTip(mLabel); - setIcon(mListener->getIcon()); - time_t creation_date = mListener->getCreationDate(); - if ((creation_date > 0) && (mCreationDate != creation_date)) - { - setCreationDate(creation_date); - dirtyFilter(); - } - if (mRoot->useLabelSuffix()) - { - mLabelStyle = mListener->getLabelStyle(); - mLabelSuffix = mListener->getLabelSuffix(); - } - } -} - -void LLFolderViewItem::refresh() -{ - refreshFromListener(); - - std::string searchable_label(mLabel); - searchable_label.append(mLabelSuffix); - LLStringUtil::toUpper(searchable_label); - - if (mSearchableLabel.compare(searchable_label)) - { - mSearchableLabel.assign(searchable_label); - dirtyFilter(); - // some part of label has changed, so overall width has potentially changed, and sort order too - if (mParentFolder) - { - mParentFolder->requestSort(); - mParentFolder->requestArrange(); - } - } - - mLabelWidthDirty = true; -} - -void LLFolderViewItem::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor) -{ - functor(mListener); -} - -// This function is called when items are added or view filters change. It's -// implemented here but called by derived classes when folding the -// views. -void LLFolderViewItem::filterFromRoot( void ) -{ - LLFolderViewItem* root = getRoot(); - - root->filter(*((LLFolderView*)root)->getFilter()); -} - -// This function is called when the folder view is dirty. It's -// implemented here but called by derived classes when folding the -// views. -void LLFolderViewItem::arrangeFromRoot() -{ - LLFolderViewItem* root = getRoot(); - - S32 height = 0; - S32 width = 0; - S32 total_height = root->arrange( &width, &height, 0 ); - - LLSD params; - params["action"] = "size_changes"; - params["height"] = total_height; - getParent()->notifyParent(params); -} - -// Utility function for LLFolderView -void LLFolderViewItem::arrangeAndSet(BOOL set_selection, - BOOL take_keyboard_focus) -{ - LLFolderView* root = getRoot(); - if (getParentFolder()) - { - getParentFolder()->requestArrange(); - } - if(set_selection) - { - setSelectionFromRoot(this, TRUE, take_keyboard_focus); - if(root) - { - root->scrollToShowSelection(); - } - } -} - -// This function clears the currently selected item, and records the -// specified selected item appropriately for display and use in the -// UI. If open is TRUE, then folders are opened up along the way to -// the selection. -void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection, - BOOL openitem, - BOOL take_keyboard_focus) -{ - getRoot()->setSelection(selection, openitem, take_keyboard_focus); -} - -// helper function to change the selection from the root. -void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected) -{ - 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; - return selection; -} - -EInventorySortGroup LLFolderViewItem::getSortGroup() const -{ - return SG_ITEM; -} - -// addToFolder() returns TRUE if it succeeds. FALSE otherwise -BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) -{ - if (!folder) - { - return FALSE; - } - mParentFolder = folder; - root->addItemID(getListener()->getUUID(), this); - return folder->addItem(this); -} - - -// Finds width and height of this object and it's children. Also -// makes sure that this view and it's children are the right size. -S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation) -{ - const Params& p = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>(); - S32 indentation = p.folder_indentation(); - // Only indent deeper items in hierarchy - mIndentation = (getParentFolder() - && getParentFolder()->getParentFolder() ) - ? mParentFolder->getIndentation() + indentation - : 0; - if (mLabelWidthDirty) - { - mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + getLabelFontForStyle(mLabelStyle)->getWidth(mSearchableLabel); - mLabelWidthDirty = false; - } - - *width = llmax(*width, mLabelWidth + mIndentation); - - // determine if we need to use ellipses to avoid horizontal scroll. EXT-719 - bool use_ellipses = getRoot()->getUseEllipses(); - if (use_ellipses) - { - // limit to set rect to avoid horizontal scrollbar - *width = llmin(*width, getRoot()->getRect().getWidth()); - } - *height = getItemHeight(); - return *height; -} - -S32 LLFolderViewItem::getItemHeight() -{ - return mItemHeight; -} - -void LLFolderViewItem::filter( LLInventoryFilter& filter) -{ - const BOOL previous_passed_filter = mPassedFilter; - const BOOL passed_filter = filter.check(this); - - // If our visibility will change as a result of this filter, then - // we need to be rearranged in our parent folder - if (mParentFolder) - { - if (getVisible() != passed_filter - || previous_passed_filter != passed_filter ) - mParentFolder->requestArrange(); - } - - setFiltered(passed_filter, filter.getCurrentGeneration()); - mStringMatchOffset = filter.getStringMatchOffset(); - filter.decrementFilterCount(); - - if (getRoot()->getDebugFilters()) - { - mStatusText = llformat("%d", mLastFilterGeneration); - } -} - -void LLFolderViewItem::dirtyFilter() -{ - mLastFilterGeneration = -1; - // bubble up dirty flag all the way to root - if (getParentFolder()) - { - getParentFolder()->setCompletedFilterGeneration(-1, TRUE); - } -} - -// *TODO: This can be optimized a lot by simply recording that it is -// selected in the appropriate places, and assuming that set selection -// means 'deselect' for a leaf item. Do this optimization after -// multiple selection is implemented to make sure it all plays nice -// together. -BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus) -{ - if (selection == this && !mIsSelected) - { - selectItem(); - if (mListener) - { - mListener->selectItem(); - } - } - else if (mIsSelected) // Deselect everything else. - { - deselectItem(); - } - return mIsSelected; -} - -BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected) -{ - if (selection == this && mIsSelected != selected) - { - if (mIsSelected) - { - deselectItem(); - } - else - { - selectItem(); - } - if (mListener) - { - mListener->selectItem(); - } - return TRUE; - } - return FALSE; -} - -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) - { - parent_folder->recursiveIncrementNumDescendantsSelected(1); - } -} - -BOOL LLFolderViewItem::isMovable() -{ - if( mListener ) - { - return mListener->isItemMovable(); - } - else - { - return TRUE; - } -} - -BOOL LLFolderViewItem::isRemovable() -{ - if( mListener ) - { - return mListener->isItemRemovable(); - } - else - { - return TRUE; - } -} - -void LLFolderViewItem::destroyView() -{ - if (mParentFolder) - { - // removeView deletes me - mParentFolder->removeView(this); - } -} - -// Call through to the viewed object and return true if it can be -// removed. -//BOOL LLFolderViewItem::removeRecursively(BOOL single_item) -BOOL LLFolderViewItem::remove() -{ - if(!isRemovable()) - { - return FALSE; - } - if(mListener) - { - return mListener->removeItem(); - } - return TRUE; -} - -// Build an appropriate context menu for the item. -void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags) -{ - if(mListener) - { - mListener->buildContextMenu(menu, flags); - } -} - -void LLFolderViewItem::openItem( void ) -{ - if( mListener ) - { - mListener->openItem(); - } -} - -void LLFolderViewItem::preview( void ) -{ - if (mListener) - { - mListener->previewItem(); - } -} - -void LLFolderViewItem::rename(const std::string& new_name) -{ - if( !new_name.empty() ) - { - if( mListener ) - { - mListener->renameItem(new_name); - - if(mParentFolder) - { - mParentFolder->requestSort(); - } - } - } -} - -const std::string& LLFolderViewItem::getSearchableLabel() const -{ - return mSearchableLabel; -} - -LLViewerInventoryItem * LLFolderViewItem::getInventoryItem(void) -{ - if (!getListener()) return NULL; - return gInventory.getItem(getListener()->getUUID()); -} - -const std::string& LLFolderViewItem::getName( void ) const -{ - if(mListener) - { - return mListener->getName(); - } - return mLabel; -} - -// LLView functionality -BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask ) -{ - if(!mIsSelected) - { - setSelectionFromRoot(this, FALSE); - } - make_ui_sound("UISndClick"); - return TRUE; -} - -BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - if (LLView::childrenHandleMouseDown(x, y, mask)) - { - return TRUE; - } - - // No handler needed for focus lost since this class has no - // state that depends on it. - gFocusMgr.setMouseCapture( this ); - - if (!mIsSelected) - { - if(mask & MASK_CONTROL) - { - changeSelectionFromRoot(this, !mIsSelected); - } - else if (mask & MASK_SHIFT) - { - extendSelectionFromRoot(this); - } - else - { - setSelectionFromRoot(this, FALSE); - } - make_ui_sound("UISndClick"); - } - else - { - mSelectPending = TRUE; - } - - if( isMovable() ) - { - S32 screen_x; - S32 screen_y; - localPointToScreen(x, y, &screen_x, &screen_y ); - LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y ); - } - return TRUE; -} - -BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask ) -{ - mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight)); - - if( hasMouseCapture() && isMovable() ) - { - S32 screen_x; - S32 screen_y; - localPointToScreen(x, y, &screen_x, &screen_y ); - BOOL can_drag = TRUE; - if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) ) - { - LLFolderView* root = getRoot(); - - if(root->getCurSelectedItem()) - { - LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_WORLD; - - // *TODO: push this into listener and remove - // dependency on llagent - if (mListener - && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getRootFolderID())) - { - src = LLToolDragAndDrop::SOURCE_AGENT; - } - else if (mListener - && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getLibraryRootFolderID())) - { - src = LLToolDragAndDrop::SOURCE_LIBRARY; - } - - can_drag = root->startDrag(src); - if (can_drag) - { - // if (mListener) mListener->startDrag(); - // RN: when starting drag and drop, clear out last auto-open - root->autoOpenTest(NULL); - root->setShowSelectionContext(TRUE); - - // Release keyboard focus, so that if stuff is dropped into the - // world, pressing the delete key won't blow away the inventory - // item. - gFocusMgr.setKeyboardFocus(NULL); - - return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask ); - } - } - } - - if (can_drag) - { - gViewerWindow->setCursor(UI_CURSOR_ARROW); - } - else - { - gViewerWindow->setCursor(UI_CURSOR_NOLOCKED); - } - return TRUE; - } - else - { - getRoot()->setShowSelectionContext(FALSE); - gViewerWindow->setCursor(UI_CURSOR_ARROW); - // let parent handle this then... - return FALSE; - } -} - - -BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask ) -{ - preview(); - return TRUE; -} - -BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask ) -{ - if (LLView::childrenHandleMouseUp(x, y, mask)) - { - return TRUE; - } - - // if mouse hasn't moved since mouse down... - if ( pointInView(x, y) && mSelectPending ) - { - //...then select - if(mask & MASK_CONTROL) - { - changeSelectionFromRoot(this, !mIsSelected); - } - else if (mask & MASK_SHIFT) - { - extendSelectionFromRoot(this); - } - else - { - setSelectionFromRoot(this, FALSE); - } - } - - mSelectPending = FALSE; - - if( hasMouseCapture() ) - { - getRoot()->setShowSelectionContext(FALSE); - gFocusMgr.setMouseCapture( NULL ); - } - return TRUE; -} - -void LLFolderViewItem::onMouseLeave(S32 x, S32 y, MASK mask) -{ - mIsMouseOverTitle = false; -} - -BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - BOOL accepted = FALSE; - BOOL handled = FALSE; - if(mListener) - { - accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg); - handled = accepted; - if (accepted) - { - mDragAndDropTarget = TRUE; - *accept = ACCEPT_YES_MULTI; - } - else - { - *accept = ACCEPT_NO; - } - } - if(mParentFolder && !handled) - { - // store this item to get it in LLFolderBridge::dragItemIntoFolder on drop event. - mRoot->setDraggingOverItem(this); - handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg); - mRoot->setDraggingOverItem(NULL); - } - if (handled) - { - lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl; - } - - return handled; -} - -void LLFolderViewItem::draw() -{ - static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); - static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE); - static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE); - static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE); - static LLUIColor sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE); - static LLUIColor sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE); - static LLUIColor sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE); - static LLUIColor sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE); - static LLUIColor sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE); - static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE); - static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE); - - const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>(); - const S32 TOP_PAD = default_params.item_top_pad; - const S32 FOCUS_LEFT = 1; - const LLFontGL* font = getLabelFontForStyle(mLabelStyle); - - const BOOL in_inventory = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getRootFolderID()); - const BOOL in_library = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getLibraryRootFolderID()); - - //--------------------------------------------------------------------------------// - // Draw open folder arrow - // - const bool up_to_date = mListener && mListener->isUpToDate(); - const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) // we fetched our children and some of them have passed the filter... - || (!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter) - if (possibly_has_children) - { - LLUIImage* arrow_image = default_params.folder_arrow_image; - gl_draw_scaled_rotated_image( - mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD - TOP_PAD, - ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, arrow_image->getImage(), sFgColor); - } - - - //--------------------------------------------------------------------------------// - // Draw highlight for selected items - // - const BOOL show_context = getRoot()->getShowSelectionContext(); - const BOOL filled = show_context || (getRoot()->getParentPanel()->hasFocus()); // If we have keyboard focus, draw selection filled - const S32 focus_top = getRect().getHeight(); - const S32 focus_bottom = getRect().getHeight() - mItemHeight; - const bool folder_open = (getRect().getHeight() > mItemHeight + 4); - if (mIsSelected) // always render "current" item. Only render other selected items if mShowSingleSelection is FALSE - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLColor4 bg_color = sHighlightBgColor; - if (!mIsCurSelection) - { - // do time-based fade of extra objects - F32 fade_time = getRoot()->getSelectionFadeElapsedTime(); - if (getRoot()->getShowSingleSelection()) - { - // fading out - bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f); - } - else - { - // fading in - bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]); - } - } - gl_rect_2d(FOCUS_LEFT, - focus_top, - getRect().getWidth() - 2, - focus_bottom, - bg_color, filled); - if (mIsCurSelection) - { - gl_rect_2d(FOCUS_LEFT, - focus_top, - getRect().getWidth() - 2, - focus_bottom, - sFocusOutlineColor, FALSE); - } - if (folder_open) - { - gl_rect_2d(FOCUS_LEFT, - focus_bottom + 1, // overlap with bottom edge of above rect - getRect().getWidth() - 2, - 0, - sFocusOutlineColor, FALSE); - if (show_context) - { - gl_rect_2d(FOCUS_LEFT, - focus_bottom + 1, - getRect().getWidth() - 2, - 0, - sHighlightBgColor, TRUE); - } - } - } - else if (mIsMouseOverTitle) - { - gl_rect_2d(FOCUS_LEFT, - focus_top, - getRect().getWidth() - 2, - focus_bottom, - sMouseOverColor, FALSE); - } - - //--------------------------------------------------------------------------------// - // Draw DragNDrop highlight - // - if (mDragAndDropTarget) - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gl_rect_2d(FOCUS_LEFT, - focus_top, - getRect().getWidth() - 2, - focus_bottom, - sHighlightBgColor, FALSE); - if (folder_open) - { - gl_rect_2d(FOCUS_LEFT, - focus_bottom + 1, // overlap with bottom edge of above rect - getRect().getWidth() - 2, - 0, - sHighlightBgColor, FALSE); - } - mDragAndDropTarget = FALSE; - } - - const LLViewerInventoryItem *item = getInventoryItem(); - const BOOL highlight_link = mIconOverlay && item && item->getIsLinkType(); - //--------------------------------------------------------------------------------// - // Draw open icon - // - const S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD; - if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders - { - mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1); - } - else if (mIcon) - { - mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1); - } - - if (highlight_link) - { - mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1); - } - - //--------------------------------------------------------------------------------// - // Exit if no label to draw - // - if (mLabel.empty()) - { - return; - } - - LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor; - if (highlight_link) color = sLinkColor; - if (in_library) color = sLibraryColor; - - F32 right_x = 0; - F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD; - F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation); - - //--------------------------------------------------------------------------------// - // Highlight filtered text - // - if (getRoot()->getDebugFilters()) - { - if (!getFiltered() && !possibly_has_children) - { - color.mV[VALPHA] *= 0.5f; - } - LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? - LLColor4(0.5f, 0.8f, 0.5f, 1.f) : - LLColor4(0.8f, 0.5f, 0.5f, 1.f); - LLFontGL::getFontMonospace()->renderUTF8(mStatusText, 0, text_left, y, filter_color, - LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - S32_MAX, S32_MAX, &right_x, FALSE ); - text_left = right_x; - } - //--------------------------------------------------------------------------------// - // Draw the actual label text - // - font->renderUTF8(mLabel, 0, text_left, y, color, - LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - S32_MAX, getRect().getWidth() - (S32) text_left, &right_x, TRUE); - - //--------------------------------------------------------------------------------// - // Draw "Loading..." text - // - bool root_is_loading = false; - if (in_inventory) - { - root_is_loading = LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress(); - } - if (in_library) - { - root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress(); - } - if ((mIsLoading - && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime")) - || (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() - && root_is_loading - && mShowLoadStatus)) - { - std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) "; - font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor, - LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - S32_MAX, S32_MAX, &right_x, FALSE); - } - - //--------------------------------------------------------------------------------// - // Draw label suffix - // - if (!mLabelSuffix.empty()) - { - font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor, - LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - S32_MAX, S32_MAX, &right_x, FALSE ); - } - - //--------------------------------------------------------------------------------// - // Highlight string match - // - if (mStringMatchOffset != std::string::npos) - { - // don't draw backgrounds for zero-length strings - S32 filter_string_length = getRoot()->getFilterSubString().size(); - if (filter_string_length > 0) - { - std::string combined_string = mLabel + mLabelSuffix; - S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1; - S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2; - S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD); - S32 top = getRect().getHeight() - TOP_PAD; - - LLUIImage* box_image = default_params.selection_image; - LLRect box_rect(left, top, right, bottom); - box_image->draw(box_rect, sFilterBGColor); - F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset); - F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD; - font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy, - sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - filter_string_length, S32_MAX, &right_x, FALSE ); - } - } -} - - -///---------------------------------------------------------------------------- -/// Class LLFolderViewFolder -///---------------------------------------------------------------------------- - -LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): - LLFolderViewItem( p ), // 0 = no create time - mNumDescendantsSelected(0), - mIsOpen(FALSE), - mExpanderHighlighted(FALSE), - mCurHeight(0.f), - mTargetHeight(0.f), - mAutoOpenCountdown(0.f), - mSubtreeCreationDate(0), - mAmTrash(LLFolderViewFolder::UNKNOWN), - mLastArrangeGeneration( -1 ), - mLastCalculatedWidth(0), - mCompletedFilterGeneration(-1), - mMostFilteredDescendantGeneration(-1), - mNeedsSort(false), - mPassedFolderFilter(FALSE) -{ -} - -// Destroys the object -LLFolderViewFolder::~LLFolderViewFolder( void ) -{ - // The LLView base class takes care of object destruction. make sure that we - // don't have mouse or keyboard focus - gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() -} - -void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation) -{ - mPassedFolderFilter = filtered; - mLastFilterGeneration = filter_generation; -} - -bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation) -{ - return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration(); -} - -// addToFolder() returns TRUE if it succeeds. FALSE otherwise -BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) -{ - if (!folder) - { - return FALSE; - } - mParentFolder = folder; - root->addItemID(getListener()->getUUID(), this); - return folder->addFolder(this); -} - -// Finds width and height of this object and it's children. Also -// makes sure that this view and it's children are the right size. -S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation) -{ - // sort before laying out contents - if (mNeedsSort) - { - mFolders.sort(mSortFunction); - mItems.sort(mSortFunction); - mNeedsSort = false; - } - - mHasVisibleChildren = hasFilteredDescendants(filter_generation); - - // calculate height as a single item (without any children), and reshapes rectangle to match - LLFolderViewItem::arrange( width, height, filter_generation ); - - // clamp existing animated height so as to never get smaller than a single item - mCurHeight = llmax((F32)*height, mCurHeight); - - // initialize running height value as height of single item in case we have no children - *height = getItemHeight(); - F32 running_height = (F32)*height; - F32 target_height = (F32)*height; - - // are my children visible? - if (needsArrange()) - { - // set last arrange generation first, in case children are animating - // and need to be arranged again - mLastArrangeGeneration = getRoot()->getArrangeGeneration(); - if (mIsOpen) - { - // Add sizes of children - S32 parent_item_height = getRect().getHeight(); - - for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit) - { - LLFolderViewFolder* folderp = (*fit); - if (getRoot()->getDebugFilters()) - { - folderp->setVisible(TRUE); - } - else - { - folderp->setVisible( folderp->getListener() - && (folderp->getFiltered(filter_generation) - || (folderp->getFilteredFolder(filter_generation) - && folderp->hasFilteredDescendants(filter_generation)))); // passed filter or has descendants that passed filter - } - - if (folderp->getVisible()) - { - S32 child_width = *width; - S32 child_height = 0; - S32 child_top = parent_item_height - llround(running_height); - - target_height += folderp->arrange( &child_width, &child_height, filter_generation ); - - running_height += (F32)child_height; - *width = llmax(*width, child_width); - folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() ); - } - } - for(items_t::iterator iit = mItems.begin(); - iit != mItems.end(); ++iit) - { - LLFolderViewItem* itemp = (*iit); - if (getRoot()->getDebugFilters()) - { - itemp->setVisible(TRUE); - } - else - { - itemp->setVisible(itemp->getFiltered(filter_generation)); - } - - if (itemp->getVisible()) - { - S32 child_width = *width; - S32 child_height = 0; - S32 child_top = parent_item_height - llround(running_height); - - target_height += itemp->arrange( &child_width, &child_height, filter_generation ); - // don't change width, as this item is as wide as its parent folder by construction - itemp->reshape( itemp->getRect().getWidth(), child_height); - - running_height += (F32)child_height; - *width = llmax(*width, child_width); - itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() ); - } - } - } - - mTargetHeight = target_height; - // cache this width so next time we can just return it - mLastCalculatedWidth = *width; - } - else - { - // just use existing width - *width = mLastCalculatedWidth; - } - - // animate current height towards target height - if (llabs(mCurHeight - mTargetHeight) > 1.f) - { - mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT)); - - requestArrange(); - - // hide child elements that fall out of current animated height - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - // number of pixels that bottom of folder label is from top of parent folder - if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight() - > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP) - { - // hide if beyond current folder height - (*fit)->setVisible(FALSE); - } - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - // number of pixels that bottom of item label is from top of parent folder - if (getRect().getHeight() - (*iit)->getRect().mBottom - > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP) - { - (*iit)->setVisible(FALSE); - } - } - } - else - { - mCurHeight = mTargetHeight; - } - - // don't change width as this item is already as wide as its parent folder - reshape(getRect().getWidth(),llround(mCurHeight)); - - // pass current height value back to parent - *height = llround(mCurHeight); - - return llround(mTargetHeight); -} - -BOOL LLFolderViewFolder::needsArrange() -{ - return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); -} - -void LLFolderViewFolder::requestSort() -{ - mNeedsSort = true; - // whenever item order changes, we need to lay things out again - requestArrange(); -} - -void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up) -{ - mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation); - mCompletedFilterGeneration = generation; - // only aggregate up if we are a lower (older) value - if (recurse_up - && mParentFolder - && generation < mParentFolder->getCompletedFilterGeneration()) - { - mParentFolder->setCompletedFilterGeneration(generation, TRUE); - } -} - -void LLFolderViewFolder::filter( LLInventoryFilter& filter) -{ - S32 filter_generation = filter.getCurrentGeneration(); - // if failed to pass filter newer than must_pass_generation - // you will automatically fail this time, so we only - // check against items that have passed the filter - S32 must_pass_generation = filter.getMustPassGeneration(); - - bool autoopen_folders = (filter.hasFilterString()); - - // if we have already been filtered against this generation, skip out - if (getCompletedFilterGeneration() >= filter_generation) - { - return; - } - - // filter folder itself - if (getLastFilterGeneration() < filter_generation) - { - if (getLastFilterGeneration() >= must_pass_generation // folder has been compared to a valid precursor filter - && !mPassedFilter) // and did not pass the filter - { - // go ahead and flag this folder as done - mLastFilterGeneration = filter_generation; - } - else // filter self only on first pass through - { - // filter against folder rules - filterFolder(filter); - // and then item rules - LLFolderViewItem::filter( filter ); - } - } - - if (getRoot()->getDebugFilters()) - { - mStatusText = llformat("%d", mLastFilterGeneration); - mStatusText += llformat("(%d)", mCompletedFilterGeneration); - mStatusText += llformat("+%d", mMostFilteredDescendantGeneration); - } - - // all descendants have been filtered later than must pass generation - // but none passed - if(getCompletedFilterGeneration() >= must_pass_generation && !hasFilteredDescendants(must_pass_generation)) - { - // don't traverse children if we've already filtered them since must_pass_generation - // and came back with nothing - return; - } - - // we entered here with at least one filter iteration left - // check to see if we have any more before continuing on to children - if (filter.getFilterCount() < 0) - { - return; - } - - // when applying a filter, matching folders get their contents downloaded first - if (filter.isNotDefault() - && getFiltered(filter.getMinRequiredGeneration()) - && (mListener - && !gInventory.isCategoryComplete(mListener->getUUID()))) - { - LLInventoryModelBackgroundFetch::instance().start(mListener->getUUID()); - } - - // now query children - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end(); - ++iter) - { - LLFolderViewFolder* folder = (*iter); - // have we run out of iterations this frame? - if (filter.getFilterCount() < 0) - { - break; - } - - // mMostFilteredDescendantGeneration might have been reset - // in which case we need to update it even for folders that - // don't need to be filtered anymore - if (folder->getCompletedFilterGeneration() >= filter_generation) - { - // track latest generation to pass any child items - if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getMinRequiredGeneration())) - { - mMostFilteredDescendantGeneration = filter_generation; - requestArrange(); - } - // just skip it, it has already been filtered - continue; - } - - // update this folders filter status (and children) - folder->filter( filter ); - - // track latest generation to pass any child items - if (folder->getFiltered() || folder->hasFilteredDescendants(filter_generation)) - { - mMostFilteredDescendantGeneration = filter_generation; - requestArrange(); - if (getRoot()->needsAutoSelect() && autoopen_folders) - { - folder->setOpenArrangeRecursively(TRUE); - } - } - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end(); - ++iter) - { - LLFolderViewItem* item = (*iter); - if (filter.getFilterCount() < 0) - { - break; - } - if (item->getLastFilterGeneration() >= filter_generation) - { - if (item->getFiltered()) - { - mMostFilteredDescendantGeneration = filter_generation; - requestArrange(); - } - continue; - } - - if (item->getLastFilterGeneration() >= must_pass_generation && - !item->getFiltered(must_pass_generation)) - { - // failed to pass an earlier filter that was a subset of the current one - // go ahead and flag this item as done - item->setFiltered(FALSE, filter_generation); - continue; - } - - item->filter( filter ); - - if (item->getFiltered(filter.getMinRequiredGeneration())) - { - mMostFilteredDescendantGeneration = filter_generation; - requestArrange(); - } - } - - // if we didn't use all filter iterations - // that means we filtered all of our descendants - // instead of exhausting the filter count for this frame - if (filter.getFilterCount() > 0) - { - // flag this folder as having completed filter pass for all descendants - setCompletedFilterGeneration(filter_generation, FALSE/*dont recurse up to root*/); - } -} - -void LLFolderViewFolder::filterFolder(LLInventoryFilter& filter) -{ - const BOOL previous_passed_filter = mPassedFolderFilter; - const BOOL passed_filter = filter.checkFolder(this); - - // If our visibility will change as a result of this filter, then - // we need to be rearranged in our parent folder - if (mParentFolder) - { - if (getVisible() != passed_filter - || previous_passed_filter != passed_filter ) - { - mParentFolder->requestArrange(); - } - } - - setFilteredFolder(passed_filter, filter.getCurrentGeneration()); - filter.decrementFilterCount(); - - if (getRoot()->getDebugFilters()) - { - mStatusText = llformat("%d", mLastFilterGeneration); - } -} - -void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation) -{ - // if this folder is now filtered, but wasn't before - // (it just passed) - if (filtered && !mPassedFilter) - { - // reset current height, because last time we drew it - // it might have had more visible items than now - mCurHeight = 0.f; - } - - LLFolderViewItem::setFiltered(filtered, filter_generation); -} - -void LLFolderViewFolder::dirtyFilter() -{ - // we're a folder, so invalidate our completed generation - setCompletedFilterGeneration(-1, FALSE); - LLFolderViewItem::dirtyFilter(); -} - -BOOL LLFolderViewFolder::getFiltered() -{ - return getFilteredFolder(getRoot()->getFilter()->getMinRequiredGeneration()) - && LLFolderViewItem::getFiltered(); -} - -BOOL LLFolderViewFolder::getFiltered(S32 filter_generation) -{ - return getFilteredFolder(filter_generation) && LLFolderViewItem::getFiltered(filter_generation); -} - -BOOL LLFolderViewFolder::hasFilteredDescendants(S32 filter_generation) -{ - return mMostFilteredDescendantGeneration >= filter_generation; -} - - -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, - BOOL take_keyboard_focus) -{ - BOOL rv = FALSE; - if (selection == this) - { - if (!isSelected()) - { - selectItem(); - } - if (mListener) - { - mListener->selectItem(); - } - rv = TRUE; - } - else - { - if (isSelected()) - { - deselectItem(); - } - rv = FALSE; - } - BOOL child_selected = FALSE; - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - if((*fit)->setSelection(selection, openitem, take_keyboard_focus)) - { - rv = TRUE; - child_selected = TRUE; - } - } - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if((*iit)->setSelection(selection, openitem, take_keyboard_focus)) - { - rv = TRUE; - child_selected = TRUE; - } - } - if(openitem && child_selected) - { - setOpenArrangeRecursively(TRUE); - } - return rv; -} - -// This method is used to change the selection of an item. -// Recursively traverse all children; if 'selection' is 'this' then change -// the select status if necessary. -// Returns TRUE if the selection state of this folder, or of a child, was changed. -BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selected) -{ - BOOL rv = FALSE; - if(selection == this) - { - if (isSelected() != selected) - { - rv = TRUE; - if (selected) - { - selectItem(); - } - else - { - deselectItem(); - } - } - if (mListener && selected) - { - mListener->selectItem(); - } - } - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - if((*fit)->changeSelection(selection, selected)) - { - rv = TRUE; - } - } - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if((*iit)->changeSelection(selection, selected)) - { - rv = TRUE; - } - } - return rv; -} - -void LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& selected_items) -{ - // pass on to child folders first - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->extendSelection(selection, last_selected, selected_items); - } - - // 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; - - //...folders first... - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - item = (*fit); - if(item == selection) - { - found_selection = TRUE; - } - else if (item == last_selected) - { - found_last_selected = TRUE; - if (found_selection) - { - reverse_select = TRUE; - } - } - - if (found_selection || found_last_selected) - { - // deselect currently selected items so they can be pushed back on queue - if (item->isSelected()) - { - item->changeSelection(item, FALSE); - } - items_to_select.put(item); - } - - if (found_selection && found_last_selected) - { - break; - } - } - - if (!(found_selection && found_last_selected)) - { - //,,,then items - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - item = (*iit); - if(item == selection) - { - found_selection = TRUE; - } - else if (item == last_selected) - { - found_last_selected = TRUE; - if (found_selection) - { - reverse_select = TRUE; - } - } - - if (found_selection || found_last_selected) - { - // deselect currently selected items so they can be pushed back on queue - if (item->isSelected()) - { - item->changeSelection(item, FALSE); - } - items_to_select.put(item); - } - - if (found_selection && found_last_selected) - { - break; - } - } - } - - if (found_last_selected && found_selection) - { - // 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++) - { - LLFolderViewItem* item = items_to_select[index]; - if (item->changeSelection(item, TRUE)) - { - selected_items.put(item); - } - } - } - else if (found_selection) - { - // last selection was not in this folder....go ahead and select just the new item - if (selection->changeSelection(selection, TRUE)) - { - selected_items.put(selection); - } - } -} - -void LLFolderViewFolder::destroyView() -{ - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - LLFolderViewItem* item = (*iit); - getRoot()->removeItemID(item->getListener()->getUUID()); - } - - std::for_each(mItems.begin(), mItems.end(), DeletePointer()); - mItems.clear(); - - while (!mFolders.empty()) - { - LLFolderViewFolder *folderp = mFolders.back(); - folderp->destroyView(); // removes entry from mFolders - } - - //deleteAllChildren(); - - if (mParentFolder) - { - mParentFolder->removeView(this); - } -} - -// remove the specified item (and any children) if possible. Return -// TRUE if the item was deleted. -BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item) -{ - if(item->remove()) - { - return TRUE; - } - return FALSE; -} - -// simply remove the view (and any children) Don't bother telling the -// listeners. -void LLFolderViewFolder::removeView(LLFolderViewItem* item) -{ - if (!item || item->getParentFolder() != this) - { - return; - } - // deselect without traversing hierarchy - if (item->isSelected()) - { - item->deselectItem(); - } - getRoot()->removeFromSelectionList(item); - extractItem(item); - delete item; -} - -// extractItem() removes the specified item from the folder, but -// doesn't delete it. -void LLFolderViewFolder::extractItem( LLFolderViewItem* item ) -{ - items_t::iterator it = std::find(mItems.begin(), mItems.end(), item); - if(it == mItems.end()) - { - // This is an evil downcast. However, it's only doing - // pointer comparison to find if (which it should be ) the - // item is in the container, so it's pretty safe. - LLFolderViewFolder* f = static_cast<LLFolderViewFolder*>(item); - folders_t::iterator ft; - 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 - dirtyFilter(); - //because an item is going away regardless of filter status, force rearrange - requestArrange(); - getRoot()->removeItemID(item->getListener()->getUUID()); - removeChild(item); -} - -bool LLFolderViewFolder::isTrash() const -{ - if (mAmTrash == LLFolderViewFolder::UNKNOWN) - { - mAmTrash = mListener->getUUID() == gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH, false) ? LLFolderViewFolder::TRASH : LLFolderViewFolder::NOT_TRASH; - } - return mAmTrash == LLFolderViewFolder::TRASH; -} - -void LLFolderViewFolder::sortBy(U32 order) -{ - if (!mSortFunction.updateSort(order)) - { - // No changes. - return; - } - - // Propagate this change to sub folders - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->sortBy(order); - } - - // Don't sort the topmost folders (My Inventory and Library) - if (mListener->getUUID().notNull()) - { - mFolders.sort(mSortFunction); - mItems.sort(mSortFunction); - } - - if (order & LLInventoryFilter::SO_DATE) - { - time_t latest = 0; - - if (!mItems.empty()) - { - LLFolderViewItem* item = *(mItems.begin()); - latest = item->getCreationDate(); - } - - if (!mFolders.empty()) - { - LLFolderViewFolder* folder = *(mFolders.begin()); - if (folder->getCreationDate() > latest) - { - latest = folder->getCreationDate(); - } - } - mSubtreeCreationDate = latest; - } -} - -void LLFolderViewFolder::setItemSortOrder(U32 ordering) -{ - if (mSortFunction.updateSort(ordering)) - { - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->setItemSortOrder(ordering); - } - - mFolders.sort(mSortFunction); - mItems.sort(mSortFunction); - } -} - -EInventorySortGroup LLFolderViewFolder::getSortGroup() const -{ - if (isTrash()) - { - return SG_TRASH_FOLDER; - } - - if( mListener ) - { - if(LLFolderType::lookupIsProtectedType(mListener->getPreferredType())) - { - return SG_SYSTEM_FOLDER; - } - } - - return SG_NORMAL_FOLDER; -} - -BOOL LLFolderViewFolder::isMovable() -{ - if( mListener ) - { - if( !(mListener->isItemMovable()) ) - { - return FALSE; - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if(!(*iit)->isMovable()) - { - return FALSE; - } - } - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - if(!(*fit)->isMovable()) - { - return FALSE; - } - } - } - return TRUE; -} - - -BOOL LLFolderViewFolder::isRemovable() -{ - if( mListener ) - { - if( !(mListener->isItemRemovable()) ) - { - return FALSE; - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if(!(*iit)->isRemovable()) - { - return FALSE; - } - } - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - if(!(*fit)->isRemovable()) - { - return FALSE; - } - } - } - return TRUE; -} - -// this is an internal method used for adding items to folders. -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); - - addChild(item); - - item->dirtyFilter(); - - // Update the folder creation date if the child is newer than our current date - setCreationDate(llmax<time_t>(mCreationDate, item->getCreationDate())); - - // Handle sorting - requestArrange(); - requestSort(); - - // Traverse parent folders and update creation date and resort, if necessary - 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())); - - if (parentp->mSortFunction.isByDate()) - { - // parent folder doesn't have a time stamp yet, so get it from us - parentp->requestSort(); - } - - parentp = parentp->getParentFolder(); - } - - return TRUE; -} - -// this is an internal method used for adding items to folders. -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); - addChild( folder ); - folder->dirtyFilter(); - // rearrange all descendants too, as our indentation level might have changed - folder->requestArrange(TRUE); - requestSort(); - LLFolderViewFolder* parentp = getParentFolder(); - while (parentp && !parentp->mSortFunction.isByDate()) - { - // parent folder doesn't have a time stamp yet, so get it from us - parentp->requestSort(); - parentp = parentp->getParentFolder(); - } - return TRUE; -} - -void LLFolderViewFolder::requestArrange(BOOL include_descendants) -{ - mLastArrangeGeneration = -1; - // flag all items up to root - if (mParentFolder) - { - mParentFolder->requestArrange(); - } - - if (include_descendants) - { - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end(); - ++iter) - { - (*iter)->requestArrange(TRUE); - } - } -} - -void LLFolderViewFolder::toggleOpen() -{ - setOpen(!mIsOpen); -} - -// Force a folder open or closed -void LLFolderViewFolder::setOpen(BOOL openitem) -{ - setOpenArrangeRecursively(openitem); -} - -void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse) -{ - BOOL was_open = mIsOpen; - mIsOpen = openitem; - if (mListener) - { - if(!was_open && openitem) - { - mListener->openItem(); - } - else if(was_open && !openitem) - { - mListener->closeItem(); - } - } - - if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN) - { - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN); /* Flawfinder: ignore */ - } - } - if (mParentFolder - && (recurse == RECURSE_UP - || recurse == RECURSE_UP_DOWN)) - { - mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP); - } - - if (was_open != mIsOpen) - { - requestArrange(); - } -} - -BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask, - BOOL drop, - EDragAndDropType c_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg); - if (accepted) - { - mDragAndDropTarget = TRUE; - *accept = ACCEPT_YES_MULTI; - } - else - { - *accept = ACCEPT_NO; - } - - // drag and drop to child item, so clear pending auto-opens - getRoot()->autoOpenTest(NULL); - - return TRUE; -} - -void LLFolderViewFolder::openItem( void ) -{ - toggleOpen(); -} - -void LLFolderViewFolder::applyFunctorToChildren(LLFolderViewFunctor& functor) -{ - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - functor.doItem((*fit)); - } - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - functor.doItem((*iit)); - } -} - -void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor) -{ - functor.doFolder(this); - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->applyFunctorRecursively(functor); - } - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - functor.doItem((*iit)); - } -} - -void LLFolderViewFolder::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor) -{ - functor(mListener); - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->applyListenerFunctorRecursively(functor); - } - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - (*iit)->applyListenerFunctorRecursively(functor); - } -} - -// LLView functionality -BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask, - BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - LLFolderView* root_view = getRoot(); - - BOOL handled = FALSE; - if(mIsOpen) - { - 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); - } - - lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl; - } - - return TRUE; -} - - -BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - // fetch contents of this folder, as context menu can depend on contents - // still, user would have to open context menu again to see the changes - gInventory.fetchDescendentsOf(mListener->getUUID()); - - if( mIsOpen ) - { - handled = childrenHandleRightMouseDown( x, y, mask ) != NULL; - } - if (!handled) - { - handled = LLFolderViewItem::handleRightMouseDown( x, y, mask ); - } - return handled; -} - - -BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask) -{ - mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight)); - - BOOL handled = LLView::handleHover(x, y, mask); - - if (!handled) - { - // this doesn't do child processing - handled = LLFolderViewItem::handleHover(x, y, mask); - } - - return handled; -} - -BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - if( mIsOpen ) - { - handled = childrenHandleMouseDown(x,y,mask) != NULL; - } - if( !handled ) - { - if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD) - { - toggleOpen(); - handled = TRUE; - } - else - { - // do normal selection logic - handled = LLFolderViewItem::handleMouseDown(x, y, mask); - } - } - - return handled; -} - -BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask ) -{ - /* Disable outfit double click to wear - const LLUUID &cat_uuid = getListener()->getUUID(); - const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid); - if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT) - { - getListener()->performAction(NULL, NULL,"replaceoutfit"); - return TRUE; - } - */ - - BOOL handled = FALSE; - if( mIsOpen ) - { - handled = childrenHandleDoubleClick( x, y, mask ) != NULL; - } - if( !handled ) - { - if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD) - { - // don't select when user double-clicks plus sign - // so as not to contradict single-click behavior - toggleOpen(); - } - else - { - setSelectionFromRoot(this, FALSE); - toggleOpen(); - } - handled = TRUE; - } - return handled; -} - -void LLFolderViewFolder::draw() -{ - if (mAutoOpenCountdown != 0.f) - { - mControlLabelRotation = mAutoOpenCountdown * -90.f; - } - else if (mIsOpen) - { - mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f)); - } - else - { - mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f)); - } - - bool possibly_has_children = false; - bool up_to_date = mListener && mListener->isUpToDate(); - if(!up_to_date - && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter) - { - possibly_has_children = true; - } - - - BOOL loading = (mIsOpen - && possibly_has_children - && !up_to_date ); - - if ( loading && !mIsLoading ) - { - // Measure how long we've been in the loading state - mTimeSinceRequestStart.reset(); - } - - mIsLoading = loading; - - LLFolderViewItem::draw(); - - // draw children if root folder, or any other folder that is open or animating to closed state - if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight )) - { - LLView::draw(); - } - - mExpanderHighlighted = FALSE; -} - -time_t LLFolderViewFolder::getCreationDate() const -{ - return llmax<time_t>(mCreationDate, mSubtreeCreationDate); -} - - -BOOL LLFolderViewFolder::potentiallyVisible() -{ - // folder should be visible by it's own filter status - return LLFolderViewItem::potentiallyVisible() - // or one or more of its descendants have passed the minimum filter requirement - || hasFilteredDescendants(getRoot()->getFilter()->getMinRequiredGeneration()) - // or not all of its descendants have been checked against minimum filter requirement - || getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration(); -} - -// this does prefix traversal, as folders are listed above their contents -LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children ) -{ - BOOL found_item = FALSE; - - LLFolderViewItem* result = NULL; - // when not starting from a given item, start at beginning - if(item == NULL) - { - found_item = TRUE; - } - - // find current item among children - folders_t::iterator fit = mFolders.begin(); - folders_t::iterator fend = mFolders.end(); - - items_t::iterator iit = mItems.begin(); - items_t::iterator iend = mItems.end(); - - // if not trivially starting at the beginning, we have to find the current item - if (!found_item) - { - // first, look among folders, since they are always above items - for(; fit != fend; ++fit) - { - if(item == (*fit)) - { - found_item = TRUE; - // if we are on downwards traversal - if (include_children && (*fit)->isOpen()) - { - // look for first descendant - return (*fit)->getNextFromChild(NULL, TRUE); - } - // otherwise advance to next folder - ++fit; - include_children = TRUE; - break; - } - } - - // didn't find in folders? Check items... - if (!found_item) - { - for(; iit != iend; ++iit) - { - if(item == (*iit)) - { - found_item = TRUE; - // point to next item - ++iit; - break; - } - } - } - } - - if (!found_item) - { - // you should never call this method with an item that isn't a child - // so we should always find something - llassert(FALSE); - return NULL; - } - - // at this point, either iit or fit point to a candidate "next" item - // if both are out of range, we need to punt up to our parent - - // now, starting from found folder, continue through folders - // searching for next visible folder - while(fit != fend && !(*fit)->getVisible()) - { - // turn on downwards traversal for next folder - ++fit; - } - - if (fit != fend) - { - result = (*fit); - } - else - { - // otherwise, scan for next visible item - while(iit != iend && !(*iit)->getVisible()) - { - ++iit; - } - - // check to see if we have a valid item - if (iit != iend) - { - result = (*iit); - } - } - - if( !result && mParentFolder ) - { - // If there are no siblings or children to go to, recurse up one level in the tree - // and skip children for this folder, as we've already discounted them - result = mParentFolder->getNextFromChild(this, FALSE); - } - - return result; -} - -// this does postfix traversal, as folders are listed above their contents -LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children ) -{ - BOOL found_item = FALSE; - - LLFolderViewItem* result = NULL; - // when not starting from a given item, start at end - if(item == NULL) - { - found_item = TRUE; - } - - // find current item among children - folders_t::reverse_iterator fit = mFolders.rbegin(); - folders_t::reverse_iterator fend = mFolders.rend(); - - items_t::reverse_iterator iit = mItems.rbegin(); - items_t::reverse_iterator iend = mItems.rend(); - - // if not trivially starting at the end, we have to find the current item - if (!found_item) - { - // first, look among items, since they are always below the folders - for(; iit != iend; ++iit) - { - if(item == (*iit)) - { - found_item = TRUE; - // point to next item - ++iit; - break; - } - } - - // didn't find in items? Check folders... - if (!found_item) - { - for(; fit != fend; ++fit) - { - if(item == (*fit)) - { - found_item = TRUE; - // point to next folder - ++fit; - break; - } - } - } - } - - if (!found_item) - { - // you should never call this method with an item that isn't a child - // so we should always find something - llassert(FALSE); - return NULL; - } - - // at this point, either iit or fit point to a candidate "next" item - // if both are out of range, we need to punt up to our parent - - // now, starting from found item, continue through items - // searching for next visible item - while(iit != iend && !(*iit)->getVisible()) - { - ++iit; - } - - if (iit != iend) - { - // we found an appropriate item - result = (*iit); - } - else - { - // otherwise, scan for next visible folder - while(fit != fend && !(*fit)->getVisible()) - { - ++fit; - } - - // check to see if we have a valid folder - if (fit != fend) - { - // try selecting child element of this folder - if ((*fit)->isOpen()) - { - result = (*fit)->getPreviousFromChild(NULL); - } - else - { - result = (*fit); - } - } - } - - if( !result ) - { - // If there are no siblings or children to go to, recurse up one level in the tree - // which gets back to this folder, which will only be visited if it is a valid, visible item - result = this; - } - - return result; -} - - -bool LLInventorySort::updateSort(U32 order) -{ - if (order != mSortOrder) - { - mSortOrder = order; - mByDate = (order & LLInventoryFilter::SO_DATE); - mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP); - mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME); - return true; - } - return false; -} - -bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b) -{ - // ignore sort order for landmarks in the Favorites folder. - // they should be always sorted as in Favorites bar. See EXT-719 - if (a->getSortGroup() == SG_ITEM - && b->getSortGroup() == SG_ITEM - && a->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK - && b->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) - { - - static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); - - LLUUID a_uuid = a->getParentFolder()->getListener()->getUUID(); - LLUUID b_uuid = b->getParentFolder()->getListener()->getUUID(); - - if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id)) - { - // *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem - // or to LLInvFVBridge - LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a->getListener()))->getItem(); - LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b->getListener()))->getItem(); - if (!aitem || !bitem) - return false; - S32 a_sort = aitem->getSortField(); - S32 b_sort = bitem->getSortField(); - return a_sort < b_sort; - } - } - - // We sort by name if we aren't sorting by date - // OR if these are folders and we are sorting folders by name. - bool by_name = (!mByDate - || (mFoldersByName - && (a->getSortGroup() != SG_ITEM))); - - if (a->getSortGroup() != b->getSortGroup()) - { - if (mSystemToTop) - { - // Group order is System Folders, Trash, Normal Folders, Items - return (a->getSortGroup() < b->getSortGroup()); - } - else if (mByDate) - { - // Trash needs to go to the bottom if we are sorting by date - if ( (a->getSortGroup() == SG_TRASH_FOLDER) - || (b->getSortGroup() == SG_TRASH_FOLDER)) - { - return (b->getSortGroup() == SG_TRASH_FOLDER); - } - } - } - - if (by_name) - { - S32 compare = LLStringUtil::compareDict(a->getLabel(), b->getLabel()); - if (0 == compare) - { - return (a->getCreationDate() > b->getCreationDate()); - } - else - { - return (compare < 0); - } - } - else - { - // BUG: This is very very slow. The getCreationDate() is log n in number - // of inventory items. - time_t first_create = a->getCreationDate(); - time_t second_create = b->getCreationDate(); - if (first_create == second_create) - { - return (LLStringUtil::compareDict(a->getLabel(), b->getLabel()) < 0); - } - else - { - return (first_create > second_create); - } - } -} diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h deleted file mode 100644 index 3433e3f7f3..0000000000 --- a/indra/newview/llfolderviewitem.h +++ /dev/null @@ -1,579 +0,0 @@ -/** -* @file llfolderviewitem.h -* @brief Items and folders that can appear in a hierarchical folder view -* -* $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$ -*/ -#ifndef LLFOLDERVIEWITEM_H -#define LLFOLDERVIEWITEM_H - -#include "llview.h" -#include "lldarray.h" // *TODO: Eliminate, forward declare -#include "lluiimage.h" - -class LLFontGL; -class LLFolderView; -class LLFolderViewEventListener; -class LLFolderViewFolder; -class LLFolderViewFunctor; -class LLFolderViewItem; -class LLFolderViewListenerFunctor; -class LLInventoryFilter; -class LLMenuGL; -class LLUIImage; -class LLViewerInventoryItem; - -// These are grouping of inventory types. -// Order matters when sorting system folders to the top. -enum EInventorySortGroup -{ - SG_SYSTEM_FOLDER, - SG_TRASH_FOLDER, - SG_NORMAL_FOLDER, - SG_ITEM -}; - -// *TODO: do we really need one sort object per folder? -// can we just have one of these per LLFolderView ? -class LLInventorySort -{ -public: - LLInventorySort() - : mSortOrder(0), - mByDate(false), - mSystemToTop(false), - mFoldersByName(false) { } - - // Returns true if order has changed - bool updateSort(U32 order); - U32 getSort() { return mSortOrder; } - bool isByDate() { return mByDate; } - - bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b); -private: - U32 mSortOrder; - bool mByDate; - bool mSystemToTop; - bool mFoldersByName; -}; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewItem -// -// An instance of this class represents a single item in a folder view -// such as an inventory item or a file. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLFolderViewItem : public LLView -{ -public: - static void initClass(); - static void cleanupClass(); - - struct Params : public LLInitParam::Block<Params, LLView::Params> - { - Optional<LLUIImage*> icon; - Optional<LLUIImage*> icon_open; // used for folders - Optional<LLUIImage*> icon_overlay; // for links - Optional<LLFolderView*> root; - Mandatory<LLFolderViewEventListener*> listener; - - Optional<LLUIImage*> folder_arrow_image; - Optional<S32> folder_indentation; // pixels - Optional<LLUIImage*> selection_image; - Optional<S32> item_height; // pixels - Optional<S32> item_top_pad; // pixels - - Optional<S32> creation_date; //UTC seconds - - Params(); - }; - - // layout constants - static const S32 LEFT_PAD = 5; - // LEFT_INDENTATION is set via folder_indentation above - static const S32 ICON_PAD = 2; - static const S32 ICON_WIDTH = 16; - static const S32 TEXT_PAD = 1; - static const S32 ARROW_SIZE = 12; - static const S32 MAX_FOLDER_ITEM_OVERLAP = 2; - // animation parameters - static const F32 FOLDER_CLOSE_TIME_CONSTANT; - static const F32 FOLDER_OPEN_TIME_CONSTANT; - - // Mostly for debugging printout purposes. - const std::string& getSearchableLabel() { return mSearchableLabel; } - -private: - BOOL mIsSelected; - -protected: - friend class LLUICtrlFactory; - friend class LLFolderViewEventListener; - - LLFolderViewItem(const Params& p); - - std::string mLabel; - std::string mSearchableLabel; - S32 mLabelWidth; - bool mLabelWidthDirty; - time_t mCreationDate; - LLFolderViewFolder* mParentFolder; - LLFolderViewEventListener* mListener; - BOOL mIsCurSelection; - BOOL mSelectPending; - LLFontGL::StyleFlags mLabelStyle; - std::string mLabelSuffix; - LLUIImagePtr mIcon; - std::string mStatusText; - LLUIImagePtr mIconOpen; - LLUIImagePtr mIconOverlay; - BOOL mHasVisibleChildren; - S32 mIndentation; - S32 mItemHeight; - BOOL mPassedFilter; - S32 mLastFilterGeneration; - std::string::size_type mStringMatchOffset; - F32 mControlLabelRotation; - LLFolderView* mRoot; - BOOL mDragAndDropTarget; - BOOL mIsLoading; - LLTimer mTimeSinceRequestStart; - bool mShowLoadStatus; - bool mIsMouseOverTitle; - - // 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; } - virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; } - - static LLFontGL* getLabelFontForStyle(U8 style); - - virtual void setCreationDate(time_t creation_date_utc) { mCreationDate = creation_date_utc; } - -public: - BOOL postBuild(); - - // This function clears the currently selected item, and records - // the specified selected item appropriately for display and use - // in the UI. If open is TRUE, then folders are opened up along - // the way to the selection. - void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus = TRUE); - - // This function is called when the folder view is dirty. It's - // implemented here but called by derived classes when folding the - // views. - void arrangeFromRoot(); - void filterFromRoot( void ); - - void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus); - - virtual ~LLFolderViewItem( void ); - - // addToFolder() returns TRUE if it succeeds. FALSE otherwise - enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE }; - virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); - - virtual EInventorySortGroup getSortGroup() const; - - // Finds width and height of this object and it's children. Also - // makes sure that this view and it's children are the right size. - virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); - virtual S32 getItemHeight(); - - // applies filters to control visibility of inventory items - virtual void filter( LLInventoryFilter& filter); - - // updates filter serial number and optionally propagated value up to root - S32 getLastFilterGeneration() { return mLastFilterGeneration; } - - virtual void dirtyFilter(); - - // If 'selection' is 'this' then note that otherwise ignore. - // Returns TRUE if this item ends up being selected. - virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus); - - // This method is used to set the selection state of an item. - // If 'selection' is 'this' then note selection. - // 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(); - - // this method is used to select this element - virtual void selectItem(); - - // gets multiple-element selection - virtual std::set<LLUUID> getSelectionList() const; - - // Returns true is this object and all of its children can be removed (deleted by user) - virtual BOOL isRemovable(); - - // Returns true is this object and all of its children can be moved - virtual BOOL isMovable(); - - // destroys this item recursively - virtual void destroyView(); - - BOOL isSelected() const { return mIsSelected; } - - void setUnselected() { mIsSelected = FALSE; } - - void setIsCurSelection(BOOL select) { mIsCurSelection = select; } - - BOOL getIsCurSelection() { return mIsCurSelection; } - - BOOL hasVisibleChildren() { return mHasVisibleChildren; } - - void setShowLoadStatus(bool status) { mShowLoadStatus = status; } - - // Call through to the viewed object and return true if it can be - // removed. Returns true if it's removed. - //virtual BOOL removeRecursively(BOOL single_item); - BOOL remove(); - - // Build an appropriate context menu for the item. Flags unused. - void buildContextMenu(LLMenuGL& menu, U32 flags); - - // This method returns the actual name of the thing being - // viewed. This method will ask the viewed object itself. - const std::string& getName( void ) const; - - const std::string& getSearchableLabel( void ) const; - - // This method returns the label displayed on the view. This - // method was primarily added to allow sorting on the folder - // contents possible before the entire view has been constructed. - const std::string& getLabel() const { return mLabel; } - - // Used for sorting, like getLabel() above. - virtual time_t getCreationDate() const { return mCreationDate; } - - LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; } - const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; } - - LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE ); - LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE ); - - const LLFolderViewEventListener* getListener( void ) const { return mListener; } - LLFolderViewEventListener* getListener( void ) { return mListener; } - - // Gets the inventory item if it exists (null otherwise) - LLViewerInventoryItem * getInventoryItem(void); - - // just rename the object. - void rename(const std::string& new_name); - - // open - virtual void openItem( void ); - virtual void preview(void); - - // Show children (unfortunate that this is called "open") - virtual void setOpen(BOOL open = TRUE) {}; - - virtual BOOL isOpen() const { return FALSE; } - - virtual LLFolderView* getRoot(); - BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor ); - S32 getIndentation() { return mIndentation; } - - virtual BOOL potentiallyVisible(); // do we know for a fact that this item has been filtered out? - - virtual BOOL getFiltered(); - virtual BOOL getFiltered(S32 filter_generation); - virtual void setFiltered(BOOL filtered, S32 filter_generation); - - // change the icon - void setIcon(LLUIImagePtr icon); - - // refresh information from the object being viewed. - void refreshFromListener(); - virtual void refresh(); - - virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor); - - // LLView functionality - virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleHover( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); - virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); - - virtual void onMouseLeave(S32 x, S32 y, MASK mask); - - virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return NULL; } - - // virtual void handleDropped(); - virtual void draw(); - virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg); - -private: - static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts -}; - - -// function used for sorting. -typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b); - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewFolder -// -// An instance of an LLFolderViewFolder represents a collection of -// more folders and items. This is used to build the hierarchy of -// items found in the folder view. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLFolderViewFolder : public LLFolderViewItem -{ -protected: - LLFolderViewFolder( const LLFolderViewItem::Params& ); - friend class LLUICtrlFactory; - -public: - typedef enum e_trash - { - UNKNOWN, TRASH, NOT_TRASH - } ETrash; - - 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; - LLInventorySort mSortFunction; - - BOOL mIsOpen; - BOOL mExpanderHighlighted; - F32 mCurHeight; - F32 mTargetHeight; - F32 mAutoOpenCountdown; - time_t mSubtreeCreationDate; - mutable ETrash mAmTrash; - S32 mLastArrangeGeneration; - S32 mLastCalculatedWidth; - S32 mCompletedFilterGeneration; - S32 mMostFilteredDescendantGeneration; - bool mNeedsSort; - bool mPassedFolderFilter; - -public: - typedef enum e_recurse_type - { - RECURSE_NO, - RECURSE_UP, - RECURSE_DOWN, - RECURSE_UP_DOWN - } ERecurseType; - - - virtual ~LLFolderViewFolder( void ); - - virtual BOOL potentiallyVisible(); - - LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE ); - LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE ); - - // addToFolder() returns TRUE if it succeeds. FALSE otherwise - virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); - - // Finds width and height of this object and it's children. Also - // makes sure that this view and it's children are the right size. - virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); - - BOOL needsArrange(); - void requestSort(); - - // Returns the sort group (system, trash, folder) for this folder. - virtual EInventorySortGroup getSortGroup() const; - - virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up); - virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; } - - BOOL hasFilteredDescendants(S32 filter_generation); - BOOL hasFilteredDescendants(); - - // applies filters to control visibility of inventory items - virtual void filter( LLInventoryFilter& filter); - virtual void setFiltered(BOOL filtered, S32 filter_generation); - virtual BOOL getFiltered(); - virtual BOOL getFiltered(S32 filter_generation); - - virtual void dirtyFilter(); - - // folder-specific filtering (filter status propagates top down instead of bottom up) - void filterFolder(LLInventoryFilter& filter); - void setFilteredFolder(bool filtered, S32 filter_generation); - bool getFilteredFolder(S32 filter_generation); - - // Passes selection information on to children and record - // selection information if necessary. - // Returns TRUE if this object (or a child) ends up being selected. - // If 'openitem' is TRUE then folders are opened up along the way to the selection. - virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus); - - // This method is used to change the selection of an item. - // Recursively traverse all children; if 'selection' is 'this' then change - // the select status if necessary. - // Returns TRUE if the selection state of this folder, or of a child, 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); - - // Returns true is this object and all of its children can be removed. - virtual BOOL isRemovable(); - - // Returns true is this object and all of its children can be moved - virtual BOOL isMovable(); - - // destroys this folder, and all children - virtual void destroyView(); - - // If this folder can be removed, remove all children that can be - // removed, return TRUE if this is empty after the operation and - // it's viewed folder object can be removed. - //virtual BOOL removeRecursively(BOOL single_item); - //virtual BOOL remove(); - - // remove the specified item (and any children) if - // possible. Return TRUE if the item was deleted. - BOOL removeItem(LLFolderViewItem* item); - - // simply remove the view (and any children) Don't bother telling - // the listeners. - void removeView(LLFolderViewItem* item); - - // extractItem() removes the specified item from the folder, but - // doesn't delete it. - void extractItem( LLFolderViewItem* item ); - - // This function is called by a child that needs to be resorted. - void resort(LLFolderViewItem* item); - - void setItemSortOrder(U32 ordering); - void sortBy(U32); - //BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b)); - - void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; } - - // folders can be opened. This will usually be called by internal - // methods. - virtual void toggleOpen(); - - // Force a folder open or closed - virtual void setOpen(BOOL openitem = TRUE); - - // Called when a child is refreshed. - // don't rearrange child folder contents unless explicitly requested - virtual void requestArrange(BOOL include_descendants = FALSE); - - // internal method which doesn't update the entire view. This - // method was written because the list iterators destroy the state - // of other iterations, thus, we can't arrange while iterating - // through the children (such as when setting which is selected. - virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO); - - // Get the current state of the folder. - virtual BOOL isOpen() const { return mIsOpen; } - - // special case if an object is dropped on the child. - BOOL handleDragAndDropFromChild(MASK mask, - BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg); - - void applyFunctorRecursively(LLFolderViewFunctor& functor); - virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor); - - // Just apply this functor to the folder's immediate children. - void applyFunctorToChildren(LLFolderViewFunctor& functor); - - virtual void openItem( void ); - virtual BOOL addItem(LLFolderViewItem* item); - virtual BOOL addFolder( LLFolderViewFolder* folder); - - // LLView functionality - virtual BOOL handleHover(S32 x, S32 y, MASK mask); - virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); - virtual BOOL handleDragAndDrop(S32 x, S32 y, 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(); } - folders_t::size_type getFoldersCount() const { return mFolders.size(); } - - 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(); } -}; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewListenerFunctor -// -// This simple abstract base class can be used to applied to all -// listeners in a hierarchy. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLFolderViewListenerFunctor -{ -public: - virtual ~LLFolderViewListenerFunctor() {} - virtual void operator()(LLFolderViewEventListener* listener) = 0; -}; - -#endif // LLFOLDERVIEWITEM_H diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp new file mode 100644 index 0000000000..586965e5a0 --- /dev/null +++ b/indra/newview/llfolderviewmodelinventory.cpp @@ -0,0 +1,314 @@ +/* + * @file llfolderviewmodelinventory.cpp + * @brief Implementation of the inventory-specific view model + * + * $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 "llfolderviewmodelinventory.h" +#include "llinventorymodelbackgroundfetch.h" +#include "llinventorypanel.h" +#include "lltooldraganddrop.h" +#include "llfavoritesbar.h" + +// +// class LLFolderViewModelInventory +// +static LLFastTimer::DeclareTimer FTM_INVENTORY_SORT("Sort"); + +bool LLFolderViewModelInventory::startDrag(std::vector<LLFolderViewModelItem*>& items) +{ + std::vector<EDragAndDropType> types; + uuid_vec_t cargo_ids; + std::vector<LLFolderViewModelItem*>::iterator item_it; + bool can_drag = true; + if (!items.empty()) + { + for (item_it = items.begin(); item_it != items.end(); ++item_it) + { + EDragAndDropType type = DAD_NONE; + LLUUID id = LLUUID::null; + can_drag = can_drag && static_cast<LLFolderViewModelItemInventory*>(*item_it)->startDrag(&type, &id); + + types.push_back(type); + cargo_ids.push_back(id); + } + + LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, + static_cast<LLFolderViewModelItemInventory*>(items.front())->getDragSource(), mTaskID); + } + return can_drag; +} + + +void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder ) +{ + LLFastTimer _(FTM_INVENTORY_SORT); + + if (!needsSort(folder->getViewModelItem())) return; + + LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem()); + if (modelp->getUUID().isNull()) return; + + for (std::list<LLFolderViewFolder*>::iterator it = folder->getFoldersBegin(), end_it = folder->getFoldersEnd(); + it != end_it; + ++it) + { + LLFolderViewFolder* child_folderp = *it; + sort(child_folderp); + + if (child_folderp->getFoldersCount() > 0) + { + time_t most_recent_folder_time = + static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getFoldersBegin())->getViewModelItem())->getCreationDate(); + LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem()); + if (most_recent_folder_time > modelp->getCreationDate()) + { + modelp->setCreationDate(most_recent_folder_time); + } + } + if (child_folderp->getItemsCount() > 0) + { + time_t most_recent_item_time = + static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getItemsBegin())->getViewModelItem())->getCreationDate(); + + LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem()); + if (most_recent_item_time > modelp->getCreationDate()) + { + modelp->setCreationDate(most_recent_item_time); + } + } + } + base_t::sort(folder); +} + +bool LLFolderViewModelInventory::contentsReady() +{ + return !LLInventoryModelBackgroundFetch::instance().folderFetchActive(); +} + +void LLFolderViewModelItemInventory::requestSort() +{ + LLFolderViewModelItemCommon::requestSort(); + LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(mFolderViewItem); + if (folderp) + { + folderp->requestArrange(); + } + if (static_cast<LLFolderViewModelInventory&>(mRootViewModel).getSorter().isByDate()) + { + // sort by date potentially affects parent folders which use a date + // derived from newest item in them + if (mParent) + { + mParent->requestSort(); + } + } +} + +void LLFolderViewModelItemInventory::setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset, std::string::size_type string_size) +{ + LLFolderViewModelItemCommon::setPassedFilter(passed, filter_generation, string_offset, string_size); + + bool passed_filter_before = mPrevPassedAllFilters; + mPrevPassedAllFilters = passedFilter(filter_generation); + + if (passed_filter_before != mPrevPassedAllFilters) + { + LLFolderViewFolder* parent_folder = mFolderViewItem->getParentFolder(); + if (parent_folder) + { + parent_folder->requestArrange(); + } + } +} + +bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter ) +{ + S32 filter_generation = filter.getCurrentGeneration(); + + bool continue_filtering = true; + if (item->getLastFilterGeneration() < filter_generation) + { + // recursive application of the filter for child items + continue_filtering = item->filter( filter ); + } + + // track latest generation to pass any child items, for each folder up to root + if (item->passedFilter()) + { + LLFolderViewModelItemInventory* view_model = this; + + while(view_model && view_model->mMostFilteredDescendantGeneration < filter_generation) + { + view_model->mMostFilteredDescendantGeneration = filter_generation; + view_model = static_cast<LLFolderViewModelItemInventory*>(view_model->mParent); + } + } + + return continue_filtering; +} + +bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter) +{ + const S32 filter_generation = filter.getCurrentGeneration(); + const S32 must_pass_generation = filter.getFirstRequiredGeneration(); + + if (getLastFilterGeneration() >= must_pass_generation + && getLastFolderFilterGeneration() >= must_pass_generation + && !passedFilter(must_pass_generation)) + { + // failed to pass an earlier filter that was a subset of the current one + // go ahead and flag this item as done + setPassedFilter(false, filter_generation); + setPassedFolderFilter(false, filter_generation); + return true; + } + + const bool passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY) + ? filter.checkFolder(this) + : true; + setPassedFolderFilter(passed_filter_folder, filter_generation); + + if(!mChildren.empty() + && (getLastFilterGeneration() < must_pass_generation // haven't checked descendants against minimum required generation to pass + || descendantsPassedFilter(must_pass_generation))) // or at least one descendant has passed the minimum requirement + { + // now query children + for (child_list_t::iterator iter = mChildren.begin(), end_iter = mChildren.end(); + iter != end_iter && filter.getFilterCount() > 0; + ++iter) + { + if (!filterChildItem((*iter), filter)) + { + break; + } + } + } + + // if we didn't use all filter iterations + // that means we filtered all of our descendants + // so filter ourselves now + if (filter.getFilterCount() > 0) + { + filter.decrementFilterCount(); + + const bool passed_filter = filter.check(this); + setPassedFilter(passed_filter, filter_generation, filter.getStringMatchOffset(this), filter.getFilterStringSize()); + return true; + } + else + { + return false; + } +} + +LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() +{ + return &mInventoryViewModel; +} + + +const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const +{ + return &mInventoryViewModel; +} + +bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const +{ + // Ignore sort order for landmarks in the Favorites folder. + // In that folder, landmarks should be always sorted as in the Favorites bar. See EXT-719 + if (a->getSortGroup() == SG_ITEM + && b->getSortGroup() == SG_ITEM + && a->getInventoryType() == LLInventoryType::IT_LANDMARK + && b->getInventoryType() == LLInventoryType::IT_LANDMARK) + { + static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); + // If both landmarks are in the Favorites folder... + if (gInventory.isObjectDescendentOf(a->getUUID(), favorites_folder_id) && gInventory.isObjectDescendentOf(b->getUUID(), favorites_folder_id)) + { + // Get their index in that folder + S32 a_sort = LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID()); + S32 b_sort = LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID()); + // Note: this test is a bit overkill: since they are both in the Favorites folder, we shouldn't get negative index values... + if (!((a_sort < 0) && (b_sort < 0))) + { + return a_sort < b_sort; + } + } + } + + // We sort by name if we aren't sorting by date + // OR if these are folders and we are sorting folders by name. + bool by_name = (!mByDate || (mFoldersByName && (a->getSortGroup() != SG_ITEM))); + + if (a->getSortGroup() != b->getSortGroup()) + { + if (mSystemToTop) + { + // Group order is System Folders, Trash, Normal Folders, Items + return (a->getSortGroup() < b->getSortGroup()); + } + else if (mByDate) + { + // Trash needs to go to the bottom if we are sorting by date + if ( (a->getSortGroup() == SG_TRASH_FOLDER) + || (b->getSortGroup() == SG_TRASH_FOLDER)) + { + return (b->getSortGroup() == SG_TRASH_FOLDER); + } + } + } + + if (by_name) + { + S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName()); + if (0 == compare) + { + return (a->getCreationDate() > b->getCreationDate()); + } + else + { + return (compare < 0); + } + } + else + { + time_t first_create = a->getCreationDate(); + time_t second_create = b->getCreationDate(); + if (first_create == second_create) + { + return (LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName()) < 0); + } + else + { + return (first_create > second_create); + } + } +} + +LLFolderViewModelItemInventory::LLFolderViewModelItemInventory( class LLFolderViewModelInventory& root_view_model ) + : LLFolderViewModelItemCommon(root_view_model), + mPrevPassedAllFilters(false) +{ +} diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h new file mode 100644 index 0000000000..890d03d1c9 --- /dev/null +++ b/indra/newview/llfolderviewmodelinventory.h @@ -0,0 +1,118 @@ +/** + * @file llfolderviewmodelinventory.h + * @brief view model implementation specific to inventory + * 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 + * 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_LLFOLDERVIEWMODELINVENTORY_H +#define LL_LLFOLDERVIEWMODELINVENTORY_H + +#include "llinventoryfilter.h" +#include "llinventory.h" +#include "llwearabletype.h" +#include "lltooldraganddrop.h" + +class LLFolderViewModelItemInventory + : public LLFolderViewModelItemCommon +{ +public: + LLFolderViewModelItemInventory(class LLFolderViewModelInventory& root_view_model); + virtual const LLUUID& getUUID() const = 0; + virtual time_t getCreationDate() const = 0; // UTC seconds + virtual void setCreationDate(time_t creation_date_utc) = 0; + virtual PermissionMask getPermissionMask() const = 0; + virtual LLFolderType::EType getPreferredType() const = 0; + virtual void showProperties(void) = 0; + virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual. + virtual BOOL isUpToDate() const = 0; + virtual bool hasChildren() const = 0; + virtual LLInventoryType::EType getInventoryType() const = 0; + virtual void performAction(LLInventoryModel* model, std::string action) = 0; + virtual LLWearableType::EType getWearableType() const = 0; + virtual EInventorySortGroup getSortGroup() const = 0; + virtual LLInventoryObject* getInventoryObject() const = 0; + virtual void requestSort(); + virtual void setPassedFilter(bool filtered, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0); + virtual bool filter( LLFolderViewFilter& filter); + virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter); + + virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0; + virtual LLToolDragAndDrop::ESource getDragSource() const = 0; + +protected: + bool mPrevPassedAllFilters; +}; + +class LLInventorySort +{ +public: + struct Params : public LLInitParam::Block<Params> + { + Optional<S32> order; + + Params() + : order("order", 0) + {} + }; + + LLInventorySort(S32 order = 0) + { + fromParams(Params().order(order)); + } + + bool isByDate() const { return mByDate; } + U32 getSortOrder() const { return mSortOrder; } + void toParams(Params& p) { p.order(mSortOrder);} + void fromParams(Params& p) + { + mSortOrder = p.order; + mByDate = (mSortOrder & LLInventoryFilter::SO_DATE); + mSystemToTop = (mSortOrder & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP); + mFoldersByName = (mSortOrder & LLInventoryFilter::SO_FOLDERS_BY_NAME); + } + + bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const; +private: + U32 mSortOrder; + bool mByDate; + bool mSystemToTop; + bool mFoldersByName; +}; + +class LLFolderViewModelInventory + : public LLFolderViewModel<LLInventorySort, LLFolderViewModelItemInventory, LLFolderViewModelItemInventory, LLInventoryFilter> +{ +public: + typedef LLFolderViewModel<LLInventorySort, LLFolderViewModelItemInventory, LLFolderViewModelItemInventory, LLInventoryFilter> base_t; + + void setTaskID(const LLUUID& id) {mTaskID = id;} + + void sort(LLFolderViewFolder* folder); + bool contentsReady(); + bool startDrag(std::vector<LLFolderViewModelItem*>& items); + +private: + LLUUID mTaskID; +}; +#endif // LL_LLFOLDERVIEWMODELINVENTORY_H diff --git a/indra/newview/llfollowcam.cpp b/indra/newview/llfollowcam.cpp index b670af1782..47612fe25c 100644 --- a/indra/newview/llfollowcam.cpp +++ b/indra/newview/llfollowcam.cpp @@ -38,7 +38,6 @@ std::vector<LLFollowCamParams*> LLFollowCamMgr::sParamStack; //------------------------------------------------------- // constants //------------------------------------------------------- -const F32 ONE_HALF = 0.5; const F32 FOLLOW_CAM_ZOOM_FACTOR = 0.1f; const F32 FOLLOW_CAM_MIN_ZOOM_AMOUNT = 0.1f; const F32 DISTANCE_EPSILON = 0.0001f; diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 11401d6c68..a4dfd94496 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -47,13 +47,13 @@ static const std::string INVENTORY_STRING_FRIENDS_ALL_SUBFOLDER = "All"; // helper functions // NOTE: For now Friends & All folders are created as protected folders of the LLFolderType::FT_CALLINGCARD type. -// So, their names will be processed in the LLFolderViewItem::refreshFromListener() to be localized +// So, their names will be processed in the LLFolderViewItem::refresh() to be localized // using "InvFolder LABEL_NAME" as LLTrans::findString argument. // We must use in this file their hard-coded names to ensure found them on different locales. EXT-5829. // These hard-coded names will be stored in InventoryItems but shown localized in FolderViewItems -// If hack in the LLFolderViewItem::refreshFromListener() to localize protected folder is removed +// If hack in the LLFolderViewItem::refresh() to localize protected folder is removed // or these folders are not protected these names should be localized in another place/way. inline const std::string get_friend_folder_name() { @@ -533,7 +533,7 @@ void LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID) bool shouldBeAdded = true; LLAvatarName av_name; LLAvatarNameCache::get(avatarID, &av_name); - const std::string& name = av_name.mUsername; + const std::string& name = av_name.getAccountName(); lldebugs << "Processing buddy name: " << name << ", id: " << avatarID diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 66ca76bfb0..f307505ff8 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -35,6 +35,7 @@ // library #include "llaudioengine.h" #include "lldatapacker.h" +#include "llfloaterreg.h" #include "llinventory.h" #include "llkeyframemotion.h" #include "llmultigesture.h" @@ -51,7 +52,7 @@ #include "llviewermessage.h" #include "llvoavatarself.h" #include "llviewerstats.h" -#include "llnearbychatbar.h" +#include "llfloaterimnearbychat.h" #include "llappearancemgr.h" #include "llgesturelistener.h" @@ -997,7 +998,8 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step) const BOOL animate = FALSE; - LLNearbyChatBar::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate); + (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))-> + sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate); gesture->mCurrentStep++; break; diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index 30858871ec..72bea8db10 100644 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -220,17 +220,25 @@ bool LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent, return res; } -void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent, +bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent, const LLInventoryCategory* cat, - const LLUUID& im_session_id) + const LLUUID& im_session_id, + const std::string& notification_name) { - if (!cat) return; + if (!cat) + { + return false; + } llinfos << "LLGiveInventory::giveInventoryCategory() - " << cat->getUUID() << llendl; - if (!isAgentAvatarValid()) return; + if (!isAgentAvatarValid()) + { + return false; + } + bool give_successful = true; // Test out how many items are being given. LLViewerInventoryCategory::cat_array_t cats; LLViewerInventoryItem::item_array_t items; @@ -253,24 +261,24 @@ void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent, if (!complete) { LLNotificationsUtil::add("IncompleteInventory"); - return; + give_successful = false; } count = items.count() + cats.count(); if (count > MAX_ITEMS) { LLNotificationsUtil::add("TooManyItems"); - return; + give_successful = false; } else if (count == 0) { LLNotificationsUtil::add("NoItems"); - return; + give_successful = false; } - else + else if (give_successful) { if (0 == giveable.countNoCopy()) { - LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id); + give_successful = LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id); } else { @@ -279,9 +287,16 @@ void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent, LLSD payload; payload["agent_id"] = to_agent; payload["folder_id"] = cat->getUUID(); + if (!notification_name.empty()) + { + payload["success_notification"] = notification_name; + } LLNotificationsUtil::add("CannotCopyCountItems", args, payload, &LLGiveInventory::handleCopyProtectedCategory); + give_successful = false; } } + + return give_successful; } ////////////////////////////////////////////////////////////////////////// @@ -325,6 +340,7 @@ bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LL S32 option = LLNotificationsUtil::getSelectedOption(notification, response); LLSD itmes = notification["payload"]["items"]; LLInventoryItem* item = NULL; + bool give_successful = true; switch(option) { case 0: // "Yes" @@ -343,15 +359,21 @@ bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LL else { LLNotificationsUtil::add("CannotGiveItem"); + give_successful = false; } } + if (give_successful && notification["payload"]["success_notification"].isDefined()) + { + LLNotificationsUtil::add(notification["payload"]["success_notification"].asString()); + } break; default: // no, cancel, whatever, who cares, not yes. LLNotificationsUtil::add("TransactionCancelled"); + give_successful = false; break; } - return false; + return give_successful; } // static @@ -408,13 +430,14 @@ bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, cons { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); LLInventoryCategory* cat = NULL; + bool give_successful = true; switch(option) { case 0: // "Yes" cat = gInventory.getCategory(notification["payload"]["folder_id"].asUUID()); if (cat) { - LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(), + give_successful = LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(), cat); LLViewerInventoryCategory::cat_array_t cats; LLViewerInventoryItem::item_array_t items; @@ -430,27 +453,37 @@ bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, cons gInventory.deleteObject(items.get(i)->getUUID()); } gInventory.notifyObservers(); + + if (give_successful && notification["payload"]["success_notification"].isDefined()) + { + LLNotificationsUtil::add(notification["payload"]["success_notification"].asString()); + } } else { LLNotificationsUtil::add("CannotGiveCategory"); + give_successful = false; } break; default: // no, cancel, whatever, who cares, not yes. LLNotificationsUtil::add("TransactionCancelled"); + give_successful = false; break; } - return false; + return give_successful; } // static -void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent, +bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent, const LLInventoryCategory* cat, const LLUUID& im_session_id) { - if (!cat) return; + if (!cat) + { + return false; + } llinfos << "LLGiveInventory::commitGiveInventoryCategory() - " << cat->getUUID() << llendl; @@ -467,6 +500,7 @@ void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent, LLInventoryModel::EXCLUDE_TRASH, giveable); + bool give_successful = true; // MAX ITEMS is based on (sizeof(uuid)+2) * count must be < // MTUBYTES or 18 * count < 1200 => count < 1200/18 => // 66. I've cut it down a bit from there to give some pad. @@ -474,12 +508,12 @@ void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent, if (count > MAX_ITEMS) { LLNotificationsUtil::add("TooManyItems"); - return; + give_successful = false; } else if (count == 0) { LLNotificationsUtil::add("NoItems"); - return; + give_successful = false; } else { @@ -545,6 +579,8 @@ void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent, logInventoryOffer(to_agent, im_session_id); } + + return give_successful; } // EOF diff --git a/indra/newview/llgiveinventory.h b/indra/newview/llgiveinventory.h index e1e221c75b..85bc1ed49c 100644 --- a/indra/newview/llgiveinventory.h +++ b/indra/newview/llgiveinventory.h @@ -62,9 +62,10 @@ public: /** * Gives passed inventory category to specified avatar in specified session. */ - static void doGiveInventoryCategory(const LLUUID& to_agent, + static bool doGiveInventoryCategory(const LLUUID& to_agent, const LLInventoryCategory* item, - const LLUUID &session_id = LLUUID::null); + const LLUUID &session_id = LLUUID::null, + const std::string& notification = std::string()); // give inventory item functionality static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response); @@ -85,7 +86,7 @@ private: // give inventory category functionality static bool handleCopyProtectedCategory(const LLSD& notification, const LLSD& response); - static void commitGiveInventoryCategory(const LLUUID& to_agent, + static bool commitGiveInventoryCategory(const LLUUID& to_agent, const LLInventoryCategory* cat, const LLUUID &im_session_id = LLUUID::null); diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 623ebb76f2..a0f2918bd7 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -36,10 +36,10 @@ #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llgroupmgr.h" +#include "llfloaterimcontainer.h" #include "llimview.h" // for gIMMgr #include "llnotificationsutil.h" #include "llstatusbar.h" // can_afford_transaction() -#include "llimfloater.h" #include "groupchatlistener.h" // @@ -335,7 +335,7 @@ LLUUID LLGroupActions::startIM(const LLUUID& group_id) group_id); if (session_id != LLUUID::null) { - LLIMFloater::show(session_id); + LLFloaterIMContainer::getInstance()->showConversation(session_id); } make_ui_sound("UISndStartIM"); return session_id; diff --git a/indra/newview/llgroupiconctrl.cpp b/indra/newview/llgroupiconctrl.cpp index 2f9810775b..188c4bcf25 100644 --- a/indra/newview/llgroupiconctrl.cpp +++ b/indra/newview/llgroupiconctrl.cpp @@ -38,7 +38,7 @@ #include "llcachename.h" #include "llagentdata.h" -#include "llimfloater.h" +#include "llfloaterimsession.h" */ static LLDefaultChildRegistry::Register<LLGroupIconCtrl> g_i("group_icon"); diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index f7ed1116cb..aba3d74d87 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -86,7 +86,7 @@ LLGroupList::LLGroupList(const Params& p) registrar.add("People.Groups.Action", boost::bind(&LLGroupList::onContextMenuItemClick, this, _2)); enable_registrar.add("People.Groups.Enable", boost::bind(&LLGroupList::onContextMenuItemEnable, this, _2)); - LLMenuGL* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_people_groups.xml", + LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_groups.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if(context_menu) mContextMenuHandle = context_menu->getHandle(); @@ -95,7 +95,7 @@ LLGroupList::LLGroupList(const Params& p) LLGroupList::~LLGroupList() { gAgent.removeListener(this); - delete mContextMenuHandle.get(); + if (mContextMenuHandle.get()) mContextMenuHandle.get()->die(); } // virtual @@ -112,7 +112,7 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask) { BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask); - LLMenuGL* context_menu = (LLMenuGL*)mContextMenuHandle.get(); + LLToggleableMenu* context_menu = mContextMenuHandle.get(); if (context_menu && size() > 0) { context_menu->buildDrawLabels(); @@ -123,6 +123,22 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask) return handled; } +// virtual +BOOL LLGroupList::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + BOOL handled = LLView::handleDoubleClick(x, y, mask); + // Handle double click only for the selected item in the list, skip clicks on empty space. + if (handled) + { + if (mDoubleClickSignal) + { + (*mDoubleClickSignal)(this, x, y, mask); + } + } + + return handled; +} + void LLGroupList::setNameFilter(const std::string& filter) { std::string filter_upper = filter; @@ -390,7 +406,7 @@ void LLGroupListItem::setActive(bool active) // *BUG: setName() overrides the style params. // Active group should be bold. - LLFontDescriptor new_desc(mGroupNameBox->getDefaultFont()->getFontDesc()); + LLFontDescriptor new_desc(mGroupNameBox->getFont()->getFontDesc()); // *NOTE dzaporozhan // On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h index d7051db891..e96a720886 100644 --- a/indra/newview/llgrouplist.h +++ b/indra/newview/llgrouplist.h @@ -28,10 +28,13 @@ #define LL_LLGROUPLIST_H #include "llevent.h" +#include "llpointer.h" + #include "llflatlistview.h" #include "llpanel.h" -#include "llpointer.h" #include "llstyle.h" +#include "lltoggleablemenu.h" + #include "llgroupmgr.h" /** @@ -45,17 +48,24 @@ class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener { LOG_CLASS(LLGroupList); public: + struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params> + { + Params(){}; + }; LLGroupList(const Params& p); virtual ~LLGroupList(); virtual void draw(); // from LLView /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); // from LLView + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); // from LLView void setNameFilter(const std::string& filter); void toggleIcons(); bool getIconsVisible() const { return mShowIcons; } + LLToggleableMenu* getContextMenu() const { return mContextMenuHandle.get(); } + private: void setDirty(bool val = true) { mDirty = val; } void refresh(); @@ -65,7 +75,7 @@ private: bool onContextMenuItemClick(const LLSD& userdata); bool onContextMenuItemEnable(const LLSD& userdata); - LLHandle<LLView> mContextMenuHandle; + LLHandle<LLToggleableMenu> mContextMenuHandle; bool mShowIcons; bool mDirty; diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index efffd0f98e..81eb1d397e 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -36,6 +36,7 @@ #include <vector> #include <algorithm> +#include "llappviewer.h" #include "llagent.h" #include "llui.h" #include "message.h" @@ -63,7 +64,7 @@ #pragma warning(pop) // Restore all warnings to the previous state #endif -const U32 MAX_CACHED_GROUPS = 10; +const U32 MAX_CACHED_GROUPS = 20; // // LLRoleActionSet @@ -234,8 +235,15 @@ LLGroupMgrGroupData::LLGroupMgrGroupData(const LLUUID& id) : mRoleDataComplete(FALSE), mRoleMemberDataComplete(FALSE), mGroupPropertiesDataComplete(FALSE), - mPendingRoleMemberRequest(FALSE) + mPendingRoleMemberRequest(FALSE), + mAccessTime(0.0f) { + mMemberVersion.generate(); +} + +void LLGroupMgrGroupData::setAccessed() +{ + mAccessTime = (F32)LLFrameTimer::getTotalSeconds(); } BOOL LLGroupMgrGroupData::getRoleData(const LLUUID& role_id, LLRoleData& role_data) @@ -311,14 +319,14 @@ void LLGroupMgrGroupData::setRoleData(const LLUUID& role_id, LLRoleData role_dat role_data.mChangeType = RC_UPDATE_DATA; } else - { + { role_data.mChangeType = RC_UPDATE_POWERS; } mRoleChanges[role_id] = role_data; } else - { + { llwarns << "Change being made to non-existant role " << role_id << llendl; } } @@ -417,6 +425,7 @@ void LLGroupMgrGroupData::removeMemberData() } mMembers.clear(); mMemberDataComplete = FALSE; + mMemberVersion.generate(); } void LLGroupMgrGroupData::removeRoleData() @@ -739,6 +748,7 @@ void LLGroupMgrGroupData::cancelRoleChanges() LLGroupMgr::LLGroupMgr() { + mLastGroupMembersRequestFrame = 0; } LLGroupMgr::~LLGroupMgr() @@ -937,6 +947,8 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data) } } + group_datap->mMemberVersion.generate(); + if (group_datap->mMembers.size() == (U32)group_datap->mMemberCount) { group_datap->mMemberDataComplete = TRUE; @@ -1360,7 +1372,7 @@ void LLGroupMgr::processCreateGroupReply(LLMessageSystem* msg, void ** data) LLGroupMgrGroupData* LLGroupMgr::createGroupData(const LLUUID& id) { - LLGroupMgrGroupData* group_datap; + LLGroupMgrGroupData* group_datap = NULL; group_map_t::iterator existing_group = LLGroupMgr::getInstance()->mGroups.find(id); if (existing_group == LLGroupMgr::getInstance()->mGroups.end()) @@ -1373,6 +1385,11 @@ LLGroupMgrGroupData* LLGroupMgr::createGroupData(const LLUUID& id) group_datap = existing_group->second; } + if (group_datap) + { + group_datap->setAccessed(); + } + return group_datap; } @@ -1413,25 +1430,41 @@ void LLGroupMgr::notifyObservers(LLGroupChange gc) void LLGroupMgr::addGroup(LLGroupMgrGroupData* group_datap) { - if (mGroups.size() > MAX_CACHED_GROUPS) + while (mGroups.size() >= MAX_CACHED_GROUPS) { - // get rid of groups that aren't observed - for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end() && mGroups.size() > MAX_CACHED_GROUPS / 2; ) + // LRU: Remove the oldest un-observed group from cache until group size is small enough + + F32 oldest_access = LLFrameTimer::getTotalSeconds(); + group_map_t::iterator oldest_gi = mGroups.end(); + + for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end(); ++gi ) { observer_multimap_t::iterator oi = mObservers.find(gi->first); if (oi == mObservers.end()) { - // not observed - LLGroupMgrGroupData* unobserved_groupp = gi->second; - delete unobserved_groupp; - mGroups.erase(gi++); - } - else - { - ++gi; + if (gi->second + && (gi->second->getAccessTime() < oldest_access)) + { + oldest_access = gi->second->getAccessTime(); + oldest_gi = gi; + } } } + + if (oldest_gi != mGroups.end()) + { + delete oldest_gi->second; + mGroups.erase(oldest_gi); + } + else + { + // All groups must be currently open, none to remove. + // Just add the new group anyway, but get out of this loop as it + // will never drop below max_cached_groups. + break; + } } + mGroups[group_datap->getID()] = group_datap; } @@ -1473,6 +1506,7 @@ void LLGroupMgr::sendGroupMembersRequest(const LLUUID& group_id) } } + void LLGroupMgr::sendGroupRoleDataRequest(const LLUUID& group_id) { lldebugs << "LLGroupMgr::sendGroupRoleDataRequest" << llendl; @@ -1741,8 +1775,6 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id, bool start_message = true; LLMessageSystem* msg = gMessageSystem; - - LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id); if (!group_datap) return; @@ -1803,8 +1835,193 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id, { gAgent.sendReliableMessage(); } + + group_datap->mMemberVersion.generate(); +} + + +// Responder class for capability group management +class GroupMemberDataResponder : public LLHTTPClient::Responder +{ +public: + GroupMemberDataResponder() {} + virtual ~GroupMemberDataResponder() {} + virtual void result(const LLSD& pContent); + virtual void error(U32 pStatus, const std::string& pReason); +private: + LLSD mMemberData; +}; + +void GroupMemberDataResponder::error(U32 pStatus, const std::string& pReason) +{ + LL_WARNS("GrpMgr") << "Error receiving group member data." << LL_ENDL; } +void GroupMemberDataResponder::result(const LLSD& content) +{ + LLGroupMgr::processCapGroupMembersRequest(content); +} + + +// static +void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id) +{ + // Have we requested the information already this frame? + if(mLastGroupMembersRequestFrame == gFrameCount) + return; + + LLViewerRegion* currentRegion = gAgent.getRegion(); + // Thank you FS:Ansariel! + if(!currentRegion) + { + LL_WARNS("GrpMgr") << "Agent does not have a current region. Uh-oh!" << LL_ENDL; + return; + } + + // Check to make sure we have our capabilities + if(!currentRegion->capabilitiesReceived()) + { + LL_WARNS("GrpMgr") << " Capabilities not received!" << LL_ENDL; + return; + } + + // Get our capability + std::string cap_url = currentRegion->getCapability("GroupMemberData"); + + // Thank you FS:Ansariel! + if(cap_url.empty()) + { + LL_INFOS("GrpMgr") << "Region has no GroupMemberData capability. Falling back to UDP fetch." << LL_ENDL; + sendGroupMembersRequest(group_id); + return; + } + + // Post to our service. Add a body containing the group_id. + LLSD body = LLSD::emptyMap(); + body["group_id"] = group_id; + + LLHTTPClient::ResponderPtr grp_data_responder = new GroupMemberDataResponder(); + + // This could take a while to finish, timeout after 5 minutes. + LLHTTPClient::post(cap_url, body, grp_data_responder, LLSD(), 300); + + mLastGroupMembersRequestFrame = gFrameCount; +} + + +// static +void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) +{ + // Did we get anything in content? + if(!content.size()) + { + LL_DEBUGS("GrpMgr") << "No group member data received." << LL_ENDL; + return; + } + + // If we have no members, there's no reason to do anything else + S32 num_members = content["member_count"]; + if(num_members < 1) + return; + + LLUUID group_id = content["group_id"].asUUID(); + + LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id); + if(!group_datap) + { + LL_WARNS("GrpMgr") << "Received incorrect, possibly stale, group or request id" << LL_ENDL; + return; + } + + group_datap->mMemberCount = num_members; + + LLSD member_list = content["members"]; + LLSD titles = content["titles"]; + LLSD defaults = content["defaults"]; + + std::string online_status; + std::string title; + S32 contribution; + U64 member_powers; + // If this is changed to a bool, make sure to change the LLGroupMemberData constructor + BOOL is_owner; + + // Compute this once, rather than every time. + U64 default_powers = llstrtou64(defaults["default_powers"].asString().c_str(), NULL, 16); + + LLSD::map_const_iterator member_iter_start = member_list.beginMap(); + LLSD::map_const_iterator member_iter_end = member_list.endMap(); + for( ; member_iter_start != member_iter_end; ++member_iter_start) + { + // Reset defaults + online_status = "unknown"; + title = titles[0].asString(); + contribution = 0; + member_powers = default_powers; + is_owner = false; + + const LLUUID member_id(member_iter_start->first); + LLSD member_info = member_iter_start->second; + + if(member_info.has("last_login")) + { + online_status = member_info["last_login"].asString(); + if(online_status == "Online") + online_status = LLTrans::getString("group_member_status_online"); + else + formatDateString(online_status); + } + + if(member_info.has("title")) + title = titles[member_info["title"].asInteger()].asString(); + + if(member_info.has("powers")) + member_powers = llstrtou64(member_info["powers"].asString().c_str(), NULL, 16); + + if(member_info.has("donated_square_meters")) + contribution = member_info["donated_square_meters"]; + + if(member_info.has("owner")) + is_owner = true; + + LLGroupMemberData* data = new LLGroupMemberData(member_id, + contribution, + member_powers, + title, + online_status, + is_owner); + + group_datap->mMembers[member_id] = data; + } + + group_datap->mMemberVersion.generate(); + + // Technically, we have this data, but to prevent completely overhauling + // this entire system (it would be nice, but I don't have the time), + // I'm going to be dumb and just call services I most likely don't need + // with the thought being that the system might need it to be done. + // + // TODO: + // Refactor to reduce multiple calls for data we already have. + if(group_datap->mTitles.size() < 1) + LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id); + + + group_datap->mMemberDataComplete = TRUE; + group_datap->mMemberRequestID.setNull(); + // Make the role-member data request + if (group_datap->mPendingRoleMemberRequest) + { + group_datap->mPendingRoleMemberRequest = FALSE; + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id); + } + + group_datap->mChanged = TRUE; + LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA); + +} + + void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id) { lldebugs << "LLGroupMgr::sendGroupRoleChanges" << llendl; diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index faf0531c10..d8c1ab7ef5 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -86,7 +86,7 @@ public: BOOL isInRole(const LLUUID& role_id) { return (mRolesList.find(role_id) != mRolesList.end()); } -protected: +private: LLUUID mID; S32 mContribution; U64 mAgentPowers; @@ -233,6 +233,11 @@ public: BOOL isRoleMemberDataComplete() { return mRoleMemberDataComplete; } BOOL isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; } + F32 getAccessTime() const { return mAccessTime; } + void setAccessed(); + + const LLUUID& getMemberVersion() const { return mMemberVersion; } + public: typedef std::map<LLUUID,LLGroupMemberData*> member_list_t; typedef std::map<LLUUID,LLGroupRoleData*> role_list_t; @@ -280,6 +285,10 @@ private: BOOL mGroupPropertiesDataComplete; BOOL mPendingRoleMemberRequest; + F32 mAccessTime; + + // Generate a new ID every time mMembers + LLUUID mMemberVersion; }; struct LLRoleAction @@ -336,6 +345,10 @@ public: static void sendGroupMemberEjects(const LLUUID& group_id, uuid_vec_t& member_ids); + // BAKER + void sendCapGroupMembersRequest(const LLUUID& group_id); + static void processCapGroupMembersRequest(const LLSD& content); + void cancelGroupRoleChanges(const LLUUID& group_id); static void processGroupPropertiesReply(LLMessageSystem* msg, void** data); @@ -371,6 +384,8 @@ private: typedef std::set<LLParticularGroupObserver*> observer_set_t; typedef std::map<LLUUID,observer_set_t> observer_map_t; observer_map_t mParticularObservers; + + S32 mLastGroupMembersRequestFrame; }; diff --git a/indra/newview/llhints.cpp b/indra/newview/llhints.cpp index e15862e2a4..197408b40e 100644 --- a/indra/newview/llhints.cpp +++ b/indra/newview/llhints.cpp @@ -171,12 +171,12 @@ LLHintPopup::LLHintPopup(const LLHintPopup::Params& p) } if (p.hint_image.isProvided()) { - buildFromFile("panel_hint_image.xml", NULL, p); + buildFromFile("panel_hint_image.xml", p); getChild<LLIconCtrl>("hint_image")->setImage(p.hint_image()); } else { - buildFromFile( "panel_hint.xml", NULL, p); + buildFromFile( "panel_hint.xml", p); } } diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 482294c8a6..3336097955 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -166,7 +166,6 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& } // scale screen size of borders down - //RN: for now, text on hud objects is never occluded LLVector3 x_pixel_vec; LLVector3 y_pixel_vec; @@ -187,45 +186,29 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& + (y_pixel_vec * screen_offset.mV[VY]); - //if (mUseBubble) + LLVector3 bg_pos = render_position + + (F32)mOffsetY * y_pixel_vec + - (width_vec / 2.f) + - (height_vec); + + LLVector3 v[] = { - LLVector3 bg_pos = render_position - + (F32)mOffsetY * y_pixel_vec - - (width_vec / 2.f) - - (height_vec); - //LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]); + bg_pos, + bg_pos + width_vec, + bg_pos + width_vec + height_vec, + bg_pos + height_vec, + }; - LLVector3 v[] = - { - bg_pos, - bg_pos + width_vec, - bg_pos + width_vec + height_vec, - bg_pos + height_vec, - }; + LLVector3 dir = end-start; + F32 a, b, t; - if (debug_render) + if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) || + LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) ) + { + if (t <= 1.f) { - gGL.begin(LLRender::LINE_STRIP); - gGL.vertex3fv(v[0].mV); - gGL.vertex3fv(v[1].mV); - gGL.vertex3fv(v[2].mV); - gGL.vertex3fv(v[3].mV); - gGL.vertex3fv(v[0].mV); - gGL.vertex3fv(v[2].mV); - gGL.end(); - } - - LLVector3 dir = end-start; - F32 a, b, t; - - if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) || - LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) ) - { - if (t <= 1.f) - { - intersection = start + dir*t; - return TRUE; - } + intersection = start + dir*t; + return TRUE; } } @@ -241,12 +224,6 @@ void LLHUDNameTag::render() } } -void LLHUDNameTag::renderForSelect() -{ - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - renderText(TRUE); -} - void LLHUDNameTag::renderText(BOOL for_select) { if (!mVisible || mHidden) @@ -299,24 +276,6 @@ void LLHUDNameTag::renderText(BOOL for_select) LLColor4 bg_color = LLUIColorTable::instance().getColor("NameTagBackground"); bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor); - // maybe a no-op? - //const S32 border_height = 16; - //const S32 border_width = 16; - const S32 border_height = 8; - const S32 border_width = 8; - - // *TODO move this into helper function - F32 border_scale = 1.f; - - if (border_height * 2 > mHeight) - { - border_scale = (F32)mHeight / ((F32)border_height * 2.f); - } - if (border_width * 2 > mWidth) - { - border_scale = llmin(border_scale, (F32)mWidth / ((F32)border_width * 2.f)); - } - // scale screen size of borders down //RN: for now, text on hud objects is never occluded @@ -325,152 +284,34 @@ void LLHUDNameTag::renderText(BOOL for_select) LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); - LLVector2 border_scale_vec((F32)border_width / (F32)imagep->getTextureWidth(), (F32)border_height / (F32)imagep->getTextureHeight()); LLVector3 width_vec = mWidth * x_pixel_vec; LLVector3 height_vec = mHeight * y_pixel_vec; - LLVector3 scaled_border_width = (F32)llfloor(border_scale * (F32)border_width) * x_pixel_vec; - LLVector3 scaled_border_height = (F32)llfloor(border_scale * (F32)border_height) * y_pixel_vec; mRadius = (width_vec + height_vec).magVec() * 0.5f; LLCoordGL screen_pos; LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE); - LLVector2 screen_offset; -// if (!mUseBubble) -// { -// screen_offset = mPositionOffset; -// } -// else -// { - screen_offset = updateScreenPos(mPositionOffset); -// } + LLVector2 screen_offset = updateScreenPos(mPositionOffset); LLVector3 render_position = mPositionAgent + (x_pixel_vec * screen_offset.mV[VX]) + (y_pixel_vec * screen_offset.mV[VY]); -// if (mUseBubble) + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); + LLRect screen_rect; + screen_rect.setCenterAndSize(0, static_cast<S32>(lltrunc(-mHeight / 2 + mOffsetY)), static_cast<S32>(lltrunc(mWidth)), static_cast<S32>(lltrunc(mHeight))); + imagep->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color); + if (mLabelSegments.size()) { - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - LLUI::pushMatrix(); - { - LLVector3 bg_pos = render_position - + (F32)mOffsetY * y_pixel_vec - - (width_vec / 2.f) - - (height_vec); - LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]); - - if (for_select) - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - S32 name = mSourceObject->mGLName; - LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name); - gGL.color4ubv(coloru.mV); - gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec); - LLUI::popMatrix(); - return; - } - else - { - gGL.getTexUnit(0)->bind(imagep->getImage()); - - gGL.color4fv(bg_color.mV); - gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec); - - if ( mLabelSegments.size()) - { - LLUI::pushMatrix(); - { - gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor); - LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec; - LLVector3 label_offset = height_vec - label_height; - LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]); - gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height); - } - LLUI::popMatrix(); - } - } - - BOOL outside_width = llabs(mPositionOffset.mV[VX]) > mWidth * 0.5f; - BOOL outside_height = llabs(mPositionOffset.mV[VY] + (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.5f : 0.f)) > mHeight * (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.75f : 0.5f); + LLUIImagePtr rect_top_image = LLUI::getUIImage("Rounded_Rect_Top"); + LLRect label_top_rect = screen_rect; + const S32 label_height = llround((mFontp->getLineHeight() * (F32)mLabelSegments.size() + (VERTICAL_PADDING / 3.f))); + label_top_rect.mBottom = label_top_rect.mTop - label_height; + LLColor4 label_top_color = text_color; + label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor; - // draw line segments pointing to parent object - if (!mOffscreen && (outside_width || outside_height)) - { - LLUI::pushMatrix(); - { - gGL.color4fv(bg_color.mV); - LLVector3 target_pos = -1.f * (mPositionOffset.mV[VX] * x_pixel_vec + mPositionOffset.mV[VY] * y_pixel_vec); - target_pos += (width_vec / 2.f); - target_pos += mVertAlignment == ALIGN_VERT_CENTER ? (height_vec * 0.5f) : LLVector3::zero; - target_pos -= 3.f * x_pixel_vec; - target_pos -= 6.f * y_pixel_vec; - LLUI::translate(target_pos.mV[VX], target_pos.mV[VY], target_pos.mV[VZ]); - gl_segmented_rect_3d_tex(border_scale_vec, 3.f * x_pixel_vec, 3.f * y_pixel_vec, 6.f * x_pixel_vec, 6.f * y_pixel_vec); - } - LLUI::popMatrix(); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE); - - LLVector3 box_center_offset; - box_center_offset = (width_vec * 0.5f) + (height_vec * 0.5f); - LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]); - gGL.color4fv(bg_color.mV); - LLUI::setLineWidth(2.0); - gGL.begin(LLRender::LINES); - { - if (outside_width) - { - LLVector3 vert; - // draw line in x then y - if (mPositionOffset.mV[VX] < 0.f) - { - // start at right edge - vert = width_vec * 0.5f; - gGL.vertex3fv(vert.mV); - } - else - { - // start at left edge - vert = width_vec * -0.5f; - gGL.vertex3fv(vert.mV); - } - vert = -mPositionOffset.mV[VX] * x_pixel_vec; - gGL.vertex3fv(vert.mV); - gGL.vertex3fv(vert.mV); - vert -= mPositionOffset.mV[VY] * y_pixel_vec; - vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero); - gGL.vertex3fv(vert.mV); - } - else - { - LLVector3 vert; - // draw line in y then x - if (mPositionOffset.mV[VY] < 0.f) - { - // start at top edge - vert = (height_vec * 0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec); - gGL.vertex3fv(vert.mV); - } - else - { - // start at bottom edge - vert = (height_vec * -0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec); - gGL.vertex3fv(vert.mV); - } - vert = -mPositionOffset.mV[VY] * y_pixel_vec - mPositionOffset.mV[VX] * x_pixel_vec; - vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero); - gGL.vertex3fv(vert.mV); - } - } - gGL.end(); - LLUI::setLineWidth(1.0); - - } - } - LLUI::popMatrix(); + rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color); } F32 y_offset = (F32)mOffsetY; @@ -874,29 +715,26 @@ void LLHUDNameTag::updateAll() for (r_it = sVisibleTextObjects.rbegin(); r_it != sVisibleTextObjects.rend(); ++r_it) { LLHUDNameTag* textp = (*r_it); -// if (textp->mUseBubble) -// { - if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE) - { - textp->setLOD(3); - } - else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE) - { - textp->setLOD(2); - } - else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE) - { - textp->setLOD(1); - } - else - { - textp->setLOD(0); - } - textp->updateSize(); - // find on-screen position and initialize collision rectangle - textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero); - current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight()); -// } + if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE) + { + textp->setLOD(3); + } + else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE) + { + textp->setLOD(2); + } + else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE) + { + textp->setLOD(1); + } + else + { + textp->setLOD(0); + } + textp->updateSize(); + // find on-screen position and initialize collision rectangle + textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero); + current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight()); } LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat(); @@ -914,20 +752,12 @@ void LLHUDNameTag::updateAll() { LLHUDNameTag* src_textp = (*src_it); -// if (!src_textp->mUseBubble) -// { -// continue; -// } VisibleTextObjectIterator dst_it = src_it; ++dst_it; for (; dst_it != sVisibleTextObjects.end(); ++dst_it) { LLHUDNameTag* dst_textp = (*dst_it); -// if (!dst_textp->mUseBubble) -// { -// continue; -// } if (src_textp->mSoftScreenRect.overlaps(dst_textp->mSoftScreenRect)) { LLRectf intersect_rect = src_textp->mSoftScreenRect; @@ -976,10 +806,6 @@ void LLHUDNameTag::updateAll() VisibleTextObjectIterator this_object_it; for (this_object_it = sVisibleTextObjects.begin(); this_object_it != sVisibleTextObjects.end(); ++this_object_it) { -// if (!(*this_object_it)->mUseBubble) -// { -// continue; -// } (*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC)); } } @@ -1037,10 +863,6 @@ void LLHUDNameTag::addPickable(std::set<LLViewerObject*> &pick_list) VisibleTextObjectIterator text_it; for (text_it = sVisibleTextObjects.begin(); text_it != sVisibleTextObjects.end(); ++text_it) { -// if (!(*text_it)->mUseBubble) -// { -// continue; -// } pick_list.insert((*text_it)->mSourceObject); } } diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h index 3325c22def..72647d5b26 100644 --- a/indra/newview/llhudnametag.h +++ b/indra/newview/llhudnametag.h @@ -118,7 +118,6 @@ public: /*virtual*/ void markDead(); friend class LLHUDObject; /*virtual*/ F32 getDistance() const { return mLastDistance; } - //void setUseBubble(BOOL use_bubble) { mUseBubble = use_bubble; } S32 getLOD() { return mLOD; } BOOL getVisible() { return mVisible; } BOOL getHidden() const { return mHidden; } @@ -136,7 +135,6 @@ protected: LLHUDNameTag(const U8 type); /*virtual*/ void render(); - /*virtual*/ void renderForSelect(); void renderText(BOOL for_select); static void updateAll(); void setLOD(S32 lod); diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp index 122711a86d..dff310ecf9 100644 --- a/indra/newview/llhudrender.cpp +++ b/indra/newview/llhudrender.cpp @@ -138,7 +138,7 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent, LLUI::translate((F32) winX*1.0f/LLFontGL::sScaleX, (F32) winY*1.0f/(LLFontGL::sScaleY), -(((F32) winZ*2.f)-1.f)); F32 right_x; - font.render(wstr, 0, 0, 0, color, LLFontGL::LEFT, LLFontGL::BASELINE, style, shadow, wstr.length(), 1000, &right_x); + font.render(wstr, 0, 0, 1, color, LLFontGL::LEFT, LLFontGL::BASELINE, style, shadow, wstr.length(), 1000, &right_x); LLUI::popMatrix(); gGL.popMatrix(); diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 24a876c59a..579b6008ae 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -227,7 +227,7 @@ void LLHUDText::renderText() segment_iter != mTextSegments.end(); ++segment_iter ) { const LLFontGL* fontp = segment_iter->mFont; - y_offset -= fontp->getLineHeight(); + y_offset -= fontp->getLineHeight() - 1; // correction factor to match legacy font metrics U8 style = segment_iter->mStyle; LLFontGL::ShadowType shadow = LLFontGL::DROP_SHADOW; @@ -480,8 +480,6 @@ void LLHUDText::updateSize() F32 width = 0.f; S32 max_lines = getMaxLines(); - //S32 lines = (max_lines < 0) ? (S32)mTextSegments.size() : llmin((S32)mTextSegments.size(), max_lines); - //F32 height = (F32)mFontp->getLineHeight() * (lines + mLabelSegments.size()); S32 start_segment; if (max_lines < 0) start_segment = 0; @@ -491,7 +489,7 @@ void LLHUDText::updateSize() while (iter != mTextSegments.end()) { const LLFontGL* fontp = iter->mFont; - height += fontp->getLineHeight(); + height += fontp->getLineHeight() - 1; // correction factor to match legacy font metrics width = llmax(width, llmin(iter->getWidth(fontp), HUD_TEXT_MAX_WIDTH)); ++iter; } diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp deleted file mode 100644 index f5cda52d44..0000000000 --- a/indra/newview/llimfloater.cpp +++ /dev/null @@ -1,1202 +0,0 @@ -/** - * @file llimfloater.cpp - * @brief LLIMFloater class definition - * - * $LicenseInfo:firstyear=2009&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 "llimfloater.h" - -#include "llnotificationsutil.h" - -#include "llagent.h" -#include "llappviewer.h" -#include "llavatarnamecache.h" -#include "llbutton.h" -#include "llchannelmanager.h" -#include "llchiclet.h" -#include "llchicletbar.h" -#include "llfloaterreg.h" -#include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container -#include "llinventoryfunctions.h" -#include "lllayoutstack.h" -#include "lllineeditor.h" -#include "lllogchat.h" -#include "llpanelimcontrolpanel.h" -#include "llscreenchannel.h" -#include "llsyswellwindow.h" -#include "lltrans.h" -#include "llchathistory.h" -#include "llnotifications.h" -#include "llviewerwindow.h" -#include "llvoicechannel.h" -#include "lltransientfloatermgr.h" -#include "llinventorymodel.h" -#include "llrootview.h" -#include "llspeakers.h" -#include "llviewerchat.h" - - -LLIMFloater::LLIMFloater(const LLUUID& session_id) - : LLTransientDockableFloater(NULL, true, session_id), - mControlPanel(NULL), - mSessionID(session_id), - mLastMessageIndex(-1), - mDialog(IM_NOTHING_SPECIAL), - mChatHistory(NULL), - mInputEditor(NULL), - mSavedTitle(), - mTypingStart(), - mShouldSendTypingState(false), - mMeTyping(false), - mOtherTyping(false), - mTypingTimer(), - mTypingTimeoutTimer(), - mPositioned(false), - mSessionInitialized(false) -{ - LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mSessionID); - if (im_session) - { - mSessionInitialized = im_session->mSessionInitialized; - - mDialog = im_session->mType; - switch(mDialog){ - case IM_NOTHING_SPECIAL: - case IM_SESSION_P2P_INVITE: - mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this); - break; - case IM_SESSION_CONFERENCE_START: - mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this); - break; - case IM_SESSION_GROUP_START: - mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this); - break; - case IM_SESSION_INVITE: - if (gAgent.isInGroup(mSessionID)) - { - mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this); - } - else - { - mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this); - } - break; - default: break; - } - } - setOverlapsScreenChannel(true); - - LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this); - - setDocked(true); -} - -void LLIMFloater::onFocusLost() -{ - LLIMModel::getInstance()->resetActiveSessionID(); - - LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, false); -} - -void LLIMFloater::onFocusReceived() -{ - LLIMModel::getInstance()->setActiveSessionID(mSessionID); - - LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, true); - - if (getVisible()) - { - LLIMModel::instance().sendNoUnreadMessages(mSessionID); - } -} - -// virtual -void LLIMFloater::onClose(bool app_quitting) -{ - setTyping(false); - - // The source of much argument and design thrashing - // Should the window hide or the session close when the X is clicked? - // - // Last change: - // EXT-3516 X Button should end IM session, _ button should hide - gIMMgr->leaveSession(mSessionID); -} - -/* static */ -void LLIMFloater::newIMCallback(const LLSD& data){ - - if (data["num_unread"].asInteger() > 0 || data["from_id"].asUUID().isNull()) - { - LLUUID session_id = data["session_id"].asUUID(); - - LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); - if (floater == NULL) return; - - // update if visible, otherwise will be updated when opened - if (floater->getVisible()) - { - floater->updateMessages(); - } - } -} - -void LLIMFloater::onVisibilityChange(const LLSD& new_visibility) -{ - bool visible = new_visibility.asBoolean(); - - LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); - - if (visible && voice_channel && - voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED) - { - LLFloaterReg::showInstance("voice_call", mSessionID); - } - else - { - LLFloaterReg::hideInstance("voice_call", mSessionID); - } -} - -void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata ) -{ - LLIMFloater* self = (LLIMFloater*) userdata; - self->sendMsg(); - self->setTyping(false); -} - -void LLIMFloater::sendMsg() -{ - if (!gAgent.isGodlike() - && (mDialog == IM_NOTHING_SPECIAL) - && mOtherParticipantUUID.isNull()) - { - llinfos << "Cannot send IM to everyone unless you're a god." << llendl; - return; - } - - if (mInputEditor) - { - LLWString text = mInputEditor->getConvertedText(); - if(!text.empty()) - { - // Truncate and convert to UTF8 for transport - std::string utf8_text = wstring_to_utf8str(text); - utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); - - if (mSessionInitialized) - { - LLIMModel::sendMessage(utf8_text, mSessionID, - mOtherParticipantUUID,mDialog); - } - else - { - //queue up the message to send once the session is initialized - mQueuedMsgsForInit.append(utf8_text); - } - - mInputEditor->setText(LLStringUtil::null); - - updateMessages(); - } - } -} - - - -LLIMFloater::~LLIMFloater() -{ - LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this); -} - -//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()) - { - mOtherParticipantUUID = other_party_id; - } - - mControlPanel->setSessionId(mSessionID); - mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel")); - - LLButton* slide_left = getChild<LLButton>("slide_left_btn"); - slide_left->setVisible(mControlPanel->getParent()->getVisible()); - slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); - - LLButton* slide_right = getChild<LLButton>("slide_right_btn"); - slide_right->setVisible(!mControlPanel->getParent()->getVisible()); - slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); - - mInputEditor = getChild<LLLineEditor>("chat_editor"); - mInputEditor->setMaxTextLength(1023); - // enable line history support for instant message bar - mInputEditor->setEnableLineHistory(TRUE); - - LLFontGL* font = LLViewerChat::getChatFont(); - mInputEditor->setFont(font); - - mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) ); - mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) ); - mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this ); - mInputEditor->setCommitOnFocusLost( FALSE ); - mInputEditor->setRevertOnEsc( FALSE ); - mInputEditor->setReplaceNewlinesWithSpaces( FALSE ); - mInputEditor->setPassDelete( TRUE ); - - childSetCommitCallback("chat_editor", onSendMsg, this); - - mChatHistory = getChild<LLChatHistory>("chat_history"); - - setDocked(true); - - mTypingStart = LLTrans::getString("IM_typing_start_string"); - - // Disable input editor if session cannot accept text - LLIMModel::LLIMSession* im_session = - LLIMModel::instance().findIMSession(mSessionID); - if( im_session && !im_session->mTextIMPossible ) - { - mInputEditor->setEnabled(FALSE); - mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label")); - } - - if ( im_session && im_session->isP2PSessionType()) - { - // look up display name for window title - LLAvatarNameCache::get(im_session->mOtherParticipantID, - boost::bind(&LLIMFloater::onAvatarNameCache, - this, _1, _2)); - } - else - { - std::string session_name(LLIMModel::instance().getName(mSessionID)); - updateSessionName(session_name, session_name); - } - - //*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla" - //see LLFloaterIMPanel for how it is done (IB) - - if(isChatMultiTab()) - { - return LLFloater::postBuild(); - } - else - { - return LLDockableFloater::postBuild(); - } -} - -void LLIMFloater::updateSessionName(const std::string& ui_title, - const std::string& ui_label) -{ - mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + ui_label); - setTitle(ui_title); -} - -void LLIMFloater::onAvatarNameCache(const LLUUID& agent_id, - const LLAvatarName& av_name) -{ - // Use display name only for labels, as the extended name will be in the - // floater title - std::string ui_title = av_name.getCompleteName(); - updateSessionName(ui_title, av_name.mDisplayName); - mTypingStart.setArg("[NAME]", ui_title); -} - -// virtual -void LLIMFloater::draw() -{ - if ( mMeTyping ) - { - // Time out if user hasn't typed for a while. - if ( mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS ) - { - setTyping(false); - } - } - - LLTransientDockableFloater::draw(); -} - - -// static -void* LLIMFloater::createPanelIMControl(void* userdata) -{ - LLIMFloater *self = (LLIMFloater*)userdata; - self->mControlPanel = new LLPanelIMControlPanel(); - self->mControlPanel->setXMLFilename("panel_im_control_panel.xml"); - return self->mControlPanel; -} - - -// static -void* LLIMFloater::createPanelGroupControl(void* userdata) -{ - LLIMFloater *self = (LLIMFloater*)userdata; - self->mControlPanel = new LLPanelGroupControlPanel(self->mSessionID); - self->mControlPanel->setXMLFilename("panel_group_control_panel.xml"); - return self->mControlPanel; -} - -// static -void* LLIMFloater::createPanelAdHocControl(void* userdata) -{ - LLIMFloater *self = (LLIMFloater*)userdata; - self->mControlPanel = new LLPanelAdHocControlPanel(self->mSessionID); - self->mControlPanel->setXMLFilename("panel_adhoc_control_panel.xml"); - return self->mControlPanel; -} - -void LLIMFloater::onSlide() -{ - mControlPanel->getParent()->setVisible(!mControlPanel->getParent()->getVisible()); - - gSavedSettings.setBOOL("IMShowControlPanel", mControlPanel->getParent()->getVisible()); - - 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 -LLIMFloater* LLIMFloater::show(const LLUUID& session_id) -{ - closeHiddenIMToasts(); - - if (!gIMMgr->hasSession(session_id)) return NULL; - - if(!isChatMultiTab()) - { - //hide all - LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel"); - for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); - iter != inst_list.end(); ++iter) - { - LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter); - if (floater && floater->isDocked()) - { - floater->setVisible(false); - } - } - } - - bool exist = findInstance(session_id); - - LLIMFloater* floater = getInstance(session_id); - if (!floater) return NULL; - - if(isChatMultiTab()) - { - LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance(); - - // do not add existed floaters to avoid adding torn off instances - if (!exist) - { - // LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END; - // TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists - LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END; - - if (floater_container) - { - floater_container->addFloater(floater, TRUE, i_pt); - } - } - - floater->openFloater(floater->getKey()); - } - else - { - // Docking may move chat window, hide it before moving, or user will see how window "jumps" - floater->setVisible(false); - - if (floater->getDockControl() == NULL) - { - LLChiclet* chiclet = - LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLChiclet>( - session_id); - if (chiclet == NULL) - { - llerror("Dock chiclet for LLIMFloater doesn't exists", 0); - } - else - { - LLChicletBar::getInstance()->getChicletPanel()->scrollToChiclet(chiclet); - } - - floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(), - LLDockControl::BOTTOM)); - } - - // window is positioned, now we can show it. - } - floater->setVisible(TRUE); - - return floater; -} - -void LLIMFloater::setDocked(bool docked, bool pop_on_undock) -{ - // update notification channel state - LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*> - (LLNotificationsUI::LLChannelManager::getInstance()-> - findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); - - if(!isChatMultiTab()) - { - LLTransientDockableFloater::setDocked(docked, pop_on_undock); - } - - // update notification channel state - if(channel) - { - channel->updateShowToastsState(); - channel->redrawToasts(); - } -} - -void LLIMFloater::setVisible(BOOL visible) -{ - LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*> - (LLNotificationsUI::LLChannelManager::getInstance()-> - findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); - LLTransientDockableFloater::setVisible(visible); - - // update notification channel state - if(channel) - { - channel->updateShowToastsState(); - channel->redrawToasts(); - } - - BOOL is_minimized = visible && isChatMultiTab() - ? LLIMFloaterContainer::getInstance()->isMinimized() - : !visible; - - if (!is_minimized && mChatHistory && mInputEditor) - { - //only if floater was construced and initialized from xml - updateMessages(); - //prevent stealing focus when opening a background IM tab (EXT-5387, checking focus for EXT-6781) - if (!isChatMultiTab() || hasFocus()) - { - mInputEditor->setFocus(TRUE); - } - } - - if(!visible) - { - LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(mSessionID); - if(chiclet) - { - chiclet->setToggleState(false); - } - } -} - -BOOL LLIMFloater::getVisible() -{ - if(isChatMultiTab()) - { - LLIMFloaterContainer* im_container = LLIMFloaterContainer::getInstance(); - - // Treat inactive floater as invisible. - bool is_active = im_container->getActiveFloater() == this; - - //torn off floater is always inactive - if (!is_active && getHost() != im_container) - { - return LLTransientDockableFloater::getVisible(); - } - - // getVisible() returns TRUE when Tabbed IM window is minimized. - return is_active && !im_container->isMinimized() && im_container->getVisible(); - } - else - { - return LLTransientDockableFloater::getVisible(); - } -} - -//static -bool LLIMFloater::toggle(const LLUUID& session_id) -{ - if(!isChatMultiTab()) - { - LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); - if (floater && floater->getVisible() && floater->hasFocus()) - { - // clicking on chiclet to close floater just hides it to maintain existing - // scroll/text entry state - floater->setVisible(false); - return false; - } - else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus())) - { - floater->setVisible(TRUE); - floater->setFocus(TRUE); - return true; - } - } - - // ensure the list of messages is updated when floater is made visible - show(session_id); - return true; -} - -//static -LLIMFloater* LLIMFloater::findInstance(const LLUUID& session_id) -{ - return LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); -} - -LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id) -{ - return LLFloaterReg::getTypedInstance<LLIMFloater>("impanel", session_id); -} - -void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id) -{ - mSessionInitialized = true; - - //will be different only for an ad-hoc im session - if (mSessionID != im_session_id) - { - mSessionID = im_session_id; - setKey(im_session_id); - mControlPanel->setSessionId(im_session_id); - } - - // updating "Call" button from group control panel here to enable it without placing into draw() (EXT-4796) - if(gAgent.isInGroup(im_session_id)) - { - mControlPanel->updateCallButton(); - } - - //*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB) - - - //need to send delayed messaged collected while waiting for session initialization - if (!mQueuedMsgsForInit.size()) return; - LLSD::array_iterator iter; - for ( iter = mQueuedMsgsForInit.beginArray(); - iter != mQueuedMsgsForInit.endArray(); - ++iter) - { - LLIMModel::sendMessage(iter->asString(), mSessionID, - mOtherParticipantUUID, mDialog); - } -} - -void LLIMFloater::updateMessages() -{ - bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory"); - - std::list<LLSD> messages; - - // we shouldn't reset unread message counters if IM floater doesn't have focus - if (hasFocus()) - { - LLIMModel::instance().getMessages(mSessionID, messages, mLastMessageIndex+1); - } - else - { - LLIMModel::instance().getMessagesSilently(mSessionID, messages, mLastMessageIndex+1); - } - - if (messages.size()) - { - LLSD chat_args; - chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history; - - std::ostringstream message; - std::list<LLSD>::const_reverse_iterator iter = messages.rbegin(); - std::list<LLSD>::const_reverse_iterator iter_end = messages.rend(); - for (; iter != iter_end; ++iter) - { - LLSD msg = *iter; - - std::string time = msg["time"].asString(); - LLUUID from_id = msg["from_id"].asUUID(); - std::string from = msg["from"].asString(); - std::string message = msg["message"].asString(); - bool is_history = msg["is_history"].asBoolean(); - - LLChat chat; - chat.mFromID = from_id; - chat.mSessionID = mSessionID; - chat.mFromName = from; - chat.mTimeStr = time; - chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle; - - // process offer notification - if (msg.has("notification_id")) - { - chat.mNotifId = msg["notification_id"].asUUID(); - // if notification exists - embed it - if (LLNotificationsUtil::find(chat.mNotifId) != NULL) - { - // remove embedded notification from channel - LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*> - (LLNotificationsUI::LLChannelManager::getInstance()-> - findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); - if (getVisible()) - { - // toast will be automatically closed since it is not storable toast - channel->hideToast(chat.mNotifId); - } - } - // if notification doesn't exist - try to use next message which should be log entry - else - { - continue; - } - } - //process text message - else - { - chat.mText = message; - } - - mChatHistory->appendMessage(chat, chat_args); - mLastMessageIndex = msg["index"].asInteger(); - - // if it is a notification - next message is a notification history log, so skip it - if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL) - { - if (++iter == iter_end) - { - break; - } - else - { - mLastMessageIndex++; - } - } - } - } -} - -void LLIMFloater::reloadMessages() -{ - mChatHistory->clear(); - mLastMessageIndex = -1; - updateMessages(); -} - -// static -void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ) -{ - LLIMFloater* self= (LLIMFloater*) userdata; - - // Allow enabling the LLIMFloater input editor only if session can accept text - LLIMModel::LLIMSession* im_session = - LLIMModel::instance().findIMSession(self->mSessionID); - //TODO: While disabled lllineeditor can receive focus we need to check if it is enabled (EK) - if( im_session && im_session->mTextIMPossible && self->mInputEditor->getEnabled()) - { - //in disconnected state IM input editor should be disabled - self->mInputEditor->setEnabled(!gDisconnected); - } -} - -// static -void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata) -{ - LLIMFloater* self = (LLIMFloater*) userdata; - self->setTyping(false); -} - -// static -void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata) -{ - LLIMFloater* self = (LLIMFloater*)userdata; - std::string text = self->mInputEditor->getText(); - if (!text.empty()) - { - self->setTyping(true); - } - else - { - // Deleting all text counts as stopping typing. - self->setTyping(false); - } -} - -void LLIMFloater::setTyping(bool typing) -{ - if ( typing ) - { - // Started or proceeded typing, reset the typing timeout timer - mTypingTimeoutTimer.reset(); - } - - if ( mMeTyping != typing ) - { - // Typing state is changed - mMeTyping = typing; - // So, should send current state - mShouldSendTypingState = true; - // In case typing is started, send state after some delay - mTypingTimer.reset(); - } - - // Don't want to send typing indicators to multiple people, potentially too - // much network traffic. Only send in person-to-person IMs. - if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL ) - { - if ( mMeTyping ) - { - if ( mTypingTimer.getElapsedTimeF32() > 1.f ) - { - // Still typing, send 'start typing' notification - LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, TRUE); - mShouldSendTypingState = false; - } - } - else - { - // Send 'stop typing' notification immediately - LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, FALSE); - mShouldSendTypingState = false; - } - } - - LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); - if (speaker_mgr) - speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE); - -} - -void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing) -{ - if ( typing ) - { - // other user started typing - addTypingIndicator(im_info); - } - else - { - // other user stopped typing - removeTypingIndicator(im_info); - } -} - -void LLIMFloater::processAgentListUpdates(const LLSD& body) -{ - if ( !body.isMap() ) return; - - if ( body.has("agent_updates") && body["agent_updates"].isMap() ) - { - LLSD agent_data = body["agent_updates"].get(gAgentID.asString()); - if (agent_data.isMap() && agent_data.has("info")) - { - LLSD agent_info = agent_data["info"]; - - if (agent_info.has("mutes")) - { - BOOL moderator_muted_text = agent_info["mutes"]["text"].asBoolean(); - mInputEditor->setEnabled(!moderator_muted_text); - std::string label; - if (moderator_muted_text) - label = LLTrans::getString("IM_muted_text_label"); - else - label = LLTrans::getString("IM_to_label") + " " + LLIMModel::instance().getName(mSessionID); - mInputEditor->setLabel(label); - - if (moderator_muted_text) - LLNotificationsUtil::add("TextChatIsMutedByModerator"); - } - } - } -} - -void LLIMFloater::updateChatHistoryStyle() -{ - mChatHistory->clear(); - mLastMessageIndex = -1; - updateMessages(); -} - -void LLIMFloater::processChatHistoryStyleUpdate(const LLSD& newvalue) -{ - LLFontGL* font = LLViewerChat::getChatFont(); - LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel"); - for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); - iter != inst_list.end(); ++iter) - { - LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter); - if (floater) - { - floater->updateChatHistoryStyle(); - floater->mInputEditor->setFont(font); - } - } - -} - -void LLIMFloater::processSessionUpdate(const LLSD& session_update) -{ - // *TODO : verify following code when moderated mode will be implemented - if ( false && session_update.has("moderated_mode") && - session_update["moderated_mode"].has("voice") ) - { - BOOL voice_moderated = session_update["moderated_mode"]["voice"]; - const std::string session_label = LLIMModel::instance().getName(mSessionID); - - if (voice_moderated) - { - setTitle(session_label + std::string(" ") + LLTrans::getString("IM_moderated_chat_label")); - } - else - { - setTitle(session_label); - } - - // *TODO : uncomment this when/if LLPanelActiveSpeakers panel will be added - //update the speakers dropdown too - //mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated); - } -} - -BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask, - BOOL drop, EDragAndDropType cargo_type, - void *cargo_data, EAcceptance *accept, - std::string& tooltip_msg) -{ - - if (mDialog == IM_NOTHING_SPECIAL) - { - LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop, - cargo_type, cargo_data, accept); - } - - // handle case for dropping calling cards (and folders of calling cards) onto invitation panel for invites - else if (isInviteAllowed()) - { - *accept = ACCEPT_NO; - - if (cargo_type == DAD_CALLINGCARD) - { - if (dropCallingCard((LLInventoryItem*)cargo_data, drop)) - { - *accept = ACCEPT_YES_MULTI; - } - } - else if (cargo_type == DAD_CATEGORY) - { - if (dropCategory((LLInventoryCategory*)cargo_data, drop)) - { - *accept = ACCEPT_YES_MULTI; - } - } - } - return TRUE; -} - -BOOL LLIMFloater::dropCallingCard(LLInventoryItem* item, BOOL drop) -{ - BOOL rv = isInviteAllowed(); - if(rv && item && item->getCreatorUUID().notNull()) - { - if(drop) - { - uuid_vec_t ids; - ids.push_back(item->getCreatorUUID()); - inviteToSession(ids); - } - } - else - { - // set to false if creator uuid is null. - rv = FALSE; - } - return rv; -} - -BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop) -{ - BOOL rv = isInviteAllowed(); - if(rv && category) - { - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - LLUniqueBuddyCollector buddies; - gInventory.collectDescendentsIf(category->getUUID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - buddies); - S32 count = items.count(); - if(count == 0) - { - rv = FALSE; - } - else if(drop) - { - uuid_vec_t ids; - ids.reserve(count); - for(S32 i = 0; i < count; ++i) - { - ids.push_back(items.get(i)->getCreatorUUID()); - } - inviteToSession(ids); - } - } - return rv; -} - -BOOL LLIMFloater::isInviteAllowed() const -{ - - return ( (IM_SESSION_CONFERENCE_START == mDialog) - || (IM_SESSION_INVITE == mDialog) ); -} - -class LLSessionInviteResponder : public LLHTTPClient::Responder -{ -public: - LLSessionInviteResponder(const LLUUID& session_id) - { - mSessionID = session_id; - } - - void error(U32 statusNum, const std::string& reason) - { - llinfos << "Error inviting all agents to session" << llendl; - //throw something back to the viewer here? - } - -private: - LLUUID mSessionID; -}; - -BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids) -{ - LLViewerRegion* region = gAgent.getRegion(); - if (!region) - { - return FALSE; - } - - S32 count = ids.size(); - - if( isInviteAllowed() && (count > 0) ) - { - llinfos << "LLIMFloater::inviteToSession() - inviting participants" << llendl; - - std::string url = region->getCapability("ChatSessionRequest"); - - LLSD data; - - data["params"] = LLSD::emptyArray(); - for (int i = 0; i < count; i++) - { - data["params"].append(ids[i]); - } - - data["method"] = "invite"; - data["session-id"] = mSessionID; - LLHTTPClient::post( - url, - data, - new LLSessionInviteResponder( - mSessionID)); - } - else - { - llinfos << "LLIMFloater::inviteToSession -" - << " no need to invite agents for " - << mDialog << llendl; - // successful add, because everyone that needed to get added - // was added. - } - - return TRUE; -} - -void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info) -{ - // We may have lost a "stop-typing" packet, don't add it twice - if ( im_info && !mOtherTyping ) - { - mOtherTyping = true; - - // Save and set new title - mSavedTitle = getTitle(); - setTitle (mTypingStart); - - // Update speaker - LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); - if ( speaker_mgr ) - { - speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE); - } - } -} - -void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info) -{ - if ( mOtherTyping ) - { - mOtherTyping = false; - - // Revert the title to saved one - setTitle(mSavedTitle); - - if ( im_info ) - { - // Update speaker - LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); - if ( speaker_mgr ) - { - speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE); - } - } - - } -} - -// static -void LLIMFloater::closeHiddenIMToasts() -{ - class IMToastMatcher: public LLNotificationsUI::LLScreenChannel::Matcher - { - public: - bool matches(const LLNotificationPtr notification) const - { - // "notifytoast" type of notifications is reserved for IM notifications - return "notifytoast" == notification->getType(); - } - }; - - LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getNotificationScreenChannel(); - if (channel != NULL) - { - channel->closeHiddenToasts(IMToastMatcher()); - } -} -// static -void LLIMFloater::confirmLeaveCallCallback(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - const LLSD& payload = notification["payload"]; - LLUUID session_id = payload["session_id"]; - - LLFloater* im_floater = LLFloaterReg::findInstance("impanel", session_id); - if (option == 0 && im_floater != NULL) - { - im_floater->closeFloater(); - } - - return; -} - -// static -bool LLIMFloater::isChatMultiTab() -{ - // Restart is required in order to change chat window type. - static bool is_single_window = gSavedSettings.getS32("ChatWindow") == 1; - return is_single_window; -} - -// static -void LLIMFloater::initIMFloater() -{ - // This is called on viewer start up - // init chat window type before user changed it in preferences - isChatMultiTab(); -} - -//static -void LLIMFloater::sRemoveTypingIndicator(const LLSD& data) -{ - LLUUID session_id = data["session_id"]; - if (session_id.isNull()) return; - - LLUUID from_id = data["from_id"]; - if (gAgentID == from_id || LLUUID::null == from_id) return; - - LLIMFloater* floater = LLIMFloater::findInstance(session_id); - if (!floater) return; - - if (IM_NOTHING_SPECIAL != floater->mDialog) return; - - floater->removeTypingIndicator(); -} - -void LLIMFloater::onIMChicletCreated( const LLUUID& session_id ) -{ - - if (isChatMultiTab()) - { - LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance(); - if (!im_box) return; - - if (LLIMFloater::findInstance(session_id)) return; - - LLIMFloater* new_tab = LLIMFloater::getInstance(session_id); - - im_box->addFloater(new_tab, FALSE, LLTabContainer::END); - } - -} - -void LLIMFloater::onClickCloseBtn() -{ - - LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession( - mSessionID); - - if (session == NULL) - { - llwarns << "Empty session." << llendl; - return; - } - - bool is_call_with_chat = session->isGroupSessionType() - || session->isAdHocSessionType() || session->isP2PSessionType(); - - LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); - - if (is_call_with_chat && voice_channel != NULL && voice_channel->isActive()) - { - LLSD payload; - payload["session_id"] = mSessionID; - LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback); - return; - } - - LLFloater::onClickCloseBtn(); -} diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp deleted file mode 100644 index c8e48b0d42..0000000000 --- a/indra/newview/llimfloatercontainer.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/** - * @file llimfloatercontainer.cpp - * @brief Multifloater containing active IM sessions in separate tab container tabs - * - * $LicenseInfo:firstyear=2009&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 "llimfloatercontainer.h" -#include "llfloaterreg.h" -#include "llimview.h" -#include "llavatariconctrl.h" -#include "llgroupiconctrl.h" -#include "llagent.h" -#include "lltransientfloatermgr.h" - -// -// LLIMFloaterContainer -// -LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed) -: LLMultiFloater(seed) -{ - mAutoResize = FALSE; - LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this); -} - -LLIMFloaterContainer::~LLIMFloaterContainer() -{ - mNewMessageConnection.disconnect(); - LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this); -} - -BOOL LLIMFloaterContainer::postBuild() -{ - mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLIMFloaterContainer::onNewMessageReceived, this, _1)); - // Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button - // mTabContainer will be initialized in LLMultiFloater::addChild() - return TRUE; -} - -void LLIMFloaterContainer::onOpen(const LLSD& key) -{ - LLMultiFloater::onOpen(key); -/* - if (key.isDefined()) - { - LLIMFloater* im_floater = LLIMFloater::findInstance(key.asUUID()); - if (im_floater) - { - im_floater->openFloater(); - } - } -*/ -} - -void LLIMFloaterContainer::addFloater(LLFloater* floaterp, - BOOL select_added_floater, - LLTabContainer::eInsertionPoint insertion_point) -{ - if(!floaterp) return; - - // already here - if (floaterp->getHost() == this) - { - openFloater(floaterp->getKey()); - return; - } - - LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point); - - LLUUID session_id = floaterp->getKey(); - - LLIconCtrl* icon = 0; - - if(gAgent.isInGroup(session_id, TRUE)) - { - LLGroupIconCtrl::Params icon_params; - icon_params.group_id = session_id; - icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params); - - mSessions[session_id] = floaterp; - floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id)); - } - else - { - LLUUID avatar_id = LLIMModel::getInstance()->getOtherParticipantID(session_id); - - LLAvatarIconCtrl::Params icon_params; - icon_params.avatar_id = avatar_id; - icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params); - - mSessions[session_id] = floaterp; - floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id)); - } - mTabContainer->setTabImage(floaterp, icon); -} - -void LLIMFloaterContainer::onCloseFloater(LLUUID& id) -{ - mSessions.erase(id); -} - -void LLIMFloaterContainer::onNewMessageReceived(const LLSD& data) -{ - LLUUID session_id = data["session_id"].asUUID(); - LLFloater* floaterp = get_ptr_in_map(mSessions, session_id); - LLFloater* current_floater = LLMultiFloater::getActiveFloater(); - - if(floaterp && current_floater && floaterp != current_floater) - { - if(LLMultiFloater::isFloaterFlashing(floaterp)) - LLMultiFloater::setFloaterFlashing(floaterp, FALSE); - LLMultiFloater::setFloaterFlashing(floaterp, TRUE); - } -} - -LLIMFloaterContainer* LLIMFloaterContainer::findInstance() -{ - return LLFloaterReg::findTypedInstance<LLIMFloaterContainer>("im_container"); -} - -LLIMFloaterContainer* LLIMFloaterContainer::getInstance() -{ - return LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container"); -} - -void LLIMFloaterContainer::setMinimized(BOOL b) -{ - if (isMinimized() == b) return; - - LLMultiFloater::setMinimized(b); - // Hide minimized floater (see EXT-5315) - setVisible(!b); - - if (isMinimized()) return; - - if (getActiveFloater()) - { - getActiveFloater()->setVisible(TRUE); - } -} - -// EOF diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h deleted file mode 100644 index 892ecef48d..0000000000 --- a/indra/newview/llimfloatercontainer.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file llimfloatercontainer.h - * @brief Multifloater containing active IM sessions in separate tab container tabs - * - * $LicenseInfo:firstyear=2009&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_LLIMFLOATERCONTAINER_H -#define LL_LLIMFLOATERCONTAINER_H - -#include <map> -#include <vector> - -#include "llfloater.h" -#include "llmultifloater.h" -#include "llavatarpropertiesprocessor.h" -#include "llgroupmgr.h" - -class LLTabContainer; - -class LLIMFloaterContainer : public LLMultiFloater -{ -public: - LLIMFloaterContainer(const LLSD& seed); - virtual ~LLIMFloaterContainer(); - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); - void onCloseFloater(LLUUID& id); - - /*virtual*/ void addFloater(LLFloater* floaterp, - BOOL select_added_floater, - LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END); - - static LLFloater* getCurrentVoiceFloater(); - - static LLIMFloaterContainer* findInstance(); - - static LLIMFloaterContainer* getInstance(); - - virtual void setMinimized(BOOL b); - -private: - typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t; - avatarID_panel_map_t mSessions; - boost::signals2::connection mNewMessageConnection; - - void onNewMessageReceived(const LLSD& data); -}; - -#endif // LL_LLIMFLOATERCONTAINER_H diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp index cd71da7393..c2b29f36e8 100644 --- a/indra/newview/llimhandler.cpp +++ b/indra/newview/llimhandler.cpp @@ -36,13 +36,14 @@ using namespace LLNotificationsUI; +extern void process_dnd_im(const LLSD& notification); + //-------------------------------------------------------------------------- -LLIMHandler::LLIMHandler(e_notification_type type, const LLSD& id) +LLIMHandler::LLIMHandler() +: LLCommunicationNotificationHandler("IM Notifications", "notifytoast") { - mType = type; - // Getting a Channel for our notifications - mChannel = LLChannelManager::getInstance()->createNotificationChannel(); + mChannel = LLChannelManager::getInstance()->createNotificationChannel()->getHandle(); } //-------------------------------------------------------------------------- @@ -55,76 +56,61 @@ void LLIMHandler::initChannel() { S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); - mChannel->init(channel_right_bound - channel_width, channel_right_bound); + mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound); } //-------------------------------------------------------------------------- -bool LLIMHandler::processNotification(const LLSD& notify) +bool LLIMHandler::processNotification(const LLNotificationPtr& notification) { - if(!mChannel) - { - return false; - } - - LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - - if(!notification) - return false; - - // arrange a channel on a screen - if(!mChannel->getVisible()) - { - initChannel(); - } - - if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") - { - LLSD substitutions = notification->getSubstitutions(); - - // According to comments in LLIMMgr::addMessage(), if we get message - // from ourselves, the sender id is set to null. This fixes EXT-875. - LLUUID avatar_id = substitutions["FROM_ID"].asUUID(); - if (avatar_id.isNull()) - avatar_id = gAgentID; - - LLToastIMPanel::Params im_p; - im_p.notification = notification; - im_p.avatar_id = avatar_id; - im_p.from = substitutions["FROM"].asString(); - im_p.time = substitutions["TIME"].asString(); - im_p.message = substitutions["MESSAGE"].asString(); - im_p.session_id = substitutions["SESSION_ID"].asUUID(); - - LLToastIMPanel* im_box = new LLToastIMPanel(im_p); - - LLToast::Params p; - p.notif_id = notification->getID(); - p.session_id = im_p.session_id; - p.notification = notification; - p.panel = im_box; - p.can_be_stored = false; - p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1); - LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); - if(channel) - channel->addToast(p); - - // send a signal to the counter manager; - mNewNotificationSignal(); - } - else if (notify["sigtype"].asString() == "delete") - { - mChannel->killToastByNotificationID(notification->getID()); - } - return false; -} + if(notification->isDND()) + { + LLSD data = notification->asLLSD(); //don't need this if retrieve needed data from notification getters + process_dnd_im(data); + } + else + { + if(mChannel.isDead()) + { + return false; + } + + // arrange a channel on a screen + if(!mChannel.get()->getVisible()) + { + initChannel(); + } + + LLSD substitutions = notification->getSubstitutions(); + + // According to comments in LLIMMgr::addMessage(), if we get message + // from ourselves, the sender id is set to null. This fixes EXT-875. + LLUUID avatar_id = substitutions["FROM_ID"].asUUID(); + if (avatar_id.isNull()) + avatar_id = gAgentID; + + LLToastIMPanel::Params im_p; + im_p.notification = notification; + im_p.avatar_id = avatar_id; + im_p.from = substitutions["FROM"].asString(); + im_p.time = substitutions["TIME"].asString(); + im_p.message = substitutions["MESSAGE"].asString(); + im_p.session_id = substitutions["SESSION_ID"].asUUID(); + + LLToastIMPanel* im_box = new LLToastIMPanel(im_p); + + LLToast::Params p; + p.notif_id = notification->getID(); + p.session_id = im_p.session_id; + p.notification = notification; + p.panel = im_box; + p.can_be_stored = false; + LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get()); + if(channel) + channel->addToast(p); + } -//-------------------------------------------------------------------------- -void LLIMHandler::onDeleteToast(LLToast* toast) -{ - // send a signal to the counter manager - mDelNotificationSignal(); + return false; } -//-------------------------------------------------------------------------- diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 0250af6a0e..c64ecdc47a 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -171,7 +171,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label, // enable line history support for instant message bar mInputEditor->setEnableLineHistory(TRUE); - //*TODO we probably need the same "awaiting message" thing in LLIMFloater + //*TODO we probably need the same "awaiting message" thing in LLFloaterIMSession LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mSessionUUID); if (!im_session) { diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index ed4bb727cd..37f5888e8c 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -29,6 +29,8 @@ #include "llimview.h" #include "llavatarnamecache.h" // IDEVO +#include "llavataractions.h" +#include "llfloaterconversationlog.h" #include "llfloaterreg.h" #include "llfontgl.h" #include "llgl.h" @@ -41,14 +43,15 @@ #include "lltextutil.h" #include "lltrans.h" #include "lluictrlfactory.h" - +#include "llfloaterimsessiontab.h" #include "llagent.h" #include "llagentui.h" #include "llappviewer.h" #include "llavatariconctrl.h" #include "llcallingcard.h" #include "llchat.h" -#include "llimfloater.h" +#include "llfloaterimsession.h" +#include "llfloaterimcontainer.h" #include "llgroupiconctrl.h" #include "llmd5.h" #include "llmutelist.h" @@ -57,12 +60,14 @@ #include "llviewerwindow.h" #include "llnotifications.h" #include "llnotificationsutil.h" -#include "llnearbychat.h" +#include "llfloaterimnearbychat.h" #include "llspeakers.h" //for LLIMSpeakerMgr #include "lltextbox.h" #include "lltoolbarview.h" #include "llviewercontrol.h" #include "llviewerparcelmgr.h" +#include "llconversationlog.h" +#include "message.h" const static std::string ADHOC_NAME_SUFFIX(" Conference"); @@ -97,6 +102,47 @@ BOOL LLSessionTimeoutTimer::tick() return TRUE; } + + +void process_dnd_im(const LLSD& notification) +{ + LLSD data = notification["substitutions"]; + LLUUID sessionID = data["SESSION_ID"].asUUID(); + LLUUID fromID = data["FROM_ID"].asUUID(); + + //re-create the IM session if needed + //(when coming out of DND mode upon app restart) + if(!gIMMgr->hasSession(sessionID)) + { + //reconstruct session using data from the notification + std::string name = data["FROM"]; + LLAvatarName av_name; + if (LLAvatarNameCache::get(data["FROM_ID"], &av_name)) + { + name = av_name.getDisplayName(); + } + + + LLIMModel::getInstance()->newSession(sessionID, + name, + IM_NOTHING_SPECIAL, + fromID, + false, + false); //will need slight refactor to retrieve whether offline message or not (assume online for now) + + LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); + + if (im_box) + { + im_box->flashConversationItemWidget(sessionID, true); + } + + } +} + + + + static void on_avatar_name_cache_toast(const LLUUID& agent_id, const LLAvatarName& av_name, LLSD msg) @@ -108,77 +154,168 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id, args["FROM"] = av_name.getCompleteName(); args["FROM_ID"] = msg["from_id"]; args["SESSION_ID"] = msg["session_id"]; - LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::show, msg["session_id"].asUUID())); -} - -void toast_callback(const LLSD& msg){ - // do not show toast in busy mode or it goes from agent - if (gAgent.getBusy() || gAgent.getID() == msg["from_id"]) - { - return; - } - - // check whether incoming IM belongs to an active session or not - if (LLIMModel::getInstance()->getActiveSessionID().notNull() - && LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"]) - { - return; - } - - // Skip toasting for system messages - if (msg["from_id"].asUUID() == LLUUID::null) + LLNotificationsUtil::add("IMToast", args, args, boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID())); +} + +void on_new_message(const LLSD& msg) +{ + std::string action; + LLUUID participant_id = msg["from_id"].asUUID(); + LLUUID session_id = msg["session_id"].asUUID(); + LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); + + // determine action for this session + + if (session_id.isNull()) + { + action = gSavedSettings.getString("NotificationNearbyChatOptions"); + } + else if(session->isP2PSessionType()) + { + if (LLAvatarTracker::instance().isBuddy(participant_id)) + { + action = gSavedSettings.getString("NotificationFriendIMOptions"); + } + else + { + action = gSavedSettings.getString("NotificationNonFriendIMOptions"); + } + } + else if(session->isAdHocSessionType()) + { + action = gSavedSettings.getString("NotificationConferenceIMOptions"); + } + else if(session->isGroupSessionType()) + { + action = gSavedSettings.getString("NotificationGroupChatOptions"); + } + + // do not show notification which goes from agent + if (gAgent.getID() == participant_id) + { + return; + } + + // execution of the action + + LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); + + if (im_box->isFrontmost() && im_box->getSelectedSession() == session_id) { return; } - // *NOTE Skip toasting if the user disable it in preferences/debug settings ~Alexandrea - LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession( - msg["session_id"]); - if (!gSavedSettings.getBOOL("EnableGroupChatPopups") - && session->isGroupSessionType()) - { - return; - } - if (!gSavedSettings.getBOOL("EnableIMChatPopups") - && !session->isGroupSessionType()) - { - return; - } + LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id); + + //session floater not focused (visible or not) + bool session_floater_not_focused = session_floater && !session_floater->hasFocus(); + + //conv. floater is closed + bool conversation_floater_is_closed = + !( im_box + && im_box->isInVisibleChain() + && !im_box->isMinimized()); + + //conversation floater not focused (visible or not) + bool conversation_floater_not_focused = + conversation_floater_is_closed || !im_box->hasFocus(); + // sess. floater is open + bool session_floater_is_open = + session_floater + && session_floater->isInVisibleChain() + && !session_floater->isMinimized() + && !(session_floater->getHost() && session_floater->getHost()->isMinimized()); + + if ("toast" == action && !session_floater_is_open) + { + //User is not focused on conversation containing the message + if(session_floater_not_focused) + { + if(!LLMuteList::getInstance()->isMuted(participant_id)) + { + im_box->flashConversationItemWidget(session_id, true); + } + //The conversation floater isn't focused/open + if(conversation_floater_not_focused) + { + if(!LLMuteList::getInstance()->isMuted(participant_id) + && !gAgent.isDoNotDisturb()) + { + gToolBarView->flashCommand(LLCommandId("chat"), true); + } + + //Show IM toasts (upper right toasts) + // Skip toasting for system messages and for nearby chat + if(session_id.notNull() && participant_id.notNull()) + { + LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); + } + } + } + } + + else if ("flash" == action) + { + if (!gAgent.isDoNotDisturb()) + { + im_box->flashConversationItemWidget(session_id, true); + if(conversation_floater_not_focused) + { + //User is not focused on conversation containing the message + gToolBarView->flashCommand(LLCommandId("chat"), true); + } + } + else if(session_id.notNull() && participant_id.notNull()) + { + //If a DND message, allow notification to be stored so upon DND exit + //useMostItrusiveIMNotification will be called to notify user a message exists + LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); + } + } - // Skip toasting if we have open window of IM with this session id - LLIMFloater* open_im_floater = LLIMFloater::findInstance(msg["session_id"]); - if (open_im_floater && open_im_floater->getVisible()) - { - return; - } + else if("openconversations" == action) + { + //User is not focused on conversation containing the message + if(session_floater_not_focused) + { + //Flash line item + im_box->flashConversationItemWidget(session_id, true); - LLAvatarNameCache::get(msg["from_id"].asUUID(), - boost::bind(&on_avatar_name_cache_toast, - _1, _2, msg)); -} + if(!gAgent.isDoNotDisturb()) + { + //Surface conversations floater + LLFloaterReg::showInstance("im_container"); -void LLIMModel::setActiveSessionID(const LLUUID& session_id) -{ - // check if such an ID really exists - if (!findIMSession(session_id)) - { - llwarns << "Trying to set as active a non-existent session!" << llendl; - return; - } + if (session_floater && session_floater->isMinimized()) + { + LLFloater::onClickMinimize(session_floater); + } + } - mActiveSessionID = session_id; + //If in DND mode, allow notification to be stored so upon DND exit + //useMostItrusiveIMNotification will be called to notify user a message exists + if(session_id.notNull() + && participant_id.notNull() + && gAgent.isDoNotDisturb() + && !session_floater_is_open) + { + LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); + } + } + } } LLIMModel::LLIMModel() { - addNewMsgCallback(LLIMFloater::newIMCallback); - addNewMsgCallback(toast_callback); + addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1)); + addNewMsgCallback(boost::bind(&on_new_message, _1)); } -LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice) +LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg) : mSessionID(session_id), mName(name), mType(type), + mHasOfflineMessage(has_offline_msg), mParticipantUnreadMessageCount(0), mNumUnread(0), mOtherParticipantID(other_participant_id), @@ -190,7 +327,8 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& mTextIMPossible(true), mOtherParticipantIsAvatar(true), mStartCallOnInitialize(false), - mStartedAsIMCall(voice) + mStartedAsIMCall(voice), + mAvatarNameCacheConnection() { // set P2P type by default mSessionType = P2P_SESSION; @@ -256,30 +394,22 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& } buildHistoryFileName(); - - if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) - { - std::list<LLSD> chat_history; - - //involves parsing of a chat history - LLLogChat::loadAllHistory(mHistoryFileName, chat_history); - addMessagesFromHistory(chat_history); - } + loadHistory(); // Localizing name of ad-hoc session. STORM-153 // Changing name should happen here- after the history file was created, so that // history files have consistent (English) names in different locales. if (isAdHocSessionType() && IM_SESSION_INVITE == mType) { - LLAvatarNameCache::get(mOtherParticipantID, - boost::bind(&LLIMModel::LLIMSession::onAdHocNameCache, - this, _2)); + mAvatarNameCacheConnection = LLAvatarNameCache::get(mOtherParticipantID,boost::bind(&LLIMModel::LLIMSession::onAdHocNameCache,this, _2)); } } void LLIMModel::LLIMSession::onAdHocNameCache(const LLAvatarName& av_name) { - if (av_name.mIsTemporaryName) + mAvatarNameCacheConnection.disconnect(); + + if (!av_name.isValidName()) { S32 separator_index = mName.rfind(" "); std::string name = mName.substr(0, separator_index); @@ -375,6 +505,8 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES break; } } + default: + break; } // Update speakers list when connected if (LLVoiceChannel::STATE_CONNECTED == new_state) @@ -385,6 +517,11 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES LLIMModel::LLIMSession::~LLIMSession() { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + delete mSpeakers; mSpeakers = NULL; @@ -450,11 +587,11 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo { const LLSD& msg = *it; - std::string from = msg[IM_FROM]; + std::string from = msg[LL_IM_FROM]; LLUUID from_id; - if (msg[IM_FROM_ID].isDefined()) + if (msg[LL_IM_FROM_ID].isDefined()) { - from_id = msg[IM_FROM_ID].asUUID(); + from_id = msg[LL_IM_FROM_ID].asUUID(); } else { @@ -463,8 +600,8 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo gCacheName->getUUID(legacy_name, from_id); } - std::string timestamp = msg[IM_TIME]; - std::string text = msg[IM_TEXT]; + std::string timestamp = msg[LL_IM_TIME]; + std::string text = msg[LL_IM_TEXT]; addMessage(from, from_id, text, timestamp, true); @@ -488,6 +625,20 @@ void LLIMModel::LLIMSession::chatFromLogFile(LLLogChat::ELogLineType type, const } } +void LLIMModel::LLIMSession::loadHistory() +{ + mMsgs.clear(); + + if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) + { + std::list<LLSD> chat_history; + + //involves parsing of a chat history + LLLogChat::loadChatHistory(mHistoryFileName, chat_history); + addMessagesFromHistory(chat_history); + } +} + LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const { return get_if_there(mId2SessionMap, session_id, @@ -533,7 +684,7 @@ LLIMModel::LLIMSession* LLIMModel::findAdHocIMSession(const uuid_vec_t& ids) return NULL; } -bool LLIMModel::LLIMSession::isOutgoingAdHoc() +bool LLIMModel::LLIMSession::isOutgoingAdHoc() const { return IM_SESSION_CONFERENCE_START == mType; } @@ -553,6 +704,19 @@ bool LLIMModel::LLIMSession::isOtherParticipantAvaline() return !mOtherParticipantIsAvatar; } +LLUUID LLIMModel::LLIMSession::generateOutgouigAdHocHash() const +{ + LLUUID hash = LLUUID::null; + + if (mInitialTargetIDs.size()) + { + std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end()); + hash = generateHash(sorted_uuids); + } + + return hash; +} + void LLIMModel::LLIMSession::buildHistoryFileName() { mHistoryFileName = mName; @@ -569,7 +733,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName() if (mInitialTargetIDs.size()) { std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end()); - mHistoryFileName = mName + " hash" + generateHash(sorted_uuids); + mHistoryFileName = mName + " hash" + generateHash(sorted_uuids).asString(); } else { @@ -584,15 +748,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName() // so no need for a callback in LLAvatarNameCache::get() if (LLAvatarNameCache::get(mOtherParticipantID, &av_name)) { - if (av_name.mUsername.empty()) - { - // Display names are off, use mDisplayName which will be the legacy name - mHistoryFileName = LLCacheName::buildUsername(av_name.mDisplayName); - } - else - { - mHistoryFileName = av_name.mUsername; - } + mHistoryFileName = LLCacheName::buildUsername(av_name.getUserName()); } else { @@ -603,7 +759,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName() } //static -std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids) +LLUUID LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids) { LLMD5 md5_uuid; @@ -617,7 +773,7 @@ std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_ LLUUID participants_md5_hash; md5_uuid.raw_digest((unsigned char*) participants_md5_hash.mData); - return participants_md5_hash.asString(); + return participants_md5_hash; } void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id) @@ -631,16 +787,19 @@ void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, con { mId2SessionMap.erase(old_session_id); mId2SessionMap[new_session_id] = session; - - gIMMgr->notifyObserverSessionIDUpdated(old_session_id, new_session_id); } - LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id); + LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(old_session_id); if (im_floater) { im_floater->sessionInitReplyReceived(new_session_id); } + if (old_session_id != new_session_id) + { + gIMMgr->notifyObserverSessionIDUpdated(old_session_id, new_session_id); + } + // auto-start the call on session initialization? if (session->mStartCallOnInitialize) { @@ -676,7 +835,7 @@ void LLIMModel::testMessages() //session name should not be empty bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, - const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice) + const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg) { if (name.empty()) { @@ -690,22 +849,23 @@ bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, co return false; } - LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids, voice); + LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids, voice, has_offline_msg); mId2SessionMap[session_id] = session; // When notifying observer, name of session is used instead of "name", because they may not be the // same if it is an adhoc session (in this case name is localized in LLIMSession constructor). std::string session_name = LLIMModel::getInstance()->getName(session_id); - LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, session_name, other_participant_id); + LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, session_name, other_participant_id,has_offline_msg); return true; } -bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, bool voice) +bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, bool voice, bool has_offline_msg) { - uuid_vec_t no_ids; - return newSession(session_id, name, type, other_participant_id, no_ids, voice); + uuid_vec_t ids; + ids.push_back(other_participant_id); + return newSession(session_id, name, type, other_participant_id, ids, voice, has_offline_msg); } bool LLIMModel::clearSession(const LLUUID& session_id) @@ -716,6 +876,16 @@ bool LLIMModel::clearSession(const LLUUID& session_id) return true; } +void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index, const bool sendNoUnreadMsgs) +{ + getMessagesSilently(session_id, messages, start_index); + + if (sendNoUnreadMsgs) + { + sendNoUnreadMessages(session_id); + } +} + void LLIMModel::getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index) { LLIMSession* session = findIMSession(session_id); @@ -757,13 +927,6 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id) mNoUnreadMsgsSignal(arg); } -void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index) -{ - getMessagesSilently(session_id, messages, start_index); - - sendNoUnreadMessages(session_id); -} - bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) { LLIMSession* session = findIMSession(session_id); @@ -781,19 +944,20 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) { - if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")) + if (gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 1) { std::string from_name = from; LLAvatarName av_name; if (!from_id.isNull() && LLAvatarNameCache::get(from_id, &av_name) && - !av_name.mIsDisplayNameDefault) + !av_name.isDisplayNameDefault()) { from_name = av_name.getCompleteName(); } LLLogChat::saveHistory(file_name, from_name, from_id, utf8_text); + LLConversationLog::instance().cache(); // update the conversation log too return true; } else @@ -878,7 +1042,7 @@ const std::string LLIMModel::getName(const LLUUID& session_id) const { LLIMSession* session = findIMSession(session_id); - if (!session) + if (!session) { llwarns << "session " << session_id << "does not exist " << llendl; return LLTrans::getString("no_session_message"); @@ -904,7 +1068,7 @@ const LLUUID& LLIMModel::getOtherParticipantID(const LLUUID& session_id) const LLIMSession* session = findIMSession(session_id); if (!session) { - llwarns << "session " << session_id << "does not exist " << llendl; + llwarns << "session " << session_id << " does not exist " << llendl; return LLUUID::null; } @@ -1376,7 +1540,7 @@ public: && LLIMModel::getInstance()->findIMSession(mSessionID)) { // TODO remove in 2010, for voice calls we do not open an IM window - //LLIMFloater::show(mSessionID); + //LLFloaterIMSession::show(mSessionID); } gIMMgr->clearPendingAgentListUpdates(mSessionID); @@ -1444,6 +1608,11 @@ LLUUID LLIMMgr::computeSessionID( session_id = other_participant_id ^ agent_id; } } + + if (gAgent.isInGroup(session_id) && (session_id != other_participant_id)) + { + llwarns << "Group session id different from group id: IM type = " << dialog << ", session id = " << session_id << ", group id = " << other_participant_id << llendl; + } return session_id; } @@ -1520,7 +1689,7 @@ LLIMMgr::onConfirmForceCloseError( //only 1 option really LLUUID session_id = notification["payload"]["session_id"]; - LLFloater* floater = LLIMFloater::findInstance(session_id); + LLFloater* floater = LLFloaterIMSession::findInstance(session_id); if ( floater ) { floater->closeFloater(FALSE); @@ -1878,7 +2047,7 @@ void LLOutgoingCallDialog::show(const LLSD& key) LLAvatarName av_name; if (LLAvatarNameCache::get(callee_id, &av_name)) { - final_callee_name = av_name.mDisplayName; + final_callee_name = av_name.getDisplayName(); title = av_name.getCompleteName(); } } @@ -1980,7 +2149,8 @@ BOOL LLOutgoingCallDialog::postBuild() //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) : -LLCallDialog(payload) +LLCallDialog(payload), +mAvatarNameCacheConnection() { } @@ -2050,9 +2220,11 @@ BOOL LLIncomingCallDialog::postBuild() else { // Get the full name information - LLAvatarNameCache::get(caller_id, - boost::bind(&LLIncomingCallDialog::onAvatarNameCache, - this, _1, _2, call_type)); + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(caller_id, boost::bind(&LLIncomingCallDialog::onAvatarNameCache, this, _1, _2, call_type)); } setIcon(session_id, caller_id); @@ -2078,7 +2250,6 @@ BOOL LLIncomingCallDialog::postBuild() getChildView("Start IM")->setVisible( is_avatar && notify_box_type != "VoiceInviteAdHoc" && notify_box_type != "VoiceInviteGroup"); setCanDrag(FALSE); - return TRUE; } @@ -2086,7 +2257,6 @@ void LLIncomingCallDialog::setCallerName(const std::string& ui_title, const std::string& ui_label, const std::string& call_type) { - setTitle(ui_title); // call_type may be a string like " is calling." LLUICtrl* caller_name_widget = getChild<LLUICtrl>("caller name"); @@ -2097,14 +2267,15 @@ void LLIncomingCallDialog::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, const std::string& call_type) { + mAvatarNameCacheConnection.disconnect(); std::string title = av_name.getCompleteName(); - setCallerName(title, av_name.mDisplayName, call_type); + setCallerName(title, av_name.getCompleteName(), call_type); } void LLIncomingCallDialog::onOpen(const LLSD& key) { LLCallDialog::onOpen(key); - + make_ui_sound("UISndStartIM"); LLStringUtil::format_map_t args; LLGroupData data; // if it's a group call, retrieve group name to use it in question @@ -2112,18 +2283,6 @@ void LLIncomingCallDialog::onOpen(const LLSD& key) { args["[GROUP]"] = data.mName; } - // tell the user which voice channel they would be leaving - LLVoiceChannel *voice = LLVoiceChannel::getCurrentVoiceChannel(); - if (voice && !voice->getSessionName().empty()) - { - args["[CURRENT_CHAT]"] = voice->getSessionName(); - getChild<LLUICtrl>("question")->setValue(getString(key["question_type"].asString(), args)); - } - else - { - args["[CURRENT_CHAT]"] = getString("localchat"); - getChild<LLUICtrl>("question")->setValue(getString(key["question_type"].asString(), args)); - } } //static @@ -2184,6 +2343,10 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload { gIMMgr->startCall(session_id, LLVoiceChannel::INCOMING_CALL); } + else + { + LLAvatarActions::startIM(caller_id); + } gIMMgr->clearPendingAgentListUpdates(session_id); gIMMgr->clearPendingInvitation(session_id); @@ -2386,7 +2549,7 @@ LLIMMgr::LLIMMgr() mPendingInvitations = LLSD::emptyMap(); mPendingAgentListUpdates = LLSD::emptyMap(); - LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&LLIMFloater::sRemoveTypingIndicator, _1)); + LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&LLFloaterIMSession::sRemoveTypingIndicator, _1)); } // Add a message to a session. @@ -2395,6 +2558,7 @@ void LLIMMgr::addMessage( const LLUUID& target_id, const std::string& from, const std::string& msg, + bool is_offline_msg, const std::string& session_name, EInstantMessage dialog, U32 parent_estate_id, @@ -2404,14 +2568,6 @@ void LLIMMgr::addMessage( { LLUUID other_participant_id = target_id; - // don't process muted IMs - if (LLMuteList::getInstance()->isMuted( - other_participant_id, - LLMute::flagTextChat) && !LLMuteList::getInstance()->isLinden(from)) - { - return; - } - LLUUID new_session_id = session_id; if (new_session_id.isNull()) { @@ -2421,15 +2577,22 @@ void LLIMMgr::addMessage( //*NOTE session_name is empty in case of incoming P2P sessions std::string fixed_session_name = from; + bool name_is_setted = false; if(!session_name.empty() && session_name.size()>1) { fixed_session_name = session_name; + name_is_setted = true; } bool new_session = !hasSession(new_session_id); if (new_session) { - LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id); + LLAvatarName av_name; + if (LLAvatarNameCache::get(other_participant_id, &av_name) && !name_is_setted) + { + fixed_session_name = av_name.getDisplayName(); + } + LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id, false, is_offline_msg); // When we get a new IM, and if you are a god, display a bit // of information about the source. This is to help liaisons @@ -2452,10 +2615,47 @@ void LLIMMgr::addMessage( LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str()); } - make_ui_sound("UISndNewIncomingIMSession"); + // Logically it would make more sense to reject the session sooner, in another area of the + // code, but the session has to be established inside the server before it can be left. + if (LLMuteList::getInstance()->isMuted(other_participant_id) && !LLMuteList::getInstance()->isLinden(from)) + { + llwarns << "Leaving IM session from initiating muted resident " << from << llendl; + if(!gIMMgr->leaveSession(new_session_id)) + { + llinfos << "Session " << new_session_id << " does not exist." << llendl; + } + return; + } + + //Play sound for new conversations + if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE)) + { + make_ui_sound("UISndNewIncomingIMSession"); + } + } + + bool skip_message = false; + if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly")) + { + // Evaluate if we need to skip this message when that setting is true (default is false) + LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); + skip_message = (LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL); // Skip non friends... + skip_message &= !session->isGroupSessionType(); // Do not skip group chats... + skip_message &= !(other_participant_id == gAgentID); // You are your best friend... Don't skip yourself + } + + if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message) + { + LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg); } - LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg); + // Open conversation floater if offline messages are present + if (is_offline_msg) + { + LLFloaterReg::showInstance("im_container"); + LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")-> + flashConversationItemWidget(session_id, true); + } } void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args) @@ -2470,11 +2670,9 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess LLChat chat(message); chat.mSourceType = CHAT_SOURCE_SYSTEM; - - LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar"); - LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat"); - if(nearby_chat) + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + if (nearby_chat) { nearby_chat->addMessage(chat); } @@ -2488,6 +2686,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString()); } // log message to file + else { std::string session_name; @@ -2570,7 +2769,8 @@ LLUUID LLIMMgr::addSession( { LLDynamicArray<LLUUID> ids; ids.put(other_participant_id); - return addSession(name, dialog, other_participant_id, ids, voice); + LLUUID session_id = addSession(name, dialog, other_participant_id, ids, voice); + return session_id; } // Adds a session using the given session_id. If the session already exists @@ -2579,7 +2779,8 @@ LLUUID LLIMMgr::addSession( const std::string& name, EInstantMessage dialog, const LLUUID& other_participant_id, - const LLDynamicArray<LLUUID>& ids, bool voice) + const LLDynamicArray<LLUUID>& ids, bool voice, + const LLUUID& floater_id) { if (0 == ids.getLength()) { @@ -2594,6 +2795,20 @@ LLUUID LLIMMgr::addSession( LLUUID session_id = computeSessionID(dialog,other_participant_id); + if (floater_id.notNull()) + { + LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(floater_id); + + if (im_floater) + { + // The IM floater should be initialized with a new session_id + // so that it is found by that id when creating a chiclet in LLFloaterIMSession::onIMChicletCreated, + // and a new floater is not created. + im_floater->initIMSession(session_id); + im_floater->reloadMessages(); + } + } + bool new_session = !LLIMModel::getInstance()->findIMSession(session_id); //works only for outgoing ad-hoc sessions @@ -2607,10 +2822,17 @@ LLUUID LLIMMgr::addSession( } } + //Notify observers that a session was added if (new_session) { LLIMModel::getInstance()->newSession(session_id, name, dialog, other_participant_id, ids, voice); } + //Notifies observers that the session was already added + else + { + std::string session_name = LLIMModel::getInstance()->getName(session_id); + LLIMMgr::getInstance()->notifyObserverSessionActivated(session_id, session_name, other_participant_id); + } //we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions if (!new_session) return session_id; @@ -2625,6 +2847,8 @@ LLUUID LLIMMgr::addSession( noteMutedUsers(session_id, ids); } + notifyObserverSessionVoiceOrIMStarted(session_id); + return session_id; } @@ -2661,18 +2885,15 @@ void LLIMMgr::inviteToSession( const std::string& session_handle, const std::string& session_uri) { - //ignore invites from muted residents - if (LLMuteList::getInstance()->isMuted(caller_id)) - { - return; - } - std::string notify_box_type; // voice invite question is different from default only for group call (EXT-7118) std::string question_type = "VoiceInviteQuestionDefault"; BOOL ad_hoc_invite = FALSE; BOOL voice_invite = FALSE; + bool is_linden = LLMuteList::getInstance()->isLinden(caller_name); + + if(type == IM_SESSION_P2P_INVITE) { //P2P is different...they only have voice invitations @@ -2711,7 +2932,18 @@ void LLIMMgr::inviteToSession( payload["session_uri"] = session_uri; payload["notify_box_type"] = notify_box_type; payload["question_type"] = question_type; - + + //ignore invites from muted residents + if (LLMuteList::getInstance()->isMuted(caller_id) && !is_linden) + { + if (voice_invite && "VoiceInviteQuestionDefault" == question_type) + { + llinfos << "Rejecting voice call from initiating muted resident " << caller_name << llendl; + LLIncomingCallDialog::processCallResponse(1, payload); + } + return; + } + LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(session_id); if (channelp && channelp->callStarted()) { @@ -2722,12 +2954,17 @@ void LLIMMgr::inviteToSession( if (voice_invite) { - if ( // if we are rejecting group calls - (gSavedSettings.getBOOL("VoiceCallsRejectGroup") && notify_box_type == "VoiceInviteGroup") || - // or we're rejecting non-friend voice calls and this isn't a friend - (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL)) - ) + bool isRejectGroupCall = (gSavedSettings.getBOOL("VoiceCallsRejectGroup") && (notify_box_type == "VoiceInviteGroup")); + bool isRejectNonFriendCall = (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL)); + bool isRejectDoNotDisturb = (gAgent.isDoNotDisturb() && !hasSession(session_id)); + if (isRejectGroupCall || isRejectNonFriendCall || isRejectDoNotDisturb) { + if (isRejectDoNotDisturb && !isRejectGroupCall && !isRejectNonFriendCall) + { + LLSD args; + addSystemMessage(session_id, "you_auto_rejected_call", args); + send_do_not_disturb_message(gMessageSystem, caller_id, session_id); + } // silently decline the call LLIncomingCallDialog::processCallResponse(1, payload); return; @@ -2789,7 +3026,7 @@ void LLIMMgr::clearPendingInvitation(const LLUUID& session_id) void LLIMMgr::processAgentListUpdates(const LLUUID& session_id, const LLSD& body) { - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id); if ( im_floater ) { im_floater->processAgentListUpdates(body); @@ -2895,11 +3132,27 @@ void LLIMMgr::clearPendingAgentListUpdates(const LLUUID& session_id) } } -void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) +void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, bool has_offline_msg) { for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++) { - (*it)->sessionAdded(session_id, name, other_participant_id); + (*it)->sessionAdded(session_id, name, other_participant_id, has_offline_msg); + } +} + +void LLIMMgr::notifyObserverSessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) +{ + for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++) + { + (*it)->sessionActivated(session_id, name, other_participant_id); + } +} + +void LLIMMgr::notifyObserverSessionVoiceOrIMStarted(const LLUUID& session_id) +{ + for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++) + { + (*it)->sessionVoiceOrIMStarted(session_id); } } @@ -2963,6 +3216,17 @@ bool LLIMMgr::isVoiceCall(const LLUUID& session_id) return im_session->mStartedAsIMCall; } +void LLIMMgr::addNotifiedNonFriendSessionID(const LLUUID& session_id) +{ + mNotifiedNonFriendSessions.insert(session_id); +} + +bool LLIMMgr::isNonFriendSessionNotified(const LLUUID& session_id) +{ + return mNotifiedNonFriendSessions.end() != mNotifiedNonFriendSessions.find(session_id); + +} + void LLIMMgr::noteOfflineUsers( const LLUUID& session_id, const LLDynamicArray<LLUUID>& ids) @@ -2988,7 +3252,7 @@ void LLIMMgr::noteOfflineUsers( { LLUIString offline = LLTrans::getString("offline_message"); // Use display name only because this user is your friend - offline.setArg("[NAME]", av_name.mDisplayName); + offline.setArg("[NAME]", av_name.getDisplayName()); im_model.proccessOnlineOfflineNotification(session_id, offline); } } @@ -3036,7 +3300,7 @@ void LLIMMgr::processIMTypingStop(const LLIMInfo* im_info) void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing) { LLUUID session_id = computeSessionID(im_info->mIMType, im_info->mFromID); - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id); if ( im_floater ) { im_floater->processIMTyping(im_info, typing); @@ -3081,7 +3345,7 @@ public: speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id)); } - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id); if ( im_floater ) { if ( body.has("session_info") ) @@ -3175,7 +3439,7 @@ public: const LLSD& input) const { LLUUID session_id = input["body"]["session_id"].asUUID(); - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id); if ( im_floater ) { im_floater->processSessionUpdate(input["body"]["info"]); @@ -3209,7 +3473,6 @@ public: //just like a normal IM //this is just replicated code from process_improved_im //and should really go in it's own function -jwolk - LLChat chat; std::string message = message_params["message"].asString(); std::string name = message_params["from_name"].asString(); @@ -3221,20 +3484,11 @@ public: time_t timestamp = (time_t) message_params["timestamp"].asInteger(); - BOOL is_busy = gAgent.getBusy(); - BOOL is_muted = LLMuteList::getInstance()->isMuted( - from_id, - name, - LLMute::flagTextChat); - - BOOL is_linden = LLMuteList::getInstance()->isLinden(name); - std::string separator_string(": "); - - chat.mMuted = is_muted && !is_linden; - chat.mFromID = from_id; - chat.mFromName = name; + BOOL is_do_not_disturb = gAgent.isDoNotDisturb(); - if (!is_linden && (is_busy || is_muted)) + //don't return if user is muted b/c proper way to ignore a muted user who + //initiated an adhoc/group conference is to create then leave the session (see STORM-1731) + if (is_do_not_disturb) { return; } @@ -3259,6 +3513,7 @@ public: from_id, name, buffer, + IM_OFFLINE == offline, std::string((char*)&bin_bucket[0]), IM_SESSION_INVITE, message_params["parent_estate_id"].asInteger(), @@ -3266,6 +3521,11 @@ public: ll_vector3_from_sd(message_params["position"]), true); + if (LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)) + { + return; + } + //K now we want to accept the invitation std::string url = gAgent.getRegion()->getCapability( "ChatSessionRequest"); diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index b1be26a169..da6039a3ae 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -27,7 +27,7 @@ #ifndef LL_LLIMVIEW_H #define LL_LLIMVIEW_H -#include "lldockablefloater.h" +#include "../llui/lldockablefloater.h" #include "lleventtimer.h" #include "llinstantmessage.h" @@ -70,10 +70,11 @@ public: GROUP_SESSION, ADHOC_SESSION, AVALINE_SESSION, + NONE_SESSION, } SType; LLIMSession(const LLUUID& session_id, const std::string& name, - const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice); + const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg); virtual ~LLIMSession(); void sessionInitReplyReceived(const LLUUID& new_session_id); @@ -84,7 +85,7 @@ public: /** @deprecated */ static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata); - bool isOutgoingAdHoc(); + bool isOutgoingAdHoc() const; bool isAdHoc(); bool isP2P(); bool isOtherParticipantAvaline(); @@ -94,10 +95,14 @@ public: bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;} bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;} + LLUUID generateOutgouigAdHocHash() const; + //*TODO make private /** ad-hoc sessions involve sophisticated chat history file naming schemes */ void buildHistoryFileName(); + void loadHistory(); + LLUUID mSessionID; std::string mName; EInstantMessage mType; @@ -133,27 +138,22 @@ public: //if IM session is created for a voice call bool mStartedAsIMCall; + bool mHasOfflineMessage; + private: void onAdHocNameCache(const LLAvatarName& av_name); - static std::string generateHash(const std::set<LLUUID>& sorted_uuids); + static LLUUID generateHash(const std::set<LLUUID>& sorted_uuids); + boost::signals2::connection mAvatarNameCacheConnection; }; LLIMModel(); - - //we should control the currently active session - LLUUID mActiveSessionID; - void setActiveSessionID(const LLUUID& session_id); - void resetActiveSessionID() { mActiveSessionID.setNull(); } - LLUUID getActiveSessionID() { return mActiveSessionID; } - /** Session id to session object */ std::map<LLUUID, LLIMSession*> mId2SessionMap; typedef boost::signals2::signal<void(const LLSD&)> session_signal_t; - typedef boost::function<void(const LLSD&)> session_callback_t; session_signal_t mNewMsgSignal; session_signal_t mNoUnreadMsgsSignal; @@ -174,18 +174,18 @@ public: */ void processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id); - boost::signals2::connection addNewMsgCallback( session_callback_t cb ) { return mNewMsgSignal.connect(cb); } - boost::signals2::connection addNoUnreadMsgsCallback( session_callback_t cb ) { return mNoUnreadMsgsSignal.connect(cb); } + boost::signals2::connection addNewMsgCallback(const session_signal_t::slot_type& cb ) { return mNewMsgSignal.connect(cb); } + boost::signals2::connection addNoUnreadMsgsCallback(const session_signal_t::slot_type& cb ) { return mNoUnreadMsgsSignal.connect(cb); } /** * Create new session object in a model * @param name session name should not be empty, will return false if empty */ bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, - const uuid_vec_t& ids, bool voice = false); + const uuid_vec_t& ids, bool voice = false, bool has_offline_msg = false); bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, - const LLUUID& other_participant_id, bool voice = false); + const LLUUID& other_participant_id, bool voice = false, bool has_offline_msg = false); /** * Remove all session data associated with a session specified by session_id @@ -193,12 +193,6 @@ public: bool clearSession(const LLUUID& session_id); /** - * Populate supplied std::list with messages starting from index specified by start_index without - * emitting no unread messages signal. - */ - void getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0); - - /** * Sends no unread messages signal. */ void sendNoUnreadMessages(const LLUUID& session_id); @@ -206,7 +200,7 @@ public: /** * Populate supplied std::list with messages starting from index specified by start_index */ - void getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0); + void getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0, const bool sendNoUnreadMsgs = true); /** * Add a message to an IM Model - the message is saved in a message store associated with a session specified by session_id @@ -289,6 +283,12 @@ public: private: /** + * Populate supplied std::list with messages starting from index specified by start_index without + * emitting no unread messages signal. + */ + void getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0); + + /** * Add message to a list of message associated with session specified by session_id */ bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); @@ -298,7 +298,9 @@ class LLIMSessionObserver { public: virtual ~LLIMSessionObserver() {} - virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0; + virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg) = 0; + virtual void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0; + virtual void sessionVoiceOrIMStarted(const LLUUID& session_id) = 0; virtual void sessionRemoved(const LLUUID& session_id) = 0; virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) = 0; }; @@ -325,6 +327,7 @@ public: const LLUUID& target_id, const std::string& from, const std::string& msg, + bool is_offline_msg = false, const std::string& session_name = LLStringUtil::null, EInstantMessage dialog = IM_NOTHING_SPECIAL, U32 parent_estate_id = 0, @@ -348,10 +351,12 @@ public: // Adds a session using a specific group of starting agents // the dialog type is assumed correct. Returns the uuid of the session. + // A session can be added to a floater specified by floater_id. LLUUID addSession(const std::string& name, EInstantMessage dialog, const LLUUID& other_participant_id, - const LLDynamicArray<LLUUID>& ids, bool voice = false); + const LLDynamicArray<LLUUID>& ids, bool voice = false, + const LLUUID& floater_id = LLUUID::null); /** * Creates a P2P session with the requisite handle for responding to voice calls. @@ -438,6 +443,10 @@ public: bool isVoiceCall(const LLUUID& session_id); + void addNotifiedNonFriendSessionID(const LLUUID& session_id); + + bool isNonFriendSessionNotified(const LLUUID& session_id); + private: /** @@ -456,7 +465,10 @@ private: static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group); - void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id); + void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, bool has_offline_msg); + //Triggers when a session has already been added + void notifyObserverSessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id); + void notifyObserverSessionVoiceOrIMStarted(const LLUUID& session_id); void notifyObserverSessionRemoved(const LLUUID& session_id); void notifyObserverSessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id); @@ -465,6 +477,14 @@ private: typedef std::list <LLIMSessionObserver *> session_observers_list_t; session_observers_list_t mSessionObservers; + // EXP-901 + // If "Only friends and groups can IM me" option is ON but the user got message from non-friend, + // the user should be notified that to be able to see this message the option should be OFF. + // This set stores session IDs in which user was notified. Need to store this IDs so that the user + // be notified only one time per session with non-friend. + typedef std::set<LLUUID> notified_non_friend_sessions_t; + notified_non_friend_sessions_t mNotifiedNonFriendSessions; + LLSD mPendingInvitations; LLSD mPendingAgentListUpdates; }; @@ -530,7 +550,14 @@ class LLIncomingCallDialog : public LLCallDialog { public: LLIncomingCallDialog(const LLSD& payload); - + ~LLIncomingCallDialog() + { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + } + /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); @@ -547,6 +574,8 @@ private: const LLAvatarName& av_name, const std::string& call_type); + boost::signals2::connection mAvatarNameCacheConnection; + /*virtual*/ void onLifetimeExpired(); }; diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 17d0b0ffbb..1e15dc832c 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -29,37 +29,24 @@ // viewer files #include "llagent.h" -#include "llagentdata.h" #include "llavataractions.h" +#include "llavatariconctrl.h" #include "llavatarnamecache.h" #include "llavatarpropertiesprocessor.h" -#include "llcallingcard.h" #include "lldateutil.h" -#include "llfloaterreporter.h" -#include "llfloaterworldmap.h" -#include "llimview.h" #include "llinspect.h" #include "llmutelist.h" -#include "llpanelblockedlist.h" +#include "llslurl.h" #include "llstartup.h" -#include "llspeakers.h" -#include "llviewermenu.h" #include "llvoiceclient.h" -#include "llviewerobjectlist.h" #include "lltransientfloatermgr.h" -#include "llnotificationsutil.h" // Linden libraries #include "llfloater.h" #include "llfloaterreg.h" -#include "llmenubutton.h" #include "lltextbox.h" -#include "lltoggleablemenu.h" #include "lltooltip.h" // positionViewNearMouse() #include "lltrans.h" -#include "lluictrl.h" - -#include "llavatariconctrl.h" class LLFetchAvatarData; @@ -80,70 +67,30 @@ public: // Inspector will be positioned relative to current mouse position LLInspectAvatar(const LLSD& avatar_id); virtual ~LLInspectAvatar(); - + /*virtual*/ BOOL postBuild(void); // Because floater is single instance, need to re-parse data on each spawn // (for example, inspector about same avatar but in different position) /*virtual*/ void onOpen(const LLSD& avatar_id); - // When closing they should close their gear menu - /*virtual*/ void onClose(bool app_quitting); - // Update view based on information from avatar properties processor void processAvatarData(LLAvatarData* data); - // override the inspector mouse leave so timer is only paused if - // gear menu is not open - /* virtual */ void onMouseLeave(S32 x, S32 y, MASK mask); - virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; } private: // Make network requests for all the data to display in this view. // Used on construction and if avatar id changes. void requestUpdate(); - + // Set the volume slider to this user's current client-side volume setting, // hiding/disabling if the user is not nearby. void updateVolumeSlider(); - // Shows/hides moderator panel depending on voice state - void updateModeratorPanel(); - - // Moderator ability to enable/disable voice chat for avatar - void toggleSelectedVoice(bool enabled); - // Button callbacks - void onClickAddFriend(); - void onClickViewProfile(); - void onClickIM(); - void onClickCall(); - void onClickTeleport(); - void onClickInviteToGroup(); - void onClickPay(); - void onClickShare(); - void onToggleMute(); - void onClickReport(); - void onClickFreeze(); - void onClickEject(); - void onClickKick(); - void onClickCSR(); - void onClickZoomIn(); - void onClickFindOnMap(); - bool onVisibleFindOnMap(); - bool onVisibleEject(); - bool onVisibleFreeze(); - bool onVisibleZoomIn(); void onClickMuteVolume(); void onVolumeChange(const LLSD& data); - bool enableMute(); - bool enableUnmute(); - bool enableTeleportOffer(); - bool godModeEnabled(); - - // Is used to determine if "Add friend" option should be enabled in gear menu - bool isNotFriend(); void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); @@ -155,6 +102,7 @@ private: // an in-flight request for avatar properties from LLAvatarPropertiesProcessor // is represented by this object LLFetchAvatarData* mPropertiesRequest; + boost::signals2::connection mAvatarNameCacheConnection; }; ////////////////////////////////////////////////////////////////////////////// @@ -207,41 +155,11 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd) : LLInspect( LLSD() ), // single_instance, doesn't really need key mAvatarID(), // set in onOpen() *Note: we used to show partner's name but we dont anymore --angela 3rd Dec* mAvatarName(), - mPropertiesRequest(NULL) + mPropertiesRequest(NULL), + mAvatarNameCacheConnection() { - mCommitCallbackRegistrar.add("InspectAvatar.ViewProfile", boost::bind(&LLInspectAvatar::onClickViewProfile, this)); - mCommitCallbackRegistrar.add("InspectAvatar.AddFriend", boost::bind(&LLInspectAvatar::onClickAddFriend, this)); - mCommitCallbackRegistrar.add("InspectAvatar.IM", - boost::bind(&LLInspectAvatar::onClickIM, this)); - mCommitCallbackRegistrar.add("InspectAvatar.Call", boost::bind(&LLInspectAvatar::onClickCall, this)); - mCommitCallbackRegistrar.add("InspectAvatar.Teleport", boost::bind(&LLInspectAvatar::onClickTeleport, this)); - mCommitCallbackRegistrar.add("InspectAvatar.InviteToGroup", boost::bind(&LLInspectAvatar::onClickInviteToGroup, this)); - mCommitCallbackRegistrar.add("InspectAvatar.Pay", boost::bind(&LLInspectAvatar::onClickPay, this)); - mCommitCallbackRegistrar.add("InspectAvatar.Share", boost::bind(&LLInspectAvatar::onClickShare, this)); - mCommitCallbackRegistrar.add("InspectAvatar.ToggleMute", boost::bind(&LLInspectAvatar::onToggleMute, this)); - mCommitCallbackRegistrar.add("InspectAvatar.Freeze", boost::bind(&LLInspectAvatar::onClickFreeze, this)); - mCommitCallbackRegistrar.add("InspectAvatar.Eject", boost::bind(&LLInspectAvatar::onClickEject, this)); - mCommitCallbackRegistrar.add("InspectAvatar.Kick", boost::bind(&LLInspectAvatar::onClickKick, this)); - mCommitCallbackRegistrar.add("InspectAvatar.CSR", boost::bind(&LLInspectAvatar::onClickCSR, this)); - mCommitCallbackRegistrar.add("InspectAvatar.Report", boost::bind(&LLInspectAvatar::onClickReport, this)); - mCommitCallbackRegistrar.add("InspectAvatar.FindOnMap", boost::bind(&LLInspectAvatar::onClickFindOnMap, this)); - mCommitCallbackRegistrar.add("InspectAvatar.ZoomIn", boost::bind(&LLInspectAvatar::onClickZoomIn, this)); - mCommitCallbackRegistrar.add("InspectAvatar.DisableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, false)); - mCommitCallbackRegistrar.add("InspectAvatar.EnableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, true)); - - mEnableCallbackRegistrar.add("InspectAvatar.EnableGod", boost::bind(&LLInspectAvatar::godModeEnabled, this)); - mEnableCallbackRegistrar.add("InspectAvatar.VisibleFindOnMap", boost::bind(&LLInspectAvatar::onVisibleFindOnMap, this)); - mEnableCallbackRegistrar.add("InspectAvatar.VisibleEject", boost::bind(&LLInspectAvatar::onVisibleEject, this)); - mEnableCallbackRegistrar.add("InspectAvatar.VisibleFreeze", boost::bind(&LLInspectAvatar::onVisibleFreeze, this)); - mEnableCallbackRegistrar.add("InspectAvatar.VisibleZoomIn", boost::bind(&LLInspectAvatar::onVisibleZoomIn, this)); - mEnableCallbackRegistrar.add("InspectAvatar.Gear.Enable", boost::bind(&LLInspectAvatar::isNotFriend, this)); - mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableCall", boost::bind(&LLAvatarActions::canCall)); - mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableTeleportOffer", boost::bind(&LLInspectAvatar::enableTeleportOffer, this)); - mEnableCallbackRegistrar.add("InspectAvatar.EnableMute", boost::bind(&LLInspectAvatar::enableMute, this)); - mEnableCallbackRegistrar.add("InspectAvatar.EnableUnmute", boost::bind(&LLInspectAvatar::enableUnmute, this)); - // can't make the properties request until the widgets are constructed - // as it might return immediately, so do it in postBuild. + // as it might return immediately, so do it in onOpen. LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this); LLTransientFloater::init(this); @@ -249,6 +167,10 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd) LLInspectAvatar::~LLInspectAvatar() { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } // clean up any pending requests so they don't call back into a deleted // view delete mPropertiesRequest; @@ -260,12 +182,6 @@ LLInspectAvatar::~LLInspectAvatar() /*virtual*/ BOOL LLInspectAvatar::postBuild(void) { - getChild<LLUICtrl>("add_friend_btn")->setCommitCallback( - boost::bind(&LLInspectAvatar::onClickAddFriend, this) ); - - getChild<LLUICtrl>("view_profile_btn")->setCommitCallback( - boost::bind(&LLInspectAvatar::onClickViewProfile, this) ); - getChild<LLUICtrl>("mute_btn")->setCommitCallback( boost::bind(&LLInspectAvatar::onClickMuteVolume, this) ); @@ -275,7 +191,6 @@ BOOL LLInspectAvatar::postBuild(void) return TRUE; } - // Multiple calls to showInstance("inspect_avatar", foo) will provide different // LLSD for foo, which we will catch here. //virtual @@ -287,11 +202,6 @@ void LLInspectAvatar::onOpen(const LLSD& data) // Extract appropriate avatar id mAvatarID = data["avatar_id"]; - BOOL self = mAvatarID == gAgent.getID(); - - getChild<LLUICtrl>("gear_self_btn")->setVisible(self); - getChild<LLUICtrl>("gear_btn")->setVisible(!self); - // Position the inspector relative to the mouse cursor // Similar to how tooltips are positioned // See LLToolTipMgr::createToolTip @@ -304,20 +214,15 @@ void LLInspectAvatar::onOpen(const LLSD& data) LLUI::positionViewNearMouse(this); } + // Generate link to avatar profile. + getChild<LLUICtrl>("avatar_profile_link")->setTextArg("[LINK]", LLSLURL("agent", mAvatarID, "about").getSLURLString()); + // can't call from constructor as widgets are not built yet requestUpdate(); updateVolumeSlider(); - - updateModeratorPanel(); } -// virtual -void LLInspectAvatar::onClose(bool app_quitting) -{ - getChild<LLMenuButton>("gear_btn")->hideMenu(); -} - void LLInspectAvatar::requestUpdate() { // Don't make network requests when spawning from the debug menu at the @@ -344,25 +249,6 @@ void LLInspectAvatar::requestUpdate() delete mPropertiesRequest; mPropertiesRequest = new LLFetchAvatarData(mAvatarID, this); - // You can't re-add someone as a friend if they are already your friend - bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL; - bool is_self = (mAvatarID == gAgentID); - if (is_self) - { - getChild<LLUICtrl>("add_friend_btn")->setVisible(false); - getChild<LLUICtrl>("im_btn")->setVisible(false); - } - else if (is_friend) - { - getChild<LLUICtrl>("add_friend_btn")->setVisible(false); - getChild<LLUICtrl>("im_btn")->setVisible(true); - } - else - { - getChild<LLUICtrl>("add_friend_btn")->setVisible(true); - getChild<LLUICtrl>("im_btn")->setVisible(false); - } - // Use an avatar_icon even though the image id will come down with the // avatar properties because the avatar_icon code maintains a cache of icons // and this may result in the image being visible sooner. @@ -374,9 +260,11 @@ void LLInspectAvatar::requestUpdate() getChild<LLUICtrl>("avatar_icon")->setValue(LLSD(mAvatarID) ); - LLAvatarNameCache::get(mAvatarID, - boost::bind(&LLInspectAvatar::onAvatarNameCache, - this, _1, _2)); + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID,boost::bind(&LLInspectAvatar::onAvatarNameCache,this, _1, _2)); } void LLInspectAvatar::processAvatarData(LLAvatarData* data) @@ -405,141 +293,6 @@ void LLInspectAvatar::processAvatarData(LLAvatarData* data) mPropertiesRequest = NULL; } -// For the avatar inspector, we only want to unpause the fade timer -// if neither the gear menu or self gear menu are open -void LLInspectAvatar::onMouseLeave(S32 x, S32 y, MASK mask) -{ - LLToggleableMenu* gear_menu = getChild<LLMenuButton>("gear_btn")->getMenu(); - LLToggleableMenu* gear_menu_self = getChild<LLMenuButton>("gear_self_btn")->getMenu(); - if ( gear_menu && gear_menu->getVisible() && - gear_menu_self && gear_menu_self->getVisible() ) - { - return; - } - - if(childHasVisiblePopupMenu()) - { - return; - } - - mOpenTimer.unpause(); -} - -void LLInspectAvatar::updateModeratorPanel() -{ - bool enable_moderator_panel = false; - - if (LLVoiceChannel::getCurrentVoiceChannel() && - mAvatarID != gAgent.getID()) - { - LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID(); - - if (session_id != LLUUID::null) - { - LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id); - - if (speaker_mgr) - { - LLPointer<LLSpeaker> self_speakerp = speaker_mgr->findSpeaker(gAgent.getID()); - LLPointer<LLSpeaker> selected_speakerp = speaker_mgr->findSpeaker(mAvatarID); - - if(speaker_mgr->isVoiceActive() && selected_speakerp && - selected_speakerp->isInVoiceChannel() && - ((self_speakerp && self_speakerp->mIsModerator) || gAgent.isGodlike())) - { - getChild<LLUICtrl>("enable_voice")->setVisible(selected_speakerp->mModeratorMutedVoice); - getChild<LLUICtrl>("disable_voice")->setVisible(!selected_speakerp->mModeratorMutedVoice); - - enable_moderator_panel = true; - } - } - } - } - - if (enable_moderator_panel) - { - if (!getChild<LLUICtrl>("moderator_panel")->getVisible()) - { - getChild<LLUICtrl>("moderator_panel")->setVisible(true); - // stretch the floater so it can accommodate the moderator panel - reshape(getRect().getWidth(), getRect().getHeight() + getChild<LLUICtrl>("moderator_panel")->getRect().getHeight()); - } - } - else if (getChild<LLUICtrl>("moderator_panel")->getVisible()) - { - getChild<LLUICtrl>("moderator_panel")->setVisible(false); - // shrink the inspector floater back to original size - reshape(getRect().getWidth(), getRect().getHeight() - getChild<LLUICtrl>("moderator_panel")->getRect().getHeight()); - } -} - -void LLInspectAvatar::toggleSelectedVoice(bool enabled) -{ - LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID(); - LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id); - - if (speaker_mgr) - { - if (!gAgent.getRegion()) - return; - - std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest"); - LLSD data; - data["method"] = "mute update"; - data["session-id"] = session_id; - data["params"] = LLSD::emptyMap(); - data["params"]["agent_id"] = mAvatarID; - data["params"]["mute_info"] = LLSD::emptyMap(); - // ctrl value represents ability to type, so invert - data["params"]["mute_info"]["voice"] = !enabled; - - class MuteVoiceResponder : public LLHTTPClient::Responder - { - public: - MuteVoiceResponder(const LLUUID& session_id) - { - mSessionID = session_id; - } - - virtual void error(U32 status, const std::string& reason) - { - llwarns << status << ": " << reason << llendl; - - if ( gIMMgr ) - { - //403 == you're not a mod - //should be disabled if you're not a moderator - if ( 403 == status ) - { - gIMMgr->showSessionEventError( - "mute", - "not_a_moderator", - mSessionID); - } - else - { - gIMMgr->showSessionEventError( - "mute", - "generic", - mSessionID); - } - } - } - - private: - LLUUID mSessionID; - }; - - LLHTTPClient::post( - url, - data, - new MuteVoiceResponder(speaker_mgr->getSessionID())); - } - - closeFloater(); - -} - void LLInspectAvatar::updateVolumeSlider() { bool voice_enabled = LLVoiceClient::getInstance()->getVoiceEnabled(mAvatarID); @@ -558,12 +311,11 @@ void LLInspectAvatar::updateVolumeSlider() getChild<LLUICtrl>("volume_slider")->setVisible(true); // By convention, we only display and toggle voice mutes, not all mutes - bool is_muted = LLMuteList::getInstance()-> - isMuted(mAvatarID, LLMute::flagVoiceChat); + bool is_muted = LLAvatarActions::isVoiceMuted(mAvatarID); LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn"); - bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden"); + bool is_linden = LLStringUtil::endsWith(mAvatarName.getDisplayName(), " Linden"); mute_btn->setEnabled( !is_linden); mute_btn->setValue( is_muted ); @@ -594,7 +346,7 @@ void LLInspectAvatar::onClickMuteVolume() LLMuteList* mute_list = LLMuteList::getInstance(); bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat); - LLMute mute(mAvatarID, mAvatarName.getLegacyName(), LLMute::AGENT); + LLMute mute(mAvatarID, mAvatarName.getDisplayName(), LLMute::AGENT); if (!is_muted) { mute_list->add(mute, LLMute::flagVoiceChat); @@ -617,11 +369,13 @@ void LLInspectAvatar::onAvatarNameCache( const LLUUID& agent_id, const LLAvatarName& av_name) { + mAvatarNameCacheConnection.disconnect(); + if (agent_id == mAvatarID) { - getChild<LLUICtrl>("user_name")->setValue(av_name.mDisplayName); - getChild<LLUICtrl>("user_name_small")->setValue(av_name.mDisplayName); - getChild<LLUICtrl>("user_slid")->setValue(av_name.mUsername); + getChild<LLUICtrl>("user_name")->setValue(av_name.getDisplayName()); + getChild<LLUICtrl>("user_name_small")->setValue(av_name.getDisplayName()); + getChild<LLUICtrl>("user_slid")->setValue(av_name.getUserName()); mAvatarName = av_name; // show smaller display name if too long to display in regular size @@ -640,215 +394,6 @@ void LLInspectAvatar::onAvatarNameCache( } } -void LLInspectAvatar::onClickAddFriend() -{ - LLAvatarActions::requestFriendshipDialog(mAvatarID, mAvatarName.getLegacyName()); - closeFloater(); -} - -void LLInspectAvatar::onClickViewProfile() -{ - LLAvatarActions::showProfile(mAvatarID); - closeFloater(); -} - -bool LLInspectAvatar::isNotFriend() -{ - return !LLAvatarActions::isFriend(mAvatarID); -} - -bool LLInspectAvatar::onVisibleFindOnMap() -{ - return gAgent.isGodlike() || is_agent_mappable(mAvatarID); -} - -bool LLInspectAvatar::onVisibleEject() -{ - return enable_freeze_eject( LLSD(mAvatarID) ); -} - -bool LLInspectAvatar::onVisibleFreeze() -{ - // either user is a god and can do long distance freeze - // or check for target proximity and permissions - return gAgent.isGodlike() || enable_freeze_eject(LLSD(mAvatarID)); -} - -bool LLInspectAvatar::onVisibleZoomIn() -{ - return gObjectList.findObject(mAvatarID); -} - -void LLInspectAvatar::onClickIM() -{ - LLAvatarActions::startIM(mAvatarID); - closeFloater(); -} - -void LLInspectAvatar::onClickCall() -{ - LLAvatarActions::startCall(mAvatarID); - closeFloater(); -} - -void LLInspectAvatar::onClickTeleport() -{ - LLAvatarActions::offerTeleport(mAvatarID); - closeFloater(); -} - -void LLInspectAvatar::onClickInviteToGroup() -{ - LLAvatarActions::inviteToGroup(mAvatarID); - closeFloater(); -} - -void LLInspectAvatar::onClickPay() -{ - LLAvatarActions::pay(mAvatarID); - closeFloater(); -} - -void LLInspectAvatar::onClickShare() -{ - LLAvatarActions::share(mAvatarID); - closeFloater(); -} - -void LLInspectAvatar::onToggleMute() -{ - LLMute mute(mAvatarID, mAvatarName.mDisplayName, LLMute::AGENT); - - if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName)) - { - LLMuteList::getInstance()->remove(mute); - } - else - { - LLMuteList::getInstance()->add(mute); - } - - LLPanelBlockedList::showPanelAndSelect(mute.mID); - closeFloater(); -} - -void LLInspectAvatar::onClickReport() -{ - LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName.getCompleteName()); - closeFloater(); -} - -bool godlike_freeze(const LLSD& notification, const LLSD& response) -{ - LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID(); - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - - switch (option) - { - case 0: - LLAvatarActions::freeze(avatar_id); - break; - case 1: - LLAvatarActions::unfreeze(avatar_id); - break; - default: - break; - } - - return false; -} - -void LLInspectAvatar::onClickFreeze() -{ - if (gAgent.isGodlike()) - { - // use godlike freeze-at-a-distance, with confirmation - LLNotificationsUtil::add("FreezeAvatar", - LLSD(), - LLSD().with("avatar_id", mAvatarID), - godlike_freeze); - } - else - { - // use default "local" version of freezing that requires avatar to be in range - handle_avatar_freeze( LLSD(mAvatarID) ); - } - closeFloater(); -} - -void LLInspectAvatar::onClickEject() -{ - handle_avatar_eject( LLSD(mAvatarID) ); - closeFloater(); -} - -void LLInspectAvatar::onClickKick() -{ - LLAvatarActions::kick(mAvatarID); - closeFloater(); -} - -void LLInspectAvatar::onClickCSR() -{ - std::string name; - gCacheName->getFullName(mAvatarID, name); - LLAvatarActions::csr(mAvatarID, name); - closeFloater(); -} - -void LLInspectAvatar::onClickZoomIn() -{ - handle_zoom_to_object(mAvatarID); - closeFloater(); -} - -void LLInspectAvatar::onClickFindOnMap() -{ - gFloaterWorldMap->trackAvatar(mAvatarID, mAvatarName.mDisplayName); - LLFloaterReg::showInstance("world_map"); -} - - -bool LLInspectAvatar::enableMute() -{ - bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden"); - bool is_self = mAvatarID == gAgent.getID(); - - if (!is_linden && !is_self && !LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName())) - { - return true; - } - else - { - return false; - } -} - -bool LLInspectAvatar::enableUnmute() -{ - bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden"); - bool is_self = mAvatarID == gAgent.getID(); - - if (!is_linden && !is_self && LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName())) - { - return true; - } - else - { - return false; - } -} - -bool LLInspectAvatar::enableTeleportOffer() -{ - return LLAvatarActions::canOfferTeleport(mAvatarID); -} - -bool LLInspectAvatar::godModeEnabled() -{ - return gAgent.isGodlike(); -} - ////////////////////////////////////////////////////////////////////////////// // LLInspectAvatarUtil ////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp index acc139c569..a7b93b8030 100644 --- a/indra/newview/llinspectobject.cpp +++ b/indra/newview/llinspectobject.cpp @@ -111,6 +111,7 @@ private: private: LLUUID mObjectID; + LLUUID mPreviousObjectID; S32 mObjectFace; viewer_media_t mMediaImpl; LLMediaEntry* mMediaEntry; @@ -249,6 +250,7 @@ void LLInspectObject::onClose(bool app_quitting) { // Release selection to deselect mObjectSelection = NULL; + mPreviousObjectID = mObjectID; getChild<LLMenuButton>("gear_btn")->hideMenu(); } @@ -266,6 +268,13 @@ void LLInspectObject::update() LLSelectNode* nodep = selection->getFirstRootNode(); if (!nodep) return; + // If we don't have fresh object info yet and it's the object we inspected last time, + // keep showing the previously retrieved data until we get the update. + if (!nodep->mValid && nodep->getObject()->getID() == mPreviousObjectID) + { + return; + } + updateButtons(nodep); updateName(nodep); updateDescription(nodep); 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/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp index d7b82667d1..f4fe5dec01 100644 --- a/indra/newview/llinspecttoast.cpp +++ b/indra/newview/llinspecttoast.cpp @@ -72,6 +72,8 @@ LLInspectToast::LLInspectToast(const LLSD& notification_id) : LLInspectToast::~LLInspectToast() { LLTransientFloaterMgr::getInstance()->removeControlView(this); + + mConnection.disconnect(); } // virtual diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 0c092e9a56..0ee78d57bd 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -37,6 +37,7 @@ #include "llappearancemgr.h" #include "llattachmentsmgr.h" #include "llavataractions.h" +#include "llfavoritesbar.h" // management of favorites folder #include "llfloateropenobject.h" #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" @@ -45,14 +46,15 @@ #include "llfriendcard.h" #include "llgesturemgr.h" #include "llgiveinventory.h" -#include "llimfloater.h" +#include "llfloaterimcontainer.h" #include "llimview.h" -#include "llinventoryclipboard.h" +#include "llclipboard.h" #include "llinventorydefines.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" #include "llinventorymodelbackgroundfetch.h" #include "llinventorypanel.h" +#include "llmarketplacefunctions.h" #include "llnotifications.h" #include "llnotificationsutil.h" #include "llpreviewanim.h" @@ -60,6 +62,7 @@ #include "llpreviewtexture.h" #include "llselectmgr.h" #include "llsidepanelappearance.h" +#include "lltooldraganddrop.h" #include "lltrans.h" #include "llviewerassettype.h" #include "llviewerfoldertype.h" @@ -69,9 +72,14 @@ #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llwearablelist.h" +#include "lllandmarkactions.h" + +void copy_slurl_to_clipboard_callback_inv(const std::string& slurl); // 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 1 +#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; @@ -87,21 +95,6 @@ struct LLMoveInv using namespace LLOldEvents; -// Helpers -// bug in busy count inc/dec right now, logic is complex... do we really need it? -void inc_busy_count() -{ -// gViewerWindow->getWindow()->incBusyCount(); -// check balance of these calls if this code is changed to ever actually -// *do* something! -} -void dec_busy_count() -{ -// gViewerWindow->getWindow()->decBusyCount(); -// check balance of these calls if this code is changed to ever actually -// *do* something! -} - // Function declarations void remove_inventory_category_from_avatar(LLInventoryCategory* category); void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id); @@ -109,6 +102,13 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response bool confirm_attachment_rez(const LLSD& notification, const LLSD& response); void teleport_via_landmark(const LLUUID& asset_id); static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit); +static bool check_category(LLInventoryModel* model, + const LLUUID& cat_id, + LLInventoryPanel* active_panel, + LLInventoryFilter* filter); +static bool check_item(const LLUUID& item_id, + LLInventoryPanel* active_panel, + LLInventoryFilter* filter); // Helper functions @@ -127,6 +127,46 @@ 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); +} + +// Used by LLFolderBridge as callback for directory fetching recursion +class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver +{ +public: + LLRightClickInventoryFetchDescendentsObserver(const uuid_vec_t& ids) : LLInventoryFetchDescendentsObserver(ids) {} + ~LLRightClickInventoryFetchDescendentsObserver() {} + virtual void execute(bool clear_observer = false); + virtual void done() + { + execute(true); + } +}; + +// Used by LLFolderBridge as callback for directory content items fetching +class LLRightClickInventoryFetchObserver : public LLInventoryFetchItemsObserver +{ +public: + LLRightClickInventoryFetchObserver(const uuid_vec_t& ids) : LLInventoryFetchItemsObserver(ids) { }; + ~LLRightClickInventoryFetchObserver() {} + void execute(bool clear_observer = false) + { + if (clear_observer) + { + gInventory.removeObserver(this); + delete this; + } + // we've downloaded all the items, so repaint the dialog + LLFolderBridge::staticFolderOptionsMenu(); + } + virtual void done() + { + execute(true); + } +}; + // +=================================================+ // | LLInvFVBridge | // +=================================================+ @@ -137,9 +177,10 @@ LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory, mUUID(uuid), mRoot(root), mInvType(LLInventoryType::IT_NONE), - mIsLink(FALSE) + mIsLink(FALSE), + LLFolderViewModelItemInventory(inventory->getRootViewModel()) { - mInventoryPanel = inventory->getHandle(); + mInventoryPanel = inventory->getInventoryPanelHandle(); const LLInventoryObject* obj = getInventoryObject(); mIsLink = obj && obj->getIsLinkType(); } @@ -156,7 +197,11 @@ const std::string& LLInvFVBridge::getName() const const std::string& LLInvFVBridge::getDisplayName() const { - return getName(); + if(mDisplayName.empty()) + { + buildDisplayName(); + } + return mDisplayName; } // Folders have full perms @@ -175,9 +220,24 @@ LLFolderType::EType LLInvFVBridge::getPreferredType() const // Folders don't have creation dates. time_t LLInvFVBridge::getCreationDate() const { - return 0; + LLInventoryObject* objectp = getInventoryObject(); + if (objectp) + { + return objectp->getCreationDate(); + } + return (time_t)0; } +void LLInvFVBridge::setCreationDate(time_t creation_date_utc) +{ + LLInventoryObject* objectp = getInventoryObject(); + if (objectp) + { + objectp->setCreationDate(creation_date_utc); + } +} + + // Can be destroyed (or moved to trash) BOOL LLInvFVBridge::isItemRemovable() const { @@ -195,17 +255,36 @@ BOOL LLInvFVBridge::isLink() const return mIsLink; } +BOOL LLInvFVBridge::isLibraryItem() const +{ + return gInventory.isObjectDescendentOf(getUUID(),gInventory.getLibraryRootFolderID()); +} + /*virtual*/ /** * @brief Adds this item into clipboard storage */ -void LLInvFVBridge::cutToClipboard() +BOOL LLInvFVBridge::cutToClipboard() const +{ + const LLInventoryObject* obj = gInventory.getObject(mUUID); + if (obj && isItemMovable() && isItemRemovable()) + { + LLClipboard::instance().setCutMode(true); + return LLClipboard::instance().addToClipboard(mUUID); + } + return FALSE; +} + +BOOL LLInvFVBridge::copyToClipboard() const { - if(isItemMovable()) + const LLInventoryObject* obj = gInventory.getObject(mUUID); + if (obj && isItemCopyable()) { - LLInventoryClipboard::instance().cut(mUUID); + return LLClipboard::instance().addToClipboard(mUUID); } + return FALSE; } + // *TODO: make sure this does the right thing void LLInvFVBridge::showProperties() { @@ -217,7 +296,7 @@ void LLInvFVBridge::showProperties() */ } -void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) +void LLInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch) { // Deactivate gestures when moving them into Trash LLInvFVBridge* bridge; @@ -226,11 +305,11 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc LLViewerInventoryCategory* cat = NULL; LLInventoryModel::cat_array_t descendent_categories; LLInventoryModel::item_array_t descendent_items; - S32 count = batch.count(); + S32 count = batch.size(); S32 i,j; for(i = 0; i < count; ++i) { - bridge = (LLInvFVBridge*)(batch.get(i)); + bridge = (LLInvFVBridge*)(batch[i]); if(!bridge || !bridge->isItemRemovable()) continue; item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID()); if (item) @@ -243,7 +322,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc } for(i = 0; i < count; ++i) { - bridge = (LLInvFVBridge*)(batch.get(i)); + bridge = (LLInvFVBridge*)(batch[i]); if(!bridge || !bridge->isItemRemovable()) continue; cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID()); if (cat) @@ -261,7 +340,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc removeBatchNoCheck(batch); } -void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch) +void LLInvFVBridge::removeBatchNoCheck(std::vector<LLFolderViewModelItem*>& batch) { // this method moves a bunch of items and folders to the trash. As // per design guidelines for the inventory model, the message is @@ -277,14 +356,14 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener* uuid_vec_t move_ids; LLInventoryModel::update_map_t update; bool start_new_message = true; - S32 count = batch.count(); + S32 count = batch.size(); S32 i; // first, hide any 'preview' floaters that correspond to the items // being deleted. for(i = 0; i < count; ++i) { - bridge = (LLInvFVBridge*)(batch.get(i)); + bridge = (LLInvFVBridge*)(batch[i]); if(!bridge || !bridge->isItemRemovable()) continue; item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID()); if(item) @@ -297,7 +376,7 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener* for(i = 0; i < count; ++i) { - bridge = (LLInvFVBridge*)(batch.get(i)); + bridge = (LLInvFVBridge*)(batch[i]); if(!bridge || !bridge->isItemRemovable()) continue; item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID()); if(item) @@ -338,7 +417,7 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener* for(i = 0; i < count; ++i) { - bridge = (LLInvFVBridge*)(batch.get(i)); + bridge = (LLInvFVBridge*)(batch[i]); if(!bridge || !bridge->isItemRemovable()) continue; LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID()); if(cat) @@ -380,6 +459,11 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener* for(; it != end; ++it) { gInventory.moveObject((*it), trash_id); + LLViewerInventoryItem* item = gInventory.getItem(*it); + if (item) + { + model->updateItem(item); + } } // notify inventory observers. @@ -388,7 +472,8 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener* BOOL LLInvFVBridge::isClipboardPasteable() const { - if (!LLInventoryClipboard::instance().hasContents() || !isAgentInventory()) + // Return FALSE on degenerated cases: empty clipboard, no inventory, no agent + if (!LLClipboard::instance().hasContents() || !isAgentInventory()) { return FALSE; } @@ -398,29 +483,36 @@ BOOL LLInvFVBridge::isClipboardPasteable() const return FALSE; } - const LLUUID &agent_id = gAgent.getID(); + // In cut mode, whatever is on the clipboard is always pastable + if (LLClipboard::instance().isCutMode()) + { + return TRUE; + } + // In normal mode, we need to check each element of the clipboard to know if we can paste or not LLDynamicArray<LLUUID> objects; - LLInventoryClipboard::instance().retrieve(objects); + LLClipboard::instance().pasteFromClipboard(objects); S32 count = objects.count(); for(S32 i = 0; i < count; i++) { const LLUUID &item_id = objects.get(i); - // Can't paste folders + // Folders are pastable if all items in there are copyable const LLInventoryCategory *cat = model->getCategory(item_id); if (cat) { + LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, item_id); + if (!cat_br.isItemCopyable()) return FALSE; + // Skip to the next item in the clipboard + continue; } - const LLInventoryItem *item = model->getItem(item_id); - if (item) + // Each item must be copyable to be pastable + LLItemBridge item_br(mInventoryPanel.get(), mRoot, item_id); + if (!item_br.isItemCopyable()) { - if (!item->getPermissions().allowCopyBy(agent_id)) - { - return FALSE; - } + return FALSE; } } return TRUE; @@ -428,7 +520,7 @@ BOOL LLInvFVBridge::isClipboardPasteable() const BOOL LLInvFVBridge::isClipboardPasteableAsLink() const { - if (!LLInventoryClipboard::instance().hasContents() || !isAgentInventory()) + if (!LLClipboard::instance().hasContents() || !isAgentInventory()) { return FALSE; } @@ -439,7 +531,7 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const } LLDynamicArray<LLUUID> objects; - LLInventoryClipboard::instance().retrieve(objects); + LLClipboard::instance().pasteFromClipboard(objects); S32 count = objects.count(); for(S32 i = 0; i < count; i++) { @@ -462,14 +554,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 +576,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 +583,7 @@ void hide_context_entries(LLMenuGL& menu, if (*itor2 == name) { found = true; + break; } } @@ -500,9 +591,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 +602,7 @@ void hide_context_entries(LLMenuGL& menu, { menu_item->setVisible(FALSE); } + menu_item->setEnabled(FALSE); } else @@ -520,17 +611,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) + + bool enabled = (menu_item->getEnabled() == TRUE); + for (itor2 = disabled_entries.begin(); enabled && (itor2 != disabled_entries.end()); ++itor2) { - menu_item->setEnabled(TRUE); - } - for (itor2 = disabled_entries.begin(); itor2 != disabled_entries.end(); ++itor2) - { - if (*itor2 == name) - { - menu_item->setEnabled(FALSE); - } + enabled &= (*itor2 != name); } + + menu_item->setEnabled(enabled); } } } @@ -594,29 +682,26 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Copy")); } + items.push_back(std::string("Cut")); + if (!isItemMovable() || !isItemRemovable()) + { + disabled_items.push_back(std::string("Cut")); + } + if (canListOnMarketplace()) { 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 +742,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 +819,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 { @@ -776,10 +887,16 @@ LLInventoryObject* LLInvFVBridge::getInventoryObject() const LLInventoryModel* LLInvFVBridge::getInventoryModel() const { - LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); return panel ? panel->getModel() : NULL; } +LLInventoryFilter* LLInvFVBridge::getInventoryFilter() const +{ + LLInventoryPanel* panel = mInventoryPanel.get(); + return panel ? &(panel->getFilter()) : NULL; +} + BOOL LLInvFVBridge::isItemInTrash() const { LLInventoryModel* model = getInventoryModel(); @@ -832,7 +949,7 @@ BOOL LLInvFVBridge::isCOFFolder() const BOOL LLInvFVBridge::isInboxFolder() const { - const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false); + const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false); if (inbox_id.isNull()) { @@ -854,9 +971,25 @@ 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); + const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); return outbox_id; } @@ -872,7 +1005,7 @@ void LLInvFVBridge::changeItemParent(LLInventoryModel* model, const LLUUID& new_parent_id, BOOL restamp) { - change_item_parent(model, item, new_parent_id, restamp); + model->changeItemParent(item, new_parent_id, restamp); } // static @@ -881,13 +1014,14 @@ void LLInvFVBridge::changeCategoryParent(LLInventoryModel* model, const LLUUID& new_parent_id, BOOL restamp) { - change_category_parent(model, cat, new_parent_id, restamp); + model->changeCategoryParent(cat, new_parent_id, restamp); } LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, + LLFolderViewModelInventory* view_model, LLFolderView* root, const LLUUID& uuid, U32 flags) @@ -1040,93 +1174,161 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid) } } -BOOL LLInvFVBridge::canShare() const +bool LLInvFVBridge::canShare() const { - if (!isAgentInventory()) return FALSE; - - const LLInventoryModel* model = getInventoryModel(); - if (!model) return FALSE; + bool can_share = 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 = mInventoryPanel.get() ? mInventoryPanel.get()->getFolderByID(object_id) : NULL; + if (object_folderp) + { + can_list = !static_cast<LLFolderBridge*>(object_folderp->getViewModelItem())->isLoading(); + } + } + + if (can_list) + { + // Get outbox id + const LLUUID & outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + LLFolderViewItem * outbox_itemp = mInventoryPanel.get() ? mInventoryPanel.get()->getItemByID(outbox_id) : NULL; + + 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->getViewModelItem()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg); + } + } } + + return can_list; - return TRUE; #else - return FALSE; + return false; #endif } +LLToolDragAndDrop::ESource LLInvFVBridge::getDragSource() const +{ + if (gInventory.isObjectDescendentOf(getUUID(), gInventory.getRootFolderID())) + { + return LLToolDragAndDrop::SOURCE_AGENT; + } + else if (gInventory.isObjectDescendentOf(getUUID(), gInventory.getLibraryRootFolderID())) + { + return LLToolDragAndDrop::SOURCE_LIBRARY; + } + + return LLToolDragAndDrop::SOURCE_VIEWER; +} + + // +=================================================+ // | InventoryFVBridgeBuilder | // +=================================================+ -LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset_type, +LLInvFVBridge* LLInventoryFolderViewModelBuilder::createBridge(LLAssetType::EType asset_type, LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, + LLFolderViewModelInventory* view_model, LLFolderView* root, const LLUUID& uuid, U32 flags /* = 0x00 */) const @@ -1135,6 +1337,7 @@ LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset actual_asset_type, inv_type, inventory, + view_model, root, uuid, flags); @@ -1188,6 +1391,12 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(buffer)); return; } + else if ("cut" == action) + { + cutToClipboard(); + gInventory.removeObject(mUUID); + return; + } else if ("copy" == action) { copyToClipboard(); @@ -1195,14 +1404,13 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) } else if ("paste" == action) { - // Single item only LLInventoryItem* itemp = model->getItem(mUUID); if (!itemp) return; - LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID()); + LLFolderViewItem* folder_view_itemp = mInventoryPanel.get()->getItemByID(itemp->getParentUUID()); if (!folder_view_itemp) return; - folder_view_itemp->getListener()->pasteFromClipboard(); + folder_view_itemp->getViewModelItem()->pasteFromClipboard(); return; } else if ("paste_link" == action) @@ -1211,10 +1419,10 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) LLInventoryItem* itemp = model->getItem(mUUID); if (!itemp) return; - LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID()); + LLFolderViewItem* folder_view_itemp = mInventoryPanel.get()->getItemByID(itemp->getParentUUID()); if (!folder_view_itemp) return; - folder_view_itemp->getListener()->pasteLinkFromClipboard(); + folder_view_itemp->getViewModelItem()->pasteLinkFromClipboard(); return; } else if (isMarketplaceCopyAction(action)) @@ -1224,17 +1432,41 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) LLInventoryItem* itemp = model->getItem(mUUID); if (!itemp) return; - const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); - copy_item_to_outbox(itemp, outbox_id, LLUUID::null); + const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + copy_item_to_outbox(itemp, outbox_id, LLUUID::null, LLToolDragAndDrop::getOperationId()); + } + else if ("copy_slurl" == action) + { + LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(getItem()); + if(item) + { + LLUUID asset_id = item->getAssetUUID(); + LLLandmark* landmark = gLandmarkList.getAsset(asset_id); + if (landmark) + { + LLVector3d global_pos; + landmark->getGlobalPos(global_pos); + LLLandmarkActions::getSLURLfromPosGlobal(global_pos, ©_slurl_to_clipboard_callback_inv, true); + } + } } } +void copy_slurl_to_clipboard_callback_inv(const std::string& slurl) +{ + gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(slurl)); + LLSD args; + args["SLURL"] = slurl; + LLNotificationsUtil::add("CopySLURL", args); +} + void LLItemBridge::selectItem() { LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(getItem()); if(item && !item->isFinished()) { - item->fetchFromServer(); + //item->fetchFromServer(); + LLInventoryModelBackgroundFetch::instance().start(item->getUUID(), false); } } @@ -1316,6 +1548,15 @@ LLUIImagePtr LLItemBridge::getIcon() const return LLInventoryIcon::getIcon(LLInventoryIcon::ICONNAME_OBJECT); } +LLUIImagePtr LLItemBridge::getIconOverlay() const +{ + if (getItem() && getItem()->getIsLinkType()) + { + return LLUI::getUIImage("Inv_Link"); + } + return NULL; +} + PermissionMask LLItemBridge::getPermissionMask() const { LLViewerInventoryItem* item = getItem(); @@ -1324,26 +1565,27 @@ PermissionMask LLItemBridge::getPermissionMask() const return perm_mask; } -const std::string& LLItemBridge::getDisplayName() const +void LLItemBridge::buildDisplayName() const { - if(mDisplayName.empty()) + if(getItem()) { - buildDisplayName(getItem(), mDisplayName); + mDisplayName.assign(getItem()->getName()); } - return mDisplayName; + else + { + mDisplayName.assign(LLStringUtil::null); } -void LLItemBridge::buildDisplayName(LLInventoryItem* item, std::string& name) + mSearchableName.assign(mDisplayName); + mSearchableName.append(getLabelSuffix()); + LLStringUtil::toUpper(mSearchableName); + + //Name set, so trigger a sort + if(mParent) { - if(item) - { - name.assign(item->getName()); + mParent->requestSort(); } - else - { - name.assign(LLStringUtil::null); } -} LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const { @@ -1459,18 +1701,17 @@ BOOL LLItemBridge::renameItem(const std::string& new_name) { LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); new_item->rename(new_name); - buildDisplayName(new_item, mDisplayName); new_item->updateServer(FALSE); model->updateItem(new_item); model->notifyObservers(); + buildDisplayName(); } // return FALSE because we either notified observers (& therefore // rebuilt) or we didn't update. return FALSE; } - BOOL LLItemBridge::removeItem() { if(!isItemRemovable()) @@ -1478,7 +1719,6 @@ BOOL LLItemBridge::removeItem() return FALSE; } - // move it to the trash LLPreview::hide(mUUID, TRUE); LLInventoryModel* model = getInventoryModel(); @@ -1564,21 +1804,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 FALSE; -} - -BOOL LLItemBridge::copyToClipboard() const -{ - if(isItemCopyable()) - { - LLInventoryClipboard::instance().add(mUUID); - return TRUE; + return item->getPermissions().allowCopyBy(gAgent.getID()) || gSavedSettings.getBOOL("InventoryLinking"); } return FALSE; } @@ -1616,13 +1842,110 @@ BOOL LLFolderBridge::isItemMovable() const LLInventoryObject* obj = getInventoryObject(); if(obj) { - return (!LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)obj)->getPreferredType())); + // If it's a protected type folder, we can't move it + if (LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)obj)->getPreferredType())) + return FALSE; + return TRUE; } return FALSE; } void LLFolderBridge::selectItem() { + // Have no fear: the first thing start() does is to test if everything for that folder has been fetched... + LLInventoryModelBackgroundFetch::instance().start(getUUID(), true); +} + +void LLFolderBridge::buildDisplayName() const +{ + LLFolderType::EType preferred_type = getPreferredType(); + + // *TODO: to be removed when database supports multi language. This is a + // temporary attempt to display the inventory folder in the user locale. + // mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID + // it uses the same way to find localized string + + // HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder) + // Translation of Accessories folder in Library inventory folder + bool accessories = false; + if(getName() == "Accessories") + { + //To ensure that Accessories folder is in Library we have to check its parent folder. + //Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model + LLInventoryCategory* cat = gInventory.getCategory(getUUID()); + if(cat) + { + const LLUUID& parent_folder_id = cat->getParentUUID(); + accessories = (parent_folder_id == gInventory.getLibraryRootFolderID()); + } + } + + //"Accessories" inventory category has folder type FT_NONE. So, this folder + //can not be detected as protected with LLFolderType::lookupIsProtectedType + mDisplayName.assign(getName()); + if (accessories || LLFolderType::lookupIsProtectedType(preferred_type)) + { + LLTrans::findString(mDisplayName, std::string("InvFolder ") + getName(), LLSD()); + } + + mSearchableName.assign(mDisplayName); + mSearchableName.append(getLabelSuffix()); + LLStringUtil::toUpper(mSearchableName); + + //Name set, so trigger a sort + if(mParent) + { + mParent->requestSort(); + } +} + + +void LLFolderBridge::update() +{ + bool possibly_has_children = false; + bool up_to_date = isUpToDate(); + if(!up_to_date && hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter) + { + possibly_has_children = true; + } + + bool loading = (possibly_has_children + && !up_to_date ); + + if (loading != mIsLoading) + { + if ( loading && !mIsLoading ) + { + // Measure how long we've been in the loading state + mTimeSinceRequestStart.reset(); + } + + const BOOL in_inventory = gInventory.isObjectDescendentOf(getUUID(), gInventory.getRootFolderID()); + const BOOL in_library = gInventory.isObjectDescendentOf(getUUID(), gInventory.getLibraryRootFolderID()); + + bool root_is_loading = false; + if (in_inventory) + { + root_is_loading = LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress(); + } + if (in_library) + { + root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress(); + } + if ((mIsLoading + && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime")) + || (LLInventoryModelBackgroundFetch::instance().folderFetchActive() + && root_is_loading)) + { + mDisplayName = LLInvFVBridge::getDisplayName() + " ( " + LLTrans::getString("LoadingData") + " ) "; + mIsLoading = true; + } + else + { + mDisplayName = LLInvFVBridge::getDisplayName(); + mIsLoading = false; + } + } } @@ -1634,11 +1957,11 @@ public: LLIsItemRemovable() : mPassed(TRUE) {} virtual void doFolder(LLFolderViewFolder* folder) { - mPassed &= folder->getListener()->isItemRemovable(); + mPassed &= folder->getViewModelItem()->isItemRemovable(); } virtual void doItem(LLFolderViewItem* item) { - mPassed &= item->getListener()->isItemRemovable(); + mPassed &= item->getViewModelItem()->isItemRemovable(); } BOOL mPassed; }; @@ -1651,8 +1974,8 @@ BOOL LLFolderBridge::isItemRemovable() const return FALSE; } - LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); - LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL); + LLInventoryPanel* panel = mInventoryPanel.get(); + LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getItemByID(mUUID) : NULL); if (folderp) { LLIsItemRemovable folder_test; @@ -1681,23 +2004,35 @@ 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; + // Folders are copyable if items in them are, recursively, copyable. + + // Get the content of the folder + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(mUUID,cat_array,item_array); + + // Check the items + LLInventoryModel::item_array_t item_array_copy = *item_array; + for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++) + { + LLInventoryItem* item = *iter; + LLItemBridge item_br(mInventoryPanel.get(), mRoot, item->getUUID()); + if (!item_br.isItemCopyable()) + return FALSE; } -BOOL LLFolderBridge::copyToClipboard() const + // Check the folders + LLInventoryModel::cat_array_t cat_array_copy = *cat_array; + for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) { - if(isItemCopyable()) - { - LLInventoryClipboard::instance().add(mUUID); + LLViewerInventoryCategory* category = *iter; + LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, category->getUUID()); + if (!cat_br.isItemCopyable()) + return FALSE; + } + return TRUE; } - return FALSE; -} BOOL LLFolderBridge::isClipboardPasteable() const { @@ -1714,7 +2049,7 @@ BOOL LLFolderBridge::isClipboardPasteable() const } LLDynamicArray<LLUUID> objects; - LLInventoryClipboard::instance().retrieve(objects); + LLClipboard::instance().pasteFromClipboard(objects); const LLViewerInventoryCategory *current_cat = getCategory(); // Search for the direct descendent of current Friends subfolder among all pasted items, @@ -1752,7 +2087,7 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const const BOOL is_in_friend_folder = LLFriendCardsManager::instance().isCategoryInFriendFolder( current_cat ); const LLUUID ¤t_cat_id = current_cat->getUUID(); LLDynamicArray<LLUUID> objects; - LLInventoryClipboard::instance().retrieve(objects); + LLClipboard::instance().pasteFromClipboard(objects); S32 count = objects.count(); for(S32 i = 0; i < count; i++) { @@ -1787,30 +2122,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 +2211,84 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, if (!isAgentAvatarValid()) return FALSE; if (!isAgentInventory()) return FALSE; // cannot drag categories into library + LLInventoryPanel* destination_panel = mInventoryPanel.get(); + if (!destination_panel) return false; - // 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) - && (LLToolDragAndDrop::SOURCE_AGENT == source); + LLInventoryFilter* filter = getInventoryFilter(); + if (!filter) return false; + const LLUUID &cat_id = inv_cat->getUUID(); const LLUUID ¤t_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(cat_id) != NULL) + && (LLToolDragAndDrop::SOURCE_AGENT == source); 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; - if (move_is_into_outfit) + tooltip_msg = LLTrans::getString("TooltipDragOntoOwnChild"); + } + if (is_movable && LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType())) + { + is_movable = FALSE; + // 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 +2300,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 +2315,133 @@ 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)) + 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().getCargoCount(); + } + } + + // Tally the total number of categories and items inside the master folder + + LLInventoryModel::cat_array_t existing_categories; + LLInventoryModel::item_array_t existing_items; + + 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; - break; + } + + 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; + } + } } } + } - int nested_folder_levels = get_folder_path_length(outbox_id, mUUID) + get_folder_levels(inv_cat); + if (is_movable) + { + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + is_movable = active_panel != NULL; - if (nested_folder_levels > 4) + // For a folder to pass the filter all its descendants are required to pass. + // We make this exception to allow reordering folders within an inventory panel, + // which has a filter applied, like Recent tab for example. + // There may be folders which are displayed because some of their descendants pass + // the filter, but other don't, and thus remain hidden. Without this check, + // such folders would not be allowed to be moved within a panel. + if (destination_panel == active_panel) { - tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels"); - is_movable = FALSE; + is_movable = true; } - - } + else + { + LLFolderView* active_folder_view = NULL; + + if (is_movable) + { + active_folder_view = active_panel->getRootFolder(); + is_movable = active_folder_view != NULL; + } + if (is_movable) + { + // Check whether the folder being dragged from active inventory panel + // passes the filter of the destination panel. + is_movable = check_category(model, cat_id, active_panel, filter); + } + } + } // //-------------------------------------------------------------------------------- - 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 +2473,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 +2491,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 +2503,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))) { - 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 +2524,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, NULL, NULL, filter); + } } 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) { @@ -2089,7 +2576,8 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, const LLUUID& category_id, BOOL drop, void (*callback)(S32, void*), - void* user_data) + void* user_data, + LLInventoryFilter* filter) { // Make sure the object exists. If we allowed dragging from // anonymous objects, it would be possible to bypass @@ -2113,7 +2601,7 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, return FALSE; } - BOOL accept = TRUE; + BOOL accept = FALSE; BOOL is_move = FALSE; // coming from a task. Need to figure out if the person can @@ -2122,9 +2610,16 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, LLInventoryObject::object_list_t::iterator end = inventory_objects.end(); for ( ; it != end; ++it) { + LLInventoryItem* item = dynamic_cast<LLInventoryItem*>(it->get()); + if (!item) + { + llwarns << "Invalid inventory item for drop" << llendl; + continue; + } + // coming from a task. Need to figure out if the person can // move/copy this item. - LLPermissions perm(((LLInventoryItem*)((LLInventoryObject*)(*it)))->getPermissions()); + LLPermissions perm(item->getPermissions()); if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID()) && perm.allowTransferTo(gAgent.getID()))) // || gAgent.isGodlike()) @@ -2139,9 +2634,14 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, is_move = TRUE; accept = TRUE; } - else + + if (filter && accept) + { + accept = filter->check(item); + } + + if (!accept) { - accept = FALSE; break; } } @@ -2177,122 +2677,119 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, return accept; } -//Used by LLFolderBridge as callback for directory recursion. -class LLRightClickInventoryFetchObserver : public LLInventoryFetchItemsObserver -{ -public: - LLRightClickInventoryFetchObserver(const uuid_vec_t& ids) : - LLInventoryFetchItemsObserver(ids), - mCopyItems(false) - { }; - LLRightClickInventoryFetchObserver(const uuid_vec_t& ids, - const LLUUID& cat_id, - bool copy_items) : - LLInventoryFetchItemsObserver(ids), - mCatID(cat_id), - mCopyItems(copy_items) - { }; - virtual void done() - { - // we've downloaded all the items, so repaint the dialog - LLFolderBridge::staticFolderOptionsMenu(); - - gInventory.removeObserver(this); - delete this; - } - - -protected: - LLUUID mCatID; - bool mCopyItems; - -}; - -//Used by LLFolderBridge as callback for directory recursion. -class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver -{ -public: - LLRightClickInventoryFetchDescendentsObserver(const uuid_vec_t& ids, - bool copy_items) : - LLInventoryFetchDescendentsObserver(ids), - mCopyItems(copy_items) - {} - ~LLRightClickInventoryFetchDescendentsObserver() {} - virtual void done(); -protected: - bool mCopyItems; -}; - -void LLRightClickInventoryFetchDescendentsObserver::done() +void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer) { - // Avoid passing a NULL-ref as mCompleteFolders.front() down to - // gInventory.collectDescendents() + // Bail out immediately if no descendents if( mComplete.empty() ) { llwarns << "LLRightClickInventoryFetchDescendentsObserver::done with empty mCompleteFolders" << llendl; - dec_busy_count(); + if (clear_observer) + { gInventory.removeObserver(this); delete this; + } return; } - // What we do here is get the complete information on the items in - // the library, and set up an observer that will wait for that to - // happen. - LLInventoryModel::cat_array_t cat_array; - LLInventoryModel::item_array_t item_array; - gInventory.collectDescendents(mComplete.front(), - cat_array, - item_array, - LLInventoryModel::EXCLUDE_TRASH); - S32 count = item_array.count(); -#if 0 // HACK/TODO: Why? - // This early causes a giant menu to get produced, and doesn't seem to be needed. - if(!count) - { - llwarns << "Nothing fetched in category " << mCompleteFolders.front() - << llendl; - dec_busy_count(); + // Copy the list of complete fetched folders while "this" is still valid + uuid_vec_t completed_folder = mComplete; + + // Clean up, and remove this as an observer now since recursive calls + // could notify observers and throw us into an infinite loop. + if (clear_observer) + { gInventory.removeObserver(this); delete this; - return; } -#endif - uuid_vec_t ids; - for(S32 i = 0; i < count; ++i) + for (uuid_vec_t::iterator current_folder = completed_folder.begin(); current_folder != completed_folder.end(); ++current_folder) { - ids.push_back(item_array.get(i)->getUUID()); - } + // Get the information on the fetched folder items and subfolders and fetch those + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(*current_folder, cat_array, item_array); - LLRightClickInventoryFetchObserver* outfit = new LLRightClickInventoryFetchObserver(ids, mComplete.front(), mCopyItems); + S32 item_count(0); + if( item_array ) + { + item_count = item_array->count(); + } + + S32 cat_count(0); + if( cat_array ) + { + cat_count = cat_array->count(); + } - // clean up, and remove this as an observer since the call to the - // outfit could notify observers and throw us into an infinite - // loop. - dec_busy_count(); - gInventory.removeObserver(this); - delete this; + // Move to next if current folder empty + if ((item_count == 0) && (cat_count == 0)) + { + continue; + } - // increment busy count and either tell the inventory to check & - // call done, or add this object to the inventory for observation. - inc_busy_count(); + uuid_vec_t ids; + LLRightClickInventoryFetchObserver* outfit = NULL; + LLRightClickInventoryFetchDescendentsObserver* categories = NULL; - // do the fetch + // Fetch the items + if (item_count) + { + for (S32 i = 0; i < item_count; ++i) + { + ids.push_back(item_array->get(i)->getUUID()); + } + outfit = new LLRightClickInventoryFetchObserver(ids); + } + // Fetch the subfolders + if (cat_count) + { + for (S32 i = 0; i < cat_count; ++i) + { + ids.push_back(cat_array->get(i)->getUUID()); + } + categories = new LLRightClickInventoryFetchDescendentsObserver(ids); + } + + // Perform the item fetch + if (outfit) + { outfit->startFetch(); - outfit->done(); //Not interested in waiting and this will be right 99% of the time. + outfit->execute(); // Not interested in waiting and this will be right 99% of the time. + delete outfit; //Uncomment the following code for laggy Inventory UI. -/* if(outfit->isFinished()) + /* + if (outfit->isFinished()) { // everything is already here - call done. - outfit->done(); + outfit->execute(); + delete outfit; } else { - // it's all on it's way - add an observer, and the inventory + // it's all on its way - add an observer, and the inventory // will call done for us when everything is here. gInventory.addObserver(outfit); - }*/ + } + */ + } + // Perform the subfolders fetch : this is where we truly recurse down the folder hierarchy + if (categories) + { + categories->startFetch(); + if (categories->isFinished()) + { + // everything is already here - call done. + categories->execute(); + delete categories; + } + else + { + // it's all on its way - add an observer, and the inventory + // will call done for us when everything is here. + gInventory.addObserver(categories); + } + } + } } @@ -2305,15 +2802,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 +2838,6 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask) if (mFolderAdded) { LLViewerInventoryCategory* category = gInventory.getCategory(mCatID); - if (NULL == category) { llwarns << "gInventory.getCategory(" << mCatID @@ -2368,7 +2864,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) { if ("open" == action) { - LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder *>(mRoot->getItemByID(mUUID)); + LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder *>(mInventoryPanel.get()->getItemByID(mUUID)); if (f) { f->setOpen(TRUE); @@ -2412,6 +2908,12 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) modifyOutfit(TRUE); return; } + else if ("cut" == action) + { + cutToClipboard(); + gInventory.removeObject(mUUID); + return; + } else if ("copy" == action) { copyToClipboard(); @@ -2450,9 +2952,20 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) LLInventoryCategory * cat = gInventory.getCategory(mUUID); if (!cat) return; - const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); - copy_folder_to_outbox(cat, outbox_id, cat->getUUID()); + const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + 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() @@ -2535,17 +3048,24 @@ LLUIImagePtr LLFolderBridge::getIcon() const LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type) { return LLUI::getUIImage(LLViewerFolderType::lookupIconName(preferred_type, FALSE)); - /*case LLAssetType::AT_MESH: - control = "inv_folder_mesh.tga"; - break;*/ } -LLUIImagePtr LLFolderBridge::getOpenIcon() const +LLUIImagePtr LLFolderBridge::getIconOpen() const { return LLUI::getUIImage(LLViewerFolderType::lookupIconName(getPreferredType(), TRUE)); } +LLUIImagePtr LLFolderBridge::getIconOverlay() const +{ + if (getInventoryObject() && getInventoryObject()->getIsLinkType()) + { + return LLUI::getUIImage("Inv_Link"); + } + return NULL; +} + + BOOL LLFolderBridge::renameItem(const std::string& new_name) { rename_category(getInventoryModel(), mUUID, new_name); @@ -2603,32 +3123,90 @@ bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& re { // move it to the trash LLPreview::hide(mUUID); - remove_category(getInventoryModel(), mUUID); + getInventoryModel()->removeCategory(mUUID); return TRUE; } return FALSE; } +//Recursively update the folder's creation date +void LLFolderBridge::updateHierarchyCreationDate(time_t date) +{ + if(getCreationDate() < date) + { + setCreationDate(date); + if(mParent) + { + static_cast<LLFolderBridge *>(mParent)->updateHierarchyCreationDate(date); + } + } +} + void LLFolderBridge::pasteFromClipboard() { LLInventoryModel* model = getInventoryModel(); if(model && isClipboardPasteable()) { const LLUUID ¤t_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_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); + const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); + + LLDynamicArray<LLUUID> objects; + LLClipboard::instance().pasteFromClipboard(objects); + + if (move_is_into_outbox) + { + LLFolderViewItem * outbox_itemp = mInventoryPanel.get()->getItemByID(mUUID); + + if (outbox_itemp) + { + LLToolDragAndDrop::instance().setCargoCount(objects.size()); + + BOOL can_list = TRUE; + + for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin(); + (iter != objects.end()) && (can_list == TRUE); + ++iter) + { + const LLUUID& item_id = (*iter); + LLInventoryItem *item = model->getItem(item_id); + + if (item) + { + MASK mask = 0x0; + BOOL drop = FALSE; + EDragAndDropType cargo_type = LLViewerAssetType::lookupDragAndDropType(item->getActualType()); + void * cargo_data = (void *) item; + std::string tooltip_msg; + + can_list = outbox_itemp->getViewModelItem()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg); + } + } + + LLToolDragAndDrop::instance().resetCargoCount(); + + if (can_list == FALSE) + { + // Notify user of failure somehow -- play error sound? modal dialog? + return; + } + } + } const LLUUID parent_id(mUUID); - LLDynamicArray<LLUUID> objects; - LLInventoryClipboard::instance().retrieve(objects); for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin(); iter != objects.end(); ++iter) { const LLUUID& item_id = (*iter); + LLInventoryItem *item = model->getItem(item_id); - if (item) + LLInventoryObject *obj = model->getObject(item_id); + if (obj) { if (move_is_into_current_outfit || move_is_into_outfit) { @@ -2637,17 +3215,43 @@ void LLFolderBridge::pasteFromClipboard() dropToOutfit(item, move_is_into_current_outfit); } } - else if(LLInventoryClipboard::instance().isCutMode()) + else if (LLClipboard::instance().isCutMode()) + { + // Do a move to "paste" a "cut" + // move_inventory_item() is not enough, as we have to update inventory locally too + if (LLAssetType::AT_CATEGORY == obj->getType()) + { + LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id); + llassert(vicat); + if (vicat) + { + //changeCategoryParent() implicity calls dirtyFilter + changeCategoryParent(model, vicat, parent_id, FALSE); + } + } + else { - // move_inventory_item() is not enough, - //we have to update inventory locally too LLViewerInventoryItem* viitem = dynamic_cast<LLViewerInventoryItem*>(item); llassert(viitem); if (viitem) { + //changeItemParent() implicity calls dirtyFilter changeItemParent(model, viitem, parent_id, FALSE); } } + } + else + { + // Do a "copy" to "paste" a regular copy clipboard + if (LLAssetType::AT_CATEGORY == obj->getType()) + { + LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id); + llassert(vicat); + if (vicat) + { + copy_inventory_category(model, vicat, parent_id); + } + } else { copy_inventory_item( @@ -2661,6 +3265,9 @@ void LLFolderBridge::pasteFromClipboard() } } } + // Change mode to paste for next paste + LLClipboard::instance().setCutMode(false); + } } void LLFolderBridge::pasteLinkFromClipboard() @@ -2669,13 +3276,22 @@ void LLFolderBridge::pasteLinkFromClipboard() if(model) { const LLUUID ¤t_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_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); + const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); + + if (move_is_into_outbox) + { + // Notify user of failure somehow -- play error sound? modal dialog? + return; + } const LLUUID parent_id(mUUID); LLDynamicArray<LLUUID> objects; - LLInventoryClipboard::instance().retrieve(objects); + LLClipboard::instance().pasteFromClipboard(objects); for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin(); iter != objects.end(); ++iter) @@ -2713,109 +3329,18 @@ void LLFolderBridge::pasteLinkFromClipboard() LLPointer<LLInventoryCallback>(NULL)); } } + // Change mode to paste for next paste + LLClipboard::instance().setCutMode(false); } } 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,95 +3356,92 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv return ((item_array.count() > 0) ? TRUE : FALSE ); } -// Flags unused -void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items) { - 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); + const LLUUID favorites = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE); if (lost_and_found_id == mUUID) { // This is the lost+found folder. - mItems.push_back(std::string("Empty Lost And Found")); + items.push_back(std::string("Empty Lost And Found")); - mDisabledItems.push_back(std::string("New Folder")); - mDisabledItems.push_back(std::string("New Script")); - mDisabledItems.push_back(std::string("New Note")); - mDisabledItems.push_back(std::string("New Gesture")); - mDisabledItems.push_back(std::string("New Clothes")); - mDisabledItems.push_back(std::string("New Body Parts")); + disabled_items.push_back(std::string("New Folder")); + disabled_items.push_back(std::string("New Script")); + disabled_items.push_back(std::string("New Note")); + disabled_items.push_back(std::string("New Gesture")); + disabled_items.push_back(std::string("New Clothes")); + disabled_items.push_back(std::string("New Body Parts")); + } + if (favorites == mUUID) + { + disabled_items.push_back(std::string("New Folder")); } - - // clear out old menu and folder pointers - mMenu.markDead(); - sSelf.markDead(); - if(trash_id == mUUID) { // This is the trash. - mItems.push_back(std::string("Empty Trash")); + items.push_back(std::string("Empty Trash")); } else if(isItemInTrash()) { // This is a folder in the trash. - mItems.clear(); // clear any items that used to exist - addTrashContextMenuOptions(mItems, mDisabledItems); + items.clear(); // clear any items that used to exist + addTrashContextMenuOptions(items, disabled_items); } else if(isOutboxFolder()) { - mItems.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, items, disabled_items); } 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")); - mItems.push_back(std::string("New Clothes")); - mItems.push_back(std::string("New Body Parts")); + { + items.push_back(std::string("New Folder")); + } + + items.push_back(std::string("New Script")); + items.push_back(std::string("New Note")); + items.push_back(std::string("New Gesture")); + items.push_back(std::string("New Clothes")); + items.push_back(std::string("New Body Parts")); } #if SUPPORT_ENSEMBLES // Changing folder types is an unfinished unsupported feature // and can lead to unexpected behavior if enabled. - mItems.push_back(std::string("Change Type")); + items.push_back(std::string("Change Type")); const LLViewerInventoryCategory *cat = getCategory(); if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType())) { - mDisabledItems.push_back(std::string("Change Type")); + disabled_items.push_back(std::string("Change Type")); } #endif - getClipboardEntries(false, mItems, mDisabledItems, flags); + getClipboardEntries(false, items, disabled_items, flags); } else { // Want some but not all of the items from getClipboardEntries for outfits. if (cat && (cat->getPreferredType() == LLFolderType::FT_OUTFIT)) { - mItems.push_back(std::string("Rename")); + items.push_back(std::string("Rename")); - addDeleteContextMenuOptions(mItems, mDisabledItems); + addDeleteContextMenuOptions(items, disabled_items); // EXT-4030: disallow deletion of currently worn outfit const LLViewerInventoryItem *base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink(); if (base_outfit_link && (cat == base_outfit_link->getLinkedCategory())) { - mDisabledItems.push_back(std::string("Delete")); + disabled_items.push_back(std::string("Delete")); } } } @@ -2948,46 +3470,155 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) // Preemptively disable system folder removal if more than one item selected. if ((flags & FIRST_SELECTED_ITEM) == 0) { - mDisabledItems.push_back(std::string("Delete System Folder")); + disabled_items.push_back(std::string("Delete System Folder")); } if (!isOutboxFolder()) { - mItems.push_back(std::string("Share")); + items.push_back(std::string("Share")); if (!canShare()) { - mDisabledItems.push_back(std::string("Share")); + disabled_items.push_back(std::string("Share")); } } - - hide_context_entries(menu, mItems, mDisabledItems); - // Add menu items that are dependent on the contents of the folder. - uuid_vec_t folders; - LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID); + LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID); if (category) { + uuid_vec_t folders; folders.push_back(category->getUUID()); + + sSelf = getHandle(); + LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders); + fetch->startFetch(); + if (fetch->isFinished()) + { + // Do not call execute() or done() here as if the folder is here, there's likely no point drilling down + // This saves lots of time as buildContextMenu() is called a lot + delete fetch; + buildContextMenuFolderOptions(flags, items, disabled_items); + } + 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); } +} +} - mMenu = menu.getHandle(); - sSelf = getHandle(); - LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE); - fetch->startFetch(); - inc_busy_count(); - if(fetch->isFinished()) +void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items) +{ + // Build folder specific options back up + 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)) + { + items.push_back(std::string("Calling Card Separator")); + items.push_back(std::string("Conference Chat Folder")); + items.push_back(std::string("IM All Contacts In Folder")); + } + } + + if (!isItemRemovable()) { - // everything is already here - call done. - fetch->done(); + disabled_items.push_back(std::string("Delete")); } - else + +#ifndef LL_RELEASE_FOR_DOWNLOAD + if (LLFolderType::lookupIsProtectedType(type)) { - // it's all on its way - add an observer, and the inventory will call done for us when everything is here. - gInventory.addObserver(fetch); + items.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) ) + { + items.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) + { + items.push_back(std::string("Add To Outfit")); + } + + items.push_back(std::string("Replace Outfit")); + } + if (is_ensemble) + { + items.push_back(std::string("Wear As Ensemble")); + } + items.push_back(std::string("Remove From Outfit")); + if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID)) + { + disabled_items.push_back(std::string("Remove From Outfit")); + } + if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID)) + { + disabled_items.push_back(std::string("Replace Outfit")); + } + items.push_back(std::string("Outfit Separator")); } } -BOOL LLFolderBridge::hasChildren() const +// Flags unused +void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + sSelf.markDead(); + + // fetch contents of this folder, as context menu can depend on contents + // still, user would have to open context menu again to see the changes + gInventory.fetchDescendentsOf(getUUID()); + + + menuentry_vec_t items; + menuentry_vec_t disabled_items; + + lldebugs << "LLFolderBridge::buildContextMenu()" << llendl; + + LLInventoryModel* model = getInventoryModel(); + if(!model) return; + + buildContextMenuOptions(flags, items, disabled_items); + hide_context_entries(menu, items, disabled_items); + + // Reposition the menu, in case we're adding items to an existing menu. + menu.needsArrange(); + menu.arrangeAndClear(); +} + +bool LLFolderBridge::hasChildren() const { LLInventoryModel* model = getInventoryModel(); if(!model) return FALSE; @@ -3077,25 +3708,6 @@ void LLFolderBridge::pasteClipboard(void* user_data) if(self) self->pasteFromClipboard(); } -void LLFolderBridge::createNewCategory(void* user_data) -{ - LLFolderBridge* bridge = (LLFolderBridge*)user_data; - if(!bridge) return; - LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(bridge->mInventoryPanel.get()); - if (!panel) return; - LLInventoryModel* model = panel->getModel(); - if(!model) return; - LLUUID id; - id = model->createNewCategory(bridge->getUUID(), - LLFolderType::FT_NONE, - LLStringUtil::null); - model->notifyObservers(); - - // At this point, the bridge has probably been deleted, but the - // view is still there. - panel->setSelection(id, TAKE_FOCUS_YES); -} - void LLFolderBridge::createNewShirt(void* user_data) { LLFolderBridge::createWearable((LLFolderBridge*)user_data, LLWearableType::WT_SHIRT); @@ -3161,6 +3773,24 @@ void LLFolderBridge::createNewEyes(void* user_data) LLFolderBridge::createWearable((LLFolderBridge*)user_data, LLWearableType::WT_EYES); } +EInventorySortGroup LLFolderBridge::getSortGroup() const +{ + LLFolderType::EType preferred_type = getPreferredType(); + + if (preferred_type == LLFolderType::FT_TRASH) + { + return SG_TRASH_FOLDER; + } + + if(LLFolderType::lookupIsProtectedType(preferred_type)) + { + return SG_SYSTEM_FOLDER; + } + + return SG_NORMAL_FOLDER; +} + + // static void LLFolderBridge::createWearable(LLFolderBridge* bridge, LLWearableType::EType type) { @@ -3188,13 +3818,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); } @@ -3261,11 +3891,12 @@ void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item) // use callback to rearrange favorite landmarks after adding // to have new one placed before target (on which it was dropped). See EXT-4312. LLPointer<AddFavoriteLandmarkCallback> cb = new AddFavoriteLandmarkCallback(); - LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL; - if (drag_over_item && drag_over_item->getListener()) + LLFolderViewModelItemInventory* view_model = drag_over_item ? static_cast<LLFolderViewModelItemInventory*>(drag_over_item->getViewModelItem()) : NULL; + if (view_model) { - cb.get()->setTargetLandmarkId(drag_over_item->getListener()->getUUID()); + cb.get()->setTargetLandmarkId(view_model->getUUID()); } copy_inventory_item( @@ -3307,10 +3938,16 @@ 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; + LLInventoryPanel* destination_panel = mInventoryPanel.get(); + if (!destination_panel) return false; + + LLInventoryFilter* filter = getInventoryFilter(); + if (!filter) return false; + const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false); const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); @@ -3320,7 +3957,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, const BOOL move_is_into_favorites = (mUUID == favorites_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); //(mUUID == outbox_id); + const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); const BOOL move_is_from_outbox = model->isObjectDescendentOf(inv_item->getUUID(), outbox_id); LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); @@ -3376,10 +4013,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 +4031,44 @@ 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().getCargoCount(); + + 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; + } + } + } + + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + + // Check whether the item being dragged from active inventory panel + // passes the filter of the destination panel. + if (accept && active_panel) + { + LLFolderViewItem* fv_item = active_panel->getItemByID(inv_item->getUUID()); + if (!fv_item) return false; + + accept = filter->check(fv_item->getViewModelItem()); } - if(accept && drop) + if (accept && drop) { if (inv_item->getType() == LLAssetType::AT_GESTURE && LLGestureMgr::instance().isGestureActive(inv_item->getUUID()) && move_is_into_trash) @@ -3401,15 +4077,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } // If an item is being dragged between windows, unselect everything in the active window // so that we don't follow the selection to its new location (which is very annoying). - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (active_panel) - { - LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); - if (active_panel && (panel != active_panel)) + // RN: a better solution would be to deselect automatically when an item is moved + // and then select any item that is dropped only in the panel that it is dropped in + if (active_panel && (destination_panel != active_panel)) { active_panel->unSelectAll(); } - } //-------------------------------------------------------------------------------- // Destination folder logic @@ -3419,13 +4092,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // (only reorder the item in Favorites folder) if ((mUUID == inv_item->getParentUUID()) && move_is_into_favorites) { - LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); - LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL; + LLFolderViewItem* itemp = destination_panel->getRootFolder()->getDraggingOverItem(); if (itemp) { LLUUID srcItemId = inv_item->getUUID(); - LLUUID destItemId = itemp->getListener()->getUUID(); - gInventory.rearrangeFavoriteLandmarks(srcItemId, destItemId); + LLUUID destItemId = static_cast<LLFolderViewModelItemInventory*>(itemp->getViewModelItem())->getUUID(); + LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(srcItemId, destItemId); } } @@ -3441,16 +4113,23 @@ 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) else { // set up observer to select item once drag and drop from inbox is complete - if (gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false))) + if (gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false))) { set_dad_inbox_object(inv_item->getUUID()); } @@ -3464,7 +4143,6 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // //-------------------------------------------------------------------------------- - } } else if (LLToolDragAndDrop::SOURCE_WORLD == source) @@ -3473,7 +4151,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 +4161,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 +4179,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 +4190,20 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { accept = FALSE; } + else if (move_is_into_outbox) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + + // Check whether the item being dragged from in world + // passes the filter of the destination panel. + if (accept) + { + accept = filter->check(inv_item); + } - if(drop && accept) + if (accept && drop) { LLMoveInv* move_inv = new LLMoveInv; move_inv->mObjectID = inv_item->getParentUUID(); @@ -3536,15 +4225,29 @@ 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 (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); + } + + // Check whether the item being dragged from notecard + // passes the filter of the destination panel. + if (accept) + { + accept = filter->check(inv_item); + } - if(accept && drop) + if (accept && drop) { copy_inventory_from_notecard(mUUID, // Drop to the chosen destination folder LLToolDragAndDrop::getInstance()->getObjectID(), @@ -3559,7 +4262,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); } @@ -3570,6 +4278,18 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, accept = can_move_to_landmarks(inv_item); } + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + + // Check whether the item being dragged from the library + // passes the filter of the destination panel. + if (accept && active_panel) + { + LLFolderViewItem* fv_item = active_panel->getItemByID(inv_item->getUUID()); + if (!fv_item) return false; + + accept = filter->check(fv_item->getViewModelItem()); + } + if (accept && drop) { // FAVORITES folder @@ -3604,6 +4324,69 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, return accept; } +// static +bool check_category(LLInventoryModel* model, + const LLUUID& cat_id, + LLInventoryPanel* active_panel, + LLInventoryFilter* filter) +{ + if (!model || !active_panel || !filter) + return false; + + if (!filter->checkFolder(cat_id)) + { + return false; + } + + LLInventoryModel::cat_array_t descendent_categories; + LLInventoryModel::item_array_t descendent_items; + model->collectDescendents(cat_id, descendent_categories, descendent_items, TRUE); + + S32 num_descendent_categories = descendent_categories.count(); + S32 num_descendent_items = descendent_items.count(); + + if (num_descendent_categories + num_descendent_items == 0) + { + // Empty folder should be checked as any other folder view item. + // If we are filtering by date the folder should not pass because + // it doesn't have its own creation date. See LLInvFVBridge::getCreationDate(). + return check_item(cat_id, active_panel, filter); + } + + for (S32 i = 0; i < num_descendent_categories; ++i) + { + LLInventoryCategory* category = descendent_categories[i]; + if(!check_category(model, category->getUUID(), active_panel, filter)) + { + return false; + } + } + + for (S32 i = 0; i < num_descendent_items; ++i) + { + LLViewerInventoryItem* item = descendent_items[i]; + if(!check_item(item->getUUID(), active_panel, filter)) + { + return false; + } + } + + return true; +} + +// static +bool check_item(const LLUUID& item_id, + LLInventoryPanel* active_panel, + LLInventoryFilter* filter) +{ + if (!active_panel || !filter) return false; + + LLFolderViewItem* fv_item = active_panel->getItemByID(item_id); + if (!fv_item) return false; + + return filter->check(fv_item->getViewModelItem()); +} + // +=================================================+ // | LLTextureBridge | // +=================================================+ @@ -3650,7 +4433,7 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else if(isOutboxFolder()) { - items.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, items, disabled_items); } else { @@ -3703,15 +4486,6 @@ void LLSoundBridge::openItem() } } -void LLSoundBridge::previewItem() -{ - LLViewerInventoryItem* item = getItem(); - if(item) - { - send_sound_trigger(item->getAssetUUID(), 1.0); - } -} - void LLSoundBridge::openSoundPreview(void* which) { LLSoundBridge *me = (LLSoundBridge *)which; @@ -3724,29 +4498,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,30 +4556,31 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) menuentry_vec_t disabled_items; lldebugs << "LLLandmarkBridge::buildContextMenu()" << llendl; - if(isItemInTrash()) + if(isOutboxFolder()) { - addTrashContextMenuOptions(items, disabled_items); - } - else 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("url_copy")); items.push_back(std::string("About Landmark")); } @@ -3814,6 +4589,7 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) // info panel can be shown at a time. if ((flags & FIRST_SELECTED_ITEM) == 0) { + disabled_items.push_back(std::string("url_copy")); disabled_items.push_back(std::string("About Landmark")); } @@ -3926,8 +4702,8 @@ LLCallingCardBridge::~LLCallingCardBridge() void LLCallingCardBridge::refreshFolderViewItem() { - LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); - LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL; + LLInventoryPanel* panel = mInventoryPanel.get(); + LLFolderViewItem* itemp = panel ? panel->getItemByID(mUUID) : NULL; if (itemp) { itemp->refresh(); @@ -3943,19 +4719,16 @@ void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string act if (item && (item->getCreatorUUID() != gAgent.getID()) && (!item->getCreatorUUID().isNull())) { - std::string callingcard_name; - gCacheName->getFullName(item->getCreatorUUID(), callingcard_name); - // IDEVO + std::string callingcard_name = LLCacheName::getDefaultName(); LLAvatarName av_name; - if (LLAvatarNameCache::useDisplayNames() - && LLAvatarNameCache::get(item->getCreatorUUID(), &av_name)) + if (LLAvatarNameCache::get(item->getCreatorUUID(), &av_name)) { - callingcard_name = av_name.mDisplayName + " (" + av_name.mUsername + ")"; + callingcard_name = av_name.getCompleteName(); } LLUUID session_id = gIMMgr->addSession(callingcard_name, IM_NOTHING_SPECIAL, item->getCreatorUUID()); if (session_id != LLUUID::null) { - LLIMFloater::show(session_id); + LLFloaterIMContainer::getInstance()->showConversation(session_id); } } } @@ -4033,6 +4806,10 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { disabled_items.push_back(std::string("Share")); } + if ((flags & FIRST_SELECTED_ITEM) == 0) + { + disabled_items.push_back(std::string("Open")); + } addOpenRightClickMenuOption(items); items.push_back(std::string("Properties")); @@ -4337,36 +5114,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 @@ -4376,14 +5152,14 @@ void LLAnimationBridge::performAction(LLInventoryModel* model, std::string actio { if (getItem()) { - LLPreviewAnim::e_activation_type activate = LLPreviewAnim::NONE; - if ("playworld" == action) activate = LLPreviewAnim::PLAY; - if ("playlocal" == action) activate = LLPreviewAnim::AUDITION; + LLSD::String activate = "NONE"; + if ("playworld" == action) activate = "Inworld"; + if ("playlocal" == action) activate = "Locally"; LLPreviewAnim* preview = LLFloaterReg::showTypedInstance<LLPreviewAnim>("preview_anim", LLSD(mUUID)); if (preview) { - preview->activate(activate); + preview->play(activate); } } } @@ -4698,6 +5474,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) p.on_enable.parameter = cbparams; LLView* parent = attachment->getIsHUDAttachment() ? attach_hud_menu : attach_menu; LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent); + items.push_back(p.name); } } } @@ -4719,11 +5496,10 @@ BOOL LLObjectBridge::renameItem(const std::string& new_name) { LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); new_item->rename(new_name); - buildDisplayName(new_item, mDisplayName); new_item->updateServer(FALSE); model->updateItem(new_item); - model->notifyObservers(); + buildDisplayName(); if (isAgentAvatarValid()) { @@ -5000,7 +5776,8 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Wearable Edit")); - if ((flags & FIRST_SELECTED_ITEM) == 0) + bool modifiable = !gAgentWearables.isWearableModifiable(item->getUUID()); + if (((flags & FIRST_SELECTED_ITEM) == 0) || modifiable) { disabled_items.push_back(std::string("Wearable Edit")); } @@ -5323,16 +6100,6 @@ void LLMeshBridge::openItem() } } -void LLMeshBridge::previewItem() -{ - LLViewerInventoryItem* item = getItem(); - if(item) - { - // preview mesh - } -} - - void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { lldebugs << "LLMeshBridge::buildContextMenu()" << llendl; @@ -5351,7 +6118,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 +6127,6 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) getClipboardEntries(true, items, disabled_items, flags); } - hide_context_entries(menu, items, disabled_items); } @@ -5422,14 +6188,15 @@ void LLLinkFolderBridge::gotoItem() const LLUUID &cat_uuid = getFolderID(); if (!cat_uuid.isNull()) { - if (LLFolderViewItem *base_folder = mRoot->getItemByID(cat_uuid)) + LLFolderViewItem *base_folder = mInventoryPanel.get()->getItemByID(cat_uuid); + if (base_folder) { if (LLInventoryModel* model = getInventoryModel()) { model->fetchDescendentsOf(cat_uuid); } base_folder->setOpen(TRUE); - mRoot->setSelectionFromRoot(base_folder,TRUE); + mRoot->setSelection(base_folder,TRUE); mRoot->scrollToShowSelection(); } } @@ -5760,9 +6527,8 @@ LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_ /************************************************************************/ void LLRecentItemsFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { - LLFolderBridge::buildContextMenu(menu, flags); - - menuentry_vec_t disabled_items, items = getMenuItems(); + menuentry_vec_t disabled_items, items; + buildContextMenuOptions(flags, items, disabled_items); items.erase(std::remove(items.begin(), items.end(), std::string("New Folder")), items.end()); @@ -5774,42 +6540,29 @@ LLInvFVBridge* LLRecentInventoryBridgeBuilder::createBridge( LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, + LLFolderViewModelInventory* view_model, LLFolderView* root, const LLUUID& uuid, U32 flags /*= 0x00*/ ) const { LLInvFVBridge* new_listener = NULL; - switch(asset_type) + if (asset_type == LLAssetType::AT_CATEGORY + && actual_asset_type != LLAssetType::AT_LINK_FOLDER) { - case LLAssetType::AT_CATEGORY: - if (actual_asset_type == LLAssetType::AT_LINK_FOLDER) + new_listener = new LLRecentItemsFolderBridge(inv_type, inventory, root, uuid); + } + else { - // *TODO: Create a link folder handler instead if it is necessary - new_listener = LLInventoryFVBridgeBuilder::createBridge( - asset_type, + new_listener = LLInventoryFolderViewModelBuilder::createBridge(asset_type, actual_asset_type, inv_type, inventory, + view_model, root, uuid, flags); - break; } - new_listener = new LLRecentItemsFolderBridge(inv_type, inventory, root, uuid); - break; - default: - new_listener = LLInventoryFVBridgeBuilder::createBridge( - asset_type, - actual_asset_type, - inv_type, - inventory, - root, - uuid, - flags); - } return new_listener; - } - // EOF diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 2d625befb4..5c6cf0f0f0 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -29,18 +29,21 @@ #include "llcallingcard.h" #include "llfloaterproperties.h" -#include "llfoldervieweventlistener.h" +#include "llfolderviewmodel.h" #include "llinventorymodel.h" #include "llinventoryobserver.h" +#include "llinventorypanel.h" #include "llviewercontrol.h" #include "llwearable.h" +#include "lltooldraganddrop.h" +class LLInventoryFilter; class LLInventoryPanel; class LLInventoryModel; class LLMenuGL; class LLCallingCardObserver; class LLViewerJointAttachment; - +class LLFolderView; typedef std::vector<std::string> menuentry_vec_t; @@ -55,7 +58,7 @@ typedef std::vector<std::string> menuentry_vec_t; // functionality a bit. (except for folders, you can create those // manually...) //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLInvFVBridge : public LLFolderViewEventListener +class LLInvFVBridge : public LLFolderViewModelItemInventory { public: // This method is a convenience function which creates the correct @@ -64,36 +67,39 @@ public: LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, + LLFolderViewModelInventory* view_model, LLFolderView* root, const LLUUID& uuid, 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 //-------------------------------------------------------------------- virtual const LLUUID& getUUID() const { return mUUID; } - virtual void clearDisplayName() {} + virtual void clearDisplayName() { mDisplayName.clear(); } virtual void restoreItem() {} virtual void restoreToWorld() {} //-------------------------------------------------------------------- - // Inherited LLFolderViewEventListener functions + // Inherited LLFolderViewModelItemInventory functions //-------------------------------------------------------------------- virtual const std::string& getName() const; virtual const std::string& getDisplayName() const; + const std::string& getSearchableName() const { return mSearchableName; } + virtual PermissionMask getPermissionMask() const; virtual LLFolderType::EType getPreferredType() const; virtual time_t getCreationDate() const; + virtual void setCreationDate(time_t creation_date_utc); virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; } virtual std::string getLabelSuffix() const { return LLStringUtil::null; } virtual void openItem() {} virtual void closeItem() {} - virtual void previewItem() {openItem();} virtual void showProperties(); virtual BOOL isItemRenameable() const { return TRUE; } //virtual BOOL renameItem(const std::string& new_name) {} @@ -101,12 +107,13 @@ public: virtual BOOL isItemMovable() const; virtual BOOL isItemInTrash() const; virtual BOOL isLink() const; + virtual BOOL isLibraryItem() const; //virtual BOOL removeItem() = 0; - virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch); - virtual void move(LLFolderViewEventListener* new_parent_bridge) {} + virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch); + virtual void move(LLFolderViewModelItem* new_parent_bridge) {} virtual BOOL isItemCopyable() const { return FALSE; } - virtual BOOL copyToClipboard() const { return FALSE; } - virtual void cutToClipboard(); + virtual BOOL copyToClipboard() const; + virtual BOOL cutToClipboard() const; virtual BOOL isClipboardPasteable() const; virtual BOOL isClipboardPasteableAsLink() const; virtual void pasteFromClipboard() {} @@ -114,6 +121,7 @@ public: void getClipboardEntries(bool show_asset_id, menuentry_vec_t &items, menuentry_vec_t &disabled_items, U32 flags); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); + virtual LLToolDragAndDrop::ESource getDragSource() const; virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const; virtual BOOL dragOrDrop(MASK mask, BOOL drop, EDragAndDropType cargo_type, @@ -121,6 +129,9 @@ public: std::string& tooltip_msg) { return FALSE; } virtual LLInventoryType::EType getInventoryType() const { return mInvType; } virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; } + EInventorySortGroup getSortGroup() const { return SG_ITEM; } + virtual LLInventoryObject* getInventoryObject() const; + //-------------------------------------------------------------------- // Convenience functions for adding various common menu options. @@ -131,19 +142,23 @@ 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); - LLInventoryObject* getInventoryObject() const; LLInventoryModel* getInventoryModel() const; + LLInventoryFilter* getInventoryFilter() const; BOOL isLinkedObjectInTrash() const; // Is this obj or its baseobj in the trash? BOOL isLinkedObjectMissing() const; // Is this a linked obj whose baseobj is not in inventory? BOOL isAgentInventory() const; // false if lost or in the inventory library - 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 isCOFFolder() const; // true if COF or descendant of + BOOL isInboxFolder() const; // true if COF or descendant of marketplace inbox + BOOL isOutboxFolder() const; // true if COF or descendant of marketplace outbox + BOOL isOutboxFolderDirectParent() const; const LLUUID getOutboxFolder() const; virtual BOOL isItemPermissive() const; @@ -155,30 +170,36 @@ protected: LLViewerInventoryCategory* item, const LLUUID& new_parent, BOOL restamp); - void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch); + void removeBatchNoCheck(std::vector<LLFolderViewModelItem*>& batch); protected: - LLHandle<LLPanel> mInventoryPanel; + LLHandle<LLInventoryPanel> mInventoryPanel; LLFolderView* mRoot; const LLUUID mUUID; // item id LLInventoryType::EType mInvType; - BOOL mIsLink; + bool mIsLink; + LLTimer mTimeSinceRequestStart; + mutable std::string mDisplayName; + mutable std::string mSearchableName; + void purgeItem(LLInventoryModel *model, const LLUUID &uuid); + virtual void buildDisplayName() const {} }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLInvFVBridgeBuilder +// Class LLInventoryFolderViewModelBuilder // -// This class intended to build Folder View Bridge via LLInvFVBridge::createBridge. -// It can be overridden with another way of creation necessary Inventory-Folder-View-Bridge. +// This class intended to build Folder View Model via LLInvFVBridge::createBridge. +// It can be overridden with another way of creation necessary Inventory Folder View Models. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLInventoryFVBridgeBuilder +class LLInventoryFolderViewModelBuilder { public: - virtual ~LLInventoryFVBridgeBuilder() {} + virtual ~LLInventoryFolderViewModelBuilder() {} virtual LLInvFVBridge* createBridge(LLAssetType::EType asset_type, LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, + LLFolderViewModelInventory* view_model, LLFolderView* root, const LLUUID& uuid, U32 flags = 0x00) const; @@ -192,13 +213,14 @@ public: const LLUUID& uuid) : LLInvFVBridge(inventory, root, uuid) {} + typedef boost::function<void(std::string& slurl)> slurl_callback_t; + virtual void performAction(LLInventoryModel* model, std::string action); virtual void selectItem(); virtual void restoreItem(); virtual void restoreToWorld(); virtual void gotoItem(); virtual LLUIImagePtr getIcon() const; - virtual const std::string& getDisplayName() const; virtual std::string getLabelSuffix() const; virtual LLFontGL::StyleFlags getLabelStyle() const; virtual PermissionMask getPermissionMask() const; @@ -207,20 +229,17 @@ public: virtual BOOL renameItem(const std::string& new_name); virtual BOOL removeItem(); virtual BOOL isItemCopyable() const; - virtual BOOL copyToClipboard() const; - virtual BOOL hasChildren() const { return FALSE; } + virtual bool hasChildren() const { return FALSE; } virtual BOOL isUpToDate() const { return TRUE; } - - /*virtual*/ void clearDisplayName() { mDisplayName.clear(); } + virtual LLUIImagePtr getIconOverlay() const; LLViewerInventoryItem* getItem() const; protected: BOOL confirmRemoveItem(const LLSD& notification, const LLSD& response); virtual BOOL isItemPermissive() const; - static void buildDisplayName(LLInventoryItem* item, std::string& name); + virtual void buildDisplayName() const; - mutable std::string mDisplayName; }; class LLFolderBridge : public LLInvFVBridge @@ -228,15 +247,18 @@ class LLFolderBridge : public LLInvFVBridge public: LLFolderBridge(LLInventoryPanel* inventory, LLFolderView* root, - const LLUUID& uuid) : - LLInvFVBridge(inventory, root, uuid), + const LLUUID& uuid) + : LLInvFVBridge(inventory, root, uuid), mCallingCards(FALSE), - mWearables(FALSE) + mWearables(FALSE), + mIsLoading(false) {} BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg); BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg); + virtual void buildDisplayName() const; + virtual void performAction(LLInventoryModel* model, std::string action); virtual void openItem(); virtual void closeItem(); @@ -246,7 +268,9 @@ public: virtual LLFolderType::EType getPreferredType() const; virtual LLUIImagePtr getIcon() const; - virtual LLUIImagePtr getOpenIcon() const; + virtual LLUIImagePtr getIconOpen() const; + virtual LLUIImagePtr getIconOverlay() const; + static LLUIImagePtr getIcon(LLFolderType::EType preferred_type); virtual BOOL renameItem(const std::string& new_name); @@ -254,11 +278,12 @@ public: virtual BOOL removeItem(); BOOL removeSystemFolder(); bool removeItemResponse(const LLSD& notification, const LLSD& response); + void updateHierarchyCreationDate(time_t date); virtual void pasteFromClipboard(); virtual void pasteLinkFromClipboard(); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); - virtual BOOL hasChildren() const; + virtual bool hasChildren() const; virtual BOOL dragOrDrop(MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, @@ -270,19 +295,25 @@ public: virtual BOOL isItemCopyable() const; virtual BOOL isClipboardPasteable() const; virtual BOOL isClipboardPasteableAsLink() const; - virtual BOOL copyToClipboard() const; + EInventorySortGroup getSortGroup() const; + virtual void update(); + static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type); LLViewerInventoryCategory* getCategory() const; LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; } + bool isLoading() { return mIsLoading; } + protected: + void buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items); + void buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items); + //-------------------------------------------------------------------- // Menu callbacks //-------------------------------------------------------------------- static void pasteClipboard(void* user_data); - static void createNewCategory(void* user_data); static void createNewShirt(void* user_data); static void createNewPants(void* user_data); static void createNewShoes(void* user_data); @@ -302,12 +333,8 @@ protected: void modifyOutfit(BOOL append); void determineFolderType(); - menuentry_vec_t getMenuItems() { return mItems; } // returns a copy of current menu items - 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,14 +342,13 @@ 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; + + bool mCallingCards; + bool mWearables; + bool mIsLoading; + LLTimer mTimeSinceRequestStart; LLRootHandle<LLFolderBridge> mHandle; }; @@ -352,7 +378,6 @@ public: const LLUUID& uuid) : LLItemBridge(inventory, root, uuid) {} virtual void openItem(); - virtual void previewItem(); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); static void openSoundPreview(void*); }; @@ -542,7 +567,6 @@ class LLMeshBridge : public LLItemBridge public: virtual LLUIImagePtr getIcon() const; virtual void openItem(); - virtual void previewItem(); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); protected: @@ -618,7 +642,7 @@ public: }; // Bridge builder to create Inventory-Folder-View-Bridge for Recent Inventory Panel -class LLRecentInventoryBridgeBuilder : public LLInventoryFVBridgeBuilder +class LLRecentInventoryBridgeBuilder : public LLInventoryFolderViewModelBuilder { public: // Overrides FolderBridge for Recent Inventory Panel. @@ -627,6 +651,7 @@ public: LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, + LLFolderViewModelInventory* view_model, LLFolderView* root, const LLUUID& uuid, U32 flags = 0x00) const; @@ -642,7 +667,8 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, const LLUUID& category_id, BOOL drop, void (*callback)(S32, void*) = NULL, - void* user_data = NULL); + void* user_data = NULL, + LLInventoryFilter* filter = NULL); // Utility function to hide all entries except those in the list // Can be called multiple times on the same menu (e.g. if multiple items @@ -650,7 +676,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/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 516b47e616..92f2d33073 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -29,113 +29,144 @@ #include "llinventoryfilter.h" // viewer includes -#include "llfoldervieweventlistener.h" +#include "llfolderviewmodel.h" #include "llfolderviewitem.h" #include "llinventorymodel.h" #include "llinventorymodelbackgroundfetch.h" #include "llviewercontrol.h" #include "llfolderview.h" #include "llinventorybridge.h" +#include "llviewerfoldertype.h" // linden library includes +#include "llclipboard.h" #include "lltrans.h" -LLInventoryFilter::FilterOps::FilterOps() : - mFilterObjectTypes(0xffffffffffffffffULL), - mFilterCategoryTypes(0xffffffffffffffffULL), - mFilterWearableTypes(0xffffffffffffffffULL), - mMinDate(time_min()), - mMaxDate(time_max()), - mHoursAgo(0), - mShowFolderState(SHOW_NON_EMPTY_FOLDERS), - mPermissions(PERM_NONE), - mFilterTypes(FILTERTYPE_OBJECT), - mFilterUUID(LLUUID::null), - mFilterLinks(FILTERLINK_INCLUDE_LINKS) +LLFastTimer::DeclareTimer FT_FILTER_CLIPBOARD("Filter Clipboard"); + +LLInventoryFilter::FilterOps::FilterOps(const Params& p) +: mFilterObjectTypes(p.object_types), + mFilterCategoryTypes(p.category_types), + mFilterWearableTypes(p.wearable_types), + mMinDate(p.date_range.min_date), + mMaxDate(p.date_range.max_date), + mHoursAgo(p.hours_ago), + mShowFolderState(p.show_folder_state), + mPermissions(p.permissions), + mFilterTypes(p.types), + mFilterUUID(p.uuid), + mFilterLinks(p.links) { } ///---------------------------------------------------------------------------- /// Class LLInventoryFilter ///---------------------------------------------------------------------------- -LLInventoryFilter::LLInventoryFilter(const std::string& name) -: mName(name), - mModified(FALSE), - mNeedTextRebuild(TRUE), - mEmptyLookupMessage("InventoryNoMatchingItems") +LLInventoryFilter::LLInventoryFilter(const Params& p) +: mName(p.name), + mFilterModified(FILTER_NONE), + mEmptyLookupMessage("InventoryNoMatchingItems"), + mFilterOps(p.filter_ops), + mFilterSubString(p.substring), + mCurrentGeneration(0), + mFirstRequiredGeneration(0), + mFirstSuccessGeneration(0), + mFilterCount(0) { - mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately - - mSubStringMatchOffset = 0; - mFilterSubString.clear(); - mFilterGeneration = 0; - mMustPassGeneration = S32_MAX; - mMinRequiredGeneration = 0; - mFilterCount = 0; - mNextFilterGeneration = mFilterGeneration + 1; - - mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff"); - mFilterBehavior = FILTER_NONE; + mNextFilterGeneration = mCurrentGeneration + 1; // copy mFilterOps into mDefaultFilterOps markDefault(); } -LLInventoryFilter::~LLInventoryFilter() +bool LLInventoryFilter::check(const LLFolderViewModelItem* item) { -} + const LLFolderViewModelItemInventory* listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item); + // Clipboard cut items are *always* filtered so we need this value upfront + const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE); -BOOL LLInventoryFilter::check(const LLFolderViewItem* item) -{ - // If it's a folder and we're showing all folders, return TRUE automatically. - const BOOL is_folder = (dynamic_cast<const LLFolderViewFolder*>(item) != NULL); + // If it's a folder and we're showing all folders, return automatically. + const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY; if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)) { - return TRUE; + return passed_clipboard; } - mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos; + std::string::size_type string_offset = mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) : std::string::npos; - const BOOL passed_filtertype = checkAgainstFilterType(item); - const BOOL passed_permissions = checkAgainstPermissions(item); - const BOOL passed_filterlink = checkAgainstFilterLinks(item); - const BOOL passed = (passed_filtertype && - passed_permissions && - passed_filterlink && - (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos)); + BOOL passed = (mFilterSubString.size() == 0 || string_offset != std::string::npos); + passed = passed && checkAgainstFilterType(listener); + passed = passed && checkAgainstPermissions(listener); + passed = passed && checkAgainstFilterLinks(listener); + passed = passed && passed_clipboard; return passed; } -bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) +bool LLInventoryFilter::check(const LLInventoryItem* item) { - // we're showing all folders, overriding filter - if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS) + std::string::size_type string_offset = mFilterSubString.size() ? item->getName().find(mFilterSubString) : std::string::npos; + + const bool passed_filtertype = checkAgainstFilterType(item); + const bool passed_permissions = checkAgainstPermissions(item); + const BOOL passed_clipboard = checkAgainstClipboard(item->getUUID()); + const bool passed = (passed_filtertype + && passed_permissions + && passed_clipboard + && (mFilterSubString.size() == 0 || string_offset != std::string::npos)); + + return passed; +} + +bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const +{ + const LLFolderViewModelItemInventory* listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item); + if (!listener) { - return true; + llerrs << "Folder view event listener not found." << llendl; + return false; } - const LLFolderViewEventListener* listener = folder->getListener(); const LLUUID folder_id = listener->getUUID(); + return checkFolder(folder_id); +} + +bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const +{ + // when applying a filter, matching folders get their contents downloaded first + if (isNotDefault() + && !gInventory.isCategoryComplete(folder_id)) + { + LLInventoryModelBackgroundFetch::instance().start(folder_id); + } + + // Always check against the clipboard + const BOOL passed_clipboard = checkAgainstClipboard(folder_id); + + // we're showing all folders, overriding filter + if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS) + { + return passed_clipboard; + } + if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY) { // Can only filter categories for items in your inventory // (e.g. versus in-world object contents). const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id); if (!cat) - return false; + return folder_id.isNull(); LLFolderType::EType cat_type = cat->getPreferredType(); if (cat_type != LLFolderType::FT_NONE && (1LL << cat_type & mFilterOps.mFilterCategoryTypes) == U64(0)) return false; } - return true; + return passed_clipboard; } -BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const +bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInventory* listener) const { - const LLFolderViewEventListener* listener = item->getListener(); if (!listener) return FALSE; LLInventoryType::EType object_type = listener->getInventoryType(); @@ -206,16 +237,107 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con } } + //////////////////////////////////////////////////////////////////////////////// + // FILTERTYPE_EMPTYFOLDERS + // Pass if this item is a folder and is not a system folder that should be hidden + if (filterTypes & FILTERTYPE_EMPTYFOLDERS) + { + if (object_type == LLInventoryType::IT_CATEGORY) + { + bool is_hidden_if_empty = LLViewerFolderType::lookupIsHiddenIfEmpty(listener->getPreferredType()); + if (is_hidden_if_empty) + { + // Force the fetching of those folders so they are hidden iff they really are empty... + gInventory.fetchDescendentsOf(object_id); + return FALSE; + } + } + } + return TRUE; } -BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const +bool LLInventoryFilter::checkAgainstFilterType(const LLInventoryItem* item) const +{ + LLInventoryType::EType object_type = item->getInventoryType(); + const LLUUID object_id = item->getUUID(); + + const U32 filterTypes = mFilterOps.mFilterTypes; + + //////////////////////////////////////////////////////////////////////////////// + // FILTERTYPE_OBJECT + // Pass if this item's type is of the correct filter type + if (filterTypes & FILTERTYPE_OBJECT) + { + // If it has no type, pass it, unless it's a link. + if (object_type == LLInventoryType::IT_NONE) + { + if (item && item->getIsLinkType()) + { + return false; + } + } + else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0)) + { + return false; + } + } + + //////////////////////////////////////////////////////////////////////////////// + // FILTERTYPE_UUID + // Pass if this item is the target UUID or if it links to the target UUID + if (filterTypes & FILTERTYPE_UUID) + { + if (!item) return false; + + if (item->getLinkedUUID() != mFilterOps.mFilterUUID) + return false; + } + + //////////////////////////////////////////////////////////////////////////////// + // FILTERTYPE_DATE + // Pass if this item is within the date range. + if (filterTypes & FILTERTYPE_DATE) + { + // We don't get the updated item creation date for the task inventory or + // a notecard embedded item. See LLTaskInvFVBridge::getCreationDate(). + return false; + } + + return true; +} + +// Items and folders that are on the clipboard or, recursively, in a folder which +// is on the clipboard must be filtered out if the clipboard is in the "cut" mode. +bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const +{ + if (LLClipboard::instance().isCutMode()) + { + LLFastTimer ft(FT_FILTER_CLIPBOARD); + LLUUID current_id = object_id; + LLInventoryObject *current_object = gInventory.getObject(object_id); + while (current_id.notNull() && current_object) + { + if (LLClipboard::instance().isOnClipboard(current_id)) + { + return false; + } + current_id = current_object->getParentUUID(); + if (current_id.notNull()) + { + current_object = gInventory.getObject(current_id); + } + } + } + return true; +} + +bool LLInventoryFilter::checkAgainstPermissions(const LLFolderViewModelItemInventory* listener) const { - const LLFolderViewEventListener* listener = item->getListener(); if (!listener) return FALSE; PermissionMask perm = listener->getPermissionMask(); - const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(item->getListener()); + const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(listener); if (bridge && bridge->isLink()) { const LLUUID& linked_uuid = gInventory.getLinkedItemID(bridge->getUUID()); @@ -226,9 +348,19 @@ BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) co return (perm & mFilterOps.mPermissions) == mFilterOps.mPermissions; } -BOOL LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const +bool LLInventoryFilter::checkAgainstPermissions(const LLInventoryItem* item) const +{ + if (!item) return false; + + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); + PermissionMask perm = new_item->getPermissionMask(); + new_item = NULL; + + return (perm & mFilterOps.mPermissions) == mFilterOps.mPermissions; +} + +bool LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewModelItemInventory* listener) const { - const LLFolderViewEventListener* listener = item->getListener(); if (!listener) return TRUE; const LLUUID object_id = listener->getUUID(); @@ -248,15 +380,20 @@ const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const return mFilterSubString; } -std::string::size_type LLInventoryFilter::getStringMatchOffset() const +std::string::size_type LLInventoryFilter::getStringMatchOffset(LLFolderViewModelItem* item) const { - return mSubStringMatchOffset; + return mFilterSubString.size() ? item->getSearchableName().find(mFilterSubString) : std::string::npos; +} + +bool LLInventoryFilter::isDefault() const +{ + return !isNotDefault(); } // has user modified default filter params? -BOOL LLInventoryFilter::isNotDefault() const +bool LLInventoryFilter::isNotDefault() const { - BOOL not_default = FALSE; + S32 not_default = 0; not_default |= (mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes); not_default |= (mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes); @@ -269,10 +406,10 @@ BOOL LLInventoryFilter::isNotDefault() const not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate); not_default |= (mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo); - return not_default; + return not_default != 0; } -BOOL LLInventoryFilter::isActive() const +bool LLInventoryFilter::isActive() const { return mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL || mFilterOps.mFilterCategoryTypes != 0xffffffffffffffffULL @@ -286,16 +423,9 @@ BOOL LLInventoryFilter::isActive() const || mFilterOps.mHoursAgo != 0; } -BOOL LLInventoryFilter::isModified() const -{ - return mModified; -} - -BOOL LLInventoryFilter::isModifiedAndClear() +bool LLInventoryFilter::isModified() const { - BOOL ret = mModified; - mModified = FALSE; - return ret; + return mFilterModified != FILTER_NONE; } void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types) @@ -343,6 +473,11 @@ void LLInventoryFilter::setFilterWearableTypes(U64 types) mFilterOps.mFilterTypes |= FILTERTYPE_WEARABLE; } +void LLInventoryFilter::setFilterEmptySystemFolders() +{ + mFilterOps.mFilterTypes |= FILTERTYPE_EMPTYFOLDERS; +} + void LLInventoryFilter::setFilterUUID(const LLUUID& object_id) { if (mFilterOps.mFilterUUID == LLUUID::null) @@ -441,35 +576,53 @@ void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date) mFilterOps.mMaxDate = llmax(mFilterOps.mMinDate, max_date); setModified(); } - mFilterOps.mFilterTypes |= FILTERTYPE_DATE; + + if (areDateLimitsSet()) + { + mFilterOps.mFilterTypes |= FILTERTYPE_DATE; + } + else + { + mFilterOps.mFilterTypes &= ~FILTERTYPE_DATE; + } } void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl) { + static LLCachedControl<U32> s_last_logoff(gSavedPerAccountSettings, "LastLogoff", 0); if (sl && !isSinceLogoff()) { - setDateRange(mLastLogoff, time_max()); + setDateRange(s_last_logoff(), time_max()); setModified(); } if (!sl && isSinceLogoff()) { - setDateRange(0, time_max()); + setDateRange(time_min(), time_max()); setModified(); } - mFilterOps.mFilterTypes |= FILTERTYPE_DATE; + + if (areDateLimitsSet()) + { + mFilterOps.mFilterTypes |= FILTERTYPE_DATE; + } + else + { + mFilterOps.mFilterTypes &= ~FILTERTYPE_DATE; + } } -BOOL LLInventoryFilter::isSinceLogoff() const +bool LLInventoryFilter::isSinceLogoff() const { - return (mFilterOps.mMinDate == (time_t)mLastLogoff) && + static LLCachedControl<U32> s_last_logoff(gSavedSettings, "LastLogoff", 0); + + return (mFilterOps.mMinDate == (time_t)s_last_logoff()) && (mFilterOps.mMaxDate == time_max()) && (mFilterOps.mFilterTypes & FILTERTYPE_DATE); } void LLInventoryFilter::clearModified() { - mModified = FALSE; - mFilterBehavior = FILTER_NONE; + mFilterModified = FILTER_NONE; } void LLInventoryFilter::setHoursAgo(U32 hours) @@ -479,7 +632,7 @@ void LLInventoryFilter::setHoursAgo(U32 hours) bool are_date_limits_valid = mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max(); bool is_increasing = hours > mFilterOps.mHoursAgo; - bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo; + bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo && !isSinceLogoff(); // *NOTE: need to cache last filter time, in case filter goes stale BOOL less_restrictive = (are_date_limits_valid && ((is_increasing && mFilterOps.mHoursAgo)) || !hours); @@ -501,7 +654,15 @@ void LLInventoryFilter::setHoursAgo(U32 hours) setModified(FILTER_RESTART); } } - mFilterOps.mFilterTypes |= FILTERTYPE_DATE; + + if (areDateLimitsSet()) + { + mFilterOps.mFilterTypes |= FILTERTYPE_DATE; + } + else + { + mFilterOps.mFilterTypes &= ~FILTERTYPE_DATE; + } } void LLInventoryFilter::setFilterLinks(U64 filter_links) @@ -539,15 +700,6 @@ void LLInventoryFilter::setShowFolderState(EFolderShow state) } } -void LLInventoryFilter::setSortOrder(U32 order) -{ - if (mOrder != order) - { - mOrder = order; - setModified(); - } -} - void LLInventoryFilter::markDefault() { mDefaultFilterOps = mFilterOps; @@ -559,83 +711,68 @@ void LLInventoryFilter::resetDefault() setModified(); } -void LLInventoryFilter::setModified(EFilterBehavior behavior) +void LLInventoryFilter::setModified(EFilterModified behavior) { - mModified = TRUE; - mNeedTextRebuild = TRUE; - mFilterGeneration = mNextFilterGeneration++; + mFilterText.clear(); + mCurrentGeneration = mNextFilterGeneration++; - if (mFilterBehavior == FILTER_NONE) + if (mFilterModified == FILTER_NONE) { - mFilterBehavior = behavior; + mFilterModified = behavior; } - else if (mFilterBehavior != behavior) + else if (mFilterModified != behavior) { // trying to do both less restrictive and more restrictive filter // basically means restart from scratch - mFilterBehavior = FILTER_RESTART; + mFilterModified = FILTER_RESTART; } - if (isNotDefault()) + // if not keeping current filter results, update last valid as well + switch(mFilterModified) { - // if not keeping current filter results, update last valid as well - switch(mFilterBehavior) - { - case FILTER_RESTART: - mMustPassGeneration = mFilterGeneration; - mMinRequiredGeneration = mFilterGeneration; - break; - case FILTER_LESS_RESTRICTIVE: - mMustPassGeneration = mFilterGeneration; - break; - case FILTER_MORE_RESTRICTIVE: - mMinRequiredGeneration = mFilterGeneration; - // must have passed either current filter generation (meaningless, as it hasn't been run yet) - // or some older generation, so keep the value - mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration); - break; - default: - llerrs << "Bad filter behavior specified" << llendl; - } - } - else - { - // shortcut disabled filters to show everything immediately - mMinRequiredGeneration = 0; - mMustPassGeneration = S32_MAX; + case FILTER_RESTART: + mFirstRequiredGeneration = mCurrentGeneration; + mFirstSuccessGeneration = mCurrentGeneration; + break; + case FILTER_LESS_RESTRICTIVE: + mFirstRequiredGeneration = mCurrentGeneration; + break; + case FILTER_MORE_RESTRICTIVE: + mFirstSuccessGeneration = mCurrentGeneration; + break; + default: + llerrs << "Bad filter behavior specified" << llendl; } } -BOOL LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const +bool LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const { return mFilterOps.mFilterObjectTypes & (1LL << t); } const std::string& LLInventoryFilter::getFilterText() { - if (!mNeedTextRebuild) + if (!mFilterText.empty()) { return mFilterText; } - mNeedTextRebuild = FALSE; std::string filtered_types; std::string not_filtered_types; BOOL filtered_by_type = FALSE; BOOL filtered_by_all_types = TRUE; S32 num_filter_types = 0; + mFilterText.clear(); if (isFilterObjectTypesWith(LLInventoryType::IT_ANIMATION)) { - //filtered_types += " Animations,"; filtered_types += LLTrans::getString("Animations"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Animations,"; not_filtered_types += LLTrans::getString("Animations"); filtered_by_all_types = FALSE; @@ -643,145 +780,125 @@ const std::string& LLInventoryFilter::getFilterText() if (isFilterObjectTypesWith(LLInventoryType::IT_CALLINGCARD)) { - //filtered_types += " Calling Cards,"; filtered_types += LLTrans::getString("Calling Cards"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Calling Cards,"; not_filtered_types += LLTrans::getString("Calling Cards"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_WEARABLE)) { - //filtered_types += " Clothing,"; filtered_types += LLTrans::getString("Clothing"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Clothing,"; not_filtered_types += LLTrans::getString("Clothing"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_GESTURE)) { - //filtered_types += " Gestures,"; filtered_types += LLTrans::getString("Gestures"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Gestures,"; not_filtered_types += LLTrans::getString("Gestures"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_LANDMARK)) { - //filtered_types += " Landmarks,"; filtered_types += LLTrans::getString("Landmarks"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Landmarks,"; not_filtered_types += LLTrans::getString("Landmarks"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD)) { - //filtered_types += " Notecards,"; filtered_types += LLTrans::getString("Notecards"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Notecards,"; not_filtered_types += LLTrans::getString("Notecards"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_OBJECT) && isFilterObjectTypesWith(LLInventoryType::IT_ATTACHMENT)) { - //filtered_types += " Objects,"; filtered_types += LLTrans::getString("Objects"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Objects,"; not_filtered_types += LLTrans::getString("Objects"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_LSL)) { - //filtered_types += " Scripts,"; filtered_types += LLTrans::getString("Scripts"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Scripts,"; not_filtered_types += LLTrans::getString("Scripts"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_SOUND)) { - //filtered_types += " Sounds,"; filtered_types += LLTrans::getString("Sounds"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Sounds,"; not_filtered_types += LLTrans::getString("Sounds"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_TEXTURE)) { - //filtered_types += " Textures,"; filtered_types += LLTrans::getString("Textures"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Textures,"; not_filtered_types += LLTrans::getString("Textures"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_SNAPSHOT)) { - //filtered_types += " Snapshots,"; filtered_types += LLTrans::getString("Snapshots"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Snapshots,"; not_filtered_types += LLTrans::getString("Snapshots"); filtered_by_all_types = FALSE; } - if (!LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() + if (!LLInventoryModelBackgroundFetch::instance().folderFetchActive() && filtered_by_type && !filtered_by_all_types) { @@ -792,7 +909,6 @@ const std::string& LLInventoryFilter::getFilterText() } else { - //mFilterText += "No "; mFilterText += LLTrans::getString("No Filters"); mFilterText += not_filtered_types; } @@ -802,66 +918,55 @@ const std::string& LLInventoryFilter::getFilterText() if (isSinceLogoff()) { - //mFilterText += " - Since Logoff"; mFilterText += LLTrans::getString("Since Logoff"); } return mFilterText; } -void LLInventoryFilter::toLLSD(LLSD& data) const -{ - data["filter_types"] = (LLSD::Integer)getFilterObjectTypes(); - data["min_date"] = (LLSD::Integer)getMinDate(); - data["max_date"] = (LLSD::Integer)getMaxDate(); - data["hours_ago"] = (LLSD::Integer)getHoursAgo(); - data["show_folder_state"] = (LLSD::Integer)getShowFolderState(); - data["permissions"] = (LLSD::Integer)getFilterPermissions(); - data["substring"] = (LLSD::String)getFilterSubString(); - data["sort_order"] = (LLSD::Integer)getSortOrder(); - data["since_logoff"] = (LLSD::Boolean)isSinceLogoff(); -} -void LLInventoryFilter::fromLLSD(LLSD& data) +LLInventoryFilter& LLInventoryFilter::operator=( const LLInventoryFilter& other ) { - if(data.has("filter_types")) - { - setFilterObjectTypes((U32)data["filter_types"].asInteger()); - } - - if(data.has("min_date") && data.has("max_date")) - { - setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger()); - } - - if(data.has("hours_ago")) - { - setHoursAgo((U32)data["hours_ago"].asInteger()); - } - - if(data.has("show_folder_state")) - { - setShowFolderState((EFolderShow)data["show_folder_state"].asInteger()); - } + setFilterObjectTypes(other.getFilterObjectTypes()); + setDateRange(other.getMinDate(), other.getMaxDate()); + setHoursAgo(other.getHoursAgo()); + setShowFolderState(other.getShowFolderState()); + setFilterPermissions(other.getFilterPermissions()); + setFilterSubString(other.getFilterSubString()); + setDateRangeLastLogoff(other.isSinceLogoff()); + return *this; +} - if(data.has("permissions")) - { - setFilterPermissions((PermissionMask)data["permissions"].asInteger()); - } - if(data.has("substring")) - { - setFilterSubString(std::string(data["substring"].asString())); - } +void LLInventoryFilter::toParams(Params& params) const +{ + params.filter_ops.types = getFilterObjectTypes(); + params.filter_ops.category_types = getFilterCategoryTypes(); + params.filter_ops.wearable_types = getFilterWearableTypes(); + params.filter_ops.date_range.min_date = getMinDate(); + params.filter_ops.date_range.max_date = getMaxDate(); + params.filter_ops.hours_ago = getHoursAgo(); + params.filter_ops.show_folder_state = getShowFolderState(); + params.filter_ops.permissions = getFilterPermissions(); + params.substring = getFilterSubString(); + params.since_logoff = isSinceLogoff(); +} - if(data.has("sort_order")) +void LLInventoryFilter::fromParams(const Params& params) +{ + if (!params.validateBlock()) { - setSortOrder((U32)data["sort_order"].asInteger()); + return; } - if(data.has("since_logoff")) - { - setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean()); - } + setFilterObjectTypes(params.filter_ops.types); + setFilterCategoryTypes(params.filter_ops.category_types); + setFilterWearableTypes(params.filter_ops.wearable_types); + setDateRange(params.filter_ops.date_range.min_date, params.filter_ops.date_range.max_date); + setHoursAgo(params.filter_ops.hours_ago); + setShowFolderState(params.filter_ops.show_folder_state); + setFilterPermissions(params.filter_ops.permissions); + setFilterSubString(params.substring); + setDateRangeLastLogoff(params.since_logoff); } U64 LLInventoryFilter::getFilterObjectTypes() const @@ -874,11 +979,21 @@ U64 LLInventoryFilter::getFilterCategoryTypes() const return mFilterOps.mFilterCategoryTypes; } -BOOL LLInventoryFilter::hasFilterString() const +U64 LLInventoryFilter::getFilterWearableTypes() const +{ + return mFilterOps.mFilterWearableTypes; +} + +bool LLInventoryFilter::hasFilterString() const { return mFilterSubString.size() > 0; } +std::string::size_type LLInventoryFilter::getFilterStringSize() const +{ + return mFilterSubString.size(); +} + PermissionMask LLInventoryFilter::getFilterPermissions() const { return mFilterOps.mPermissions; @@ -905,14 +1020,6 @@ LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const { return mFilterOps.mShowFolderState; } -U32 LLInventoryFilter::getSortOrder() const -{ - return mOrder; -} -const std::string& LLInventoryFilter::getName() const -{ - return mName; -} void LLInventoryFilter::setFilterCount(S32 count) { @@ -930,15 +1037,15 @@ void LLInventoryFilter::decrementFilterCount() S32 LLInventoryFilter::getCurrentGeneration() const { - return mFilterGeneration; + return mCurrentGeneration; } -S32 LLInventoryFilter::getMinRequiredGeneration() const +S32 LLInventoryFilter::getFirstSuccessGeneration() const { - return mMinRequiredGeneration; + return mFirstSuccessGeneration; } -S32 LLInventoryFilter::getMustPassGeneration() const +S32 LLInventoryFilter::getFirstRequiredGeneration() const { - return mMustPassGeneration; + return mFirstRequiredGeneration; } void LLInventoryFilter::setEmptyLookupMessage(const std::string& message) @@ -946,8 +1053,42 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message) mEmptyLookupMessage = message; } -const std::string& LLInventoryFilter::getEmptyLookupMessage() const +std::string LLInventoryFilter::getEmptyLookupMessage() const +{ + LLStringUtil::format_map_t args; + args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig()); + + return LLTrans::getString(mEmptyLookupMessage, args); + +} + +bool LLInventoryFilter::areDateLimitsSet() { - return mEmptyLookupMessage; + return mFilterOps.mMinDate != time_min() + || mFilterOps.mMaxDate != time_max() + || mFilterOps.mHoursAgo != 0; +} +bool LLInventoryFilter::showAllResults() const +{ + return hasFilterString(); +} + + + +bool LLInventoryFilter::FilterOps::DateRange::validateBlock( bool emit_errors /*= true*/ ) const +{ + bool valid = LLInitParam::Block<DateRange>::validateBlock(emit_errors); + if (valid) + { + if (max_date() < min_date()) + { + if (emit_errors) + { + llwarns << "max_date should be greater or equal to min_date" << llendl; + } + valid = false; + } + } + return valid; } diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index f9460822f7..4912b5ca91 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -29,11 +29,13 @@ #include "llinventorytype.h" #include "llpermissionsflags.h" +#include "llfolderviewmodel.h" class LLFolderViewItem; class LLFolderViewFolder; +class LLInventoryItem; -class LLInventoryFilter +class LLInventoryFilter : public LLFolderViewFilter { public: enum EFolderShow @@ -43,21 +45,14 @@ public: SHOW_NO_FOLDERS }; - enum EFilterBehavior - { - FILTER_NONE, // nothing to do, already filtered - FILTER_RESTART, // restart filtering from scratch - FILTER_LESS_RESTRICTIVE, // existing filtered items will certainly pass this filter - FILTER_MORE_RESTRICTIVE // if you didn't pass the previous filter, you definitely won't pass this one - }; - enum EFilterType { FILTERTYPE_NONE = 0, FILTERTYPE_OBJECT = 0x1 << 0, // normal default search-by-object-type FILTERTYPE_CATEGORY = 0x1 << 1, // search by folder type FILTERTYPE_UUID = 0x1 << 2, // find the object with UUID and any links to it FILTERTYPE_DATE = 0x1 << 3, // search by date range - FILTERTYPE_WEARABLE = 0x1 << 4 // search by wearable type + FILTERTYPE_WEARABLE = 0x1 << 4, // search by wearable type + FILTERTYPE_EMPTYFOLDERS = 0x1 << 5 // pass if folder is not a system folder to be hidden if }; enum EFilterLink @@ -75,25 +70,102 @@ public: SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2 // Force system folders to be on top }; - LLInventoryFilter(const std::string& name); - virtual ~LLInventoryFilter(); + struct FilterOps + { + struct DateRange : public LLInitParam::Block<DateRange> + { + Optional<time_t> min_date, + max_date; + + DateRange() + : min_date("min_date", time_min()), + max_date("max_date", time_max()) + {} + + bool validateBlock(bool emit_errors = true) const; + }; + + struct Params : public LLInitParam::Block<Params> + { + Optional<U32> types; + Optional<U64> object_types, + wearable_types, + category_types; + Optional<EFilterLink> links; + Optional<LLUUID> uuid; + Optional<DateRange> date_range; + Optional<S32> hours_ago; + Optional<EFolderShow> show_folder_state; + Optional<PermissionMask> permissions; + + Params() + : types("filter_types", FILTERTYPE_OBJECT), + object_types("object_types", 0xffffFFFFffffFFFFULL), + wearable_types("wearable_types", 0xffffFFFFffffFFFFULL), + category_types("category_types", 0xffffFFFFffffFFFFULL), + links("links", FILTERLINK_INCLUDE_LINKS), + uuid("uuid"), + date_range("date_range"), + hours_ago("hours_ago", 0), + show_folder_state("show_folder_state", SHOW_NON_EMPTY_FOLDERS), + permissions("permissions", PERM_NONE) + {} + }; + + FilterOps(const Params& = Params()); + + U32 mFilterTypes; + U64 mFilterObjectTypes, // For _OBJECT + mFilterWearableTypes, + mFilterLinks, + mFilterCategoryTypes; // For _CATEGORY + LLUUID mFilterUUID; // for UUID + + time_t mMinDate, + mMaxDate; + U32 mHoursAgo; + + EFolderShow mShowFolderState; + PermissionMask mPermissions; + }; + + struct Params : public LLInitParam::Block<Params> + { + Optional<std::string> name; + Optional<FilterOps::Params> filter_ops; + Optional<std::string> substring; + Optional<bool> since_logoff; + + Params() + : name("name"), + filter_ops(""), + substring("substring"), + since_logoff("since_logoff") + {} + }; + + LLInventoryFilter(const Params& p = Params()); + LLInventoryFilter(const LLInventoryFilter& other) { *this = other; } + virtual ~LLInventoryFilter() {} // +-------------------------------------------------------------------+ // + Parameters // +-------------------------------------------------------------------+ - void setFilterObjectTypes(U64 types); U64 getFilterObjectTypes() const; U64 getFilterCategoryTypes() const; - BOOL isFilterObjectTypesWith(LLInventoryType::EType t) const; + U64 getFilterWearableTypes() const; + bool isFilterObjectTypesWith(LLInventoryType::EType t) const; + void setFilterObjectTypes(U64 types); void setFilterCategoryTypes(U64 types); void setFilterUUID(const LLUUID &object_id); void setFilterWearableTypes(U64 types); + void setFilterEmptySystemFolders(); void updateFilterTypes(U64 types, U64& current_types); void setFilterSubString(const std::string& string); const std::string& getFilterSubString(BOOL trim = FALSE) const; const std::string& getFilterSubStringOrig() const { return mFilterSubStringOrig; } - BOOL hasFilterString() const; + bool hasFilterString() const; void setFilterPermissions(PermissionMask perms); PermissionMask getFilterPermissions() const; @@ -112,38 +184,35 @@ public: // +-------------------------------------------------------------------+ // + Execution And Results // +-------------------------------------------------------------------+ - BOOL check(const LLFolderViewItem* item); - bool checkFolder(const LLFolderViewFolder* folder); - BOOL checkAgainstFilterType(const LLFolderViewItem* item) const; - BOOL checkAgainstPermissions(const LLFolderViewItem* item) const; - BOOL checkAgainstFilterLinks(const LLFolderViewItem* item) const; + bool check(const LLFolderViewModelItem* listener); + bool check(const LLInventoryItem* item); + bool checkFolder(const LLFolderViewModelItem* listener) const; + bool checkFolder(const LLUUID& folder_id) const; - std::string::size_type getStringMatchOffset() const; + bool showAllResults() const; + std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const; + std::string::size_type getFilterStringSize() const; // +-------------------------------------------------------------------+ // + Presentation // +-------------------------------------------------------------------+ void setShowFolderState( EFolderShow state); EFolderShow getShowFolderState() const; - void setSortOrder(U32 order); - U32 getSortOrder() const; - void setEmptyLookupMessage(const std::string& message); - const std::string& getEmptyLookupMessage() const; + std::string getEmptyLookupMessage() const; // +-------------------------------------------------------------------+ // + Status // +-------------------------------------------------------------------+ - BOOL isActive() const; - BOOL isModified() const; - BOOL isModifiedAndClear(); - BOOL isSinceLogoff() const; + bool isActive() const; + bool isModified() const; + bool isSinceLogoff() const; void clearModified(); - const std::string& getName() const; + const std::string& getName() const { return mName; } const std::string& getFilterText(); //RN: this is public to allow system to externally force a global refilter - void setModified(EFilterBehavior behavior = FILTER_RESTART); + void setModified(EFilterModified behavior = FILTER_RESTART); // +-------------------------------------------------------------------+ // + Count @@ -155,7 +224,8 @@ public: // +-------------------------------------------------------------------+ // + Default // +-------------------------------------------------------------------+ - BOOL isNotDefault() const; + bool isDefault() const; + bool isNotDefault() const; void markDefault(); void resetDefault(); @@ -163,55 +233,42 @@ public: // + Generation // +-------------------------------------------------------------------+ S32 getCurrentGeneration() const; - S32 getMinRequiredGeneration() const; - S32 getMustPassGeneration() const; + S32 getFirstSuccessGeneration() const; + S32 getFirstRequiredGeneration() const; + // +-------------------------------------------------------------------+ // + Conversion // +-------------------------------------------------------------------+ - void toLLSD(LLSD& data) const; - void fromLLSD(LLSD& data); - -private: - struct FilterOps - { - FilterOps(); - U32 mFilterTypes; + void toParams(Params& params) const; + void fromParams(const Params& p); - U64 mFilterObjectTypes; // For _OBJECT - U64 mFilterWearableTypes; - U64 mFilterCategoryTypes; // For _CATEGORY - LLUUID mFilterUUID; // for UUID + LLInventoryFilter& operator =(const LLInventoryFilter& other); - time_t mMinDate; - time_t mMaxDate; - U32 mHoursAgo; - EFolderShow mShowFolderState; - PermissionMask mPermissions; - U64 mFilterLinks; - }; - - U32 mOrder; - U32 mLastLogoff; +private: + bool areDateLimitsSet(); + bool checkAgainstFilterType(const class LLFolderViewModelItemInventory* listener) const; + bool checkAgainstFilterType(const LLInventoryItem* item) const; + bool checkAgainstPermissions(const class LLFolderViewModelItemInventory* listener) const; + bool checkAgainstPermissions(const LLInventoryItem* item) const; + bool checkAgainstFilterLinks(const class LLFolderViewModelItemInventory* listener) const; + bool checkAgainstClipboard(const LLUUID& object_id) const; FilterOps mFilterOps; FilterOps mDefaultFilterOps; - std::string::size_type mSubStringMatchOffset; std::string mFilterSubString; std::string mFilterSubStringOrig; const std::string mName; - S32 mFilterGeneration; - S32 mMustPassGeneration; - S32 mMinRequiredGeneration; + S32 mCurrentGeneration; + S32 mFirstRequiredGeneration; + S32 mFirstSuccessGeneration; S32 mNextFilterGeneration; S32 mFilterCount; - EFilterBehavior mFilterBehavior; + EFilterModified mFilterModified; - BOOL mModified; - BOOL mNeedTextRebuild; std::string mFilterText; std::string mEmptyLookupMessage; }; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 5fb3f15cd5..f1a4889f5a 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -45,7 +45,8 @@ // newview includes #include "llappearancemgr.h" #include "llappviewer.h" -//#include "llfirstuse.h" +#include "llclipboard.h" +#include "lldonotdisturbnotificationstorage.h" #include "llfloaterinventory.h" #include "llfloatersidepanelcontainer.h" #include "llfocusmgr.h" @@ -54,10 +55,10 @@ #include "lliconctrl.h" #include "llimview.h" #include "llinventorybridge.h" -#include "llinventoryclipboard.h" #include "llinventorymodel.h" #include "llinventorypanel.h" #include "lllineeditor.h" +#include "llmarketplacenotifications.h" #include "llmenugl.h" #include "llnotificationsutil.h" #include "llpanelmaininventory.h" @@ -74,14 +75,18 @@ #include "llsidepanelinventory.h" #include "lltabcontainer.h" #include "lltooldraganddrop.h" +#include "lltrans.h" #include "lluictrlfactory.h" #include "llviewermessage.h" +#include "llviewerfoldertype.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llwearablelist.h" +#include <boost/foreach.hpp> + BOOL LLInventoryState::sWearNewClothing = FALSE; LLUUID LLInventoryState::sWearNewClothingTransactionID; @@ -106,91 +111,6 @@ void append_path(const LLUUID& id, std::string& path) path.append(temp); } -void change_item_parent(LLInventoryModel* model, - LLViewerInventoryItem* item, - const LLUUID& new_parent_id, - BOOL restamp) -{ - if (item->getParentUUID() != new_parent_id) - { - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); - update.push_back(old_folder); - LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); - update.push_back(new_folder); - gInventory.accountForUpdate(update); - - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); - new_item->setParent(new_parent_id); - new_item->updateParentOnServer(restamp); - model->updateItem(new_item); - model->notifyObservers(); - } -} - -void change_category_parent(LLInventoryModel* model, - LLViewerInventoryCategory* cat, - const LLUUID& new_parent_id, - BOOL restamp) -{ - if (!model || !cat) - { - return; - } - - // Can't move a folder into a child of itself. - if (model->isObjectDescendentOf(new_parent_id, cat->getUUID())) - { - return; - } - - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1); - update.push_back(old_folder); - LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); - update.push_back(new_folder); - model->accountForUpdate(update); - - LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); - new_cat->setParent(new_parent_id); - new_cat->updateParentOnServer(restamp); - model->updateCategory(new_cat); - model->notifyObservers(); -} - -void remove_category(LLInventoryModel* model, const LLUUID& cat_id) -{ - if (!model || !get_is_category_removable(model, cat_id)) - { - return; - } - - // Look for any gestures and deactivate them - LLInventoryModel::cat_array_t descendent_categories; - LLInventoryModel::item_array_t descendent_items; - gInventory.collectDescendents(cat_id, descendent_categories, descendent_items, FALSE); - - for (LLInventoryModel::item_array_t::const_iterator iter = descendent_items.begin(); - iter != descendent_items.end(); - ++iter) - { - const LLViewerInventoryItem* item = (*iter); - const LLUUID& item_id = item->getUUID(); - if (item->getType() == LLAssetType::AT_GESTURE - && LLGestureMgr::instance().isGestureActive(item_id)) - { - LLGestureMgr::instance().deactivateGesture(item_id); - } - } - - LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); - if (cat) - { - const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); - change_category_parent(model, cat, trash_id, TRUE); - } -} - void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name) { LLViewerInventoryCategory* cat; @@ -211,6 +131,49 @@ void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::s model->notifyObservers(); } +void copy_inventory_category(LLInventoryModel* model, + LLViewerInventoryCategory* cat, + const LLUUID& parent_id, + const LLUUID& root_copy_id) +{ + // Create the initial folder + LLUUID new_cat_uuid = gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName()); + model->notifyObservers(); + + // We need to exclude the initial root of the copy to avoid recursively copying the copy, etc... + LLUUID root_id = (root_copy_id.isNull() ? new_cat_uuid : root_copy_id); + + // Get the content of the folder + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); + + // Copy all the items + LLInventoryModel::item_array_t item_array_copy = *item_array; + for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++) + { + LLInventoryItem* item = *iter; + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + new_cat_uuid, + std::string(), + LLPointer<LLInventoryCallback>(NULL)); + } + + // Copy all the folders + LLInventoryModel::cat_array_t cat_array_copy = *cat_array; + for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) + { + LLViewerInventoryCategory* category = *iter; + if (category->getUUID() != root_id) + { + copy_inventory_category(model, category, new_cat_uuid, root_id); + } + } +} + class LLInventoryCollectAllItems : public LLInventoryCollectFunctor { public: @@ -480,7 +443,7 @@ void show_item_original(const LLUUID& item_uuid) //sidetray inventory panel LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); - bool reset_inventory_filter = !floater_inventory->isInVisibleChain(); + bool do_reset_inventory_filter = !floater_inventory->isInVisibleChain(); LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(); if (!active_panel) @@ -500,67 +463,94 @@ void show_item_original(const LLUUID& item_uuid) } active_panel->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_NO); - if(reset_inventory_filter) + if(do_reset_inventory_filter) { - //inventory floater - bool floater_inventory_visible = false; + reset_inventory_filter(); + } +} + - 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) +void reset_inventory_filter() +{ + //inventory floater + bool floater_inventory_visible = false; + + 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* floater_inventory = dynamic_cast<LLFloaterInventory*>(*iter); + if (floater_inventory) { - LLFloaterInventory* floater_inventory = dynamic_cast<LLFloaterInventory*>(*iter); - if (floater_inventory) - { - LLPanelMainInventory* main_inventory = floater_inventory->getMainInventoryPanel(); + LLPanelMainInventory* main_inventory = floater_inventory->getMainInventoryPanel(); - main_inventory->onFilterEdit(""); + main_inventory->onFilterEdit(""); - if(floater_inventory->getVisible()) - { - floater_inventory_visible = true; - } + if(floater_inventory->getVisible()) + { + floater_inventory_visible = true; } } - if(sidepanel_inventory && !floater_inventory_visible) + } + + if(!floater_inventory_visible) + { + LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); + if (sidepanel_inventory) { LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel(); - - main_inventory->onFilterEdit(""); + if (main_inventory) + { + main_inventory->onFilterEdit(""); + } } } } -void move_to_outbox_cb(const LLSD& notification, const LLSD& response) +void open_outbox() { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) return; // canceled + LLFloaterReg::showInstance("outbox"); +} - LLViewerInventoryItem * viitem = gInventory.getItem(notification["payload"]["item_id"].asUUID()); - LLUUID dest_folder_id = notification["payload"]["dest_folder_id"].asUUID(); +LLUUID create_folder_in_outbox_for_item(LLInventoryItem* item, const LLUUID& destFolderId, S32 operation_id) +{ + 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; +} + +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(); - change_item_parent( - &gInventory, + gInventory.changeItemParent( viitem, 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; @@ -577,7 +567,7 @@ void move_to_outbox_cb(const LLSD& notification, const LLSD& response) if (cat_array->empty() && item_array->empty()) { - remove_category(&gInventory, parent); + gInventory.removeCategory(parent); } if (parent == top_level_folder) @@ -589,42 +579,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; + + gInventory.changeItemParent( + 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 +662,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 +670,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(); } ///---------------------------------------------------------------------------- @@ -943,21 +962,24 @@ void LLSaveFolderState::setApply(BOOL apply) void LLSaveFolderState::doFolder(LLFolderViewFolder* folder) { - LLMemType mt(LLMemType::MTYPE_INVENTORY_DO_FOLDER); + LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getViewModelItem(); + if(!bridge) return; + if(mApply) { // we're applying the open state - LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener(); - if(!bridge) return; LLUUID id(bridge->getUUID()); if(mOpenFolders.find(id) != mOpenFolders.end()) { - folder->setOpen(TRUE); + if (!folder->isOpen()) + { + folder->setOpen(TRUE); + } } else { // keep selected filter in its current state, this is less jarring to user - if (!folder->isSelected()) + if (!folder->isSelected() && folder->isOpen()) { folder->setOpen(FALSE); } @@ -968,8 +990,6 @@ void LLSaveFolderState::doFolder(LLFolderViewFolder* folder) // we're recording state at this point if(folder->isOpen()) { - LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener(); - if(!bridge) return; mOpenFolders.insert(bridge->getUUID()); } } @@ -977,7 +997,7 @@ void LLSaveFolderState::doFolder(LLFolderViewFolder* folder) void LLOpenFilteredFolders::doItem(LLFolderViewItem *item) { - if (item->getFiltered()) + if (item->passedFilter()) { item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); } @@ -985,12 +1005,12 @@ void LLOpenFilteredFolders::doItem(LLFolderViewItem *item) void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder) { - if (folder->getFiltered() && folder->getParentFolder()) + if (folder->LLFolderViewItem::passedFilter() && folder->getParentFolder()) { folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); } // if this folder didn't pass the filter, and none of its descendants did - else if (!folder->getFiltered() && !folder->hasFilteredDescendants()) + else if (!folder->getViewModelItem()->passedFilter() && !folder->getViewModelItem()->descendantsPassedFilter()) { folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_NO); } @@ -998,29 +1018,25 @@ void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder) void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item) { - if (item->getFiltered() && !mItemSelected) + if (item->passedFilter() && !mItemSelected) { item->getRoot()->setSelection(item, FALSE, FALSE); if (item->getParentFolder()) { item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); } - item->getRoot()->scrollToShowSelection(); mItemSelected = TRUE; } } void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder) { - if (folder->getFiltered() && !mItemSelected) + // Skip if folder or item already found, if not filtered or if no parent (root folder is not selectable) + if (!mFolderSelected && !mItemSelected && folder->LLFolderViewItem::passedFilter() && folder->getParentFolder()) { folder->getRoot()->setSelection(folder, FALSE, FALSE); - if (folder->getParentFolder()) - { - folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); - } - folder->getRoot()->scrollToShowSelection(); - mItemSelected = TRUE; + folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + mFolderSelected = TRUE; } } @@ -1040,3 +1056,113 @@ void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder) } } +void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root, const std::string& action) +{ + if ("rename" == action) + { + root->startRenamingSelectedItem(); + return; + } + if ("delete" == action) + { + LLSD args; + args["QUESTION"] = LLTrans::getString(root->getSelectedCount() > 1 ? "DeleteItems" : "DeleteItem"); + LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root)); + return; + } + if (("copy" == action) || ("cut" == action)) + { + // Clear the clipboard before we start adding things on it + LLClipboard::instance().reset(); + } + + static const std::string change_folder_string = "change_folder_type_"; + if (action.length() > change_folder_string.length() && + (action.compare(0,change_folder_string.length(),"change_folder_type_") == 0)) + { + LLFolderType::EType new_folder_type = LLViewerFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length())); + LLFolderViewModelItemInventory* inventory_item = static_cast<LLFolderViewModelItemInventory*>(root->getViewModelItem()); + LLViewerInventoryCategory *cat = model->getCategory(inventory_item->getUUID()); + if (!cat) return; + cat->changeType(new_folder_type); + return; + } + + + std::set<LLFolderViewItem*> selected_items = root->getSelectionList(); + + LLMultiPreview* multi_previewp = NULL; + LLMultiProperties* multi_propertiesp = NULL; + + if (("task_open" == action || "open" == action) && selected_items.size() > 1) + { + multi_previewp = new LLMultiPreview(); + gFloaterView->addChild(multi_previewp); + + LLFloater::setFloaterHost(multi_previewp); + + } + else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1) + { + multi_propertiesp = new LLMultiProperties(); + gFloaterView->addChild(multi_propertiesp); + + LLFloater::setFloaterHost(multi_propertiesp); + } + + std::set<LLFolderViewItem*>::iterator set_iter; + + for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter) + { + LLFolderViewItem* folder_item = *set_iter; + if(!folder_item) continue; + LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem(); + if(!bridge) continue; + bridge->performAction(model, action); + } + + LLFloater::setFloaterHost(NULL); + if (multi_previewp) + { + multi_previewp->openFloater(LLSD()); + } + else if (multi_propertiesp) + { + multi_propertiesp->openFloater(LLSD()); + } +} + +void LLInventoryAction::removeItemFromDND(LLFolderView* root) +{ + if(gAgent.isDoNotDisturb()) + { + //Get selected items + LLFolderView::selected_items_t selectedItems = root->getSelectedItems(); + LLFolderViewModelItemInventory * viewModel = NULL; + + //If user is in DND and deletes item, make sure the notification is not displayed by removing the notification + //from DND history and .xml file. Once this is done, upon exit of DND mode the item deleted will not show a notification. + for(LLFolderView::selected_items_t::iterator it = selectedItems.begin(); it != selectedItems.end(); ++it) + { + viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*it)->getViewModelItem()); + + if(viewModel && viewModel->getUUID().notNull()) + { + //Will remove the item offer notification + LLDoNotDisturbNotificationStorage::instance().removeNotification(LLDoNotDisturbNotificationStorage::offerName, viewModel->getUUID()); + } + } + } +} + +void LLInventoryAction::onItemsRemovalConfirmation( const LLSD& notification, const LLSD& response, LLFolderView* root ) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) + { + //Need to remove item from DND before item is removed from root folder view + //because once removed from root folder view the item is no longer a selected item + removeItemFromDND(root); + root->removeSelectedItems(); + } +} diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 7b452537f8..f1066a4dc9 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -56,27 +56,19 @@ void show_item_profile(const LLUUID& item_uuid); void show_task_item_profile(const LLUUID& item_uuid, const LLUUID& object_id); void show_item_original(const LLUUID& item_uuid); - -void change_item_parent(LLInventoryModel* model, - LLViewerInventoryItem* item, - const LLUUID& new_parent_id, - BOOL restamp); - -void change_category_parent(LLInventoryModel* model, - LLViewerInventoryCategory* cat, - const LLUUID& new_parent_id, - BOOL restamp); - -void remove_category(LLInventoryModel* model, const LLUUID& cat_id); +void reset_inventory_filter(); void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name); +void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& parent_id, const LLUUID& root_copy_id = LLUUID::null); + // 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 ** ** @@ -427,21 +419,6 @@ public: class LLFolderViewItem; class LLFolderViewFolder; -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewFunctor -// -// Simple abstract base class for applying a functor to folders and -// items in a folder view hierarchy. This is suboptimal for algorithms -// that only work folders or only work on items, but I'll worry about -// that later when it's determined to be too slow. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLFolderViewFunctor -{ -public: - virtual ~LLFolderViewFunctor() {} - virtual void doFolder(LLFolderViewFolder* folder) = 0; - virtual void doItem(LLFolderViewItem* item) = 0; -}; class LLInventoryState { @@ -451,49 +428,14 @@ public: static LLUUID sWearNewClothingTransactionID; // wear all clothing in this transaction }; -class LLSelectFirstFilteredItem : public LLFolderViewFunctor +struct LLInventoryAction { -public: - LLSelectFirstFilteredItem() : mItemSelected(FALSE) {} - virtual ~LLSelectFirstFilteredItem() {} - virtual void doFolder(LLFolderViewFolder* folder); - virtual void doItem(LLFolderViewItem* item); - BOOL wasItemSelected() { return mItemSelected; } -protected: - BOOL mItemSelected; -}; + static void doToSelected(class LLInventoryModel* model, class LLFolderView* root, const std::string& action); -class LLOpenFilteredFolders : public LLFolderViewFunctor -{ -public: - LLOpenFilteredFolders() {} - virtual ~LLOpenFilteredFolders() {} - virtual void doFolder(LLFolderViewFolder* folder); - virtual void doItem(LLFolderViewItem* item); + static void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLFolderView* root); + static void removeItemFromDND(LLFolderView* root); }; -class LLSaveFolderState : public LLFolderViewFunctor -{ -public: - LLSaveFolderState() : mApply(FALSE) {} - virtual ~LLSaveFolderState() {} - virtual void doFolder(LLFolderViewFolder* folder); - virtual void doItem(LLFolderViewItem* item) {} - void setApply(BOOL apply); - void clearOpenFolders() { mOpenFolders.clear(); } -protected: - std::set<LLUUID> mOpenFolders; - BOOL mApply; -}; - -class LLOpenFoldersWithSelection : public LLFolderViewFunctor -{ -public: - LLOpenFoldersWithSelection() {} - virtual ~LLOpenFoldersWithSelection() {} - virtual void doFolder(LLFolderViewFolder* folder); - virtual void doItem(LLFolderViewItem* item); -}; #endif // LL_LLINVENTORYFUNCTIONS_H diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h index c7e2998a20..5c8acf9e85 100644 --- a/indra/newview/llinventoryicon.h +++ b/indra/newview/llinventoryicon.h @@ -1,5 +1,5 @@ /** - * @file llinventoryfunctions.h + * @file llinventoryicon.h * @brief Miscellaneous inventory-related functions and classes * class definition * diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index dc25689fa3..e7d59d92d9 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -30,6 +30,7 @@ #include "llagent.h" #include "llagentwearables.h" #include "llappearancemgr.h" +#include "llclipboard.h" #include "llinventorypanel.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" @@ -46,6 +47,8 @@ #include "llviewerregion.h" #include "llcallbacklist.h" #include "llvoavatarself.h" +#include "llgesturemgr.h" +#include <typeinfo> //#define DIFF_INVENTORY_FILES #ifdef DIFF_INVENTORY_FILES @@ -217,6 +220,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 { @@ -338,13 +373,12 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id) // specifies 'type' as what it defaults to containing. The category is // not necessarily only for that type. *NOTE: This will create a new // inventory category on the fly if one does not exist. -const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, - bool create_folder, - bool find_in_library) +const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder/*, + bool find_in_library*/) { LLUUID rv = LLUUID::null; - const LLUUID &root_id = (find_in_library) ? gInventory.getLibraryRootFolderID() : gInventory.getRootFolderID(); + const LLUUID &root_id = /*(find_in_library) ? gInventory.getLibraryRootFolderID() :*/ gInventory.getRootFolderID(); if(LLFolderType::FT_ROOT_INVENTORY == preferred_type) { rv = root_id; @@ -367,7 +401,44 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe } } - if(rv.isNull() && isInventoryUsable() && (create_folder && !find_in_library)) + if(rv.isNull() && isInventoryUsable() && (create_folder && true/*!find_in_library*/)) + { + if(root_id.notNull()) + { + return createNewCategory(root_id, preferred_type, LLStringUtil::null); + } + } + return rv; +} + +const LLUUID LLInventoryModel::findLibraryCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder) +{ + LLUUID rv = LLUUID::null; + + const LLUUID &root_id = gInventory.getLibraryRootFolderID(); + if(LLFolderType::FT_ROOT_INVENTORY == preferred_type) + { + rv = root_id; + } + else if (root_id.notNull()) + { + cat_array_t* cats = NULL; + cats = get_ptr_in_map(mParentChildCategoryTree, root_id); + if(cats) + { + S32 count = cats->count(); + for(S32 i = 0; i < count; ++i) + { + if(cats->get(i)->getPreferredType() == preferred_type) + { + rv = cats->get(i)->getUUID(); + break; + } + } + } + } + + if(rv.isNull() && isInventoryUsable() && (create_folder && true/*!find_in_library*/)) { if(root_id.notNull()) { @@ -377,14 +448,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 +532,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 = @@ -705,6 +858,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item) { parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); new_item->setParent(parent_id); + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate new_folder(parent_id, 1); + update.push_back(new_folder); + accountForUpdate(update); + } item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, parent_id); if(item_array) @@ -828,6 +986,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat) cat_array->put(old_cat); } mask |= LLInventoryObserver::STRUCTURE; + mask |= LLInventoryObserver::INTERNAL; } if(old_cat->getName() != cat->getName()) { @@ -903,6 +1062,66 @@ void LLInventoryModel::moveObject(const LLUUID& object_id, const LLUUID& cat_id) } } +// Migrated from llinventoryfunctions +void LLInventoryModel::changeItemParent(LLViewerInventoryItem* item, + const LLUUID& new_parent_id, + BOOL restamp) +{ + if (item->getParentUUID() == new_parent_id) + { + LL_DEBUGS("Inventory") << "'" << item->getName() << "' (" << item->getUUID() + << ") is already in folder " << new_parent_id << LL_ENDL; + } + else + { + LL_INFOS("Inventory") << "Moving '" << item->getName() << "' (" << item->getUUID() + << ") from " << item->getParentUUID() << " to folder " + << new_parent_id << LL_ENDL; + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); + update.push_back(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); + update.push_back(new_folder); + accountForUpdate(update); + + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); + new_item->setParent(new_parent_id); + new_item->updateParentOnServer(restamp); + updateItem(new_item); + notifyObservers(); + } +} + +// Migrated from llinventoryfunctions +void LLInventoryModel::changeCategoryParent(LLViewerInventoryCategory* cat, + const LLUUID& new_parent_id, + BOOL restamp) +{ + if (!cat) + { + return; + } + + // Can't move a folder into a child of itself. + if (isObjectDescendentOf(new_parent_id, cat->getUUID())) + { + return; + } + + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1); + update.push_back(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); + update.push_back(new_folder); + accountForUpdate(update); + + LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); + new_cat->setParent(new_parent_id); + new_cat->updateParentOnServer(restamp); + updateCategory(new_cat); + notifyObservers(); +} + // Delete a particular inventory object by ID. void LLInventoryModel::deleteObject(const LLUUID& id) { @@ -996,50 +1215,101 @@ void LLInventoryModel::purgeDescendentsOf(const LLUUID& id) return; } LLPointer<LLViewerInventoryCategory> cat = getCategory(id); - if(cat.notNull()) - { - // do the cache accounting - llinfos << "LLInventoryModel::purgeDescendentsOf " << cat->getName() - << llendl; - S32 descendents = cat->getDescendentCount(); - if(descendents > 0) - { - LLCategoryUpdate up(id, -descendents); - accountForUpdate(up); + if (cat.notNull()) + { + if (LLClipboard::instance().hasContents() && LLClipboard::instance().isCutMode()) + { + // Something on the clipboard is in "cut mode" and needs to be preserved + llinfos << "LLInventoryModel::purgeDescendentsOf " << cat->getName() + << " iterate and purge non hidden items" << llendl; + cat_array_t* categories; + item_array_t* items; + // Get the list of direct descendants in tha categoy passed as argument + getDirectDescendentsOf(id, categories, items); + std::vector<LLUUID> list_uuids; + // Make a unique list with all the UUIDs of the direct descendants (items and categories are not treated differently) + // Note: we need to do that shallow copy as purging things will invalidate the categories or items lists + for (cat_array_t::const_iterator it = categories->begin(); it != categories->end(); ++it) + { + list_uuids.push_back((*it)->getUUID()); + } + for (item_array_t::const_iterator it = items->begin(); it != items->end(); ++it) + { + list_uuids.push_back((*it)->getUUID()); + } + // Iterate through the list and only purge the UUIDs that are not on the clipboard + for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it) + { + if (!LLClipboard::instance().isOnClipboard(*it)) + { + purgeObject(*it); + } + } } + else + { + // Fast purge + // do the cache accounting + llinfos << "LLInventoryModel::purgeDescendentsOf " << cat->getName() + << llendl; + S32 descendents = cat->getDescendentCount(); + if(descendents > 0) + { + LLCategoryUpdate up(id, -descendents); + accountForUpdate(up); + } - // we know that descendent count is 0, aide since the - // accounting may actually not do an update, we should force - // it here. - cat->setDescendentCount(0); + // we know that descendent count is 0, however since the + // accounting may actually not do an update, we should force + // it here. + cat->setDescendentCount(0); + + // send it upstream + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("PurgeInventoryDescendents"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->addUUID("SessionID", gAgent.getSessionID()); + msg->nextBlock("InventoryData"); + msg->addUUID("FolderID", id); + gAgent.sendReliableMessage(); - // send it upstream - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("PurgeInventoryDescendents"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - msg->nextBlock("InventoryData"); - msg->addUUID("FolderID", id); - gAgent.sendReliableMessage(); - - // unceremoniously remove anything we have locally stored. - cat_array_t categories; - item_array_t items; - collectDescendents(id, - categories, - items, - INCLUDE_TRASH); - S32 count = items.count(); - S32 i; - for(i = 0; i < count; ++i) - { - deleteObject(items.get(i)->getUUID()); - } - count = categories.count(); - for(i = 0; i < count; ++i) - { - deleteObject(categories.get(i)->getUUID()); + // unceremoniously remove anything we have locally stored. + cat_array_t categories; + item_array_t items; + collectDescendents(id, + categories, + items, + INCLUDE_TRASH); + S32 count = items.count(); + + item_map_t::iterator item_map_end = mItemMap.end(); + cat_map_t::iterator cat_map_end = mCategoryMap.end(); + LLUUID uu_id; + + for(S32 i = 0; i < count; ++i) + { + uu_id = items.get(i)->getUUID(); + + // This check prevents the deletion of a previously deleted item. + // This is necessary because deletion is not done in a hierarchical + // order. The current item may have been already deleted as a child + // of its deleted parent. + if (mItemMap.find(uu_id) != item_map_end) + { + deleteObject(uu_id); + } + } + + count = categories.count(); + for(S32 i = 0; i < count; ++i) + { + uu_id = categories.get(i)->getUUID(); + if (mCategoryMap.find(uu_id) != cat_map_end) + { + deleteObject(uu_id); + } + } } } } @@ -1087,7 +1357,6 @@ void LLInventoryModel::notifyObservers() iter != mObservers.end(); ) { LLInventoryObserver* observer = *iter; - observer->changed(mModifyMask); // safe way to increment since changed may delete entries! (@!##%@!@&*!) @@ -1551,6 +1820,7 @@ bool LLInventoryModel::loadSkeleton( update_map_t child_counts; cat_array_t categories; item_array_t items; + item_array_t possible_broken_links; cat_set_t invalid_categories; // Used to mark categories that weren't successfully loaded. std::string owner_id_str; owner_id.toString(owner_id_str); @@ -1599,7 +1869,7 @@ bool LLInventoryModel::loadSkeleton( LLViewerInventoryCategory* tcat = *cit; // we can safely ignore anything loaded from file, but - // not sent down in the skeleton. + // not sent down in the skeleton. Must have been removed from inventory. if(cit == not_cached) { continue; @@ -1637,6 +1907,8 @@ bool LLInventoryModel::loadSkeleton( // Add all the items loaded which are parented to a // category with a correctly cached parent S32 bad_link_count = 0; + S32 good_link_count = 0; + S32 recovered_link_count = 0; cat_map_t::iterator unparented = mCategoryMap.end(); for(item_array_t::const_iterator item_iter = items.begin(); item_iter != items.end(); @@ -1653,26 +1925,56 @@ bool LLInventoryModel::loadSkeleton( // This can happen if the linked object's baseobj is removed from the cache but the linked object is still in the cache. if (item->getIsBrokenLink()) { - bad_link_count++; + //bad_link_count++; lldebugs << "Attempted to add cached link item without baseobj present ( name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ). Ignoring and invalidating " << cat->getName() << " . " << llendl; - invalid_categories.insert(cit->second); + possible_broken_links.push_back(item); continue; } + else if (item->getIsLinkType()) + { + good_link_count++; + } addItem(item); cached_item_count += 1; ++child_counts[cat->getUUID()]; } } } - if (bad_link_count > 0) + if (possible_broken_links.size() > 0) { - llinfos << "Attempted to add " << bad_link_count - << " cached link items without baseobj present. " - << "The corresponding categories were invalidated." << llendl; + for(item_array_t::const_iterator item_iter = possible_broken_links.begin(); + item_iter != possible_broken_links.end(); + ++item_iter) + { + LLViewerInventoryItem *item = (*item_iter).get(); + const cat_map_t::iterator cit = mCategoryMap.find(item->getParentUUID()); + const LLViewerInventoryCategory* cat = cit->second.get(); + if (item->getIsBrokenLink()) + { + bad_link_count++; + invalid_categories.insert(cit->second); + //llinfos << "link still broken: " << item->getName() << " in folder " << cat->getName() << llendl; + } + else + { + // was marked as broken because of loading order, its actually fine to load + addItem(item); + cached_item_count += 1; + ++child_counts[cat->getUUID()]; + recovered_link_count++; + } + } + + llinfos << "Attempted to add " << bad_link_count + << " cached link items without baseobj present. " + << good_link_count << " link items were successfully added. " + << recovered_link_count << " links added in recovery. " + << "The corresponding categories were invalidated." << llendl; } + } else { @@ -2570,11 +2872,11 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) { LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem; titem->unpackMessage(msg, _PREHASH_ItemData, i); - llinfos << "unpaked item '" << titem->getName() << "' in " + llinfos << "unpacked item '" << titem->getName() << "' in " << 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())); @@ -2818,21 +3120,77 @@ void LLInventoryModel::emptyFolderType(const std::string notification, LLFolderT void LLInventoryModel::removeItem(const LLUUID& item_id) { LLViewerInventoryItem* item = getItem(item_id); - const LLUUID new_parent = findCategoryUUIDForType(LLFolderType::FT_TRASH); - if (item && item->getParentUUID() != new_parent) + if (! item) { - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); - update.push_back(old_folder); - LLInventoryModel::LLCategoryUpdate new_folder(new_parent, 1); - update.push_back(new_folder); - accountForUpdate(update); + LL_WARNS("Inventory") << "couldn't find inventory item " << item_id << LL_ENDL; + } + else + { + const LLUUID new_parent = findCategoryUUIDForType(LLFolderType::FT_TRASH); + if (new_parent.notNull()) + { + LL_INFOS("Inventory") << "Moving to Trash (" << new_parent << "):" << LL_ENDL; + changeItemParent(item, new_parent, TRUE); + } + } +} - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); - new_item->setParent(new_parent); - new_item->updateParentOnServer(TRUE); - updateItem(new_item); - notifyObservers(); +void LLInventoryModel::removeCategory(const LLUUID& category_id) +{ + if (! get_is_category_removable(this, category_id)) + { + return; + } + + // Look for any gestures and deactivate them + LLInventoryModel::cat_array_t descendent_categories; + LLInventoryModel::item_array_t descendent_items; + collectDescendents(category_id, descendent_categories, descendent_items, FALSE); + + for (LLInventoryModel::item_array_t::const_iterator iter = descendent_items.begin(); + iter != descendent_items.end(); + ++iter) + { + const LLViewerInventoryItem* item = (*iter); + const LLUUID& item_id = item->getUUID(); + if (item->getType() == LLAssetType::AT_GESTURE + && LLGestureMgr::instance().isGestureActive(item_id)) + { + LLGestureMgr::instance().deactivateGesture(item_id); + } + } + + LLViewerInventoryCategory* cat = getCategory(category_id); + if (cat) + { + const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH); + if (trash_id.notNull()) + { + changeCategoryParent(cat, trash_id, TRUE); + } + } +} + +void LLInventoryModel::removeObject(const LLUUID& object_id) +{ + LLInventoryObject* obj = getObject(object_id); + if (dynamic_cast<LLViewerInventoryItem*>(obj)) + { + removeItem(object_id); + } + else if (dynamic_cast<LLViewerInventoryCategory*>(obj)) + { + removeCategory(object_id); + } + else if (obj) + { + LL_WARNS("Inventory") << "object ID " << object_id + << " is an object of unrecognized class " + << typeid(*obj).name() << LL_ENDL; + } + else + { + LL_WARNS("Inventory") << "object ID " << object_id << " not found" << LL_ENDL; } } @@ -2937,68 +3295,7 @@ void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, c } } -//* @param[in] items vector of items in order to be saved. -void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& items) -{ - int sortField = 0; - - // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field - for (item_array_t::const_iterator i = items.begin(); i != items.end(); ++i) - { - LLViewerInventoryItem* item = *i; - - item->setSortField(++sortField); - item->setComplete(TRUE); - item->updateServer(FALSE); - - updateItem(item); - // Tell the parent folder to refresh its sort order. - addChangedMask(LLInventoryObserver::SORT, item->getParentUUID()); - } - - notifyObservers(); -} - -// See also LLInventorySort where landmarks in the Favorites folder are sorted. -class LLViewerInventoryItemSort -{ -public: - bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b) - { - return a->getSortField() < b->getSortField(); - } -}; - -/** - * Sorts passed items by LLViewerInventoryItem sort field. - * - * @param[in, out] items - array of items, not sorted. - */ -static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items) -{ - static LLViewerInventoryItemSort sort_functor; - std::sort(items.begin(), items.end(), sort_functor); -} - -// * @param source_item_id - LLUUID of the source item to be moved into new position -// * @param target_item_id - LLUUID of the target item before which source item should be placed. -void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id) -{ - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - LLIsType is_type(LLAssetType::AT_LANDMARK); - LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); - gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type); - - // ensure items are sorted properly before changing order. EXT-3498 - rearrange_item_order_by_sort_field(items); - - // update order - updateItemsOrder(items, source_item_id, target_item_id); - - saveItemsOrder(items); -} //---------------------------------------------------------------------------- diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index a0fd455cf3..503de627a0 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; @@ -230,14 +231,18 @@ public: // Returns the uuid of the category that specifies 'type' as what it // defaults to containing. The category is not necessarily only for that type. // NOTE: If create_folder is true, this will create a new inventory category - // on the fly if one does not exist. *NOTE: if find_in_library is true it - // will search in the user's library folder instead of "My Inventory" + // on the fly if one does not exist. const LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type, - bool create_folder = true, - bool find_in_library = false); + bool create_folder = true); + // will search in the user's library folder instead of "My Inventory" + const LLUUID findLibraryCategoryUUIDForType(LLFolderType::EType preferred_type, + bool create_folder = true); // 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 @@ -302,6 +307,16 @@ public: // observer notification, or server update is performed. void moveObject(const LLUUID& object_id, const LLUUID& cat_id); + // Migrated from llinventoryfunctions + void changeItemParent(LLViewerInventoryItem* item, + const LLUUID& new_parent_id, + BOOL restamp); + + // Migrated from llinventoryfunctions + void changeCategoryParent(LLViewerInventoryCategory* cat, + const LLUUID& new_parent_id, + BOOL restamp); + //-------------------------------------------------------------------- // Delete //-------------------------------------------------------------------- @@ -311,8 +326,13 @@ public: // consistent internal state. No cache accounting, observer // notification, or server update is performed. void deleteObject(const LLUUID& id); + /// move Item item_id to Trash void removeItem(const LLUUID& item_id); - + /// move Category category_id to Trash + void removeCategory(const LLUUID& category_id); + /// removeItem() or removeCategory(), whichever is appropriate + void removeObject(const LLUUID& object_id); + // Delete a particular inventory object by ID, and delete it from // the server. Also updates linked items. void purgeObject(const LLUUID& id); @@ -343,15 +363,6 @@ public: // Returns end() of the vector if not found. static LLInventoryModel::item_array_t::iterator findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id); - // Saves current order of the passed items using inventory item sort field. - // Resets 'items' sort fields and saves them on server. - // Is used to save order for Favorites folder. - void saveItemsOrder(const LLInventoryModel::item_array_t& items); - - // Rearranges Landmarks inside Favorites folder. - // Moves source landmark before target one. - void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id); - //-------------------------------------------------------------------- // Creation //-------------------------------------------------------------------- @@ -360,7 +371,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 @@ -411,7 +424,7 @@ public: // Return (yes/no/maybe) child status of category children. EHasChildren categoryHasChildren(const LLUUID& cat_id) const; - // Returns true iff category version is known and theoretical + // Returns true if category version is known and theoretical // descendents == actual descendents. bool isCategoryComplete(const LLUUID& cat_id) const; diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 91fdd67806..f4d0110b0f 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -43,6 +43,7 @@ const S32 MAX_FETCH_RETRIES = 10; LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch() : mBackgroundFetchActive(FALSE), + mFolderFetchActive(false), mAllFoldersFetched(FALSE), mRecursiveInventoryFetchStarted(FALSE), mRecursiveLibraryFetchStarted(FALSE), @@ -50,7 +51,7 @@ LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch() : mMinTimeBetweenFetches(0.3f), mMaxTimeBetweenFetches(10.f), mTimelyFetchPending(FALSE), - mBulkFetchCount(0) + mFetchCount(0) { } @@ -60,7 +61,7 @@ LLInventoryModelBackgroundFetch::~LLInventoryModelBackgroundFetch() bool LLInventoryModelBackgroundFetch::isBulkFetchProcessingComplete() const { - return mFetchQueue.empty() && mBulkFetchCount<=0; + return mFetchQueue.empty() && mFetchCount<=0; } bool LLInventoryModelBackgroundFetch::libraryFetchStarted() const @@ -98,19 +99,21 @@ bool LLInventoryModelBackgroundFetch::isEverythingFetched() const return mAllFoldersFetched; } -BOOL LLInventoryModelBackgroundFetch::backgroundFetchActive() const +BOOL LLInventoryModelBackgroundFetch::folderFetchActive() const { - return mBackgroundFetchActive; + return mFolderFetchActive; } -void LLInventoryModelBackgroundFetch::start(const LLUUID& cat_id, BOOL recursive) +void LLInventoryModelBackgroundFetch::start(const LLUUID& id, BOOL recursive) { - if (!mAllFoldersFetched || cat_id.notNull()) - { - LL_DEBUGS("InventoryFetch") << "Start fetching category: " << cat_id << ", recursive: " << recursive << LL_ENDL; + LLViewerInventoryCategory* cat = gInventory.getCategory(id); + if (cat || (id.isNull() && !isEverythingFetched())) + { // it's a folder, do a bulk fetch + LL_DEBUGS("InventoryFetch") << "Start fetching category: " << id << ", recursive: " << recursive << LL_ENDL; mBackgroundFetchActive = TRUE; - if (cat_id.isNull()) + mFolderFetchActive = true; + if (id.isNull()) { if (!mRecursiveInventoryFetchStarted) { @@ -128,41 +131,41 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& cat_id, BOOL recursive else { // Specific folder requests go to front of queue. - if (mFetchQueue.empty() || mFetchQueue.front().mCatUUID != cat_id) + if (mFetchQueue.empty() || mFetchQueue.front().mUUID != id) { - mFetchQueue.push_front(FetchQueueInfo(cat_id, recursive)); + mFetchQueue.push_front(FetchQueueInfo(id, recursive)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } - if (cat_id == gInventory.getLibraryRootFolderID()) + if (id == gInventory.getLibraryRootFolderID()) { mRecursiveLibraryFetchStarted |= recursive; } - if (cat_id == gInventory.getRootFolderID()) + if (id == gInventory.getRootFolderID()) { mRecursiveInventoryFetchStarted |= recursive; } } } + else if (LLViewerInventoryItem* itemp = gInventory.getItem(id)) + { + if (!itemp->mIsComplete && (mFetchQueue.empty() || mFetchQueue.front().mUUID != id)) + { + mBackgroundFetchActive = TRUE; + + mFetchQueue.push_front(FetchQueueInfo(id, false, false)); + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + } + } } void LLInventoryModelBackgroundFetch::findLostItems() { mBackgroundFetchActive = TRUE; + mFolderFetchActive = true; mFetchQueue.push_back(FetchQueueInfo(LLUUID::null, TRUE)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } -void LLInventoryModelBackgroundFetch::stopBackgroundFetch() -{ - if (mBackgroundFetchActive) - { - mBackgroundFetchActive = FALSE; - gIdleCallbacks.deleteFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); - mBulkFetchCount=0; - mMinTimeBetweenFetches=0.0f; - } -} - void LLInventoryModelBackgroundFetch::setAllFoldersFetched() { if (mRecursiveInventoryFetchStarted && @@ -170,7 +173,7 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched() { mAllFoldersFetched = TRUE; } - stopBackgroundFetch(); + mFolderFetchActive = false; } void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *) @@ -183,10 +186,9 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() if (mBackgroundFetchActive && gAgent.getRegion()) { // If we'll be using the capability, we'll be sending batches and the background thing isn't as important. - std::string url = gAgent.getRegion()->getCapability("FetchInventoryDescendents2"); - if (gSavedSettings.getBOOL("UseHTTPInventory") && !url.empty()) + if (gSavedSettings.getBOOL("UseHTTPInventory")) { - bulkFetch(url); + bulkFetch(); return; } @@ -201,6 +203,9 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() llinfos << "Inventory fetch completed" << llendl; setAllFoldersFetched(); + mBackgroundFetchActive = false; + mFolderFetchActive = false; + return; } @@ -230,80 +235,114 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() } const FetchQueueInfo info = mFetchQueue.front(); - LLViewerInventoryCategory* cat = gInventory.getCategory(info.mCatUUID); - // Category has been deleted, remove from queue. - if (!cat) + if (info.mIsCategory) { - mFetchQueue.pop_front(); - continue; - } + + LLViewerInventoryCategory* cat = gInventory.getCategory(info.mUUID); + + // Category has been deleted, remove from queue. + if (!cat) + { + mFetchQueue.pop_front(); + continue; + } - if (mFetchTimer.getElapsedTimeF32() > mMinTimeBetweenFetches && - LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) - { - // Category exists but has no children yet, fetch the descendants - // for now, just request every time and rely on retry timer to throttle. - if (cat->fetch()) + if (mFetchTimer.getElapsedTimeF32() > mMinTimeBetweenFetches && + LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) { - mFetchTimer.reset(); - mTimelyFetchPending = TRUE; + // Category exists but has no children yet, fetch the descendants + // for now, just request every time and rely on retry timer to throttle. + if (cat->fetch()) + { + mFetchTimer.reset(); + mTimelyFetchPending = TRUE; + } + else + { + // The catagory also tracks if it has expired and here it says it hasn't + // yet. Get out of here because nothing is going to happen until we + // update the timers. + break; + } } - else + // Do I have all my children? + else if (gInventory.isCategoryComplete(info.mUUID)) { - // The catagory also tracks if it has expired and here it says it hasn't - // yet. Get out of here because nothing is going to happen until we - // update the timers. + // Finished with this category, remove from queue. + mFetchQueue.pop_front(); + + // Add all children to queue. + LLInventoryModel::cat_array_t* categories; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); + for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); + it != categories->end(); + ++it) + { + mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(),info.mRecursive)); + } + + // We received a response in less than the fast time. + if (mTimelyFetchPending && mFetchTimer.getElapsedTimeF32() < fast_fetch_time) + { + // Shrink timeouts based on success. + mMinTimeBetweenFetches = llmax(mMinTimeBetweenFetches * 0.8f, 0.3f); + mMaxTimeBetweenFetches = llmax(mMaxTimeBetweenFetches * 0.8f, 10.f); + lldebugs << "Inventory fetch times shrunk to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << llendl; + } + + mTimelyFetchPending = FALSE; + continue; + } + else if (mFetchTimer.getElapsedTimeF32() > mMaxTimeBetweenFetches) + { + // Received first packet, but our num descendants does not match db's num descendants + // so try again later. + mFetchQueue.pop_front(); + + if (mNumFetchRetries++ < MAX_FETCH_RETRIES) + { + // push on back of queue + mFetchQueue.push_back(info); + } + mTimelyFetchPending = FALSE; + mFetchTimer.reset(); break; } + + // Not enough time has elapsed to do a new fetch + break; } - // Do I have all my children? - else if (gInventory.isCategoryComplete(info.mCatUUID)) + else { - // Finished with this category, remove from queue. - mFetchQueue.pop_front(); + LLViewerInventoryItem* itemp = gInventory.getItem(info.mUUID); - // Add all children to queue. - LLInventoryModel::cat_array_t* categories; - LLInventoryModel::item_array_t* items; - gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); - for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); - it != categories->end(); - ++it) + mFetchQueue.pop_front(); + if (!itemp) { - mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(),info.mRecursive)); + continue; } - // We received a response in less than the fast time. - if (mTimelyFetchPending && mFetchTimer.getElapsedTimeF32() < fast_fetch_time) + if (mFetchTimer.getElapsedTimeF32() > mMinTimeBetweenFetches) { - // Shrink timeouts based on success. - mMinTimeBetweenFetches = llmax(mMinTimeBetweenFetches * 0.8f, 0.3f); - mMaxTimeBetweenFetches = llmax(mMaxTimeBetweenFetches * 0.8f, 10.f); - lldebugs << "Inventory fetch times shrunk to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << llendl; + itemp->fetchFromServer(); + mFetchTimer.reset(); + mTimelyFetchPending = TRUE; } - - mTimelyFetchPending = FALSE; - continue; - } - else if (mFetchTimer.getElapsedTimeF32() > mMaxTimeBetweenFetches) - { - // Received first packet, but our num descendants does not match db's num descendants - // so try again later. - mFetchQueue.pop_front(); - - if (mNumFetchRetries++ < MAX_FETCH_RETRIES) + else if (itemp->mIsComplete) + { + mTimelyFetchPending = FALSE; + } + else if (mFetchTimer.getElapsedTimeF32() > mMaxTimeBetweenFetches) { - // push on back of queue mFetchQueue.push_back(info); + mFetchTimer.reset(); + mTimelyFetchPending = FALSE; } - mTimelyFetchPending = FALSE; - mFetchTimer.reset(); + // Not enough time has elapsed to do a new fetch break; } - - // Not enough time has elapsed to do a new fetch - break; } // @@ -313,15 +352,35 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() } } -void LLInventoryModelBackgroundFetch::incrBulkFetch(S16 fetching) +void LLInventoryModelBackgroundFetch::incrFetchCount(S16 fetching) { - mBulkFetchCount += fetching; - if (mBulkFetchCount < 0) + mFetchCount += fetching; + if (mFetchCount < 0) { - mBulkFetchCount = 0; + mFetchCount = 0; } } +class LLInventoryModelFetchItemResponder : public LLInventoryModel::fetchInventoryResponder +{ +public: + LLInventoryModelFetchItemResponder(const LLSD& request_sd) : LLInventoryModel::fetchInventoryResponder(request_sd) {}; + void result(const LLSD& content); + void error(U32 status, const std::string& reason); +}; + +void LLInventoryModelFetchItemResponder::result( const LLSD& content ) +{ + LLInventoryModel::fetchInventoryResponder::result(content); + LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); +} + +void LLInventoryModelFetchItemResponder::error( U32 status, const std::string& reason ) +{ + LLInventoryModel::fetchInventoryResponder::error(status, reason); + LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); +} + class LLInventoryModelFetchDescendentsResponder: public LLHTTPClient::Responder { @@ -458,7 +517,7 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content) } } - fetcher->incrBulkFetch(-1); + fetcher->incrFetchCount(-1); if (fetcher->isBulkFetchProcessingComplete()) { @@ -477,7 +536,7 @@ void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::str llinfos << "LLInventoryModelFetchDescendentsResponder::error " << status << ": " << reason << llendl; - fetcher->incrBulkFetch(-1); + fetcher->incrFetchCount(-1); if (status==499) // timed out { @@ -508,12 +567,13 @@ BOOL LLInventoryModelFetchDescendentsResponder::getIsRecursive(const LLUUID& cat // Bundle up a bunch of requests to send all at once. // static -void LLInventoryModelBackgroundFetch::bulkFetch(std::string url) +void LLInventoryModelBackgroundFetch::bulkFetch() { //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. //If there are items in mFetchQueue, we want to check the time since the last bulkFetch was //sent. If it exceeds our retry time, go ahead and fire off another batch. - //Stopbackgroundfetch will be run from the Responder instead of here. + LLViewerRegion* region = gAgent.getRegion(); + if (!region) return; S16 max_concurrent_fetches=8; F32 new_min_time = 0.5f; //HACK! Clean this up when old code goes away entirely. @@ -523,12 +583,13 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url) } if (gDisconnected || - (mBulkFetchCount > max_concurrent_fetches) || + (mFetchCount > max_concurrent_fetches) || (mFetchTimer.getElapsedTimeF32() < mMinTimeBetweenFetches)) { return; // just bail if we are disconnected } + U32 item_count=0; U32 folder_count=0; U32 max_batch_size=5; @@ -536,83 +597,159 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url) uuid_vec_t recursive_cats; - LLSD body; - LLSD body_lib; + LLSD folder_request_body; + LLSD folder_request_body_lib; + LLSD item_request_body; + LLSD item_request_body_lib; - while (!(mFetchQueue.empty()) && (folder_count < max_batch_size)) + while (!mFetchQueue.empty() + && (item_count + folder_count) < max_batch_size) { const FetchQueueInfo& fetch_info = mFetchQueue.front(); - const LLUUID &cat_id = fetch_info.mCatUUID; - if (cat_id.isNull()) //DEV-17797 - { - LLSD folder_sd; - folder_sd["folder_id"] = LLUUID::null.asString(); - folder_sd["owner_id"] = gAgent.getID(); - folder_sd["sort_order"] = (LLSD::Integer)sort_order; - folder_sd["fetch_folders"] = (LLSD::Boolean)FALSE; - folder_sd["fetch_items"] = (LLSD::Boolean)TRUE; - body["folders"].append(folder_sd); - folder_count++; - } - else - { - const LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); + if (fetch_info.mIsCategory) + { + const LLUUID &cat_id = fetch_info.mUUID; + if (cat_id.isNull()) //DEV-17797 + { + LLSD folder_sd; + folder_sd["folder_id"] = LLUUID::null.asString(); + folder_sd["owner_id"] = gAgent.getID(); + folder_sd["sort_order"] = (LLSD::Integer)sort_order; + folder_sd["fetch_folders"] = (LLSD::Boolean)FALSE; + folder_sd["fetch_items"] = (LLSD::Boolean)TRUE; + folder_request_body["folders"].append(folder_sd); + folder_count++; + } + else + { + const LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); - if (cat) - { - if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) - { - LLSD folder_sd; - folder_sd["folder_id"] = cat->getUUID(); - folder_sd["owner_id"] = cat->getOwnerID(); - folder_sd["sort_order"] = (LLSD::Integer)sort_order; - folder_sd["fetch_folders"] = TRUE; //(LLSD::Boolean)sFullFetchStarted; - folder_sd["fetch_items"] = (LLSD::Boolean)TRUE; - - if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) - body_lib["folders"].append(folder_sd); - else - body["folders"].append(folder_sd); - folder_count++; - } - // May already have this folder, but append child folders to list. - if (fetch_info.mRecursive) - { - LLInventoryModel::cat_array_t* categories; - LLInventoryModel::item_array_t* items; - gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); - for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); - it != categories->end(); - ++it) + if (cat) + { + if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) { - mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); - } - } - } - } - if (fetch_info.mRecursive) - recursive_cats.push_back(cat_id); + LLSD folder_sd; + folder_sd["folder_id"] = cat->getUUID(); + folder_sd["owner_id"] = cat->getOwnerID(); + folder_sd["sort_order"] = (LLSD::Integer)sort_order; + folder_sd["fetch_folders"] = TRUE; //(LLSD::Boolean)sFullFetchStarted; + folder_sd["fetch_items"] = (LLSD::Boolean)TRUE; + + if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) + folder_request_body_lib["folders"].append(folder_sd); + else + folder_request_body["folders"].append(folder_sd); + folder_count++; + } + // May already have this folder, but append child folders to list. + if (fetch_info.mRecursive) + { + LLInventoryModel::cat_array_t* categories; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); + for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); + it != categories->end(); + ++it) + { + mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); + } + } + } + } + if (fetch_info.mRecursive) + recursive_cats.push_back(cat_id); + } + else + { + LLViewerInventoryItem* itemp = gInventory.getItem(fetch_info.mUUID); + if (itemp) + { + LLSD item_sd; + item_sd["owner_id"] = itemp->getPermissions().getOwner(); + item_sd["item_id"] = itemp->getUUID(); + if (itemp->getPermissions().getOwner() == gAgent.getID()) + { + item_request_body.append(item_sd); + } + else + { + item_request_body_lib.append(item_sd); + } + //itemp->fetchFromServer(); + item_count++; + } + } mFetchQueue.pop_front(); } - if (folder_count > 0) + if (item_count + folder_count > 0) { - mBulkFetchCount++; - if (body["folders"].size()) + if (folder_count) { - LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(body, recursive_cats); - LLHTTPClient::post(url, body, fetcher, 300.0); + std::string url = region->getCapability("FetchInventoryDescendents2"); + mFetchCount++; + if (folder_request_body["folders"].size()) + { + LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); + LLHTTPClient::post(url, folder_request_body, fetcher, 300.0); + } + if (folder_request_body_lib["folders"].size()) + { + std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); + + LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); + LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0); + } } - if (body_lib["folders"].size()) + if (item_count) { - std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); - - LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(body_lib, recursive_cats); - LLHTTPClient::post(url_lib, body_lib, fetcher, 300.0); + std::string url; + + if (item_request_body.size()) + { + mFetchCount++; + url = region->getCapability("FetchInventory2"); + if (!url.empty()) + { + LLSD body; + body["agent_id"] = gAgent.getID(); + body["items"] = item_request_body; + + LLHTTPClient::post(url, body, new LLInventoryModelFetchItemResponder(body)); + } + //else + //{ + // LLMessageSystem* msg = gMessageSystem; + // msg->newMessage("FetchInventory"); + // msg->nextBlock("AgentData"); + // msg->addUUID("AgentID", gAgent.getID()); + // msg->addUUID("SessionID", gAgent.getSessionID()); + // msg->nextBlock("InventoryData"); + // msg->addUUID("OwnerID", mPermissions.getOwner()); + // msg->addUUID("ItemID", mUUID); + // gAgent.sendReliableMessage(); + //} + } + + if (item_request_body_lib.size()) + { + mFetchCount++; + + url = region->getCapability("FetchLib2"); + if (!url.empty()) + { + LLSD body; + body["agent_id"] = gAgent.getID(); + body["items"] = item_request_body_lib; + + LLHTTPClient::post(url, body, new LLInventoryModelFetchItemResponder(body)); + } + } } mFetchTimer.reset(); } + else if (isBulkFetchProcessingComplete()) { setAllFoldersFetched(); @@ -624,7 +761,7 @@ bool LLInventoryModelBackgroundFetch::fetchQueueContainsNoDescendentsOf(const LL for (fetch_queue_t::const_iterator it = mFetchQueue.begin(); it != mFetchQueue.end(); ++it) { - const LLUUID& fetch_id = (*it).mCatUUID; + const LLUUID& fetch_id = (*it).mUUID; if (gInventory.isObjectDescendentOf(fetch_id, cat_id)) return false; } diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index c35c785ceb..9dfedddd6d 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -48,7 +48,7 @@ public: // This gets triggered when performing a filter-search. void start(const LLUUID& cat_id = LLUUID::null, BOOL recursive = TRUE); - BOOL backgroundFetchActive() const; + BOOL folderFetchActive() const; bool isEverythingFetched() const; // completing the fetch once per session should be sufficient bool libraryFetchStarted() const; @@ -60,14 +60,13 @@ public: bool inventoryFetchInProgress() const; void findLostItems(); + void incrFetchCount(S16 fetching); protected: - void incrBulkFetch(S16 fetching); bool isBulkFetchProcessingComplete() const; - void bulkFetch(std::string url); + void bulkFetch(); void backgroundFetch(); static void backgroundFetchCB(void*); // background fetch idle function - void stopBackgroundFetch(); // stop fetch process void setAllFoldersFetched(); bool fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) const; @@ -77,7 +76,8 @@ private: BOOL mAllFoldersFetched; BOOL mBackgroundFetchActive; - S16 mBulkFetchCount; + bool mFolderFetchActive; + S16 mFetchCount; BOOL mTimelyFetchPending; S32 mNumFetchRetries; @@ -87,11 +87,11 @@ private: struct FetchQueueInfo { - FetchQueueInfo(const LLUUID& id, BOOL recursive) : - mCatUUID(id), mRecursive(recursive) - { - } - LLUUID mCatUUID; + FetchQueueInfo(const LLUUID& id, BOOL recursive, bool is_category = true) : + mUUID(id), mRecursive(recursive), mIsCategory(is_category) + {} + LLUUID mUUID; + bool mIsCategory; BOOL mRecursive; }; typedef std::deque<FetchQueueInfo> fetch_queue_t; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index acbec531b6..fabcd50c7d 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -33,16 +33,20 @@ #include "llagentwearables.h" #include "llappearancemgr.h" #include "llavataractions.h" +#include "llclipboard.h" #include "llfloaterinventory.h" #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llfolderview.h" -#include "llimfloater.h" +#include "llfolderviewitem.h" +#include "llfloaterimcontainer.h" #include "llimview.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llinventorymodelbackgroundfetch.h" +#include "llpreview.h" #include "llsidepanelinventory.h" +#include "lltrans.h" #include "llviewerattachmenu.h" #include "llviewerfoldertype.h" #include "llvoavatarself.h" @@ -52,8 +56,16 @@ static LLDefaultChildRegistry::Register<LLInventoryPanel> r("inventory_panel"); const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder"); const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder"); const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string(""); -static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER; +static const LLInventoryFolderViewModelBuilder INVENTORY_BRIDGE_BUILDER; +// statics +bool LLInventoryPanel::sColorSetInitialized = false; +LLUIColor LLInventoryPanel::sDefaultColor; +LLUIColor LLInventoryPanel::sDefaultHighlightColor; +LLUIColor LLInventoryPanel::sLibraryColor; +LLUIColor LLInventoryPanel::sLinkColor; + +const LLColor4U DEFAULT_WHITE(255, 255, 255); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLInventoryPanelObserver @@ -132,85 +144,94 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) : mAcceptsDragAndDrop(p.accepts_drag_and_drop), mAllowMultiSelect(p.allow_multi_select), mShowItemLinkOverlays(p.show_item_link_overlays), - mShowLoadStatus(p.show_load_status), + mShowEmptyMessage(p.show_empty_message), mViewsInitialized(false), mInvFVBridgeBuilder(NULL) { mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER; - // contex menu callbacks + if (!sColorSetInitialized) + { + sDefaultColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + sDefaultHighlightColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE); + sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE); + sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE); + sColorSetInitialized = true; + } + + // context menu callbacks mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryPanel::doToSelected, this, _2)); mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH)); mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND)); mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLInventoryPanel::doCreate, this, _2)); mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2)); mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this)); - mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars)); + mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this)); } -void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params) +LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id ) { - // Determine the root folder in case specified, and - // build the views starting with that folder. - - std::string start_folder_name(params.start_folder()); - - const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(start_folder_name); - - LLUUID root_id; - - if ("LIBRARY" == params.start_folder()) - { - root_id = gInventory.getLibraryRootFolderID(); - } - else - { - root_id = (preferred_type != LLFolderType::FT_NONE) - ? gInventory.findCategoryUUIDForType(preferred_type, false, false) - : LLUUID::null; - } - - if ((root_id == LLUUID::null) && !start_folder_name.empty()) - { - llwarns << "No category found that matches start_folder: " << start_folder_name << llendl; - root_id = LLUUID::generateNewID(); - } - - LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY, + LLFolderView::Params p(mParams.folder_view); + p.name = getName(); + p.title = getLabel(); + p.rect = LLRect(0, 0, getRect().getWidth(), 0); + p.parent_panel = this; + p.tool_tip = p.name; + p.listener = mInvFVBridgeBuilder->createBridge( LLAssetType::AT_CATEGORY, LLAssetType::AT_CATEGORY, LLInventoryType::IT_CATEGORY, this, + &mInventoryViewModel, NULL, root_id); + p.view_model = &mInventoryViewModel; + p.use_label_suffix = mParams.use_label_suffix; + p.allow_multiselect = mAllowMultiSelect; + p.show_empty_message = mShowEmptyMessage; + p.show_item_link_overlays = mShowItemLinkOverlays; + p.root = NULL; + p.options_menu = "menu_inventory.xml"; - mFolderRoot = createFolderView(new_listener, params.use_label_suffix()); + return LLUICtrlFactory::create<LLFolderView>(p); } void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params) { - LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD); + // save off copy of params + mParams = params; + // Clear up the root view + // Note: This needs to be done *before* we build the new folder view + LLUUID root_id = getRootFolderID(); + if (mFolderRoot) + { + removeItemID(root_id); + mFolderRoot->destroyView(); + mFolderRoot = NULL; + } mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves + { + // Determine the root folder in case specified, and + // build the views starting with that folder. + mFolderRoot = createFolderRoot(root_id); - buildFolderView(params); - + addItemID(root_id, mFolderRoot); + } mCommitCallbackRegistrar.popScope(); - mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); // Scroller - { LLRect scroller_view_rect = getRect(); scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); - LLScrollContainer::Params scroller_params(params.scroll()); + LLScrollContainer::Params scroller_params(mParams.scroll()); scroller_params.rect(scroller_view_rect); - mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroller_params); + mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params); addChild(mScroller); mScroller->addChild(mFolderRoot); mFolderRoot->setScrollContainer(mScroller); + mFolderRoot->setFollowsAll(); mFolderRoot->addChild(mFolderRoot->mStatusTextBox); - } // Set up the callbacks from the inventory we're viewing, and then build everything. mInventoryObserver = new LLInventoryPanelObserver(this); @@ -225,6 +246,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params) { initializeViews(); } + gIdleCallbacks.addFunction(onIdle, (void*)this); if (mSortOrderSetting != INHERIT_SORT_ORDER) @@ -237,23 +259,31 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params) } // hide inbox - getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX)); - getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX)); + getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX)); + getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX)); + // set the filter for the empty folder if the debug setting is on + if (gSavedSettings.getBOOL("DebugHideEmptySystemFolders")) + { + getFilter().setFilterEmptySystemFolders(); + } + + // keep track of the clipboard state so that we avoid filtering too much + mClipboardState = LLClipboard::instance().getGeneration(); + // Initialize base class params. - LLPanel::initFromParams(params); + LLPanel::initFromParams(mParams); } LLInventoryPanel::~LLInventoryPanel() { - if (mFolderRoot) - { - U32 sort_order = mFolderRoot->getSortOrder(); + gIdleCallbacks.deleteFunction(idle, this); + + U32 sort_order = getFolderViewModel()->getSorter().getSortOrder(); if (mSortOrderSetting != INHERIT_SORT_ORDER) { gSavedSettings.setU32(mSortOrderSetting, sort_order); } - } gIdleCallbacks.deleteFunction(onIdle, this); @@ -269,74 +299,68 @@ LLInventoryPanel::~LLInventoryPanel() void LLInventoryPanel::draw() { // Select the desired item (in case it wasn't loaded when the selection was requested) - mFolderRoot->updateSelection(); + updateSelection(); + LLPanel::draw(); } -LLInventoryFilter* LLInventoryPanel::getFilter() +const LLInventoryFilter& LLInventoryPanel::getFilter() const { - if (mFolderRoot) - { - return mFolderRoot->getFilter(); - } - return NULL; + return getFolderViewModel()->getFilter(); } -const LLInventoryFilter* LLInventoryPanel::getFilter() const +LLInventoryFilter& LLInventoryPanel::getFilter() { - if (mFolderRoot) - { - return mFolderRoot->getFilter(); - } - return NULL; + return getFolderViewModel()->getFilter(); } void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type) { if (filter_type == LLInventoryFilter::FILTERTYPE_OBJECT) - getFilter()->setFilterObjectTypes(types); + getFilter().setFilterObjectTypes(types); if (filter_type == LLInventoryFilter::FILTERTYPE_CATEGORY) - getFilter()->setFilterCategoryTypes(types); + getFilter().setFilterCategoryTypes(types); } U32 LLInventoryPanel::getFilterObjectTypes() const { - return mFolderRoot->getFilterObjectTypes(); + return getFilter().getFilterObjectTypes(); } U32 LLInventoryPanel::getFilterPermMask() const { - return mFolderRoot->getFilterPermissions(); + return getFilter().getFilterPermissions(); } void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask) { - getFilter()->setFilterPermissions(filter_perm_mask); + getFilter().setFilterPermissions(filter_perm_mask); } void LLInventoryPanel::setFilterWearableTypes(U64 types) { - getFilter()->setFilterWearableTypes(types); + getFilter().setFilterWearableTypes(types); } void LLInventoryPanel::setFilterSubString(const std::string& string) { - getFilter()->setFilterSubString(string); + getFilter().setFilterSubString(string); } const std::string LLInventoryPanel::getFilterSubString() { - return mFolderRoot->getFilterSubString(); + return getFilter().getFilterSubString(); } void LLInventoryPanel::setSortOrder(U32 order) { - getFilter()->setSortOrder(order); - if (getFilter()->isModified()) + LLInventorySort sorter(order); + if (order != getFolderViewModel()->getSorter().getSortOrder()) { - mFolderRoot->setSortOrder(order); + getFolderViewModel()->setSorter(sorter); + mFolderRoot->arrangeAll(); // try to keep selection onscreen, even if it wasn't to start with mFolderRoot->scrollToShowSelection(); } @@ -344,37 +368,32 @@ void LLInventoryPanel::setSortOrder(U32 order) U32 LLInventoryPanel::getSortOrder() const { - return mFolderRoot->getSortOrder(); -} - -void LLInventoryPanel::requestSort() -{ - mFolderRoot->requestSort(); + return getFolderViewModel()->getSorter().getSortOrder(); } void LLInventoryPanel::setSinceLogoff(BOOL sl) { - getFilter()->setDateRangeLastLogoff(sl); + getFilter().setDateRangeLastLogoff(sl); } void LLInventoryPanel::setHoursAgo(U32 hours) { - getFilter()->setHoursAgo(hours); + getFilter().setHoursAgo(hours); } void LLInventoryPanel::setFilterLinks(U64 filter_links) { - getFilter()->setFilterLinks(filter_links); + getFilter().setFilterLinks(filter_links); } void LLInventoryPanel::setShowFolderState(LLInventoryFilter::EFolderShow show) { - getFilter()->setShowFolderState(show); + getFilter().setShowFolderState(show); } LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState() { - return getFilter()->getShowFolderState(); + return getFilter().getShowFolderState(); } void LLInventoryPanel::modelChanged(U32 mask) @@ -398,11 +417,20 @@ void LLInventoryPanel::modelChanged(U32 mask) { const LLUUID& item_id = (*items_iter); const LLInventoryObject* model_item = model->getObject(item_id); - LLFolderViewItem* view_item = mFolderRoot->getItemByID(item_id); + LLFolderViewItem* view_item = getItemByID(item_id); + LLFolderViewModelItemInventory* viewmodel_item = + static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL); // LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item // to folder is the fast way to get a folder without searching through folders tree. - LLFolderViewFolder* view_folder = dynamic_cast<LLFolderViewFolder*>(view_item); + LLFolderViewFolder* view_folder = NULL; + + // Check requires as this item might have already been deleted + // as a child of its deleted parent. + if (model_item && view_item) + { + view_folder = dynamic_cast<LLFolderViewFolder*>(view_item); + } ////////////////////////////// // LABEL Operation @@ -413,7 +441,7 @@ void LLInventoryPanel::modelChanged(U32 mask) if (view_item) { // Request refresh on this item (also flags for filtering) - LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getListener(); + LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getViewModelItem(); if(bridge) { // Clear the display name first, so it gets properly re-built during refresh() bridge->clearDisplayName(); @@ -429,11 +457,15 @@ void LLInventoryPanel::modelChanged(U32 mask) if (mask & LLInventoryObserver::REBUILD) { handled = true; - if (model_item && view_item) + if (model_item && view_item && viewmodel_item) { + const LLUUID& idp = viewmodel_item->getUUID(); view_item->destroyView(); + removeItemID(idp); } view_item = buildNewViews(item_id); + viewmodel_item = + static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL); view_folder = dynamic_cast<LLFolderViewFolder *>(view_item); } @@ -455,7 +487,7 @@ void LLInventoryPanel::modelChanged(U32 mask) { if (view_folder) { - view_folder->requestSort(); + view_folder->getViewModelItem()->requestSort(); } } @@ -490,20 +522,24 @@ void LLInventoryPanel::modelChanged(U32 mask) else if (model_item && view_item) { // Don't process the item if it is the root - if (view_item->getRoot() != view_item) + if (view_item->getParentFolder()) { - LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolderRoot->getItemByID(model_item->getParentUUID()); + LLFolderViewFolder* new_parent = (LLFolderViewFolder*)getItemByID(model_item->getParentUUID()); // Item has been moved. if (view_item->getParentFolder() != new_parent) { if (new_parent != NULL) { // Item is to be moved and we found its new parent in the panel's directory, so move the item's UI. - view_item->getParentFolder()->extractItem(view_item); - view_item->addToFolder(new_parent, mFolderRoot); + view_item->addToFolder(new_parent); + addItemID(viewmodel_item->getUUID(), view_item); } else { + // Remove the item ID before destroying the view because the view-model-item gets + // destroyed when the view is destroyed + removeItemID(viewmodel_item->getUUID()); + // Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that // doesn't include trash). Just remove the item's UI. view_item->destroyView(); @@ -515,9 +551,10 @@ void LLInventoryPanel::modelChanged(U32 mask) ////////////////////////////// // REMOVE Operation // This item has been removed from memory, but its associated UI element still exists. - else if (!model_item && view_item) + else if (!model_item && view_item && viewmodel_item) { // Remove the item's UI. + removeItemID(viewmodel_item->getUUID()); view_item->destroyView(); } } @@ -529,6 +566,43 @@ LLFolderView* LLInventoryPanel::getRootFolder() return mFolderRoot; } +LLUUID LLInventoryPanel::getRootFolderID() +{ + if (mFolderRoot && mFolderRoot->getViewModelItem()) + { + return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot->getViewModelItem())->getUUID(); + + } + else + { + LLUUID root_id; + if (mParams.start_folder.id.isChosen()) + { + root_id = mParams.start_folder.id; + } + else + { + const LLFolderType::EType preferred_type = mParams.start_folder.type.isChosen() + ? mParams.start_folder.type + : LLViewerFolderType::lookupTypeFromNewCategoryName(mParams.start_folder.name); + + if ("LIBRARY" == mParams.start_folder.name()) + { + root_id = gInventory.getLibraryRootFolderID(); + } + else if (preferred_type != LLFolderType::FT_NONE) + { + root_id = gInventory.findCategoryUUIDForType(preferred_type, false); + if (root_id.isNull()) + { + llwarns << "Could not find folder of type " << preferred_type << llendl; + root_id.generateNewID(); + } + } + } + return root_id; + } +} // static void LLInventoryPanel::onIdle(void *userdata) @@ -548,16 +622,73 @@ void LLInventoryPanel::onIdle(void *userdata) } } -const LLUUID& LLInventoryPanel::getRootFolderID() const +struct DirtyFilterFunctor : public LLFolderViewFunctor +{ + /*virtual*/ void doFolder(LLFolderViewFolder* folder) + { + folder->getViewModelItem()->dirtyFilter(); + } + /*virtual*/ void doItem(LLFolderViewItem* item) + { + item->getViewModelItem()->dirtyFilter(); + } +}; + +void LLInventoryPanel::idle(void* user_data) { - return mFolderRoot->getListener()->getUUID(); + LLInventoryPanel* panel = (LLInventoryPanel*)user_data; + // Nudge the filter if the clipboard state changed + if (panel->mClipboardState != LLClipboard::instance().getGeneration()) + { + panel->mClipboardState = LLClipboard::instance().getGeneration(); + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + LLFolderViewFolder* trash_folder = panel->getFolderByID(trash_id); + if (trash_folder) + { + DirtyFilterFunctor dirtyFilterFunctor; + trash_folder->applyFunctorToChildren(dirtyFilterFunctor); + } + + } + + panel->mFolderRoot->update(); + // while dragging, update selection rendering to reflect single/multi drag status + if (LLToolDragAndDrop::getInstance()->hasMouseCapture()) + { + EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept(); + if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE) + { + panel->mFolderRoot->setShowSingleSelection(TRUE); + } + else + { + panel->mFolderRoot->setShowSingleSelection(FALSE); + } +} + else + { + panel->mFolderRoot->setShowSingleSelection(FALSE); + } } + void LLInventoryPanel::initializeViews() { if (!gInventory.isInventoryUsable()) return; - rebuildViewsFor(getRootFolderID()); + LLUUID root_id = getRootFolderID(); + if (root_id.notNull()) + { + buildNewViews(getRootFolderID()); + } + else + { + // Default case: always add "My Inventory" first, "Library" second + buildNewViews(gInventory.getRootFolderID()); // My Inventory + buildNewViews(gInventory.getLibraryRootFolderID()); // Library + } + + gIdleCallbacks.addFunction(idle, this); mViewsInitialized = true; @@ -567,14 +698,14 @@ void LLInventoryPanel::initializeViews() if (gAgent.isFirstLogin()) { // Auto open the user's library - LLFolderViewFolder* lib_folder = mFolderRoot->getFolderByID(gInventory.getLibraryRootFolderID()); + LLFolderViewFolder* lib_folder = getFolderByID(gInventory.getLibraryRootFolderID()); if (lib_folder) { lib_folder->setOpen(TRUE); } // Auto close the user's my inventory folder - LLFolderViewFolder* my_inv_folder = mFolderRoot->getFolderByID(gInventory.getRootFolderID()); + LLFolderViewFolder* my_inv_folder = getFolderByID(gInventory.getRootFolderID()); if (my_inv_folder) { my_inv_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN); @@ -582,78 +713,35 @@ void LLInventoryPanel::initializeViews() } } -LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id) -{ - // Destroy the old view for this ID so we can rebuild it. - LLFolderViewItem* old_view = mFolderRoot->getItemByID(id); - if (old_view) - { - old_view->destroyView(); - } - - return buildNewViews(id); -} - -LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix) -{ - LLRect folder_rect(0, - 0, - getRect().getWidth(), - 0); - - LLFolderView::Params p; - - p.name = getName(); - p.title = getLabel(); - p.rect = folder_rect; - p.parent_panel = this; - p.tool_tip = p.name; - p.listener = bridge; - p.use_label_suffix = useLabelSuffix; - p.allow_multiselect = mAllowMultiSelect; - p.show_load_status = mShowLoadStatus; - - return LLUICtrlFactory::create<LLFolderView>(p); -} LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge) { - LLFolderViewFolder::Params params; + LLFolderViewFolder::Params params(mParams.folder); params.name = bridge->getDisplayName(); - params.icon = bridge->getIcon(); - params.icon_open = bridge->getOpenIcon(); - - if (mShowItemLinkOverlays) // if false, then links show up just like normal items - { - params.icon_overlay = LLUI::getUIImage("Inv_Link"); - } - params.root = mFolderRoot; params.listener = bridge; params.tool_tip = params.name; + params.font_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultColor)); + params.font_highlight_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultHighlightColor)); + return LLUICtrlFactory::create<LLFolderViewFolder>(params); } LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge) { - LLFolderViewItem::Params params; + LLFolderViewItem::Params params(mParams.item); params.name = bridge->getDisplayName(); - params.icon = bridge->getIcon(); - params.icon_open = bridge->getOpenIcon(); - - if (mShowItemLinkOverlays) // if false, then links show up just like normal items - { - params.icon_overlay = LLUI::getUIImage("Inv_Link"); - } - params.creation_date = bridge->getCreationDate(); params.root = mFolderRoot; params.listener = bridge; params.rect = LLRect (0, 0, 0, 0); params.tool_tip = params.name; + + params.font_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultColor)); + params.font_highlight_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultHighlightColor)); return LLUICtrlFactory::create<LLFolderViewItem>(params); } @@ -661,20 +749,15 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) { LLInventoryObject const* objectp = gInventory.getObject(id); - LLUUID root_id = mFolderRoot->getListener()->getUUID(); - LLFolderViewFolder* parent_folder = NULL; - LLFolderViewItem* itemp = NULL; - if (id == root_id) - { - parent_folder = mFolderRoot; - } - else if (objectp) - { + if (!objectp) return NULL; + + LLFolderViewItem* folder_view_item = getItemByID(id); + const LLUUID &parent_id = objectp->getParentUUID(); - parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id); + LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id); - if (parent_folder) + if (!folder_view_item && parent_folder) { if (objectp->getType() <= LLAssetType::AT_NONE || objectp->getType() >= LLAssetType::AT_COUNT) @@ -692,13 +775,12 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) objectp->getType(), LLInventoryType::IT_CATEGORY, this, + &mInventoryViewModel, mFolderRoot, objectp->getUUID()); if (new_listener) { - LLFolderViewFolder* folderp = createFolderViewFolder(new_listener); - folderp->setItemSortOrder(mFolderRoot->getSortOrder()); - itemp = folderp; + folder_view_item = createFolderViewFolder(new_listener); } } else @@ -709,28 +791,28 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) item->getActualType(), item->getInventoryType(), this, + &mInventoryViewModel, mFolderRoot, item->getUUID(), item->getFlags()); if (new_listener) { - itemp = createFolderViewItem(new_listener); + folder_view_item = createFolderViewItem(new_listener); } } - if (itemp) + if (folder_view_item) { - itemp->addToFolder(parent_folder, mFolderRoot); - } + llassert(parent_folder != NULL); + folder_view_item->addToFolder(parent_folder); + addItemID(id, folder_view_item); } } // If this is a folder, add the children of the folder and recursively add any // child folders. - if (id.isNull() - || (objectp - && objectp->getType() == LLAssetType::AT_CATEGORY)) + if (folder_view_item && objectp->getType() == LLAssetType::AT_CATEGORY) { LLViewerInventoryCategory::cat_array_t* categories; LLViewerInventoryItem::item_array_t* items; @@ -747,7 +829,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) } } - if(items && parent_folder) + if(items) { for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin(); item_iter != items->end(); @@ -760,7 +842,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) mInventory->unlockDirectDescendentArrays(id); } - return itemp; + return folder_view_item; } // bit of a hack to make sure the inventory is open. @@ -771,8 +853,8 @@ void LLInventoryPanel::openStartFolderOrMyInventory() { LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child); if (fchild - && fchild->getListener() - && fchild->getListener()->getUUID() == gInventory.getRootFolderID()) + && fchild->getViewModelItem() + && fchild->getViewModelItem()->getName() == "My Inventory") { fchild->setOpen(TRUE); break; @@ -789,7 +871,7 @@ void LLInventoryPanel::openSelected() { LLFolderViewItem* folder_item = mFolderRoot->getCurSelectedItem(); if(!folder_item) return; - LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener(); + LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem(); if(!bridge) return; bridge->openItem(); } @@ -806,7 +888,7 @@ BOOL LLInventoryPanel::handleHover(S32 x, S32 y, MASK mask) if(handled) { ECursorType cursor = getWindow()->getCursor(); - if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() && cursor == UI_CURSOR_ARROW) + if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() && cursor == UI_CURSOR_ARROW) { // replace arrow cursor with arrow and hourglass cursor getWindow()->setCursor(UI_CURSOR_WORKING); @@ -893,7 +975,7 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc { return; } - mFolderRoot->setSelectionByID(obj_id, take_keyboard_focus); + setSelectionByID(obj_id, take_keyboard_focus); } void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb) @@ -906,7 +988,7 @@ void LLInventoryPanel::setSelectCallback(const boost::function<void (const std:: void LLInventoryPanel::clearSelection() { - mFolderRoot->clearSelection(); + mSelectThisID.setNull(); } void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action) @@ -915,7 +997,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it mCompletionObserver->reset(); for (std::deque<LLFolderViewItem*>::const_iterator it = items.begin(); it != items.end(); ++it) { - LLUUID id = (*it)->getListener()->getUUID(); + LLUUID id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID(); LLViewerInventoryItem* inv_item = mInventory->getItem(id); if (inv_item && !inv_item->isFinished()) @@ -935,40 +1017,34 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it } } -void LLInventoryPanel::doToSelected(const LLSD& userdata) -{ - mFolderRoot->doToSelected(&gInventory, userdata); -} - void LLInventoryPanel::doCreate(const LLSD& userdata) { - menu_create_inventory_item(mFolderRoot, LLFolderBridge::sSelf.get(), userdata); + reset_inventory_filter(); + menu_create_inventory_item(this, LLFolderBridge::sSelf.get(), userdata); } bool LLInventoryPanel::beginIMSession() { - std::set<LLUUID> selected_items = mFolderRoot->getSelectionList(); + std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList(); std::string name; - static int session_num = 1; LLDynamicArray<LLUUID> members; EInstantMessage type = IM_SESSION_CONFERENCE_START; - std::set<LLUUID>::const_iterator iter; + std::set<LLFolderViewItem*>::const_iterator iter; for (iter = selected_items.begin(); iter != selected_items.end(); iter++) { - LLUUID item = *iter; - LLFolderViewItem* folder_item = mFolderRoot->getItemByID(item); + LLFolderViewItem* folder_item = (*iter); if(folder_item) { - LLFolderViewEventListener* fve_listener = folder_item->getListener(); + LLFolderViewModelItemInventory* fve_listener = static_cast<LLFolderViewModelItemInventory*>(folder_item->getViewModelItem()); if (fve_listener && (fve_listener->getInventoryType() == LLInventoryType::IT_CATEGORY)) { - LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getListener(); + LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getViewModelItem(); if(!bridge) return true; LLViewerInventoryCategory* cat = bridge->getCategory(); if(!cat) return true; @@ -1002,9 +1078,7 @@ bool LLInventoryPanel::beginIMSession() } else { - LLFolderViewItem* folder_item = mFolderRoot->getItemByID(item); - if(!folder_item) return true; - LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getListener(); + LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getViewModelItem(); if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD) { @@ -1030,13 +1104,13 @@ bool LLInventoryPanel::beginIMSession() if (name.empty()) { - name = llformat("Session %d", session_num++); + name = LLTrans::getString("conference-title"); } LLUUID session_id = gIMMgr->addSession(name, type, members[0], members); if (session_id != LLUUID::null) { - LLIMFloater::show(session_id); + LLFloaterIMContainer::getInstance()->showConversation(session_id); } return true; @@ -1045,13 +1119,13 @@ bool LLInventoryPanel::beginIMSession() bool LLInventoryPanel::attachObject(const LLSD& userdata) { // Copy selected item UUIDs to a vector. - std::set<LLUUID> selected_items = mFolderRoot->getSelectionList(); + std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList(); uuid_vec_t items; - for (std::set<LLUUID>::const_iterator set_iter = selected_items.begin(); + for (std::set<LLFolderViewItem*>::const_iterator set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter) { - items.push_back(*set_iter); + items.push_back(static_cast<LLFolderViewModelItemInventory*>((*set_iter)->getViewModelItem())->getUUID()); } // Attach selected items. @@ -1064,7 +1138,7 @@ bool LLInventoryPanel::attachObject(const LLSD& userdata) BOOL LLInventoryPanel::getSinceLogoff() { - return getFilter()->isSinceLogoff(); + return getFilter().isSinceLogoff(); } // DEBUG ONLY @@ -1096,30 +1170,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; } } } @@ -1136,7 +1203,7 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open) { floater_inventory->openFloater(); - res = sidepanel_inventory->getActivePanel(); + res = inventory_panel->getActivePanel(); } return res; @@ -1155,7 +1222,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; @@ -1171,10 +1237,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; @@ -1184,11 +1249,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) { @@ -1204,14 +1264,150 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L void LLInventoryPanel::addHideFolderType(LLFolderType::EType folder_type) { - getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << folder_type)); + getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << folder_type)); } BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) const { - return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type)); + return !(getFilter().getFilterCategoryTypes() & (1ULL << folder_type)); +} + +void LLInventoryPanel::addItemID( const LLUUID& id, LLFolderViewItem* itemp ) +{ + mItemMap[id] = itemp; +} + +void LLInventoryPanel::removeItemID(const LLUUID& id) +{ + LLInventoryModel::cat_array_t categories; + LLInventoryModel::item_array_t items; + gInventory.collectDescendents(id, categories, items, TRUE); + + mItemMap.erase(id); + + for (LLInventoryModel::cat_array_t::iterator it = categories.begin(), end_it = categories.end(); + it != end_it; + ++it) + { + mItemMap.erase((*it)->getUUID()); +} + + for (LLInventoryModel::item_array_t::iterator it = items.begin(), end_it = items.end(); + it != end_it; + ++it) + { + mItemMap.erase((*it)->getUUID()); + } +} + +LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID"); +LLFolderViewItem* LLInventoryPanel::getItemByID(const LLUUID& id) +{ + LLFastTimer _(FTM_GET_ITEM_BY_ID); + + std::map<LLUUID, LLFolderViewItem*>::iterator map_it; + map_it = mItemMap.find(id); + if (map_it != mItemMap.end()) + { + return map_it->second; + } + + return NULL; +} + +LLFolderViewFolder* LLInventoryPanel::getFolderByID(const LLUUID& id) +{ + LLFolderViewItem* item = getItemByID(id); + return dynamic_cast<LLFolderViewFolder*>(item); +} + + +void LLInventoryPanel::setSelectionByID( const LLUUID& obj_id, BOOL take_keyboard_focus ) +{ + LLFolderViewItem* itemp = getItemByID(obj_id); + if(itemp && itemp->getViewModelItem()) + { + itemp->arrangeAndSet(TRUE, take_keyboard_focus); + mSelectThisID.setNull(); + return; + } + else + { + // save the desired item to be selected later (if/when ready) + mSelectThisID = obj_id; + } +} + +void LLInventoryPanel::updateSelection() +{ + if (mSelectThisID.notNull()) + { + setSelectionByID(mSelectThisID, false); + } +} + +void LLInventoryPanel::doToSelected(const LLSD& userdata) +{ + LLInventoryAction::doToSelected(mInventory, mFolderRoot, userdata.asString()); + + return; +} + +BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask ) +{ + BOOL handled = FALSE; + switch (key) + { + case KEY_RETURN: + // Open selected items if enter key hit on the inventory panel + if (mask == MASK_NONE) + { + LLInventoryAction::doToSelected(mInventory, mFolderRoot, "open"); + handled = TRUE; + } + break; + case KEY_DELETE: + case KEY_BACKSPACE: + // Delete selected items if delete or backspace key hit on the inventory panel + // Note: on Mac laptop keyboards, backspace and delete are one and the same + if (isSelectionRemovable() && (mask == MASK_NONE)) + { + LLInventoryAction::doToSelected(mInventory, mFolderRoot, "delete"); + handled = TRUE; + } + break; + } + return handled; } +bool LLInventoryPanel::isSelectionRemovable() +{ + bool can_delete = false; + if (mFolderRoot) + { + std::set<LLFolderViewItem*> selection_set = mFolderRoot->getSelectionList(); + if (!selection_set.empty()) + { + can_delete = true; + for (std::set<LLFolderViewItem*>::iterator iter = selection_set.begin(); + iter != selection_set.end(); + ++iter) + { + LLFolderViewItem *item = *iter; + const LLFolderViewModelItemInventory *listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem()); + if (!listener) + { + can_delete = false; + } + else + { + can_delete &= listener->isItemRemovable() && !listener->isItemInTrash(); + } + } + } + } + return can_delete; +} /************************************************************************/ /* Recent Inventory Panel related class */ @@ -1230,7 +1426,7 @@ public: { LLInventoryPanel::initFromParams(p); // turn on inbox for recent items - getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX)); + getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX)); } protected: @@ -1245,3 +1441,34 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params) mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER; } +namespace LLInitParam +{ + void TypeValues<LLFolderType::EType>::declareValues() + { + declare(LLFolderType::lookup(LLFolderType::FT_TEXTURE) , LLFolderType::FT_TEXTURE); + declare(LLFolderType::lookup(LLFolderType::FT_SOUND) , LLFolderType::FT_SOUND); + declare(LLFolderType::lookup(LLFolderType::FT_CALLINGCARD) , LLFolderType::FT_CALLINGCARD); + declare(LLFolderType::lookup(LLFolderType::FT_LANDMARK) , LLFolderType::FT_LANDMARK); + declare(LLFolderType::lookup(LLFolderType::FT_CLOTHING) , LLFolderType::FT_CLOTHING); + declare(LLFolderType::lookup(LLFolderType::FT_OBJECT) , LLFolderType::FT_OBJECT); + declare(LLFolderType::lookup(LLFolderType::FT_NOTECARD) , LLFolderType::FT_NOTECARD); + declare(LLFolderType::lookup(LLFolderType::FT_ROOT_INVENTORY) , LLFolderType::FT_ROOT_INVENTORY); + declare(LLFolderType::lookup(LLFolderType::FT_LSL_TEXT) , LLFolderType::FT_LSL_TEXT); + declare(LLFolderType::lookup(LLFolderType::FT_BODYPART) , LLFolderType::FT_BODYPART); + declare(LLFolderType::lookup(LLFolderType::FT_TRASH) , LLFolderType::FT_TRASH); + declare(LLFolderType::lookup(LLFolderType::FT_SNAPSHOT_CATEGORY), LLFolderType::FT_SNAPSHOT_CATEGORY); + declare(LLFolderType::lookup(LLFolderType::FT_LOST_AND_FOUND) , LLFolderType::FT_LOST_AND_FOUND); + declare(LLFolderType::lookup(LLFolderType::FT_ANIMATION) , LLFolderType::FT_ANIMATION); + declare(LLFolderType::lookup(LLFolderType::FT_GESTURE) , LLFolderType::FT_GESTURE); + declare(LLFolderType::lookup(LLFolderType::FT_FAVORITE) , LLFolderType::FT_FAVORITE); + declare(LLFolderType::lookup(LLFolderType::FT_ENSEMBLE_START) , LLFolderType::FT_ENSEMBLE_START); + declare(LLFolderType::lookup(LLFolderType::FT_ENSEMBLE_END) , LLFolderType::FT_ENSEMBLE_END); + declare(LLFolderType::lookup(LLFolderType::FT_CURRENT_OUTFIT) , LLFolderType::FT_CURRENT_OUTFIT); + declare(LLFolderType::lookup(LLFolderType::FT_OUTFIT) , LLFolderType::FT_OUTFIT); + declare(LLFolderType::lookup(LLFolderType::FT_MY_OUTFITS) , LLFolderType::FT_MY_OUTFITS); + declare(LLFolderType::lookup(LLFolderType::FT_MESH ) , LLFolderType::FT_MESH ); + declare(LLFolderType::lookup(LLFolderType::FT_INBOX) , LLFolderType::FT_INBOX); + declare(LLFolderType::lookup(LLFolderType::FT_OUTBOX) , LLFolderType::FT_OUTBOX); + declare(LLFolderType::lookup(LLFolderType::FT_BASIC_ROOT) , LLFolderType::FT_BASIC_ROOT); + } +} diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 2a24327115..00a90325ad 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -30,6 +30,8 @@ #include "llassetstorage.h" #include "lldarray.h" +#include "llfolderviewitem.h" +#include "llfolderviewmodelinventory.h" #include "llfloater.h" #include "llinventory.h" #include "llinventoryfilter.h" @@ -38,22 +40,19 @@ #include "lluictrlfactory.h" #include <set> -class LLFolderView; -class LLFolderViewFolder; -class LLFolderViewItem; -class LLInventoryFilter; -class LLInventoryModel; class LLInvFVBridge; -class LLInventoryFVBridgeBuilder; -class LLMenuBarGL; -class LLCheckBoxCtrl; -class LLSpinCtrl; -class LLTextBox; -class LLIconCtrl; -class LLSaveFolderState; -class LLFilterEditor; -class LLTabContainer; +class LLInventoryFolderViewModelBuilder; class LLInvPanelComplObserver; +class LLFolderViewModelInventory; + +namespace LLInitParam +{ + template<> + struct TypeValues<LLFolderType::EType> : public TypeValuesHelper<LLFolderType::EType> + { + static void declareValues(); + }; +} class LLInventoryPanel : public LLPanel { @@ -74,6 +73,19 @@ public: {} }; + struct StartFolder : public LLInitParam::ChoiceBlock<StartFolder> + { + Alternative<std::string> name; + Alternative<LLUUID> id; + Alternative<LLFolderType::EType> type; + + StartFolder() + : name("name"), + id("id"), + type("type") + {} + }; + struct Params : public LLInitParam::Block<Params, LLPanel::Params> { @@ -82,11 +94,14 @@ public: Optional<bool> allow_multi_select; Optional<bool> show_item_link_overlays; Optional<Filter> filter; - Optional<std::string> start_folder; + Optional<StartFolder> start_folder; Optional<bool> use_label_suffix; - Optional<bool> show_load_status; + Optional<bool> show_empty_message; Optional<LLScrollContainer::Params> scroll; Optional<bool> accepts_drag_and_drop; + Optional<LLFolderView::Params> folder_view; + Optional<LLFolderViewFolder::Params> folder; + Optional<LLFolderViewItem::Params> item; Params() : sort_order_setting("sort_order_setting"), @@ -96,27 +111,39 @@ public: filter("filter"), start_folder("start_folder"), use_label_suffix("use_label_suffix", true), - show_load_status("show_load_status"), + show_empty_message("show_empty_message", true), scroll("scroll"), - accepts_drag_and_drop("accepts_drag_and_drop") + accepts_drag_and_drop("accepts_drag_and_drop"), + folder_view("folder_view"), + folder("folder"), + item("item") {} }; + struct InventoryState : public LLInitParam::Block<InventoryState> + { + Mandatory<LLInventoryFilter::Params> filter; + Mandatory<LLInventorySort::Params> sort; + }; + //-------------------------------------------------------------------- // Initialization //-------------------------------------------------------------------- protected: LLInventoryPanel(const Params&); void initFromParams(const Params&); + friend class LLUICtrlFactory; public: virtual ~LLInventoryPanel(); public: LLInventoryModel* getModel() { return mInventory; } + LLFolderViewModelInventory& getRootViewModel() { return mInventoryViewModel; } // LLView methods void draw(); + /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask ); BOOL handleHover(S32 x, S32 y, MASK mask); BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, @@ -135,8 +162,9 @@ public: void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus); void setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb); void clearSelection(); - LLInventoryFilter* getFilter(); - const LLInventoryFilter* getFilter() const; + bool isSelectionRemovable(); + LLInventoryFilter& getFilter(); + const LLInventoryFilter& getFilter() const; void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT); U32 getFilterObjectTypes() const; void setFilterPermMask(PermissionMask filter_perm_mask); @@ -154,16 +182,20 @@ public: // This method is called when something has changed about the inventory. void modelChanged(U32 mask); LLFolderView* getRootFolder(); + LLUUID getRootFolderID(); LLScrollContainer* getScrollableContainer() { return mScroller; } void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); + LLHandle<LLInventoryPanel> getInventoryPanelHandle() const { return getDerivedHandle<LLInventoryPanel>(); } + // Callbacks void doToSelected(const LLSD& userdata); void doCreate(const LLSD& userdata); bool beginIMSession(); bool attachObject(const LLSD& userdata); - + static void idle(void* user_data); + // DEBUG ONLY: static void dumpSelectionInformation(void* user_data); @@ -178,29 +210,44 @@ public: static void openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id); + void addItemID(const LLUUID& id, LLFolderViewItem* itemp); + void removeItemID(const LLUUID& id); + LLFolderViewItem* getItemByID(const LLUUID& id); + LLFolderViewFolder* getFolderByID(const LLUUID& id); + void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus); + void updateSelection(); + + LLFolderViewModelInventory* getFolderViewModel(); + const LLFolderViewModelInventory* getFolderViewModel() const; + protected: void openStartFolderOrMyInventory(); // open the first level of inventory void onItemsCompletion(); // called when selected items are complete + LLUUID mSelectThisID; LLInventoryModel* mInventory; LLInventoryObserver* mInventoryObserver; LLInvPanelComplObserver* mCompletionObserver; - BOOL mAcceptsDragAndDrop; - BOOL mAllowMultiSelect; - BOOL mShowItemLinkOverlays; // Shows link graphic over inventory item icons - BOOL mShowLoadStatus; + bool mAcceptsDragAndDrop; + bool mAllowMultiSelect; + bool mShowItemLinkOverlays; // Shows link graphic over inventory item icons + bool mShowEmptyMessage; LLFolderView* mFolderRoot; LLScrollContainer* mScroller; + LLFolderViewModelInventory mInventoryViewModel; + Params mParams; // stored copy of parameter block + + std::map<LLUUID, LLFolderViewItem*> mItemMap; /** - * Pointer to LLInventoryFVBridgeBuilder. + * Pointer to LLInventoryFolderViewModelBuilder. * * It is set in LLInventoryPanel's constructor and can be overridden in derived classes with * another implementation. * Take into account it will not be deleted by LLInventoryPanel itself. */ - const LLInventoryFVBridgeBuilder* mInvFVBridgeBuilder; + const LLInventoryFolderViewModelBuilder* mInvFVBridgeBuilder; //-------------------------------------------------------------------- @@ -213,10 +260,10 @@ public: void setSortOrder(U32 order); U32 getSortOrder() const; - void requestSort(); private: std::string mSortOrderSetting; + int mClipboardState; //-------------------------------------------------------------------- // Hidden folders @@ -225,26 +272,27 @@ public: void addHideFolderType(LLFolderType::EType folder_type); public: - BOOL getIsViewsInitialized() const { return mViewsInitialized; } - const LLUUID& getRootFolderID() const; + BOOL getIsViewsInitialized() const { return mViewsInitialized; } protected: // Builds the UI. Call this once the inventory is usable. void initializeViews(); - LLFolderViewItem* rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views. - virtual void buildFolderView(const LLInventoryPanel::Params& params); + // Specific inventory colors + static bool sColorSetInitialized; + static LLUIColor sDefaultColor; + static LLUIColor sDefaultHighlightColor; + static LLUIColor sLibraryColor; + static LLUIColor sLinkColor; + LLFolderViewItem* buildNewViews(const LLUUID& id); BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const; - virtual LLFolderView* createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix); + virtual LLFolderView * createFolderRoot(LLUUID root_id ); virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge); virtual LLFolderViewItem* createFolderViewItem(LLInvFVBridge * bridge); private: - BOOL mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild() - BOOL mViewsInitialized; // Views have been generated - // UUID of category from which hierarchy should be built. Set with the - // "start_folder" xml property. Default is LLUUID::null that means total Inventory hierarchy. - LLUUID mStartFolderID; + bool mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild() + bool mViewsInitialized; // Views have been generated }; #endif // LL_LLINVENTORYPANEL_H diff --git a/indra/newview/lllistcontextmenu.h b/indra/newview/lllistcontextmenu.h index fabd68ee20..04d3314829 100644 --- a/indra/newview/lllistcontextmenu.h +++ b/indra/newview/lllistcontextmenu.h @@ -37,7 +37,7 @@ class LLContextMenu; /** * Context menu for single or multiple list items. * - * Derived classes must implement contextMenu(). + * Derived classes must implement createMenu(). * * Typical usage: * <code> diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp new file mode 100644 index 0000000000..97ba5b634a --- /dev/null +++ b/indra/newview/lllocalbitmaps.cpp @@ -0,0 +1,940 @@ +/** + * @file lllocalbitmaps.cpp + * @author Vaalith Jinn + * @brief Local Bitmaps source + * + * $LicenseInfo:firstyear=2011&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 headers */ +#include "llviewerprecompiledheaders.h" + +/* own header */ +#include "lllocalbitmaps.h" + +/* boost: will not compile unless equivalent is undef'd, beware. */ +#include "fix_macros.h" +#include <boost/filesystem.hpp> + +/* image compression headers. */ +#include "llimagebmp.h" +#include "llimagetga.h" +#include "llimagejpeg.h" +#include "llimagepng.h" + +/* time headers */ +#include <time.h> +#include <ctime> + +/* misc headers */ +#include "llscrolllistctrl.h" +#include "llfilepicker.h" +#include "llviewertexturelist.h" +#include "llviewerobjectlist.h" +#include "llviewerobject.h" +#include "llface.h" +#include "llvoavatarself.h" +#include "llwearable.h" +#include "llagentwearables.h" +#include "lltexlayerparams.h" +#include "llvovolume.h" +#include "llnotificationsutil.h" + +/*=======================================*/ +/* Formal declarations, constants, etc. */ +/*=======================================*/ +std::list<LLLocalBitmap*> LLLocalBitmapMgr::sBitmapList; +LLLocalBitmapTimer LLLocalBitmapMgr::sTimer; +bool LLLocalBitmapMgr::sNeedsRebake; + +static const F32 LL_LOCAL_TIMER_HEARTBEAT = 3.0; +static const BOOL LL_LOCAL_USE_MIPMAPS = true; +static const S32 LL_LOCAL_DISCARD_LEVEL = 0; +static const U32 LL_LOCAL_TEXLAYER_FOR_IDX = 0; +static const bool LL_LOCAL_SLAM_FOR_DEBUG = true; +static const bool LL_LOCAL_REPLACE_ON_DEL = true; +static const S32 LL_LOCAL_UPDATE_RETRIES = 5; + +/*=======================================*/ +/* LLLocalBitmap: unit class */ +/*=======================================*/ +LLLocalBitmap::LLLocalBitmap(std::string filename) + : mFilename(filename) + , mShortName(gDirUtilp->getBaseFileName(filename, true)) + , mValid(false) + , mLastModified() + , mLinkStatus(LS_ON) + , mUpdateRetries(LL_LOCAL_UPDATE_RETRIES) +{ + mTrackingID.generate(); + + /* extension */ + std::string temp_exten = gDirUtilp->getExtension(mFilename); + + if (temp_exten == "bmp") + { + mExtension = ET_IMG_BMP; + } + else if (temp_exten == "tga") + { + mExtension = ET_IMG_TGA; + } + else if (temp_exten == "jpg" || temp_exten == "jpeg") + { + mExtension = ET_IMG_JPG; + } + else if (temp_exten == "png") + { + mExtension = ET_IMG_PNG; + } + else + { + llwarns << "File of no valid extension given, local bitmap creation aborted." << "\n" + << "Filename: " << mFilename << llendl; + return; // no valid extension. + } + + /* next phase of unit creation is nearly the same as an update cycle. + we're running updateSelf as a special case with the optional UT_FIRSTUSE + which omits the parts associated with removing the outdated texture */ + mValid = updateSelf(UT_FIRSTUSE); +} + +LLLocalBitmap::~LLLocalBitmap() +{ + // replace IDs with defaults, if set to do so. + if(LL_LOCAL_REPLACE_ON_DEL && mValid) // fix for STORM-1837 + { + replaceIDs(mWorldID, IMG_DEFAULT); + LLLocalBitmapMgr::doRebake(); + } + + // delete self from gimagelist + LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID); + gTextureList.deleteImage(image); + + if (image) + { + image->unref(); + } +} + +/* accessors */ +std::string LLLocalBitmap::getFilename() +{ + return mFilename; +} + +std::string LLLocalBitmap::getShortName() +{ + return mShortName; +} + +LLUUID LLLocalBitmap::getTrackingID() +{ + return mTrackingID; +} + +LLUUID LLLocalBitmap::getWorldID() +{ + return mWorldID; +} + +bool LLLocalBitmap::getValid() +{ + return mValid; +} + +/* update functions */ +bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate) +{ + bool updated = false; + + if (mLinkStatus == LS_ON) + { + // verifying that the file exists + if (gDirUtilp->fileExists(mFilename)) + { + // verifying that the file has indeed been modified + const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename)); + LLSD new_last_modified = asctime(localtime(&temp_time)); + + if (mLastModified.asString() != new_last_modified.asString()) + { + /* loading the image file and decoding it, here is a critical point which, + if fails, invalidates the whole update (or unit creation) process. */ + LLPointer<LLImageRaw> raw_image = new LLImageRaw(); + if (decodeBitmap(raw_image)) + { + // decode is successful, we can safely proceed. + LLUUID old_id = LLUUID::null; + if (!(optional_firstupdate == UT_FIRSTUSE) && !mWorldID.isNull()) + { + old_id = mWorldID; + } + mWorldID.generate(); + mLastModified = new_last_modified; + + LLPointer<LLViewerFetchedTexture> texture = new LLViewerFetchedTexture + ("file://"+mFilename, mWorldID, LL_LOCAL_USE_MIPMAPS); + + texture->createGLTexture(LL_LOCAL_DISCARD_LEVEL, raw_image); + texture->setCachedRawImage(LL_LOCAL_DISCARD_LEVEL, raw_image); + texture->ref(); + + gTextureList.addImage(texture); + + if (!optional_firstupdate == UT_FIRSTUSE) + { + // seek out everything old_id uses and replace it with mWorldID + replaceIDs(old_id, mWorldID); + + // remove old_id from gimagelist + LLViewerFetchedTexture* image = gTextureList.findImage(old_id); + gTextureList.deleteImage(image); + image->unref(); + } + + mUpdateRetries = LL_LOCAL_UPDATE_RETRIES; + updated = true; + } + + // if decoding failed, we get here and it will attempt to decode it in the next cycles + // until mUpdateRetries runs out. this is done because some software lock the bitmap while writing to it + else + { + if (mUpdateRetries) + { + mUpdateRetries--; + } + else + { + llwarns << "During the update process the following file was found" << "\n" + << "but could not be opened or decoded for " << LL_LOCAL_UPDATE_RETRIES << " attempts." << "\n" + << "Filename: " << mFilename << "\n" + << "Disabling further update attempts for this file." << llendl; + + LLSD notif_args; + notif_args["FNAME"] = mFilename; + notif_args["NRETRIES"] = LL_LOCAL_UPDATE_RETRIES; + LLNotificationsUtil::add("LocalBitmapsUpdateFailedFinal", notif_args); + + mLinkStatus = LS_BROKEN; + } + } + } + + } // end if file exists + + else + { + llwarns << "During the update process, the following file was not found." << "\n" + << "Filename: " << mFilename << "\n" + << "Disabling further update attempts for this file." << llendl; + + LLSD notif_args; + notif_args["FNAME"] = mFilename; + LLNotificationsUtil::add("LocalBitmapsUpdateFileNotFound", notif_args); + + mLinkStatus = LS_BROKEN; + } + } + + return updated; +} + +bool LLLocalBitmap::decodeBitmap(LLPointer<LLImageRaw> rawimg) +{ + bool decode_successful = false; + + switch (mExtension) + { + case ET_IMG_BMP: + { + LLPointer<LLImageBMP> bmp_image = new LLImageBMP; + if (bmp_image->load(mFilename) && bmp_image->decode(rawimg, 0.0f)) + { + rawimg->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + decode_successful = true; + } + break; + } + + case ET_IMG_TGA: + { + LLPointer<LLImageTGA> tga_image = new LLImageTGA; + if ((tga_image->load(mFilename) && tga_image->decode(rawimg)) + && ((tga_image->getComponents() == 3) || (tga_image->getComponents() == 4))) + { + rawimg->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + decode_successful = true; + } + break; + } + + case ET_IMG_JPG: + { + LLPointer<LLImageJPEG> jpeg_image = new LLImageJPEG; + if (jpeg_image->load(mFilename) && jpeg_image->decode(rawimg, 0.0f)) + { + rawimg->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + decode_successful = true; + } + break; + } + + case ET_IMG_PNG: + { + LLPointer<LLImagePNG> png_image = new LLImagePNG; + if (png_image->load(mFilename) && png_image->decode(rawimg, 0.0f)) + { + rawimg->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + decode_successful = true; + } + break; + } + + default: + { + // separating this into -several- llwarns calls because in the extremely unlikely case that this happens + // accessing mFilename and any other object properties might very well crash the viewer. + // getting here should be impossible, or there's been a pretty serious bug. + + llwarns << "During a decode attempt, the following local bitmap had no properly assigned extension." << llendl; + llwarns << "Filename: " << mFilename << llendl; + llwarns << "Disabling further update attempts for this file." << llendl; + mLinkStatus = LS_BROKEN; + } + } + + return decode_successful; +} + +void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id) +{ + // checking for misuse. + if (old_id == new_id) + { + llinfos << "An attempt was made to replace a texture with itself. (matching UUIDs)" << "\n" + << "Texture UUID: " << old_id.asString() << llendl; + return; + } + + updateUserPrims(old_id, new_id); + updateUserSculpts(old_id, new_id); // isn't there supposed to be an IMG_DEFAULT_SCULPT or something? + + // default safeguard image for layers + if( new_id == IMG_DEFAULT ) + { + new_id = IMG_DEFAULT_AVATAR; + } + + /* It doesn't actually update all of those, it merely checks if any of them + contain the referenced ID and if so, updates. */ + updateUserLayers(old_id, new_id, LLWearableType::WT_ALPHA); + updateUserLayers(old_id, new_id, LLWearableType::WT_EYES); + updateUserLayers(old_id, new_id, LLWearableType::WT_GLOVES); + updateUserLayers(old_id, new_id, LLWearableType::WT_JACKET); + updateUserLayers(old_id, new_id, LLWearableType::WT_PANTS); + updateUserLayers(old_id, new_id, LLWearableType::WT_SHIRT); + updateUserLayers(old_id, new_id, LLWearableType::WT_SHOES); + updateUserLayers(old_id, new_id, LLWearableType::WT_SKIN); + updateUserLayers(old_id, new_id, LLWearableType::WT_SKIRT); + updateUserLayers(old_id, new_id, LLWearableType::WT_SOCKS); + updateUserLayers(old_id, new_id, LLWearableType::WT_TATTOO); + updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERPANTS); + updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERSHIRT); +} + +// this function sorts the faces from a getFaceList[getNumFaces] into a list of objects +// in order to prevent multiple sendTEUpdate calls per object during updateUserPrims +std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id) +{ + std::vector<LLViewerObject*> obj_list; + LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id); + + for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(); face_iterator++) + { + // getting an object from a face + LLFace* face_to_object = (*old_texture->getFaceList())[face_iterator]; + + if(face_to_object) + { + LLViewerObject* affected_object = face_to_object->getViewerObject(); + + if(affected_object) + { + + // we have an object, we'll take it's UUID and compare it to + // whatever we already have in the returnable object list. + // if there is a match - we do not add (to prevent duplicates) + LLUUID mainlist_obj_id = affected_object->getID(); + bool add_object = true; + + // begin looking for duplicates + std::vector<LLViewerObject*>::iterator objlist_iter = obj_list.begin(); + for(; (objlist_iter != obj_list.end()) && add_object; objlist_iter++) + { + LLViewerObject* obj = *objlist_iter; + if (obj->getID() == mainlist_obj_id) + { + add_object = false; // duplicate found. + } + } + // end looking for duplicates + + if(add_object) + { + obj_list.push_back(affected_object); + } + + } + + } + + } // end of face-iterating for() + + return obj_list; +} + +void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id) +{ + std::vector<LLViewerObject*> objectlist = prepUpdateObjects(old_id); + + for(std::vector<LLViewerObject*>::iterator object_iterator = objectlist.begin(); + object_iterator != objectlist.end(); object_iterator++) + { + LLViewerObject* object = *object_iterator; + + if(object) + { + bool update_obj = false; + S32 num_faces = object->getNumFaces(); + + for (U8 face_iter = 0; face_iter < num_faces; face_iter++) + { + if (object->mDrawable) + { + LLFace* face = object->mDrawable->getFace(face_iter); + if (face && face->getTexture() && face->getTexture()->getID() == old_id) + { + object->setTEImage(face_iter, LLViewerTextureManager::getFetchedTexture + (new_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + + update_obj = true; + } + } + } + + if (update_obj) + { + object->sendTEUpdate(); + } + } + } + +} + +void LLLocalBitmap::updateUserSculpts(LLUUID old_id, LLUUID new_id) +{ + LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id); + for(U32 volume_iter = 0; volume_iter < old_texture->getNumVolumes(); volume_iter++) + { + LLVOVolume* volume_to_object = (*old_texture->getVolumeList())[volume_iter]; + LLViewerObject* object = (LLViewerObject*)volume_to_object; + + if(object) + { + if (object->isSculpted() && object->getVolume() && + object->getVolume()->getParams().getSculptID() == old_id) + { + LLSculptParams* old_params = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + LLSculptParams new_params(*old_params); + new_params.setSculptTexture(new_id); + object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, new_params, TRUE); + } + } + } +} + +void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type) +{ + U32 count = gAgentWearables.getWearableCount(type); + for(U32 wearable_iter = 0; wearable_iter < count; wearable_iter++) + { + LLWearable* wearable = gAgentWearables.getWearable(type, wearable_iter); + if (wearable) + { + std::vector<LLLocalTextureObject*> texture_list = wearable->getLocalTextureListSeq(); + for(std::vector<LLLocalTextureObject*>::iterator texture_iter = texture_list.begin(); + texture_iter != texture_list.end(); texture_iter++) + { + LLLocalTextureObject* lto = *texture_iter; + + if (lto && lto->getID() == old_id) + { + U32 local_texlayer_index = 0; /* can't keep that as static const, gives errors, so i'm leaving this var here */ + LLVOAvatarDefines::EBakedTextureIndex baked_texind = + lto->getTexLayer(local_texlayer_index)->getTexLayerSet()->getBakedTexIndex(); + + LLVOAvatarDefines::ETextureIndex reg_texind = getTexIndex(type, baked_texind); + if (reg_texind != LLVOAvatarDefines::TEX_NUM_INDICES) + { + U32 index = gAgentWearables.getWearableIndex(wearable); + gAgentAvatarp->setLocalTexture(reg_texind, gTextureList.getImage(new_id), FALSE, index); + gAgentAvatarp->wearableUpdated(type, FALSE); + + /* telling the manager to rebake once update cycle is fully done */ + LLLocalBitmapMgr::setNeedsRebake(); + } + + } + } + } + } +} + +LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex( + LLWearableType::EType type, LLVOAvatarDefines::EBakedTextureIndex baked_texind) +{ + LLVOAvatarDefines::ETextureIndex result = LLVOAvatarDefines::TEX_NUM_INDICES; // using as a default/fail return. + + switch(type) + { + case LLWearableType::WT_ALPHA: + { + switch(baked_texind) + { + case LLVOAvatarDefines::BAKED_EYES: + { + result = LLVOAvatarDefines::TEX_EYES_ALPHA; + break; + } + + case LLVOAvatarDefines::BAKED_HAIR: + { + result = LLVOAvatarDefines::TEX_HAIR_ALPHA; + break; + } + + case LLVOAvatarDefines::BAKED_HEAD: + { + result = LLVOAvatarDefines::TEX_HEAD_ALPHA; + break; + } + + case LLVOAvatarDefines::BAKED_LOWER: + { + result = LLVOAvatarDefines::TEX_LOWER_ALPHA; + break; + } + case LLVOAvatarDefines::BAKED_UPPER: + { + result = LLVOAvatarDefines::TEX_UPPER_ALPHA; + break; + } + + default: + { + break; + } + + } + break; + + } + + case LLWearableType::WT_EYES: + { + if (baked_texind == LLVOAvatarDefines::BAKED_EYES) + { + result = LLVOAvatarDefines::TEX_EYES_IRIS; + } + + break; + } + + case LLWearableType::WT_GLOVES: + { + if (baked_texind == LLVOAvatarDefines::BAKED_UPPER) + { + result = LLVOAvatarDefines::TEX_UPPER_GLOVES; + } + + break; + } + + case LLWearableType::WT_JACKET: + { + if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) + { + result = LLVOAvatarDefines::TEX_LOWER_JACKET; + } + else if (baked_texind == LLVOAvatarDefines::BAKED_UPPER) + { + result = LLVOAvatarDefines::TEX_UPPER_JACKET; + } + + break; + } + + case LLWearableType::WT_PANTS: + { + if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) + { + result = LLVOAvatarDefines::TEX_LOWER_PANTS; + } + + break; + } + + case LLWearableType::WT_SHIRT: + { + if (baked_texind == LLVOAvatarDefines::BAKED_UPPER) + { + result = LLVOAvatarDefines::TEX_UPPER_SHIRT; + } + + break; + } + + case LLWearableType::WT_SHOES: + { + if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) + { + result = LLVOAvatarDefines::TEX_LOWER_SHOES; + } + + break; + } + + case LLWearableType::WT_SKIN: + { + switch(baked_texind) + { + case LLVOAvatarDefines::BAKED_HEAD: + { + result = LLVOAvatarDefines::TEX_HEAD_BODYPAINT; + break; + } + + case LLVOAvatarDefines::BAKED_LOWER: + { + result = LLVOAvatarDefines::TEX_LOWER_BODYPAINT; + break; + } + case LLVOAvatarDefines::BAKED_UPPER: + { + result = LLVOAvatarDefines::TEX_UPPER_BODYPAINT; + break; + } + + default: + { + break; + } + + } + break; + } + + case LLWearableType::WT_SKIRT: + { + if (baked_texind == LLVOAvatarDefines::BAKED_SKIRT) + { + result = LLVOAvatarDefines::TEX_SKIRT; + } + + break; + } + + case LLWearableType::WT_SOCKS: + { + if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) + { + result = LLVOAvatarDefines::TEX_LOWER_SOCKS; + } + + break; + } + + case LLWearableType::WT_TATTOO: + { + switch(baked_texind) + { + case LLVOAvatarDefines::BAKED_HEAD: + { + result = LLVOAvatarDefines::TEX_HEAD_TATTOO; + break; + } + + case LLVOAvatarDefines::BAKED_LOWER: + { + result = LLVOAvatarDefines::TEX_LOWER_TATTOO; + break; + } + case LLVOAvatarDefines::BAKED_UPPER: + { + result = LLVOAvatarDefines::TEX_UPPER_TATTOO; + break; + } + + default: + { + break; + } + + } + break; + } + + case LLWearableType::WT_UNDERPANTS: + { + if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) + { + result = LLVOAvatarDefines::TEX_LOWER_UNDERPANTS; + } + + break; + } + + case LLWearableType::WT_UNDERSHIRT: + { + if (baked_texind == LLVOAvatarDefines::BAKED_UPPER) + { + result = LLVOAvatarDefines::TEX_UPPER_UNDERSHIRT; + } + + break; + } + + default: + { + llwarns << "Unknown wearable type: " << (int)type << "\n" + << "Baked Texture Index: " << (int)baked_texind << "\n" + << "Filename: " << mFilename << "\n" + << "TrackingID: " << mTrackingID << "\n" + << "InworldID: " << mWorldID << llendl; + } + + } + return result; +} + +/*=======================================*/ +/* LLLocalBitmapTimer: timer class */ +/*=======================================*/ +LLLocalBitmapTimer::LLLocalBitmapTimer() : LLEventTimer(LL_LOCAL_TIMER_HEARTBEAT) +{ +} + +LLLocalBitmapTimer::~LLLocalBitmapTimer() +{ +} + +void LLLocalBitmapTimer::startTimer() +{ + mEventTimer.start(); +} + +void LLLocalBitmapTimer::stopTimer() +{ + mEventTimer.stop(); +} + +bool LLLocalBitmapTimer::isRunning() +{ + return mEventTimer.getStarted(); +} + +BOOL LLLocalBitmapTimer::tick() +{ + LLLocalBitmapMgr::doUpdates(); + return FALSE; +} + +/*=======================================*/ +/* LLLocalBitmapMgr: manager class */ +/*=======================================*/ +LLLocalBitmapMgr::LLLocalBitmapMgr() +{ + // The class is all made of static members, should i even bother instantiating? +} + +LLLocalBitmapMgr::~LLLocalBitmapMgr() +{ +} + +bool LLLocalBitmapMgr::addUnit() +{ + bool add_successful = false; + + LLFilePicker& picker = LLFilePicker::instance(); + if (picker.getMultipleOpenFiles(LLFilePicker::FFLOAD_IMAGE)) + { + sTimer.stopTimer(); + + std::string filename = picker.getFirstFile(); + while(!filename.empty()) + { + LLLocalBitmap* unit = new LLLocalBitmap(filename); + + if (unit->getValid()) + { + sBitmapList.push_back(unit); + add_successful = true; + } + else + { + llwarns << "Attempted to add invalid or unreadable image file, attempt cancelled.\n" + << "Filename: " << filename << llendl; + + LLSD notif_args; + notif_args["FNAME"] = filename; + LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args); + + delete unit; + unit = NULL; + } + + filename = picker.getNextFile(); + } + + sTimer.startTimer(); + } + + return add_successful; +} + +void LLLocalBitmapMgr::delUnit(LLUUID tracking_id) +{ + if (!sBitmapList.empty()) + { + std::vector<LLLocalBitmap*> to_delete; + for (local_list_iter iter = sBitmapList.begin(); iter != sBitmapList.end(); iter++) + { /* finding which ones we want deleted and making a separate list */ + LLLocalBitmap* unit = *iter; + if (unit->getTrackingID() == tracking_id) + { + to_delete.push_back(unit); + } + } + + for(std::vector<LLLocalBitmap*>::iterator del_iter = to_delete.begin(); + del_iter != to_delete.end(); del_iter++) + { /* iterating over a temporary list, hence preserving the iterator validity while deleting. */ + LLLocalBitmap* unit = *del_iter; + sBitmapList.remove(unit); + delete unit; + unit = NULL; + } + } +} + +LLUUID LLLocalBitmapMgr::getWorldID(LLUUID tracking_id) +{ + LLUUID world_id = LLUUID::null; + + for (local_list_iter iter = sBitmapList.begin(); iter != sBitmapList.end(); iter++) + { + LLLocalBitmap* unit = *iter; + if (unit->getTrackingID() == tracking_id) + { + world_id = unit->getWorldID(); + } + } + + return world_id; +} + +std::string LLLocalBitmapMgr::getFilename(LLUUID tracking_id) +{ + std::string filename = ""; + + for (local_list_iter iter = sBitmapList.begin(); iter != sBitmapList.end(); iter++) + { + LLLocalBitmap* unit = *iter; + if (unit->getTrackingID() == tracking_id) + { + filename = unit->getFilename(); + } + } + + return filename; +} + +void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl) +{ + if (ctrl) + { + ctrl->clearRows(); + + if (!sBitmapList.empty()) + { + for (local_list_iter iter = sBitmapList.begin(); + iter != sBitmapList.end(); iter++) + { + LLSD element; + element["columns"][0]["column"] = "unit_name"; + element["columns"][0]["type"] = "text"; + element["columns"][0]["value"] = (*iter)->getShortName(); + + element["columns"][1]["column"] = "unit_id_HIDDEN"; + element["columns"][1]["type"] = "text"; + element["columns"][1]["value"] = (*iter)->getTrackingID(); + + ctrl->addElement(element); + } + } + } + +} + +void LLLocalBitmapMgr::doUpdates() +{ + // preventing theoretical overlap in cases with huge number of loaded images. + sTimer.stopTimer(); + sNeedsRebake = false; + + for (local_list_iter iter = sBitmapList.begin(); iter != sBitmapList.end(); iter++) + { + (*iter)->updateSelf(); + } + + doRebake(); + sTimer.startTimer(); +} + +void LLLocalBitmapMgr::setNeedsRebake() +{ + sNeedsRebake = true; +} + +void LLLocalBitmapMgr::doRebake() +{ /* separated that from doUpdates to insure a rebake can be called separately during deletion */ + if (sNeedsRebake) + { + gAgentAvatarp->forceBakeAllTextures(LL_LOCAL_SLAM_FOR_DEBUG); + sNeedsRebake = false; + } +} + diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h new file mode 100644 index 0000000000..7a23c7ef6e --- /dev/null +++ b/indra/newview/lllocalbitmaps.h @@ -0,0 +1,136 @@ +/** + * @file lllocalbitmaps.h + * @author Vaalith Jinn + * @brief Local Bitmaps header + * + * $LicenseInfo:firstyear=2011&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_LOCALBITMAPS_H +#define LL_LOCALBITMAPS_H + +#include "lleventtimer.h" +#include "llwearabletype.h" +#include "llvoavatardefines.h" + +class LLScrollListCtrl; + +class LLLocalBitmap +{ + public: /* main */ + LLLocalBitmap(std::string filename); + ~LLLocalBitmap(); + + public: /* accessors */ + std::string getFilename(); + std::string getShortName(); + LLUUID getTrackingID(); + LLUUID getWorldID(); + bool getValid(); + + public: /* self update public section */ + enum EUpdateType + { + UT_FIRSTUSE, + UT_REGUPDATE + }; + + bool updateSelf(EUpdateType = UT_REGUPDATE); + + private: /* self update private section */ + bool decodeBitmap(LLPointer<LLImageRaw> raw); + void replaceIDs(LLUUID old_id, LLUUID new_id); + std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id); + void updateUserPrims(LLUUID old_id, LLUUID new_id); + void updateUserSculpts(LLUUID old_id, LLUUID new_id); + void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type); + LLVOAvatarDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLVOAvatarDefines::EBakedTextureIndex baked_texind); + + private: /* private enums */ + enum ELinkStatus + { + LS_ON, + LS_BROKEN, + }; + + enum EExtension + { + ET_IMG_BMP, + ET_IMG_TGA, + ET_IMG_JPG, + ET_IMG_PNG + }; + + private: /* members */ + std::string mFilename; + std::string mShortName; + LLUUID mTrackingID; + LLUUID mWorldID; + bool mValid; + LLSD mLastModified; + EExtension mExtension; + ELinkStatus mLinkStatus; + S32 mUpdateRetries; + +}; + +class LLLocalBitmapTimer : public LLEventTimer +{ + public: + LLLocalBitmapTimer(); + ~LLLocalBitmapTimer(); + + public: + void startTimer(); + void stopTimer(); + bool isRunning(); + BOOL tick(); + +}; + +class LLLocalBitmapMgr +{ + public: + LLLocalBitmapMgr(); + ~LLLocalBitmapMgr(); + + public: + static bool addUnit(); + static void delUnit(LLUUID tracking_id); + + static LLUUID getWorldID(LLUUID tracking_id); + static std::string getFilename(LLUUID tracking_id); + + static void feedScrollList(LLScrollListCtrl* ctrl); + static void doUpdates(); + static void setNeedsRebake(); + static void doRebake(); + + private: + static std::list<LLLocalBitmap*> sBitmapList; + static LLLocalBitmapTimer sTimer; + static bool sNeedsRebake; + typedef std::list<LLLocalBitmap*>::iterator local_list_iter; +}; + +#endif + diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 025181ead5..8d9d70b50e 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -44,10 +44,14 @@ // newview includes #include "llagent.h" +#include "llenvmanager.h" #include "llfloatersidepanelcontainer.h" #include "llinventoryobserver.h" #include "lllandmarkactions.h" #include "lllandmarklist.h" +#include "llpathfindingmanager.h" +#include "llpathfindingnavmesh.h" +#include "llpathfindingnavmeshstatus.h" #include "llteleporthistory.h" #include "llslurl.h" #include "llstatusbar.h" // getHealth() @@ -191,7 +195,9 @@ LLLocationInputCtrl::Params::Params() damage_icon("damage_icon"), damage_text("damage_text"), see_avatars_icon("see_avatars_icon"), - maturity_help_topic("maturity_help_topic") + maturity_help_topic("maturity_help_topic"), + pathfinding_dirty_icon("pathfinding_dirty_icon"), + pathfinding_disabled_icon("pathfinding_disabled_icon") { } @@ -203,6 +209,9 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) mAddLandmarkBtn(NULL), mForSaleBtn(NULL), mInfoBtn(NULL), + mRegionCrossingSlot(), + mNavMeshSlot(), + mIsNavMeshDirty(false), mLandmarkImageOn(NULL), mLandmarkImageOff(NULL), mIconMaturityGeneral(NULL), @@ -270,7 +279,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) if (p.icon_maturity_general()) { mIconMaturityGeneral = p.icon_maturity_general; - } + } if (p.icon_maturity_adult()) { mIconMaturityAdult = p.icon_maturity_adult; @@ -279,7 +288,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) { mIconMaturityModerate = p.icon_maturity_moderate; } - + LLButton::Params maturity_button = p.maturity_button; mMaturityButton = LLUICtrlFactory::create<LLButton>(maturity_button); addChild(mMaturityButton); @@ -336,7 +345,21 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) mParcelIcon[DAMAGE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(damage_icon); mParcelIcon[DAMAGE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, DAMAGE_ICON)); addChild(mParcelIcon[DAMAGE_ICON]); - + + LLIconCtrl::Params pathfinding_dirty_icon = p.pathfinding_dirty_icon; + pathfinding_dirty_icon.tool_tip = LLTrans::getString("LocationCtrlPathfindingDirtyTooltip"); + pathfinding_dirty_icon.mouse_opaque = true; + mParcelIcon[PATHFINDING_DIRTY_ICON] = LLUICtrlFactory::create<LLIconCtrl>(pathfinding_dirty_icon); + mParcelIcon[PATHFINDING_DIRTY_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PATHFINDING_DIRTY_ICON)); + addChild(mParcelIcon[PATHFINDING_DIRTY_ICON]); + + LLIconCtrl::Params pathfinding_disabled_icon = p.pathfinding_disabled_icon; + pathfinding_disabled_icon.tool_tip = LLTrans::getString("LocationCtrlPathfindingDisabledTooltip"); + pathfinding_disabled_icon.mouse_opaque = true; + mParcelIcon[PATHFINDING_DISABLED_ICON] = LLUICtrlFactory::create<LLIconCtrl>(pathfinding_disabled_icon); + mParcelIcon[PATHFINDING_DISABLED_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PATHFINDING_DISABLED_ICON)); + addChild(mParcelIcon[PATHFINDING_DISABLED_ICON]); + LLTextBox::Params damage_text = p.damage_text; damage_text.tool_tip = LLTrans::getString("LocationCtrlDamageTooltip"); damage_text.mouse_opaque = true; @@ -391,6 +414,9 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) mLocationHistoryConnection = LLLocationHistory::getInstance()->setChangedCallback( boost::bind(&LLLocationInputCtrl::onLocationHistoryChanged, this,_1)); + mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLLocationInputCtrl::onRegionBoundaryCrossed, this)); + createNavMeshStatusListenerForCurrentRegion(); + mRemoveLandmarkObserver = new LLRemoveLandmarkObserver(this); mAddLandmarkObserver = new LLAddLandmarkObserver(this); gInventory.addObserver(mRemoveLandmarkObserver); @@ -415,6 +441,8 @@ LLLocationInputCtrl::~LLLocationInputCtrl() LLViewerParcelMgr::getInstance()->removeObserver(mParcelChangeObserver); delete mParcelChangeObserver; + mRegionCrossingSlot.disconnect(); + mNavMeshSlot.disconnect(); mCoordinatesControlConnection.disconnect(); mParcelPropertiesControlConnection.disconnect(); mParcelMgrConnection.disconnect(); @@ -636,6 +664,17 @@ void LLLocationInputCtrl::onMaturityButtonClicked() LLUI::sHelpImpl->showTopic(mMaturityHelpTopic); } +void LLLocationInputCtrl::onRegionBoundaryCrossed() +{ + createNavMeshStatusListenerForCurrentRegion(); +} + +void LLLocationInputCtrl::onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus) +{ + mIsNavMeshDirty = pNavMeshStatus.isValid() && (pNavMeshStatus.getStatus() != LLPathfindingNavMeshStatus::kComplete); + refreshParcelIcons(); +} + void LLLocationInputCtrl::onLandmarkLoaded(LLLandmark* lm) { (void) lm; @@ -819,6 +858,7 @@ void LLLocationInputCtrl::refreshParcelIcons() bool allow_scripts = vpm->allowAgentScripts(agent_region, current_parcel); bool allow_damage = vpm->allowAgentDamage(agent_region, current_parcel); bool see_avs = current_parcel->getSeeAVs(); + bool pathfinding_dynamic_enabled = agent_region->dynamicPathfindingEnabled(); // Most icons are "block this ability" mParcelIcon[VOICE_ICON]->setVisible( !allow_voice ); @@ -827,6 +867,9 @@ void LLLocationInputCtrl::refreshParcelIcons() mParcelIcon[BUILD_ICON]->setVisible( !allow_build ); mParcelIcon[SCRIPTS_ICON]->setVisible( !allow_scripts ); mParcelIcon[DAMAGE_ICON]->setVisible( allow_damage ); + mParcelIcon[PATHFINDING_DIRTY_ICON]->setVisible(mIsNavMeshDirty); + mParcelIcon[PATHFINDING_DISABLED_ICON]->setVisible(!mIsNavMeshDirty && !pathfinding_dynamic_enabled); + mDamageText->setVisible(allow_damage); mParcelIcon[SEE_AVATARS_ICON]->setVisible( !see_avs ); @@ -1165,6 +1208,12 @@ void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon) case BUILD_ICON: LLNotificationsUtil::add("NoBuild"); break; + case PATHFINDING_DIRTY_ICON: + LLNotificationsUtil::add("PathfindingDirty"); + break; + case PATHFINDING_DISABLED_ICON: + LLNotificationsUtil::add("DynamicPathfindingDisabled"); + break; case SCRIPTS_ICON: { LLViewerRegion* region = gAgent.getRegion(); @@ -1193,3 +1242,18 @@ void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon) // no default to get compiler warning when a new icon gets added } } + +void LLLocationInputCtrl::createNavMeshStatusListenerForCurrentRegion() +{ + if (mNavMeshSlot.connected()) + { + mNavMeshSlot.disconnect(); + } + + LLViewerRegion *currentRegion = gAgent.getRegion(); + if (currentRegion != NULL) + { + mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLLocationInputCtrl::onNavMeshStatusChange, this, _2)); + LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true); + } +} diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index ed47ba73e3..cd6fd24077 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -31,6 +31,7 @@ #include "lliconctrl.h" // Params #include "lltextbox.h" // Params #include "lllocationhistory.h" +#include "llpathfindingnavmesh.h" class LLLandmark; @@ -40,6 +41,7 @@ class LLRemoveLandmarkObserver; class LLParcelChangeObserver; class LLMenuGL; class LLTeleportHistoryItem; +class LLPathfindingNavMeshStatus; /** * Location input control. @@ -78,7 +80,9 @@ public: build_icon, scripts_icon, damage_icon, - see_avatars_icon; + see_avatars_icon, + pathfinding_dirty_icon, + pathfinding_disabled_icon; Optional<LLTextBox::Params> damage_text; Params(); }; @@ -110,13 +114,15 @@ private: enum EParcelIcon { VOICE_ICON = 0, - FLY_ICON, // 1 - PUSH_ICON, // 2 - BUILD_ICON, // 3 - SCRIPTS_ICON, // 4 - DAMAGE_ICON, // 5 - SEE_AVATARS_ICON, // 6 - ICON_COUNT // 7 total + FLY_ICON, // 1 + PUSH_ICON, // 2 + BUILD_ICON, // 3 + SCRIPTS_ICON, // 4 + DAMAGE_ICON, // 5 + SEE_AVATARS_ICON, // 6 + PATHFINDING_DIRTY_ICON, // 7 + PATHFINDING_DISABLED_ICON,// 8 + ICON_COUNT // 9 total }; friend class LLUICtrlFactory; @@ -155,11 +161,15 @@ private: void onAddLandmarkButtonClicked(); void onAgentParcelChange(); void onMaturityButtonClicked(); + void onRegionBoundaryCrossed(); + void onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus); // callbacks bool onLocationContextMenuItemEnabled(const LLSD& userdata); void onLocationContextMenuItemClicked(const LLSD& userdata); void onParcelIconClick(EParcelIcon icon); + void createNavMeshStatusListenerForCurrentRegion(); + LLMenuGL* mLocationContextMenu; LLButton* mAddLandmarkBtn; LLButton* mForSaleBtn; @@ -179,11 +189,15 @@ private: boost::signals2::connection mParcelPropertiesControlConnection; boost::signals2::connection mParcelMgrConnection; boost::signals2::connection mLocationHistoryConnection; + boost::signals2::connection mRegionCrossingSlot; + LLPathfindingNavMesh::navmesh_slot_t mNavMeshSlot; + bool mIsNavMeshDirty; LLUIImage* mLandmarkImageOn; LLUIImage* mLandmarkImageOff; LLPointer<LLUIImage> mIconMaturityGeneral; LLPointer<LLUIImage> mIconMaturityAdult; LLPointer<LLUIImage> mIconMaturityModerate; + LLPointer<LLUIImage> mIconPathfindingDynamic; std::string mAddLandmarkTooltip; std::string mEditLandmarkTooltip; diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index ebb5912ace..2d7454b636 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -28,11 +28,13 @@ #include "llagent.h" #include "llagentui.h" +#include "llavatarnamecache.h" #include "lllogchat.h" #include "lltrans.h" #include "llviewercontrol.h" #include "lldiriterator.h" +#include "llfloaterimsessiontab.h" #include "llinstantmessage.h" #include "llsingleton.h" // for LLSingleton @@ -40,6 +42,7 @@ #include <boost/algorithm/string/replace.hpp> #include <boost/regex.hpp> #include <boost/regex/v4/match_results.hpp> +#include <boost/foreach.hpp> #if LL_MSVC #pragma warning(push) @@ -58,10 +61,11 @@ const S32 LOG_RECALL_SIZE = 2048; -const std::string IM_TIME("time"); -const std::string IM_TEXT("message"); -const std::string IM_FROM("from"); -const std::string IM_FROM_ID("from_id"); +const std::string LL_IM_TIME("time"); +const std::string LL_IM_TEXT("message"); +const std::string LL_IM_FROM("from"); +const std::string LL_IM_FROM_ID("from_id"); +const std::string LL_TRANSCRIPT_FILE_EXTENSION("txt"); const static std::string IM_SEPARATOR(": "); const static std::string NEW_LINE("\n"); @@ -84,6 +88,7 @@ const static std::string MULTI_LINE_PREFIX(" "); * Note: "You" was used as an avatar names in viewers of previous versions */ const static boost::regex TIMESTAMP_AND_STUFF("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}\\]\\s+|\\[\\d{1,2}:\\d{2}\\]\\s+)?(.*)$"); +const static boost::regex TIMESTAMP("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}\\]|\\[\\d{1,2}:\\d{2}\\]).*"); /** * Regular expression suitable to match names like @@ -116,6 +121,15 @@ const static int IDX_TEXT = 3; using namespace boost::posix_time; using namespace boost::gregorian; +void append_to_last_message(std::list<LLSD>& messages, const std::string& line) +{ + if (!messages.size()) return; + + std::string im_text = messages.back()[LL_IM_TEXT].asString(); + im_text.append(line); + messages.back()[LL_IM_TEXT] = im_text; +} + class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner> { public: @@ -191,15 +205,17 @@ private: std::stringstream mTimeStream; }; +LLLogChat::save_history_signal_t * LLLogChat::sSaveHistorySignal = NULL; + //static std::string LLLogChat::makeLogFileName(std::string filename) { /** - * Testing for in bound and out bound ad-hoc file names - * if it is then skip date stamping. - **/ - //LL_INFOS("") << "Befor:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */ - boost::match_results<std::string::const_iterator> matches; + * Testing for in bound and out bound ad-hoc file names + * if it is then skip date stamping. + **/ + + boost::match_results<std::string::const_iterator> matches; bool inboundConf = boost::regex_match(filename, matches, INBOUND_CONFERENCE); bool outboundConf = boost::regex_match(filename, matches, OUTBOUND_CONFERENCE); if (!(inboundConf || outboundConf)) @@ -220,17 +236,17 @@ std::string LLLogChat::makeLogFileName(std::string filename) filename += dbuffer; } } - //LL_INFOS("") << "After:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */ + filename = cleanFileName(filename); - filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS,filename); - filename += ".txt"; - //LL_INFOS("") << "Full:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */ + filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename); + filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION; + return filename; } std::string LLLogChat::cleanFileName(std::string filename) { - std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars + std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars std::string::size_type position = filename.find_first_of(invalidChars); while (position != filename.npos) { @@ -242,27 +258,24 @@ std::string LLLogChat::cleanFileName(std::string filename) std::string LLLogChat::timestamp(bool withdate) { - time_t utc_time; - utc_time = time_corrected(); - std::string timeStr; - LLSD substitution; - substitution["datetime"] = (S32) utc_time; - if (withdate) { - timeStr = "["+LLTrans::getString ("TimeYear")+"]/[" - +LLTrans::getString ("TimeMonth")+"]/[" - +LLTrans::getString ("TimeDay")+"] [" - +LLTrans::getString ("TimeHour")+"]:[" - +LLTrans::getString ("TimeMin")+"]"; + timeStr = "[" + LLTrans::getString ("TimeYear") + "]/[" + + LLTrans::getString ("TimeMonth") + "]/[" + + LLTrans::getString ("TimeDay") + "] [" + + LLTrans::getString ("TimeHour") + "]:[" + + LLTrans::getString ("TimeMin") + "]"; } else { timeStr = "[" + LLTrans::getString("TimeHour") + "]:[" - + LLTrans::getString ("TimeMin")+"]"; + + LLTrans::getString ("TimeMin")+"]"; } + LLSD substitution; + substitution["datetime"] = (S32)time_corrected(); + LLStringUtil::format (timeStr, substitution); return timeStr; } @@ -270,9 +283,9 @@ std::string LLLogChat::timestamp(bool withdate) //static void LLLogChat::saveHistory(const std::string& filename, - const std::string& from, - const LLUUID& from_id, - const std::string& line) + const std::string& from, + const LLUUID& from_id, + const std::string& line) { std::string tmp_filename = filename; LLStringUtil::trim(tmp_filename); @@ -312,108 +325,41 @@ void LLLogChat::saveHistory(const std::string& filename, file << LLChatLogFormatter(item) << std::endl; file.close(); -} -void LLLogChat::loadHistory(const std::string& filename, void (*callback)(ELogLineType, const LLSD&, void*), void* userdata) -{ - if(!filename.size()) - { - llwarns << "Filename is Empty!" << llendl; - return ; - } - - LLFILE* fptr = LLFile::fopen(makeLogFileName(filename), "r"); /*Flawfinder: ignore*/ - if (!fptr) - { - callback(LOG_EMPTY, LLSD(), userdata); - return; //No previous conversation with this name. - } - else + if (NULL != sSaveHistorySignal) { - char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/ - char *bptr; - S32 len; - bool firstline=TRUE; - - if ( fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END) ) - { //File is smaller than recall size. Get it all. - firstline = FALSE; - if ( fseek(fptr, 0, SEEK_SET) ) - { - fclose(fptr); - return; - } - } - - while ( fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr) ) - { - len = strlen(buffer) - 1; /*Flawfinder: ignore*/ - for ( bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0'; - - if (!firstline) - { - LLSD item; - std::string line(buffer); - std::istringstream iss(line); - - if (!LLChatLogParser::parse(line, item)) - { - item["message"] = line; - callback(LOG_LINE, item, userdata); - } - else - { - callback(LOG_LLSD, item, userdata); - } - } - else - { - firstline = FALSE; - } - } - callback(LOG_END, LLSD(), userdata); - - fclose(fptr); + (*sSaveHistorySignal)(); } } -void append_to_last_message(std::list<LLSD>& messages, const std::string& line) -{ - if (!messages.size()) return; - - std::string im_text = messages.back()[IM_TEXT].asString(); - im_text.append(line); - messages.back()[IM_TEXT] = im_text; -} - // static -void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& messages) +void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params) { if (file_name.empty()) { llwarns << "Session name is Empty!" << llendl; return ; } - //LL_INFOS("") << "Loading:" << file_name << LL_ENDL;/* uncomment if you want to verify step, delete on commit */ - //LL_INFOS("") << "Current:" << makeLogFileName(file_name) << LL_ENDL;/* uncomment if you want to verify step, delete on commit */ + + bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false; + LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");/*Flawfinder: ignore*/ if (!fptr) - { + { fptr = LLFile::fopen(oldLogFileName(file_name), "r");/*Flawfinder: ignore*/ - if (!fptr) - { - if (!fptr) return; //No previous conversation with this name. - } + if (!fptr) + { + return; //No previous conversation with this name. + } } - //LL_INFOS("") << "Reading:" << file_name << LL_ENDL; char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/ char *bptr; S32 len; bool firstline = TRUE; - if (fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END)) - { //File is smaller than recall size. Get it all. + if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END)) + { //We need to load the whole historyFile or it's smaller than recall size, so get it all. firstline = FALSE; if (fseek(fptr, 0, SEEK_SET)) { @@ -449,9 +395,9 @@ void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& me else { LLSD item; - if (!LLChatLogParser::parse(line, item)) + if (!LLChatLogParser::parse(line, item, load_params)) { - item[IM_TEXT] = line; + item[LL_IM_TEXT] = line; } messages.push_back(item); } @@ -459,9 +405,259 @@ void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& me fclose(fptr); } +// static +std::string LLLogChat::oldLogFileName(std::string filename) +{ + // get Users log directory + std::string directory = gDirUtilp->getPerAccountChatLogsDir(); + + // add final OS dependent delimiter + directory += gDirUtilp->getDirDelimiter(); + + // lest make sure the file name has no invalid characters before making the pattern + filename = cleanFileName(filename); + + // create search pattern + std::string pattern = filename + ( filename == "chat" ? "-???\?-?\?-??.txt" : "-???\?-??.txt"); + + std::vector<std::string> allfiles; + LLDirIterator iter(directory, pattern); + std::string scanResult; + + while (iter.next(scanResult)) + { + allfiles.push_back(scanResult); + } + + if (allfiles.size() == 0) // if no result from date search, return generic filename + { + scanResult = directory + filename + '.' + LL_TRANSCRIPT_FILE_EXTENSION; + } + else + { + sort(allfiles.begin(), allfiles.end()); + scanResult = directory + allfiles.back(); + // this file is now the most recent version of the file. + } + + return scanResult; +} + +// static +void LLLogChat::findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions) +{ + // get Users log directory + std::string dirname = gDirUtilp->getPerAccountChatLogsDir(); + + // add final OS dependent delimiter + dirname += gDirUtilp->getDirDelimiter(); + + LLDirIterator iter(dirname, pattern); + std::string filename; + while (iter.next(filename)) + { + std::string fullname = gDirUtilp->add(dirname, filename); + + LLFILE * filep = LLFile::fopen(fullname, "rb"); + if (NULL != filep) + { + char buffer[LOG_RECALL_SIZE]; + + fseek(filep, 0, SEEK_END); // seek to end of file + S32 bytes_to_read = ftell(filep); // get current file pointer + fseek(filep, 0, SEEK_SET); // seek back to beginning of file + + // limit the number characters to read from file + if (bytes_to_read >= LOG_RECALL_SIZE) + { + bytes_to_read = LOG_RECALL_SIZE - 1; + } + + if (bytes_to_read > 0 && NULL != fgets(buffer, bytes_to_read, filep)) + { + //matching a timestamp + boost::match_results<std::string::const_iterator> matches; + if (boost::regex_match(std::string(buffer), matches, TIMESTAMP)) + { + list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename)); + } + } + LLFile::close(filep); + } + } +} + +// static +void LLLogChat::getListOfTranscriptFiles(std::vector<std::string>& list_of_transcriptions) +{ + // create search pattern + std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION; + findTranscriptFiles(pattern, list_of_transcriptions); +} + +// static +void LLLogChat::getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions) +{ + // create search pattern + std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION + ".backup*"; + findTranscriptFiles(pattern, list_of_transcriptions); +} + +//static +boost::signals2::connection LLLogChat::setSaveHistorySignal(const save_history_signal_t::slot_type& cb) +{ + if (NULL == sSaveHistorySignal) + { + sSaveHistorySignal = new save_history_signal_t(); + } + + return sSaveHistorySignal->connect(cb); +} + +//static +bool LLLogChat::moveTranscripts(const std::string originDirectory, + const std::string targetDirectory, + std::vector<std::string>& listOfFilesToMove, + std::vector<std::string>& listOfFilesMoved) +{ + std::string newFullPath; + bool movedAllTranscripts = true; + std::string backupFileName; + unsigned backupFileCount; + + BOOST_FOREACH(const std::string& fullpath, listOfFilesToMove) + { + backupFileCount = 0; + newFullPath = targetDirectory + fullpath.substr(originDirectory.length(), std::string::npos); + + //The target directory contains that file already, so lets store it + if(LLFile::isfile(newFullPath)) + { + backupFileName = newFullPath + ".backup"; + + //If needed store backup file as .backup1 etc. + while(LLFile::isfile(backupFileName)) + { + ++backupFileCount; + backupFileName = newFullPath + ".backup" + boost::lexical_cast<std::string>(backupFileCount); + } + + //Rename the file to its backup name so it is not overwritten + LLFile::rename(newFullPath, backupFileName); + } + + S32 retry_count = 0; + while (retry_count < 5) + { + //success is zero + if (LLFile::rename(fullpath, newFullPath) != 0) + { + retry_count++; + S32 result = errno; + LL_WARNS("LLLogChat::moveTranscripts") << "Problem renaming " << fullpath << " - errorcode: " + << result << " attempt " << retry_count << LL_ENDL; + + ms_sleep(100); + } + else + { + listOfFilesMoved.push_back(newFullPath); + + if (retry_count) + { + LL_WARNS("LLLogChat::moveTranscripts") << "Successfully renamed " << fullpath << LL_ENDL; + } + break; + } + } + } + + if(listOfFilesMoved.size() != listOfFilesToMove.size()) + { + movedAllTranscripts = false; + } + + return movedAllTranscripts; +} + +//static +bool LLLogChat::moveTranscripts(const std::string currentDirectory, + const std::string newDirectory, + std::vector<std::string>& listOfFilesToMove) +{ + std::vector<std::string> listOfFilesMoved; + return moveTranscripts(currentDirectory, newDirectory, listOfFilesToMove, listOfFilesMoved); +} + +//static +void LLLogChat::deleteTranscripts() +{ + std::vector<std::string> list_of_transcriptions; + getListOfTranscriptFiles(list_of_transcriptions); + getListOfTranscriptBackupFiles(list_of_transcriptions); + + BOOST_FOREACH(const std::string& fullpath, list_of_transcriptions) + { + S32 retry_count = 0; + while (retry_count < 5) + { + if (0 != LLFile::remove(fullpath)) + { + retry_count++; + S32 result = errno; + LL_WARNS("LLLogChat::deleteTranscripts") << "Problem removing " << fullpath << " - errorcode: " + << result << " attempt " << retry_count << LL_ENDL; + + if(retry_count >= 5) + { + LL_WARNS("LLLogChat::deleteTranscripts") << "Failed to remove " << fullpath << LL_ENDL; + return; + } + + ms_sleep(100); + } + else + { + if (retry_count) + { + LL_WARNS("LLLogChat::deleteTranscripts") << "Successfully removed " << fullpath << LL_ENDL; + } + break; + } + } + } + + LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true); +} + +// static +bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id) +{ + std::vector<std::string> list_of_transcriptions; + LLLogChat::getListOfTranscriptFiles(list_of_transcriptions); + + if (list_of_transcriptions.size() > 0) + { + LLAvatarName avatar_name; + LLAvatarNameCache::get(avatar_id, &avatar_name); + std::string avatar_user_name = avatar_name.getAccountName(); + std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_'); + + BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) + { + if (std::string::npos != transcript_file_name.find(avatar_user_name)) + { + return true; + } + } + } + + return false; +} + //*TODO mark object's names in a special way so that they will be distinguishable form avatar name //which are more strict by its nature (only firstname and secondname) -//Example, an object's name can be writen like "Object <actual_object's_name>" +//Example, an object's name can be written like "Object <actual_object's_name>" void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const { if (!im.isMap()) @@ -470,19 +666,19 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const return; } - if (im[IM_TIME].isDefined()) + if (im[LL_IM_TIME].isDefined()) { - std::string timestamp = im[IM_TIME].asString(); + std::string timestamp = im[LL_IM_TIME].asString(); boost::trim(timestamp); ostr << '[' << timestamp << ']' << TWO_SPACES; } //*TODO mark object's names in a special way so that they will be distinguishable form avatar name //which are more strict by its nature (only firstname and secondname) - //Example, an object's name can be writen like "Object <actual_object's_name>" - if (im[IM_FROM].isDefined()) + //Example, an object's name can be written like "Object <actual_object's_name>" + if (im[LL_IM_FROM].isDefined()) { - std::string from = im[IM_FROM].asString(); + std::string from = im[LL_IM_FROM].asString(); boost::trim(from); if (from.size()) { @@ -490,9 +686,9 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const } } - if (im[IM_TEXT].isDefined()) + if (im[LL_IM_TEXT].isDefined()) { - std::string im_text = im[IM_TEXT].asString(); + std::string im_text = im[LL_IM_TEXT].asString(); //multilined text will be saved with prepended spaces boost::replace_all(im_text, NEW_LINE, NEW_LINE_SPACE_PREFIX); @@ -500,10 +696,11 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const } } -bool LLChatLogParser::parse(std::string& raw, LLSD& im) +bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params) { if (!raw.length()) return false; + bool cut_off_todays_date = parse_params.has("cut_off_todays_date") ? parse_params["cut_off_todays_date"].asBoolean() : true; im = LLSD::emptyMap(); //matching a timestamp @@ -518,13 +715,18 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im) boost::trim(timestamp); timestamp.erase(0, 1); timestamp.erase(timestamp.length()-1, 1); - LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp); - im[IM_TIME] = timestamp; + + if (cut_off_todays_date) + { + LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp); + } + + im[LL_IM_TIME] = timestamp; } else { //timestamp is optional - im[IM_TIME] = ""; + im[LL_IM_TIME] = ""; } bool has_stuff = matches[IDX_STUFF].matched; @@ -550,8 +752,8 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im) if (!has_name || name == SYSTEM_FROM) { //name is optional too - im[IM_FROM] = SYSTEM_FROM; - im[IM_FROM_ID] = LLUUID::null; + im[LL_IM_FROM] = SYSTEM_FROM; + im[LL_IM_FROM_ID] = LLUUID::null; } //possibly a case of complex object names consisting of 3+ words @@ -560,8 +762,8 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im) U32 divider_pos = stuff.find(NAME_TEXT_DIVIDER); if (divider_pos != std::string::npos && divider_pos < (stuff.length() - NAME_TEXT_DIVIDER.length())) { - im[IM_FROM] = stuff.substr(0, divider_pos); - im[IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length()); + im[LL_IM_FROM] = stuff.substr(0, divider_pos); + im[LL_IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length()); return true; } } @@ -569,7 +771,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im) if (!has_name) { //text is mandatory - im[IM_TEXT] = stuff; + im[LL_IM_TEXT] = stuff; return true; //parse as a message from Second Life } @@ -581,45 +783,15 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im) { std::string agent_name; LLAgentUI::buildFullname(agent_name); - im[IM_FROM] = agent_name; - im[IM_FROM_ID] = gAgentID; + im[LL_IM_FROM] = agent_name; + im[LL_IM_FROM_ID] = gAgentID; } else { - im[IM_FROM] = name; + im[LL_IM_FROM] = name; } - im[IM_TEXT] = name_and_text[IDX_TEXT]; + im[LL_IM_TEXT] = name_and_text[IDX_TEXT]; return true; //parsed name and message text, maybe have a timestamp too } -std::string LLLogChat::oldLogFileName(std::string filename) -{ - std::string scanResult; - std::string directory = gDirUtilp->getPerAccountChatLogsDir();/* get Users log directory */ - directory += gDirUtilp->getDirDelimiter();/* add final OS dependent delimiter */ - filename=cleanFileName(filename);/* lest make shure the file name has no invalad charecters befor making the pattern */ - std::string pattern = (filename+(( filename == "chat" ) ? "-???\?-?\?-??.txt" : "-???\?-??.txt"));/* create search pattern*/ - //LL_INFOS("") << "Checking:" << directory << " for " << pattern << LL_ENDL;/* uncomment if you want to verify step, delete on commit */ - std::vector<std::string> allfiles; - - LLDirIterator iter(directory, pattern); - while (iter.next(scanResult)) - { - //LL_INFOS("") << "Found :" << scanResult << LL_ENDL; - allfiles.push_back(scanResult); - } - - if (allfiles.size() == 0) // if no result from date search, return generic filename - { - scanResult = directory + filename + ".txt"; - } - else - { - std::sort(allfiles.begin(), allfiles.end()); - scanResult = directory + allfiles.back(); - // thisfile is now the most recent version of the file. - } - //LL_INFOS("") << "Reading:" << scanResult << LL_ENDL;/* uncomment if you want to verify step, delete on commit */ - return scanResult; -} diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index 27752452c9..e819f00dd9 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -49,15 +49,29 @@ public: const std::string& from, const LLUUID& from_id, const std::string& line); + static void findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions); + static void getListOfTranscriptFiles(std::vector<std::string>& list); + static void getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions); - /** @deprecated @see loadAllHistory() */ - static void loadHistory(const std::string& filename, - void (*callback)(ELogLineType, const LLSD&, void*), - void* userdata); + static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD()); + + typedef boost::signals2::signal<void ()> save_history_signal_t; + static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb); + + static bool moveTranscripts(const std::string currentDirectory, + const std::string newDirectory, + std::vector<std::string>& listOfFilesToMove, + std::vector<std::string>& listOfFilesMoved); + static bool moveTranscripts(const std::string currentDirectory, + const std::string newDirectory, + std::vector<std::string>& listOfFilesToMove); + + static void deleteTranscripts(); + static bool isTranscriptExist(const LLUUID& avatar_id); - static void loadAllHistory(const std::string& file_name, std::list<LLSD>& messages); private: static std::string cleanFileName(std::string filename); + static save_history_signal_t * sSaveHistorySignal; }; /** @@ -105,7 +119,7 @@ public: * * @return false if failed to parse mandatory data - message text */ - static bool parse(std::string& raw, LLSD& im); + static bool parse(std::string& raw, LLSD& im, const LLSD& parse_params = LLSD()); protected: LLChatLogParser(); @@ -113,9 +127,10 @@ protected: }; // LLSD map lookup constants -extern const std::string IM_TIME; //("time"); -extern const std::string IM_TEXT; //("message"); -extern const std::string IM_FROM; //("from"); -extern const std::string IM_FROM_ID; //("from_id"); +extern const std::string LL_IM_TIME; //("time"); +extern const std::string LL_IM_TEXT; //("message"); +extern const std::string LL_IM_FROM; //("from"); +extern const std::string LL_IM_FROM_ID; //("from_id"); +extern const std::string LL_TRANSCRIPT_FILE_EXTENSION; //("txt"); #endif diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp index 778693876e..cd6473921d 100644 --- a/indra/newview/llmachineid.cpp +++ b/indra/newview/llmachineid.cpp @@ -252,12 +252,20 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len) if (has_static_unique_id) { memcpy ( unique_id, &static_unique_id, len); - LL_DEBUGS("AppInit") << "UniqueID: " << unique_id[0] << unique_id[1]<< unique_id[2] << unique_id[3] << unique_id[4] << unique_id [5] << LL_ENDL; + LL_DEBUGS("AppInit") << "UniqueID: 0x"; + // Code between here and LL_ENDL is not executed unless the LL_DEBUGS + // actually produces output + for (size_t i = 0; i < len; ++i) + { + // Copy each char to unsigned int to hexify. Sending an unsigned + // char to a std::ostream tries to represent it as a char, not + // what we want here. + unsigned byte = unique_id[i]; + LL_CONT << std::hex << std::setw(2) << std::setfill('0') << byte; + } + // Reset default output formatting to avoid nasty surprises! + LL_CONT << std::dec << std::setw(0) << std::setfill(' ') << LL_ENDL; return 1; } return 0; } - - - - diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 6e0f360cbc..9ec5d7c20c 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -72,7 +72,6 @@ void LLManip::rebuild(LLViewerObject* vobj) LLDrawable* drawablep = vobj->mDrawable; if (drawablep && drawablep->getVOVolume()) { - gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME, TRUE); drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED drawablep->updateMove(); @@ -82,6 +81,14 @@ void LLManip::rebuild(LLViewerObject* vobj) group->dirtyGeom(); gPipeline.markRebuild(group, TRUE); } + + LLViewerObject::const_child_list_t& child_list = vobj->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(), endIter = child_list.end(); + iter != endIter; ++iter) + { + LLViewerObject* child = *iter; + rebuild(child); + } } } diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index a8da94f75e..c8b446872b 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -479,9 +479,12 @@ BOOL LLManipRotate::handleMouseUp(S32 x, S32 y, MASK mask) { LLSelectNode* selectNode = *iter; LLViewerObject* object = selectNode->getObject(); + LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit(); // have permission to move and object is root of selection or individually selected - if (object->permMove() && (object->isRootEdit() || selectNode->mIndividualSelection)) + if (object->permMove() && !object->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + (object->isRootEdit() || selectNode->mIndividualSelection)) { object->mUnselectedChildrenPositions.clear() ; } @@ -567,9 +570,12 @@ void LLManipRotate::drag( S32 x, S32 y ) { LLSelectNode* selectNode = *iter; LLViewerObject* object = selectNode->getObject(); + LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit(); // have permission to move and object is root of selection or individually selected - if (object->permMove() && (object->isRootEdit() || selectNode->mIndividualSelection)) + if (object->permMove() && !object->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + (object->isRootEdit() || selectNode->mIndividualSelection)) { if (!object->isRootEdit()) { @@ -621,9 +627,11 @@ void LLManipRotate::drag( S32 x, S32 y ) { LLSelectNode* selectNode = *iter; LLViewerObject* object = selectNode->getObject(); + LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit(); // to avoid cumulative position changes we calculate the objects new position using its saved position - if (object && object->permMove()) + if (object && object->permMove() && !object->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced())) { LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); @@ -704,7 +712,10 @@ void LLManipRotate::drag( S32 x, S32 y ) { LLSelectNode* selectNode = *iter; LLViewerObject*cur = selectNode->getObject(); - if( cur->permModify() && cur->permMove() && !cur->isAvatar()) + LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit(); + if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + !cur->isAvatar()) { selectNode->mLastRotation = cur->getRotation(); selectNode->mLastPositionLocal = cur->getPosition(); @@ -1365,74 +1376,28 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) BOOL hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); projected_mouse -= snap_plane_center; - S32 snap_plane = 0; - - F32 dot = cam_to_snap_plane * constraint_axis; - if (llabs(dot) < 0.01f) - { - // looking at ring edge on, project onto view plane and check if mouse is past ring - getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); - projected_mouse -= snap_plane_center; - dot = projected_mouse * constraint_axis; - if (projected_mouse * constraint_axis > 0) - { - snap_plane = 1; - } - projected_mouse -= dot * constraint_axis; - } - else if (dot > 0.f) - { - // look for mouse position outside and in front of snap circle - if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) - { - snap_plane = 1; - } - } - else - { - // look for mouse position inside or in back of snap circle - if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) - { - snap_plane = 1; - } - } - - if (snap_plane == 0) - { - // try other plane - snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f)); - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - cam_to_snap_plane.setVec(1.f, 0.f, 0.f); - } - else - { - cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent(); - cam_to_snap_plane.normVec(); - } - - hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); - projected_mouse -= snap_plane_center; - - dot = cam_to_snap_plane * constraint_axis; + if (gSavedSettings.getBOOL("SnapEnabled")) { + S32 snap_plane = 0; + + F32 dot = cam_to_snap_plane * constraint_axis; if (llabs(dot) < 0.01f) { // looking at ring edge on, project onto view plane and check if mouse is past ring getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); projected_mouse -= snap_plane_center; dot = projected_mouse * constraint_axis; - if (projected_mouse * constraint_axis < 0) + if (projected_mouse * constraint_axis > 0) { - snap_plane = 2; + snap_plane = 1; } projected_mouse -= dot * constraint_axis; } - else if (dot < 0.f) + else if (dot > 0.f) { // look for mouse position outside and in front of snap circle if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) { - snap_plane = 2; + snap_plane = 1; } } else @@ -1440,78 +1405,136 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) // look for mouse position inside or in back of snap circle if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) { - snap_plane = 2; + snap_plane = 1; } } - } - - if (snap_plane > 0) - { - LLVector3 cam_at_axis; - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - cam_at_axis.setVec(1.f, 0.f, 0.f); - } - else - { - cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent(); - cam_at_axis.normVec(); - } - - // first, project mouse onto screen plane at point tangent to rotation radius. - getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis); - // project that point onto rotation plane - projected_mouse -= snap_plane_center; - projected_mouse -= projected_vec(projected_mouse, constraint_axis); - - F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec()); - F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; - if (llabs(mouse_lateral_dist) > 0.01f) - { - mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - - (mouse_lateral_dist * mouse_lateral_dist)); - } - LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis); - projected_mouse -= mouse_depth * projected_camera_at; - - if (!mInSnapRegime) + + if (snap_plane == 0) { - mSmoothRotate = TRUE; + // try other plane + snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f)); + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + cam_to_snap_plane.setVec(1.f, 0.f, 0.f); + } + else + { + cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent(); + cam_to_snap_plane.normVec(); + } + + hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); + projected_mouse -= snap_plane_center; + + dot = cam_to_snap_plane * constraint_axis; + if (llabs(dot) < 0.01f) + { + // looking at ring edge on, project onto view plane and check if mouse is past ring + getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); + projected_mouse -= snap_plane_center; + dot = projected_mouse * constraint_axis; + if (projected_mouse * constraint_axis < 0) + { + snap_plane = 2; + } + projected_mouse -= dot * constraint_axis; + } + else if (dot < 0.f) + { + // look for mouse position outside and in front of snap circle + if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) + { + snap_plane = 2; + } + } + else + { + // look for mouse position inside or in back of snap circle + if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) + { + snap_plane = 2; + } + } } - mInSnapRegime = TRUE; - // 0 to 360 deg - F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f); - F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT); - //fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f); - - LLVector3 object_axis; - getObjectAxisClosestToMouse(object_axis); - object_axis = object_axis * first_object_node->mSavedRotation; - - // project onto constraint plane - object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); - object_axis.normVec(); - - if (relative_mouse_angle < SNAP_ANGLE_DETENTE) + if (snap_plane > 0) { - F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f)); - angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + LLVector3 cam_at_axis; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + cam_at_axis.setVec(1.f, 0.f, 0.f); + } + else + { + cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent(); + cam_at_axis.normVec(); + } + + // first, project mouse onto screen plane at point tangent to rotation radius. + getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis); + // project that point onto rotation plane + projected_mouse -= snap_plane_center; + projected_mouse -= projected_vec(projected_mouse, constraint_axis); + + F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec()); + F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; + if (llabs(mouse_lateral_dist) > 0.01f) + { + mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - + (mouse_lateral_dist * mouse_lateral_dist)); + } + LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis); + projected_mouse -= mouse_depth * projected_camera_at; + + if (!mInSnapRegime) + { + mSmoothRotate = TRUE; + } + mInSnapRegime = TRUE; + // 0 to 360 deg + F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f); + + F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT); + //fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f); + + LLVector3 object_axis; + getObjectAxisClosestToMouse(object_axis); + object_axis = object_axis * first_object_node->mSavedRotation; + + // project onto constraint plane + object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); + object_axis.normVec(); + + if (relative_mouse_angle < SNAP_ANGLE_DETENTE) + { + F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f)); + angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + } + else + { + angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + } + return LLQuaternion( -angle, constraint_axis ); } else { - angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + if (mInSnapRegime) + { + mSmoothRotate = TRUE; + } + mInSnapRegime = FALSE; } - return LLQuaternion( -angle, constraint_axis ); } - else - { + else { if (mInSnapRegime) { mSmoothRotate = TRUE; } mInSnapRegime = FALSE; - + } + + if (!mInSnapRegime) + { LLVector3 up_from_axis = mCenterToCamNorm % constraint_axis; up_from_axis.normVec(); LLVector3 cur_intersection; @@ -1871,7 +1894,10 @@ BOOL LLManipRotate::canAffectSelection() { virtual bool apply(LLViewerObject* objectp) { - return objectp->permMove() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); + LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit(); + return objectp->permMove() && !objectp->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); } } func; can_rotate = mObjectSelection->applyToObjects(&func); diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index f6df4cdfbf..00a0bf8894 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -826,7 +826,10 @@ void LLManipScale::drag( S32 x, S32 y ) { LLSelectNode* selectNode = *iter; LLViewerObject*cur = selectNode->getObject(); - if( cur->permModify() && cur->permMove() && !cur->isAvatar()) + LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit(); + if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + !cur->isAvatar()) { selectNode->mLastScale = cur->getScale(); selectNode->mLastPositionLocal = cur->getPosition(); @@ -973,7 +976,10 @@ void LLManipScale::dragCorner( S32 x, S32 y ) { LLSelectNode* selectNode = *iter; LLViewerObject* cur = selectNode->getObject(); - if( cur->permModify() && cur->permMove() && !cur->isAvatar() ) + LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit(); + if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + !cur->isAvatar() ) { const LLVector3& scale = selectNode->mSavedScale; @@ -995,7 +1001,10 @@ void LLManipScale::dragCorner( S32 x, S32 y ) { LLSelectNode* selectNode = *iter; LLViewerObject* cur = selectNode->getObject(); - if( cur->permModify() && cur->permMove() && !cur->isAvatar() && cur->isRootEdit() ) + LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit(); + if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + !cur->isAvatar() && cur->isRootEdit() ) { const LLVector3& scale = selectNode->mSavedScale; cur->setScale( scale_factor * scale ); @@ -1043,7 +1052,10 @@ void LLManipScale::dragCorner( S32 x, S32 y ) { LLSelectNode* selectNode = *iter; LLViewerObject*cur = selectNode->getObject(); - if( cur->permModify() && cur->permMove() && !cur->isAvatar() && !cur->isRootEdit() ) + LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit(); + if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + !cur->isAvatar() && !cur->isRootEdit() ) { const LLVector3& scale = selectNode->mSavedScale; cur->setScale( scale_factor * scale, FALSE ); @@ -1251,7 +1263,10 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto { LLSelectNode* selectNode = *iter; LLViewerObject*cur = selectNode->getObject(); - if( cur->permModify() && cur->permMove() && !cur->isAvatar() ) + LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit(); + if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + !cur->isAvatar() ) { LLBBox cur_bbox = cur->getBoundingBoxAgent(); LLVector3 start_local = cur_bbox.agentToLocal( drag_start_agent ); @@ -2057,7 +2072,10 @@ BOOL LLManipScale::canAffectSelection() { virtual bool apply(LLViewerObject* objectp) { - return objectp->permModify() && objectp->permMove() && !objectp->isSeat(); + LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit(); + return objectp->permModify() && objectp->permMove() && !objectp->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + !objectp->isSeat(); } } func; can_scale = mObjectSelection->applyToObjects(&func); diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 3a88fbd96d..362308c176 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -60,6 +60,7 @@ #include "llworld.h" #include "llui.h" #include "pipeline.h" +#include "llviewershadermgr.h" const S32 NUM_AXES = 3; const S32 MOUSE_DRAG_SLOP = 2; // pixels @@ -687,7 +688,9 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) } } - if (object->permMove()) + LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit(); + if (object->permMove() && !object->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced())) { // handle attachments in local space if (object->isAttachment() && object->mDrawable.notNull()) @@ -1580,7 +1583,11 @@ void LLManipTranslate::renderSnapGuides() LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER); LLGLEnable stipple(GL_LINE_STIPPLE); gGL.flush(); - glLineStipple(1, 0x3333); + + if (!LLGLSLShader::sNoFixedFunction) + { + glLineStipple(1, 0x3333); + } switch (mManipPart) { @@ -1645,17 +1652,28 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, LLQuaternion grid_rotation, LLColor4 inner_color) { - if (!gSavedSettings.getBOOL("GridCrossSections")) + if (!gSavedSettings.getBOOL("GridCrossSections") || !LLGLSLShader::sNoFixedFunction) { return; } + + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + + U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY }; U32 num_types = LL_ARRAY_SIZE(types); GLuint stencil_mask = 0xFFFFFFFF; //stencil in volumes + gGL.flush(); + + if (shader) + { + gClipProgram.bind(); + } + { glStencilMask(stencil_mask); glClearStencil(1); @@ -1666,6 +1684,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, glStencilFunc(GL_ALWAYS, 0, stencil_mask); gGL.setColorMask(false, false); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.diffuseColor4f(1,1,1,1); //setup clip plane @@ -1675,10 +1694,12 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, normal = -normal; } F32 d = -(selection_center * normal); - F64 plane[] = { normal.mV[0], normal.mV[1], normal.mV[2], d }; - LLGLEnable clip(GL_CLIP_PLANE0); - glClipPlane(GL_CLIP_PLANE0, plane); + glh::vec4f plane(normal.mV[0], normal.mV[1], normal.mV[2], d ); + + gGL.getModelviewMatrix().inverse().mult_vec_matrix(plane); + gClipProgram.uniform4fv("clip_plane", 1, plane.v); + BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES); BOOL clouds = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS); @@ -1729,6 +1750,16 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, F32 sz = mGridSizeMeters; F32 tiles = sz; + if (shader) + { + shader->bind(); + } + + if (shader) + { + shader->bind(); + } + //draw volume/plane intersections { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -2281,7 +2312,10 @@ BOOL LLManipTranslate::canAffectSelection() { virtual bool apply(LLViewerObject* objectp) { - return objectp->permMove() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); + LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit(); + return objectp->permMove() && !objectp->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); } } func; can_move = mObjectSelection->applyToObjects(&func); diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp new file mode 100644 index 0000000000..0b009b68f7 --- /dev/null +++ b/indra/newview/llmarketplacefunctions.cpp @@ -0,0 +1,484 @@ +/** + * @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 "lltimer.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_id = LLGridManager::getInstance()->getGridId(); + const std::string& grid_id_lower = utf8str_tolower(grid_id); + + if (grid_id_lower == "damballah") + { + domain = "secondlife-staging.com"; + } + else + { + domain = llformat("%s.lindenlab.com", grid_id_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(); + + static LLTimer slmGetTimer; + static LLTimer slmPostTimer; + + // Responders + + class LLImportPostResponder : public LLHTTPClient::Responder + { + public: + LLImportPostResponder() : LLCurl::Responder() {} + + void completed(U32 status, const std::string& reason, const LLSD& content) + { + slmPostTimer.stop(); + + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM POST status: " << status << llendl; + llinfos << " SLM POST reason: " << reason << llendl; + llinfos << " SLM POST content: " << content.asString() << llendl; + + llinfos << " SLM POST timer: " << slmPostTimer.getElapsedTimeF32() << 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) + { + slmGetTimer.stop(); + + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM GET status: " << status << llendl; + llinfos << " SLM GET reason: " << reason << llendl; + llinfos << " SLM GET content: " << content.asString() << llendl; + + llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << 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; + } + + slmGetTimer.start(); + 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; + } + + slmGetTimer.start(); + 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; + } + + slmPostTimer.start(); + LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers); + + return true; + } +} + + +// +// Interface class +// + +static const F32 MARKET_IMPORTER_UPDATE_FREQUENCY = 1.0f; + +//static +void LLMarketplaceInventoryImporter::update() +{ + if (instanceExists()) + { + static LLTimer update_timer; + if (update_timer.hasExpired()) + { + LLMarketplaceInventoryImporter::instance().updateImport(); + update_timer.setTimerExpirySec(MARKET_IMPORTER_UPDATE_FREQUENCY); + } + } +} + +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(¬ifyNoCopyCallback, _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..99b4707158 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() @@ -559,32 +564,13 @@ void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type) // void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in ) { - std::string language = LLUI::getLanguage(); - std::string delim = gDirUtilp->getDirDelimiter(); - std::string filename; - - filename += subdir; - filename += delim; - filename += filename_in; + std::string filename(gDirUtilp->add(subdir, filename_in)); + std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", filename); - std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", language, filename); - - if (! gDirUtilp->fileExists(expanded_filename)) + if (expanded_filename.empty()) { - if (language != "en") - { - expanded_filename = gDirUtilp->findSkinnedFilename("html", "en", filename); - if (! gDirUtilp->fileExists(expanded_filename)) - { - llwarns << "File " << subdir << delim << filename_in << "not found" << llendl; - return; - } - } - else - { - llwarns << "File " << subdir << delim << filename_in << "not found" << llendl; - return; - } + llwarns << "File " << filename << "not found" << llendl; + return; } if (ensureMediaSourceExists()) { @@ -592,7 +578,6 @@ void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::str mMediaSource->setSize(mTextureWidth, mTextureHeight); mMediaSource->navigateTo(expanded_filename, "text/html", false); } - } //////////////////////////////////////////////////////////////////////////////// @@ -1092,39 +1077,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/llmemoryview.cpp b/indra/newview/llmemoryview.cpp deleted file mode 100644 index 7e9c3c84a7..0000000000 --- a/indra/newview/llmemoryview.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/** - * @file llmemoryview.cpp - * @brief LLMemoryView class implementation - * - * $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 "llmemoryview.h" - -#include "llappviewer.h" -#include "llallocator_heap_profile.h" -#include "llgl.h" // LLGLSUIDefault -#include "llviewerwindow.h" -#include "llviewercontrol.h" - -#include <sstream> -#include <boost/algorithm/string/split.hpp> - -#include "llmemory.h" - -LLMemoryView::LLMemoryView(const LLMemoryView::Params& p) -: LLView(p), - mPaused(FALSE), - //mDelay(120), - mAlloc(NULL) -{ -} - -LLMemoryView::~LLMemoryView() -{ -} - -BOOL LLMemoryView::handleMouseDown(S32 x, S32 y, MASK mask) -{ - if (mask & MASK_SHIFT) - { - } - else if (mask & MASK_CONTROL) - { - } - else - { - mPaused = !mPaused; - } - return TRUE; -} - -BOOL LLMemoryView::handleMouseUp(S32 x, S32 y, MASK mask) -{ - return TRUE; -} - - -BOOL LLMemoryView::handleHover(S32 x, S32 y, MASK mask) -{ - return FALSE; -} - -void LLMemoryView::refreshProfile() -{ - /* - LLAllocator & alloc = LLAppViewer::instance()->getAllocator(); - if(alloc.isProfiling()) { - std::string profile_text = alloc.getRawProfile(); - - boost::algorithm::split(mLines, profile_text, boost::bind(std::equal_to<llwchar>(), '\n', _1)); - } else { - mLines.clear(); - } - */ - if (mAlloc == NULL) { - mAlloc = &LLAppViewer::instance()->getAllocator(); - } - - mLines.clear(); - - if(mAlloc->isProfiling()) - { - const LLAllocatorHeapProfile &prof = mAlloc->getProfile(); - for(size_t i = 0; i < prof.mLines.size(); ++i) - { - std::stringstream ss; - ss << "Unfreed Mem: " << (prof.mLines[i].mLiveSize >> 20) << " M Trace: "; - for(size_t k = 0; k < prof.mLines[i].mTrace.size(); ++k) - { - ss << LLMemType::getNameFromID(prof.mLines[i].mTrace[k]) << " "; - } - mLines.push_back(utf8string_to_wstring(ss.str())); - } - } -} - -void LLMemoryView::draw() -{ - const S32 UPDATE_INTERVAL = 60; - const S32 MARGIN_AMT = 10; - static S32 curUpdate = UPDATE_INTERVAL; - static LLUIColor s_console_color = LLUIColorTable::instance().getColor("ConsoleBackground", LLColor4U::black); - - // setup update interval - if (curUpdate >= UPDATE_INTERVAL) - { - refreshProfile(); - curUpdate = 0; - } - curUpdate++; - - // setup window properly - S32 height = (S32) (gViewerWindow->getWindowRectScaled().getHeight()*0.75f); - S32 width = (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.9f); - setRect(LLRect().setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height)); - - // setup window color - F32 console_opacity = llclamp(gSavedSettings.getF32("ConsoleBackgroundOpacity"), 0.f, 1.f); - LLColor4 color = s_console_color; - color.mV[VALPHA] *= console_opacity; - - LLGLSUIDefault gls_ui; - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gl_rect_2d(0, height, width, 0, color); - - LLFontGL * font = LLFontGL::getFontSansSerifSmall(); - - // draw remaining lines - F32 y_pos = 0.f; - F32 y_off = 0.f; - - F32 line_height = font->getLineHeight(); - S32 target_width = width - 2 * MARGIN_AMT; - - // cut off lines on bottom - U32 max_lines = U32((height - 2 * line_height) / line_height); - y_pos = height - MARGIN_AMT - line_height; - y_off = 0.f; - -#if !MEM_TRACK_MEM - std::vector<LLWString>::const_iterator end = mLines.end(); - if(mLines.size() > max_lines) { - end = mLines.begin() + max_lines; - } - for (std::vector<LLWString>::const_iterator i = mLines.begin(); i != end; ++i) - { - font->render(*i, 0, MARGIN_AMT, y_pos - y_off, - LLColor4::white, - LLFontGL::LEFT, - LLFontGL::BASELINE, - LLFontGL::NORMAL, - LLFontGL::DROP_SHADOW, - S32_MAX, - target_width - ); - y_off += line_height; - } - -#else - LLMemTracker::getInstance()->preDraw(mPaused) ; - - { - F32 x_pos = MARGIN_AMT ; - U32 lines = 0 ; - const char* str = LLMemTracker::getInstance()->getNextLine() ; - while(str != NULL) - { - lines++ ; - font->renderUTF8(str, 0, x_pos, y_pos - y_off, - LLColor4::white, - LLFontGL::LEFT, - LLFontGL::BASELINE, - LLFontGL::NORMAL, - LLFontGL::DROP_SHADOW, - S32_MAX, - target_width, - NULL, FALSE); - - str = LLMemTracker::getInstance()->getNextLine() ; - y_off += line_height; - - if(lines >= max_lines) - { - lines = 0 ; - x_pos += 512.f ; - if(x_pos + 512.f > target_width) - { - break ; - } - - y_pos = height - MARGIN_AMT - line_height; - y_off = 0.f; - } - } - } - - LLMemTracker::getInstance()->postDraw() ; -#endif - -#if MEM_TRACK_TYPE - - S32 left, top, right, bottom; - S32 x, y; - - S32 margin = 10; - S32 texth = (S32)LLFontGL::getFontMonospace()->getLineHeight(); - - S32 xleft = margin; - S32 ytop = height - margin; - S32 labelwidth = 0; - S32 maxmaxbytes = 1; - - // Make sure all timers are accounted for - // Set 'MT_OTHER' to unaccounted ticks last frame - { - S32 display_memtypes[LLMemType::MTYPE_NUM_TYPES]; - for (S32 i=0; i < LLMemType::MTYPE_NUM_TYPES; i++) - { - display_memtypes[i] = 0; - } - for (S32 i=0; i < MTV_DISPLAY_NUM; i++) - { - S32 tidx = mtv_display_table[i].memtype; - display_memtypes[tidx]++; - } - LLMemType::sMemCount[LLMemType::MTYPE_OTHER] = 0; - LLMemType::sMaxMemCount[LLMemType::MTYPE_OTHER] = 0; - for (S32 tidx = 0; tidx < LLMemType::MTYPE_NUM_TYPES; tidx++) - { - if (display_memtypes[tidx] == 0) - { - LLMemType::sMemCount[LLMemType::MTYPE_OTHER] += LLMemType::sMemCount[tidx]; - LLMemType::sMaxMemCount[LLMemType::MTYPE_OTHER] += LLMemType::sMaxMemCount[tidx]; - } - } - } - - // Labels - { - y = ytop; - S32 peak = 0; - for (S32 i=0; i<MTV_DISPLAY_NUM; i++) - { - x = xleft; - - int tidx = mtv_display_table[i].memtype; - S32 bytes = LLMemType::sMemCount[tidx]; - S32 maxbytes = LLMemType::sMaxMemCount[tidx]; - maxmaxbytes = llmax(maxbytes, maxmaxbytes); - peak += maxbytes; - S32 mbytes = bytes >> 20; - - tdesc = llformat("%s [%4d MB] in %06d NEWS",mtv_display_table[i].desc,mbytes, LLMemType::sNewCount[tidx]); - LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); - - y -= (texth + 2); - - S32 textw = LLFontGL::getFontMonospace()->getWidth(tdesc); - if (textw > labelwidth) - labelwidth = textw; - } - - S32 num_avatars = 0; - S32 num_motions = 0; - S32 num_loading_motions = 0; - S32 num_loaded_motions = 0; - S32 num_active_motions = 0; - S32 num_deprecated_motions = 0; - for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) - { - num_avatars++; - (*iter)->getMotionController().incMotionCounts(num_motions, num_loading_motions, num_loaded_motions, num_active_motions, num_deprecated_motions); - } - - x = xleft; - tdesc = llformat("Total Bytes: %d MB Overhead: %d KB Avs %d Motions:%d Loading:%d Loaded:%d Active:%d Dep:%d", - LLMemType::sTotalMem >> 20, LLMemType::sOverheadMem >> 10, - num_avatars, num_motions, num_loading_motions, num_loaded_motions, num_active_motions, num_deprecated_motions); - LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); - } - - // Bars - y = ytop; - labelwidth += 8; - S32 barw = width - labelwidth - xleft - margin; - for (S32 i=0; i<MTV_DISPLAY_NUM; i++) - { - x = xleft + labelwidth; - - int tidx = mtv_display_table[i].memtype; - S32 bytes = LLMemType::sMemCount[tidx]; - F32 frac = (F32)bytes / (F32)maxmaxbytes; - S32 w = (S32)(frac * (F32)barw); - left = x; right = x + w; - top = y; bottom = y - texth; - gl_rect_2d(left, top, right, bottom, *mtv_display_table[i].color); - - S32 maxbytes = LLMemType::sMaxMemCount[tidx]; - F32 frac2 = (F32)maxbytes / (F32)maxmaxbytes; - S32 w2 = (S32)(frac2 * (F32)barw); - left = x + w + 1; right = x + w2; - top = y; bottom = y - texth; - LLColor4 tcolor = *mtv_display_table[i].color; - tcolor.setAlpha(.5f); - gl_rect_2d(left, top, right, bottom, tcolor); - - y -= (texth + 2); - } - - dumpData(); - -#endif - - LLView::draw(); -} diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp deleted file mode 100644 index 4b7f9432e3..0000000000 --- a/indra/newview/llmenucommands.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/** - * @file llmenucommands.cpp - * @brief Implementations of menu commands. - * - * $LicenseInfo:firstyear=2003&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 "llmenucommands.h" - -#include "imageids.h" -#include "llfloaterreg.h" -#include "llfontgl.h" -#include "llrect.h" -#include "llerror.h" -#include "llstring.h" -#include "message.h" - -#include "llagentcamera.h" -#include "llcallingcard.h" -#include "llviewercontrol.h" -//#include "llfirstuse.h" -#include "llfloaterworldmap.h" -#include "lllineeditor.h" -#include "llstatusbar.h" -#include "llimview.h" -#include "lltextbox.h" -#include "llui.h" -#include "llviewergesture.h" // for triggering gestures -#include "llviewermessage.h" -#include "llviewerparceloverlay.h" -#include "llviewerregion.h" -#include "llviewerstats.h" -#include "lluictrlfactory.h" -#include "llviewerwindow.h" -#include "llworld.h" -#include "llworldmap.h" -#include "llfocusmgr.h" -#include "llnearbychatbar.h" - -void handle_mouselook(void*) -{ - gAgentCamera.changeCameraToMouselook(); -} - - -void handle_chat(void*) -{ - // give focus to chatbar if it's open but not focused - if (gSavedSettings.getBOOL("ChatVisible") && - gFocusMgr.childHasKeyboardFocus(LLNearbyChatBar::getInstance()->getChatBox())) - { - LLNearbyChatBar::stopChat(); - } - else - { - LLNearbyChatBar::startChat(NULL); - } -} - -void handle_slash_key(void*) -{ - // LLBottomTray::startChat("/"); - // - // Don't do this, it results in a double-slash in the input field. - // Another "/" will be automatically typed for us, because the WM_KEYDOWN event - // that generated the menu accelerator call (and hence puts focus in - // the chat edtior) will be followed by a "/" WM_CHAR character message, - // which will type the slash. Yes, it's weird. It only matters for - // menu accelerators that put input focus into a field. And Mac works - // the same way. JC - - LLNearbyChatBar::startChat(NULL); -} diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp new file mode 100644 index 0000000000..2b92b0b3d1 --- /dev/null +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp @@ -0,0 +1,245 @@ +/** +* @file llmenuoptionpathfindingrebakenavmesh.cpp +* @brief Implementation of llmenuoptionpathfindingrebakenavmesh +* @author Prep@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llmenuoptionpathfindingrebakenavmesh.h" + +#include <boost/bind.hpp> +#include <boost/signals2.hpp> + +#include "llagent.h" +#include "llenvmanager.h" +#include "llnotificationsutil.h" +#include "llpathfindingmanager.h" +#include "llpathfindingnavmesh.h" +#include "llpathfindingnavmeshstatus.h" +#include "llviewerregion.h" + +LLMenuOptionPathfindingRebakeNavmesh::LLMenuOptionPathfindingRebakeNavmesh() + : LLSingleton<LLMenuOptionPathfindingRebakeNavmesh>(), + mIsInitialized(false), + mCanRebakeRegion(false), + mRebakeNavMeshMode(kRebakeNavMesh_Default), + mNavMeshSlot(), + mRegionCrossingSlot(), + mAgentStateSlot() +{ +} + +LLMenuOptionPathfindingRebakeNavmesh::~LLMenuOptionPathfindingRebakeNavmesh() +{ + if (mIsInitialized) + { + if (mRebakeNavMeshMode == kRebakeNavMesh_RequestSent) + { + LL_WARNS("navmeshRebaking") << "During destruction of the LLMenuOptionPathfindingRebakeNavmesh " + << "singleton, the mode indicates that a request has been sent for which a response has yet " + << "to be received. This could contribute to a crash on exit." << LL_ENDL; + } + + quit(); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::initialize() +{ + if (!mIsInitialized) + { + mIsInitialized = true; + + setMode(kRebakeNavMesh_Default); + + createNavMeshStatusListenerForCurrentRegion(); + + if ( !mRegionCrossingSlot.connected() ) + { + mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this)); + } + + if (!mAgentStateSlot.connected()) + { + mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleAgentState, this, _1)); + } + LLPathfindingManager::getInstance()->requestGetAgentState(); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::quit() +{ + if (mIsInitialized) + { + if (mNavMeshSlot.connected()) + { + mNavMeshSlot.disconnect(); + } + + if (mRegionCrossingSlot.connected()) + { + mRegionCrossingSlot.disconnect(); + } + + if (mAgentStateSlot.connected()) + { + mAgentStateSlot.disconnect(); + } + + mIsInitialized = false; + } +} + +bool LLMenuOptionPathfindingRebakeNavmesh::canRebakeRegion() const +{ + if (!mIsInitialized) + { + LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized " + << "when the ability to rebake navmesh is being requested." << LL_ENDL; + } + return mCanRebakeRegion; +} + +LLMenuOptionPathfindingRebakeNavmesh::ERebakeNavMeshMode LLMenuOptionPathfindingRebakeNavmesh::getMode() const +{ + if (!mIsInitialized) + { + LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized " + << "when the mode is being requested." << LL_ENDL; + } + return mRebakeNavMeshMode; +} + +void LLMenuOptionPathfindingRebakeNavmesh::sendRequestRebakeNavmesh() +{ + if (!mIsInitialized) + { + LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized " + << "when the request is being made to rebake the navmesh." << LL_ENDL; + } + else + { + if (!canRebakeRegion()) + { + LL_WARNS("navmeshRebaking") << "attempting to rebake navmesh when user does not have permissions " + << "on this region" << LL_ENDL; + } + if (getMode() != kRebakeNavMesh_Available) + { + LL_WARNS("navmeshRebaking") << "attempting to rebake navmesh when mode is not available" + << LL_ENDL; + } + + setMode(kRebakeNavMesh_RequestSent); + LLPathfindingManager::getInstance()->requestRebakeNavMesh(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRebakeNavMeshResponse, this, _1)); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::setMode(ERebakeNavMeshMode pRebakeNavMeshMode) +{ + mRebakeNavMeshMode = pRebakeNavMeshMode; +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleAgentState(BOOL pCanRebakeRegion) +{ + llassert(mIsInitialized); + mCanRebakeRegion = pCanRebakeRegion; +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleRebakeNavMeshResponse(bool pResponseStatus) +{ + llassert(mIsInitialized); + if (mIsInitialized) + { + if (getMode() == kRebakeNavMesh_RequestSent) + { + setMode(pResponseStatus ? kRebakeNavMesh_InProgress : kRebakeNavMesh_Default); + } + + if (!pResponseStatus) + { + LLNotificationsUtil::add("PathfindingCannotRebakeNavmesh"); + } + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleNavMeshStatus(const LLPathfindingNavMeshStatus &pNavMeshStatus) +{ + llassert(mIsInitialized); + if (mIsInitialized) + { + ERebakeNavMeshMode rebakeNavMeshMode = kRebakeNavMesh_Default; + if (pNavMeshStatus.isValid()) + { + switch (pNavMeshStatus.getStatus()) + { + case LLPathfindingNavMeshStatus::kPending : + case LLPathfindingNavMeshStatus::kRepending : + rebakeNavMeshMode = kRebakeNavMesh_Available; + break; + case LLPathfindingNavMeshStatus::kBuilding : + rebakeNavMeshMode = kRebakeNavMesh_InProgress; + break; + case LLPathfindingNavMeshStatus::kComplete : + rebakeNavMeshMode = kRebakeNavMesh_NotAvailable; + break; + default : + rebakeNavMeshMode = kRebakeNavMesh_Default; + llassert(0); + break; + } + } + + setMode(rebakeNavMeshMode); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed() +{ + llassert(mIsInitialized); + if (mIsInitialized) + { + createNavMeshStatusListenerForCurrentRegion(); + mCanRebakeRegion = FALSE; + LLPathfindingManager::getInstance()->requestGetAgentState(); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::createNavMeshStatusListenerForCurrentRegion() +{ + if (mNavMeshSlot.connected()) + { + mNavMeshSlot.disconnect(); + } + + LLViewerRegion *currentRegion = gAgent.getRegion(); + if (currentRegion != NULL) + { + mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleNavMeshStatus, this, _2)); + LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true); + } +} + diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.h b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h new file mode 100644 index 0000000000..7b1d2873ba --- /dev/null +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h @@ -0,0 +1,85 @@ +/** +* @file llmenuoptionpathfindingrebakenavmesh.h +* @brief Header file for llmenuoptionpathfindingrebakenavmesh +* @author Prep@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H +#define LL_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H + +#include <boost/signals2.hpp> + +#include "llpathfindingmanager.h" +#include "llpathfindingnavmesh.h" +#include "llsingleton.h" + +class LLPathfindingNavMeshStatus; + +class LLMenuOptionPathfindingRebakeNavmesh : public LLSingleton<LLMenuOptionPathfindingRebakeNavmesh> +{ + LOG_CLASS(LLMenuOptionPathfindingRebakeNavmesh); + +public: + typedef enum + { + kRebakeNavMesh_Available, + kRebakeNavMesh_RequestSent, + kRebakeNavMesh_InProgress, + kRebakeNavMesh_NotAvailable, + kRebakeNavMesh_Default = kRebakeNavMesh_NotAvailable + } ERebakeNavMeshMode; + + LLMenuOptionPathfindingRebakeNavmesh(); + virtual ~LLMenuOptionPathfindingRebakeNavmesh(); + + void initialize(); + void quit(); + + bool canRebakeRegion() const; + ERebakeNavMeshMode getMode() const; + + void sendRequestRebakeNavmesh(); + +protected: + +private: + void setMode(ERebakeNavMeshMode pRebakeNavMeshMode); + + void handleAgentState(BOOL pCanRebakeRegion); + void handleRebakeNavMeshResponse(bool pResponseStatus); + void handleNavMeshStatus(const LLPathfindingNavMeshStatus &pNavMeshStatus); + void handleRegionBoundaryCrossed(); + + void createNavMeshStatusListenerForCurrentRegion(); + + bool mIsInitialized; + + bool mCanRebakeRegion; + ERebakeNavMeshMode mRebakeNavMeshMode; + + LLPathfindingNavMesh::navmesh_slot_t mNavMeshSlot; + boost::signals2::connection mRegionCrossingSlot; + LLPathfindingManager::agent_state_slot_t mAgentStateSlot; +}; + +#endif // LL_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index a97e256c89..1223615079 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; @@ -201,10 +204,30 @@ class LLMeshHeaderResponder : public LLCurl::Responder { public: LLVolumeParams mMeshParams; - + bool mProcessed; + LLMeshHeaderResponder(const LLVolumeParams& mesh_params) : mMeshParams(mesh_params) { + LLMeshRepoThread::incActiveHeaderRequests(); + mProcessed = false; + } + + ~LLMeshHeaderResponder() + { + if (!LLApp::isQuitting()) + { + if (!mProcessed) + { //something went wrong, retry + llwarns << "Timeout or service unavailable, retrying." << llendl; + LLMeshRepository::sHTTPRetryCount++; + LLMeshRepoThread::HeaderRequest req(mMeshParams); + LLMutexLock lock(gMeshRepo.mThread->mMutex); + gMeshRepo.mThread->mHeaderReqQ.push(req); + } + + LLMeshRepoThread::decActiveHeaderRequests(); + } } virtual void completedRaw(U32 status, const std::string& reason, @@ -220,10 +243,27 @@ public: S32 mLOD; U32 mRequestedBytes; U32 mOffset; + bool mProcessed; LLMeshLODResponder(const LLVolumeParams& mesh_params, S32 lod, U32 offset, U32 requested_bytes) : mMeshParams(mesh_params), mLOD(lod), mOffset(offset), mRequestedBytes(requested_bytes) { + LLMeshRepoThread::incActiveLODRequests(); + mProcessed = false; + } + + ~LLMeshLODResponder() + { + if (!LLApp::isQuitting()) + { + if (!mProcessed) + { + llwarns << "Killed without being processed, retrying." << llendl; + LLMeshRepository::sHTTPRetryCount++; + gMeshRepo.mThread->lockAndLoadMeshLOD(mMeshParams, mLOD); + } + LLMeshRepoThread::decActiveLODRequests(); + } } virtual void completedRaw(U32 status, const std::string& reason, @@ -238,10 +278,17 @@ public: LLUUID mMeshID; U32 mRequestedBytes; U32 mOffset; + bool mProcessed; LLMeshSkinInfoResponder(const LLUUID& id, U32 offset, U32 size) : mMeshID(id), mRequestedBytes(size), mOffset(offset) { + mProcessed = false; + } + + ~LLMeshSkinInfoResponder() + { + llassert(mProcessed); } virtual void completedRaw(U32 status, const std::string& reason, @@ -256,10 +303,17 @@ public: LLUUID mMeshID; U32 mRequestedBytes; U32 mOffset; + bool mProcessed; LLMeshDecompositionResponder(const LLUUID& id, U32 offset, U32 size) : mMeshID(id), mRequestedBytes(size), mOffset(offset) { + mProcessed = false; + } + + ~LLMeshDecompositionResponder() + { + llassert(mProcessed); } virtual void completedRaw(U32 status, const std::string& reason, @@ -274,10 +328,17 @@ public: LLUUID mMeshID; U32 mRequestedBytes; U32 mOffset; + bool mProcessed; LLMeshPhysicsShapeResponder(const LLUUID& id, U32 offset, U32 size) : mMeshID(id), mRequestedBytes(size), mOffset(offset) { + mProcessed = false; + } + + ~LLMeshPhysicsShapeResponder() + { + llassert(mProcessed); } virtual void completedRaw(U32 status, const std::string& reason, @@ -346,7 +407,20 @@ public: mModelData(model_data), mObserverHandle(observer_handle) { + if (mThread) + { + mThread->startRequest(); + } } + + ~LLWholeModelFeeResponder() + { + if (mThread) + { + mThread->stopRequest(); + } + } + virtual void completed(U32 status, const std::string& reason, const LLSD& content) @@ -357,7 +431,6 @@ public: cc = llsd_from_file("fake_upload_error.xml"); } - mThread->mPendingUploads--; dump_llsd_to_file(cc,make_dump_name("whole_model_fee_response_",dump_num)); LLWholeModelFeeObserver* observer = mObserverHandle.get(); @@ -400,7 +473,20 @@ public: mModelData(model_data), mObserverHandle(observer_handle) { + if (mThread) + { + mThread->startRequest(); + } } + + ~LLWholeModelUploadResponder() + { + if (mThread) + { + mThread->stopRequest(); + } + } + virtual void completed(U32 status, const std::string& reason, const LLSD& content) @@ -411,7 +497,6 @@ public: cc = llsd_from_file("fake_upload_error.xml"); } - mThread->mPendingUploads--; dump_llsd_to_file(cc,make_dump_name("whole_model_upload_response_",dump_num)); LLWholeModelUploadObserver* observer = mObserverHandle.get(); @@ -493,28 +578,35 @@ void LLMeshRepoThread::run() while (!mLODReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && sActiveLODRequests < sMaxConcurrentRequests) { + if (mMutex) { 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(); } } } while (!mHeaderReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && sActiveHeaderRequests < sMaxConcurrentRequests) { + if (mMutex) { mMutex->lock(); 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(); } } } @@ -592,17 +684,26 @@ void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id) mPhysicsShapeRequests.insert(mesh_id); } +void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) +{ + if (!LLAppViewer::isQuitting()) + { + loadMeshLOD(mesh_params, lod); + } +} + -void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) -{ //protected by mSignal, no locking needed here +void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) +{ //could be called from any thread + LLMutexLock lock(mMutex); mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID()); if (iter != mMeshHeader.end()) { //if we have the header, request LOD byte range LODRequest req(mesh_params, lod); { - LLMutexLock lock(mMutex); mLODReqQ.push(req); + LLMeshRepository::sLODProcessing++; } } else @@ -618,7 +719,6 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) } else { //if no header request is pending, fetch header - LLMutexLock lock(mMutex); mHeaderReqQ.push(req); mPendingLOD[mesh_params].push_back(lod); } @@ -650,6 +750,12 @@ std::string LLMeshRepoThread::constructUrl(LLUUID mesh_id) bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) { //protected by mMutex + + if (!mHeaderMutex) + { + return false; + } + mHeaderMutex->lock(); if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) @@ -658,6 +764,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 +780,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 +796,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 +811,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, - new LLMeshSkinInfoResponder(mesh_id, offset, size)); + { + ret = mCurlRequest->getByteRange(http_url, headers, offset, size, + new LLMeshSkinInfoResponder(mesh_id, offset, size)); + if(ret) + { + LLMeshRepository::sHTTPRequestCount++; + } } } } @@ -718,11 +827,16 @@ 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) { //protected by mMutex + if (!mHeaderMutex) + { + return false; + } + mHeaderMutex->lock(); if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) @@ -732,7 +846,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 +863,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 +893,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, - new LLMeshDecompositionResponder(mesh_id, offset, size)); + { + ret = mCurlRequest->getByteRange(http_url, headers, offset, size, + new LLMeshDecompositionResponder(mesh_id, offset, size)); + if(ret) + { + LLMeshRepository::sHTTPRequestCount++; + } } } } @@ -791,11 +909,16 @@ 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) { //protected by mMutex + if (!mHeaderMutex) + { + return false; + } + mHeaderMutex->lock(); if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) @@ -805,6 +928,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) } U32 header_size = mMeshHeaderSize[mesh_id]; + bool ret = true ; if (header_size > 0) { @@ -850,11 +974,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, - new LLMeshPhysicsShapeResponder(mesh_id, offset, size)); + { + ret = mCurlRequest->getByteRange(http_url, headers, offset, size, + new LLMeshPhysicsShapeResponder(mesh_id, offset, size)); + + if(ret) + { + LLMeshRepository::sHTTPRequestCount++; + } } } else @@ -868,13 +995,40 @@ 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) +//static +void LLMeshRepoThread::incActiveLODRequests() +{ + LLMutexLock lock(gMeshRepo.mThread->mMutex); + ++LLMeshRepoThread::sActiveLODRequests; +} + +//static +void LLMeshRepoThread::decActiveLODRequests() +{ + LLMutexLock lock(gMeshRepo.mThread->mMutex); + --LLMeshRepoThread::sActiveLODRequests; +} + +//static +void LLMeshRepoThread::incActiveHeaderRequests() { - bool retval = false; + LLMutexLock lock(gMeshRepo.mThread->mMutex); + ++LLMeshRepoThread::sActiveHeaderRequests; +} + +//static +void LLMeshRepoThread::decActiveHeaderRequests() +{ + LLMutexLock lock(gMeshRepo.mThread->mMutex); + --LLMeshRepoThread::sActiveHeaderRequests; +} +//return false if failed to get header +bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count) +{ { //look for mesh in asset in vfs LLVFile file(gVFS, mesh_params.getSculptID(), LLAssetType::AT_MESH); @@ -889,36 +1043,44 @@ 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 + if (!mHeaderMutex) + { + return false; + } + mHeaderMutex->lock(); - bool retval = false; + bool retval = true; LLUUID mesh_id = mesh_params.getSculptID(); @@ -955,7 +1117,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 +1130,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 { @@ -1031,20 +1196,24 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat { LLUUID mesh_id = mesh_params.getSculptID(); - mHeaderMutex->lock(); - mMeshHeaderSize[mesh_id] = header_size; - mMeshHeader[mesh_id] = header; - mHeaderMutex->unlock(); + { + LLMutexLock lock(mHeaderMutex); + mMeshHeaderSize[mesh_id] = header_size; + mMeshHeader[mesh_id] = header; + } + + + LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. //check for pending requests pending_lod_map::iterator iter = mPendingLOD.find(mesh_params); if (iter != mPendingLOD.end()) { - LLMutexLock lock(mMutex); for (U32 i = 0; i < iter->second.size(); ++i) { LODRequest req(mesh_params, iter->second[i]); mLODReqQ.push(req); + LLMeshRepository::sLODProcessing++; } } mPendingLOD.erase(iter); @@ -1055,17 +1224,19 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat bool LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size) { - LLVolume* volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod)); + LLPointer<LLVolume> volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod)); std::string mesh_string((char*) data, data_size); std::istringstream stream(mesh_string); if (volume->unpackVolumeFaces(stream, data_size)) { - LoadedMesh mesh(volume, mesh_params, lod); if (volume->getNumFaces() > 0) { - LLMutexLock lock(mMutex); - mLoadedQ.push(mesh); + LoadedMesh mesh(volume, mesh_params, lod); + { + LLMutexLock lock(mMutex); + mLoadedQ.push(mesh); + } return true; } } @@ -1540,14 +1711,23 @@ 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(); //sleep for 10ms to prevent eating a whole core apr_sleep(10000); - } while (mCurlRequest->getQueued() > 0); + } while (!LLAppViewer::isQuitting() && mPendingUploads > 0); } delete mCurlRequest; @@ -1569,17 +1749,23 @@ void LLMeshUploadThread::requestWholeModelFee() wholeModelToLLSD(model_data,false); dump_llsd_to_file(model_data,make_dump_name("whole_model_fee_request_",dump_num)); - 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 { mCurlRequest->process(); //sleep for 10ms to prevent eating a whole core apr_sleep(10000); - } while (mCurlRequest->getQueued() > 0); + } while (!LLApp::isQuitting() && mPendingUploads > 0); delete mCurlRequest; mCurlRequest = NULL; @@ -1590,6 +1776,11 @@ void LLMeshUploadThread::requestWholeModelFee() void LLMeshRepoThread::notifyLoadedMeshes() { + if (!mMutex) + { + return; + } + while (!mLoadedQ.empty()) { mMutex->lock(); @@ -1711,8 +1902,14 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { - - LLMeshRepoThread::sActiveLODRequests--; + mProcessed = true; + + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -1724,11 +1921,13 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, { if (status == 499 || status == 503) { //timeout or service unavailable, try again + llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshLOD(mMeshParams, mLOD); } else { + llassert(status == 499 || status == 503); //intentionally trigger a breakpoint llwarns << "Unhandled status " << status << llendl; } return; @@ -1767,6 +1966,14 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + mProcessed = true; + + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -1778,11 +1985,13 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason { if (status == 499 || status == 503) { //timeout or service unavailable, try again + llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshSkinInfo(mMeshID); } else { + llassert(status == 499 || status == 503); //intentionally trigger a breakpoint llwarns << "Unhandled status " << status << llendl; } return; @@ -1821,6 +2030,13 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + mProcessed = true; + + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -1832,11 +2048,13 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r { if (status == 499 || status == 503) { //timeout or service unavailable, try again + llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshDecomposition(mMeshID); } else { + llassert(status == 499 || status == 503); //intentionally trigger a breakpoint llwarns << "Unhandled status " << status << llendl; } return; @@ -1875,6 +2093,14 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + mProcessed = true; + + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -1886,11 +2112,13 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re { if (status == 499 || status == 503) { //timeout or service unavailable, try again + llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID); } else { + llassert(status == 499 || status == 503); //intentionally trigger a breakpoint llwarns << "Unhandled status " << status << llendl; } return; @@ -1929,7 +2157,14 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { - LLMeshRepoThread::sActiveHeaderRequests--; + mProcessed = true; + + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + if (status < 200 || status > 400) { //llwarns @@ -1942,8 +2177,12 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, // TODO*: Add maximum retry logic, exponential backoff // and (somewhat more optional than the others) retries // again after some set period of time + + llassert(status == 503 || status == 499); + if (status == 503 || status == 499) { //retry + llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; LLMeshRepoThread::HeaderRequest req(mMeshParams); LLMutexLock lock(gMeshRepo.mThread->mMutex); @@ -1951,6 +2190,10 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, return; } + else + { + llwarns << "Unhandled status." << llendl; + } } S32 data_size = buffer->countAfter(channels.in(), NULL); @@ -1965,7 +2208,11 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, LLMeshRepository::sBytesReceived += llmin(data_size, 4096); - if (!gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size)) + bool success = gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size); + + llassert(success); + + if (!success) { llwarns << "Unable to parse mesh header: " @@ -2147,6 +2394,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++; } } @@ -2302,92 +2550,92 @@ void LLMeshRepository::notifyLoadedMeshes() } } - mMeshMutex->lock(); - mThread->mMutex->lock(); - - //popup queued error messages from background threads - while (!mUploadErrorQ.empty()) { - LLNotificationsUtil::add("MeshUploadError", mUploadErrorQ.front()); - mUploadErrorQ.pop(); - } + LLMutexLock lock1(mMeshMutex); + LLMutexLock lock2(mThread->mMutex); + + //popup queued error messages from background threads + while (!mUploadErrorQ.empty()) + { + LLNotificationsUtil::add("MeshUploadError", mUploadErrorQ.front()); + mUploadErrorQ.pop(); + } - S32 push_count = LLMeshRepoThread::sMaxConcurrentRequests-(LLMeshRepoThread::sActiveHeaderRequests+LLMeshRepoThread::sActiveLODRequests); + S32 push_count = LLMeshRepoThread::sMaxConcurrentRequests-(LLMeshRepoThread::sActiveHeaderRequests+LLMeshRepoThread::sActiveLODRequests); - if (push_count > 0) - { - //calculate "score" for pending requests + if (push_count > 0) + { + //calculate "score" for pending requests - //create score map - std::map<LLUUID, F32> score_map; + //create score map + std::map<LLUUID, F32> score_map; - for (U32 i = 0; i < 4; ++i) - { - for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter) + for (U32 i = 0; i < 4; ++i) { - F32 max_score = 0.f; - for (std::set<LLUUID>::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) + for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter) { - LLViewerObject* object = gObjectList.findObject(*obj_iter); - - if (object) + F32 max_score = 0.f; + for (std::set<LLUUID>::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) { - LLDrawable* drawable = object->mDrawable; - if (drawable) + LLViewerObject* object = gObjectList.findObject(*obj_iter); + + if (object) { - F32 cur_score = drawable->getRadius()/llmax(drawable->mDistanceWRTCamera, 1.f); - max_score = llmax(max_score, cur_score); + LLDrawable* drawable = object->mDrawable; + if (drawable) + { + F32 cur_score = drawable->getRadius()/llmax(drawable->mDistanceWRTCamera, 1.f); + max_score = llmax(max_score, cur_score); + } } } - } - score_map[iter->first.getSculptID()] = max_score; + score_map[iter->first.getSculptID()] = max_score; + } + } + + //set "score" for pending requests + for (std::vector<LLMeshRepoThread::LODRequest>::iterator iter = mPendingRequests.begin(); iter != mPendingRequests.end(); ++iter) + { + iter->mScore = score_map[iter->mMeshParams.getSculptID()]; + } + + //sort by "score" + std::sort(mPendingRequests.begin(), mPendingRequests.end(), LLMeshRepoThread::CompareScoreGreater()); + + while (!mPendingRequests.empty() && push_count > 0) + { + LLMeshRepoThread::LODRequest& request = mPendingRequests.front(); + mThread->loadMeshLOD(request.mMeshParams, request.mLOD); + mPendingRequests.erase(mPendingRequests.begin()); + LLMeshRepository::sLODPending--; + push_count--; } } - //set "score" for pending requests - for (std::vector<LLMeshRepoThread::LODRequest>::iterator iter = mPendingRequests.begin(); iter != mPendingRequests.end(); ++iter) + //send skin info requests + while (!mPendingSkinRequests.empty()) { - iter->mScore = score_map[iter->mMeshParams.getSculptID()]; + mThread->loadMeshSkinInfo(mPendingSkinRequests.front()); + mPendingSkinRequests.pop(); } - - //sort by "score" - std::sort(mPendingRequests.begin(), mPendingRequests.end(), LLMeshRepoThread::CompareScoreGreater()); - - while (!mPendingRequests.empty() && push_count > 0) + + //send decomposition requests + while (!mPendingDecompositionRequests.empty()) { - LLMeshRepoThread::LODRequest& request = mPendingRequests.front(); - mThread->loadMeshLOD(request.mMeshParams, request.mLOD); - mPendingRequests.erase(mPendingRequests.begin()); - push_count--; + mThread->loadMeshDecomposition(mPendingDecompositionRequests.front()); + mPendingDecompositionRequests.pop(); } - } - - //send skin info requests - while (!mPendingSkinRequests.empty()) - { - mThread->loadMeshSkinInfo(mPendingSkinRequests.front()); - mPendingSkinRequests.pop(); - } - //send decomposition requests - while (!mPendingDecompositionRequests.empty()) - { - mThread->loadMeshDecomposition(mPendingDecompositionRequests.front()); - mPendingDecompositionRequests.pop(); - } + //send physics shapes decomposition requests + while (!mPendingPhysicsShapeRequests.empty()) + { + mThread->loadMeshPhysicsShape(mPendingPhysicsShapeRequests.front()); + mPendingPhysicsShapeRequests.pop(); + } - //send physics shapes decomposition requests - while (!mPendingPhysicsShapeRequests.empty()) - { - mThread->loadMeshPhysicsShape(mPendingPhysicsShapeRequests.front()); - mPendingPhysicsShapeRequests.pop(); + mThread->notifyLoadedMeshes(); } - - mThread->notifyLoadedMeshes(); - - mThread->mMutex->unlock(); - mMeshMutex->unlock(); mThread->mSignal->signal(); } @@ -3035,13 +3283,14 @@ void LLPhysicsDecomp::doDecomposition() num_hulls = LLConvexDecomposition::getInstance()->getNumHullsFromStage(stage); } - mMutex->lock(); - mCurRequest->mHull.clear(); - mCurRequest->mHull.resize(num_hulls); + { + LLMutexLock lock(mMutex); + mCurRequest->mHull.clear(); + mCurRequest->mHull.resize(num_hulls); - mCurRequest->mHullMesh.clear(); - mCurRequest->mHullMesh.resize(num_hulls); - mMutex->unlock(); + mCurRequest->mHullMesh.clear(); + mCurRequest->mHullMesh.resize(num_hulls); + } for (S32 i = 0; i < num_hulls; ++i) { @@ -3065,14 +3314,14 @@ void LLPhysicsDecomp::doDecomposition() get_vertex_buffer_from_mesh(mesh, mCurRequest->mHullMesh[i]); - mMutex->lock(); - mCurRequest->mHull[i] = p; - mMutex->unlock(); + { + LLMutexLock lock(mMutex); + mCurRequest->mHull[i] = p; + } } { LLMutexLock lock(mMutex); - mCurRequest->setStatusMessage("FAIL"); completeCurrent(); } @@ -3140,7 +3389,6 @@ void LLPhysicsDecomp::doDecompositionSingleHull() LLCDMeshData mesh; -#if 1 setMeshData(mesh, true); LLCDResult ret = decomp->buildSingleHull() ; @@ -3151,11 +3399,12 @@ void LLPhysicsDecomp::doDecompositionSingleHull() } else { - mMutex->lock(); - mCurRequest->mHull.clear(); - mCurRequest->mHull.resize(1); - mCurRequest->mHullMesh.clear(); - mMutex->unlock(); + { + LLMutexLock lock(mMutex); + mCurRequest->mHull.clear(); + mCurRequest->mHull.resize(1); + mCurRequest->mHullMesh.clear(); + } std::vector<LLVector3> p; LLCDHull hull; @@ -3171,93 +3420,12 @@ void LLPhysicsDecomp::doDecompositionSingleHull() p.push_back(vert); v = (F32*) (((U8*) v) + hull.mVertexStrideBytes); } - - mMutex->lock(); - mCurRequest->mHull[0] = p; - mMutex->unlock(); - } -#else - setMeshData(mesh, false); - - //set all parameters to default - std::map<std::string, const LLCDParam*> param_map; - - static const LLCDParam* params = NULL; - static S32 param_count = 0; - - if (!params) - { - param_count = decomp->getParameters(¶ms); - } - - for (S32 i = 0; i < param_count; ++i) - { - decomp->setParam(params[i].mName, params[i].mDefault.mIntOrEnumValue); - } - - const S32 STAGE_DECOMPOSE = mStageID["Decompose"]; - const S32 STAGE_SIMPLIFY = mStageID["Simplify"]; - const S32 DECOMP_PREVIEW = 0; - const S32 SIMPLIFY_RETAIN = 0; - - decomp->setParam("Decompose Quality", DECOMP_PREVIEW); - decomp->setParam("Simplify Method", SIMPLIFY_RETAIN); - decomp->setParam("Retain%", 0.f); - - LLCDResult ret = LLCD_OK; - ret = decomp->executeStage(STAGE_DECOMPOSE); - - if (ret) - { - llwarns << "Could not execute decomposition stage when attempting to create single hull." << llendl; - make_box(mCurRequest); - } - else - { - ret = decomp->executeStage(STAGE_SIMPLIFY); - - if (ret) + { - llwarns << "Could not execute simiplification stage when attempting to create single hull." << llendl; - make_box(mCurRequest); - } - else - { - S32 num_hulls =0; - if (LLConvexDecomposition::getInstance() != NULL) - { - num_hulls = LLConvexDecomposition::getInstance()->getNumHullsFromStage(STAGE_SIMPLIFY); - } - - mMutex->lock(); - mCurRequest->mHull.clear(); - mCurRequest->mHull.resize(num_hulls); - mCurRequest->mHullMesh.clear(); - mMutex->unlock(); - - for (S32 i = 0; i < num_hulls; ++i) - { - std::vector<LLVector3> p; - LLCDHull hull; - // if LLConvexDecomposition is a stub, num_hulls should have been set to 0 above, and we should not reach this code - LLConvexDecomposition::getInstance()->getHullFromStage(STAGE_SIMPLIFY, i, &hull); - - const F32* v = hull.mVertexBase; - - for (S32 j = 0; j < hull.mNumVertices; ++j) - { - LLVector3 vert(v[0], v[1], v[2]); - p.push_back(vert); - v = (F32*) (((U8*) v) + hull.mVertexStrideBytes); - } - - mMutex->lock(); - mCurRequest->mHull[i] = p; - mMutex->unlock(); - } + LLMutexLock lock(mMutex); + mCurRequest->mHull[0] = p; } - } -#endif + } { completeCurrent(); diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 31b84ea0d9..8602271f84 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -322,9 +322,11 @@ public: virtual void run(); + void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); 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); @@ -351,6 +353,10 @@ public: // (should hold onto mesh_id and try again later if header info does not exist) bool fetchMeshPhysicsShape(const LLUUID& mesh_id); + static void incActiveLODRequests(); + static void decActiveLODRequests(); + static void incActiveHeaderRequests(); + static void decActiveHeaderRequests(); }; @@ -405,6 +411,9 @@ public: LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()), LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>())); ~LLMeshUploadThread(); + void startRequest() { ++mPendingUploads; } + void stopRequest() { --mPendingUploads; } + bool finished() { return mFinished; } virtual void run(); void preStart(); @@ -441,6 +450,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/llmoveview.cpp b/indra/newview/llmoveview.cpp index c3d8b91d67..eb6591eb39 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -686,7 +686,7 @@ void LLPanelStandStopFlying::onStopFlyingButtonClick() gAgent.setFlying(FALSE); setFocus(FALSE); // EXT-482 - setVisible(FALSE); + mStopFlyingButton->setVisible(FALSE); } /** @@ -698,19 +698,28 @@ void LLPanelStandStopFlying::updatePosition() S32 y_pos = 0; S32 bottom_tb_center = 0; - if (LLToolBar* toolbar_bottom = gToolBarView->getChild<LLToolBar>("toolbar_bottom")) + if (LLToolBar* toolbar_bottom = gToolBarView->getToolbar(LLToolBarView::TOOLBAR_BOTTOM)) { y_pos = toolbar_bottom->getRect().getHeight(); bottom_tb_center = toolbar_bottom->getRect().getCenterX(); } S32 left_tb_width = 0; - if (LLToolBar* toolbar_left = gToolBarView->getChild<LLToolBar>("toolbar_left")) + if (LLToolBar* toolbar_left = gToolBarView->getToolbar(LLToolBarView::TOOLBAR_LEFT)) { left_tb_width = toolbar_left->getRect().getWidth(); } - if(LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("stand_stop_flying_container")) + if (!mStateManagementButtons.get()) + { + LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("state_management_buttons_container"); + if (panel_ssf_container) + { + mStateManagementButtons = panel_ssf_container->getHandle(); + } + } + + if(LLPanel* panel_ssf_container = mStateManagementButtons.get()) { panel_ssf_container->setOrigin(0, y_pos); } diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h index 744dd866d4..c525d9dfdb 100644 --- a/indra/newview/llmoveview.h +++ b/indra/newview/llmoveview.h @@ -172,6 +172,8 @@ private: */ LLHandle<LLPanel> mOriginalParent; + LLHandle<LLPanel> mStateManagementButtons; + /** * True if the panel is currently attached to the movement controls floater. * diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index a7059eb519..54522bb7f6 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -44,6 +44,8 @@ #include "llmutelist.h" +#include "pipeline.h" + #include <boost/tokenizer.hpp> #include "lldispatcher.h" @@ -192,6 +194,23 @@ BOOL LLMuteList::isLinden(const std::string& name) const return last_name == "Linden"; } +static LLVOAvatar* find_avatar(const LLUUID& id) +{ + LLViewerObject *obj = gObjectList.findObject(id); + while (obj && obj->isAttachment()) + { + obj = (LLViewerObject *)obj->getParent(); + } + + if (obj && obj->isAvatar()) + { + return (LLVOAvatar*)obj; + } + else + { + return NULL; + } +} BOOL LLMuteList::add(const LLMute& mute, U32 flags) { @@ -288,6 +307,12 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags) LLViewerPartSim::getInstance()->clearParticlesByOwnerID(localmute.mID); } } + //mute local lights that are attached to the avatar + LLVOAvatar *avatarp = find_avatar(localmute.mID); + if (avatarp) + { + LLPipeline::removeMutedAVsLights(avatarp); + } return TRUE; } } diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 04e1570081..7a70370fe3 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -29,6 +29,7 @@ #include "llstring.h" #include "lluuid.h" +#include "llextendedstatus.h" class LLViewerObject; class LLMessageSystem; diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 4e28d1f526..7f396b7b7e 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -64,11 +64,12 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p) mNameColumnIndex(p.name_column.column_index), mNameColumn(p.name_column.column_name), mAllowCallingCardDrop(p.allow_calling_card_drop), - mShortNames(p.short_names) + mShortNames(p.short_names), + mAvatarNameCacheConnection() {} // public -void LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, +LLScrollListItem* LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, BOOL enabled, const std::string& suffix) { //llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl; @@ -78,7 +79,7 @@ void LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, item.enabled = enabled; item.target = INDIVIDUAL; - addNameItemRow(item, pos, suffix); + return addNameItemRow(item, pos, suffix); } // virtual, public @@ -204,7 +205,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; S32 column_index = getColumnIndexFromOffset(x); - LLScrollListItem* hit_item = hitItem(x, y); + LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y)); if (hit_item && column_index == mNameColumnIndex) { @@ -228,7 +229,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask) LLCoordGL pos( sticky_rect.mRight - info_icon_size, sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight())/2 ); // Should we show a group or an avatar inspector? - bool is_group = hit_item->getValue()["is_group"].asBoolean(); + bool is_group = hit_item->isGroup(); LLToolTip::Params params; params.background_visible( false ); @@ -271,10 +272,10 @@ void LLNameListCtrl::addGroupNameItem(LLNameListCtrl::NameItem& item, EAddPositi addNameItemRow(item, pos); } -void LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos) +LLScrollListItem* LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos) { item.target = INDIVIDUAL; - addNameItemRow(item, pos); + return addNameItemRow(item, pos); } LLScrollListItem* LLNameListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata) @@ -293,19 +294,12 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( const std::string& suffix) { LLUUID id = name_item.value().asUUID(); - LLNameListItem* item = NULL; - - // Store item type so that we can invoke the proper inspector. - // *TODO Vadim: Is there a more proper way of storing additional item data? - { - LLNameListCtrl::NameItem item_p(name_item); - item_p.value = LLSD().with("uuid", id).with("is_group", name_item.target() == GROUP); - item = new LLNameListItem(item_p); - LLScrollListCtrl::addRow(item, item_p, pos); - } + LLNameListItem* item = new LLNameListItem(name_item,name_item.target() == GROUP); if (!item) return NULL; + LLScrollListCtrl::addRow(item, name_item, pos); + // use supplied name by default std::string fullname = name_item.name; switch(name_item.target) @@ -327,16 +321,20 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( else if (LLAvatarNameCache::get(id, &av_name)) { if (mShortNames) - fullname = av_name.mDisplayName; + fullname = av_name.getDisplayName(); else fullname = av_name.getCompleteName(); } else { // ...schedule a callback - LLAvatarNameCache::get(id, - boost::bind(&LLNameListCtrl::onAvatarNameCache, - this, _1, _2)); + // This is not correct and will likely lead to partially populated lists in cases where avatar names are not cached. + // *TODO : Change this to have 2 callbacks : one callback per list item and one for the whole list. + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, item->getHandle())); } break; } @@ -392,28 +390,28 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id) } void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, - const LLAvatarName& av_name) + const LLAvatarName& av_name, + LLHandle<LLNameListItem> item) { + mAvatarNameCacheConnection.disconnect(); + std::string name; if (mShortNames) - name = av_name.mDisplayName; + name = av_name.getDisplayName(); else name = av_name.getCompleteName(); - item_list::iterator iter; - for (iter = getItemList().begin(); iter != getItemList().end(); iter++) + LLNameListItem* list_item = item.get(); + if (list_item && list_item->getUUID() == agent_id) { - LLScrollListItem* item = *iter; - if (item->getUUID() == agent_id) + LLScrollListCell* cell = list_item->getColumn(mNameColumnIndex); + if (cell) { - LLScrollListCell* cell = item->getColumn(mNameColumnIndex); - if (cell) - { - cell->setValue(name); - } + cell->setValue(name); + setNeedsSort(); } } - + dirtyColumns(); } @@ -431,3 +429,8 @@ void LLNameListCtrl::updateColumns() } } } + +void LLNameListCtrl::sortByName(BOOL ascending) +{ + sortByColumnIndex(mNameColumnIndex,ascending); +} diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index ca9956dc53..271802d48a 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -33,6 +33,36 @@ class LLAvatarName; +/** + * LLNameListCtrl item + * + * We don't use LLScrollListItem to be able to override getUUID(), which is needed + * because the name list item value is not simply an UUID but a map (uuid, is_group). + */ +class LLNameListItem : public LLScrollListItem, public LLHandleProvider<LLNameListItem> +{ +public: + bool isGroup() const { return mIsGroup; } + void setIsGroup(bool is_group) { mIsGroup = is_group; } + +protected: + friend class LLNameListCtrl; + + LLNameListItem( const LLScrollListItem::Params& p ) + : LLScrollListItem(p), mIsGroup(false) + { + } + + LLNameListItem( const LLScrollListItem::Params& p, bool is_group ) + : LLScrollListItem(p), mIsGroup(is_group) + { + } + +private: + bool mIsGroup; +}; + + class LLNameListCtrl : public LLScrollListCtrl, public LLInstanceTracker<LLNameListCtrl> { @@ -81,13 +111,20 @@ public: protected: LLNameListCtrl(const Params&); + virtual ~LLNameListCtrl() + { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + } friend class LLUICtrlFactory; public: // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. - void addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM, + LLScrollListItem* addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null); - void addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM); + LLScrollListItem* addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM); /*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, const std::string& suffix = LLStringUtil::null); @@ -110,38 +147,22 @@ public: void setAllowCallingCardDrop(BOOL b) { mAllowCallingCardDrop = b; } + void sortByName(BOOL ascending); + /*virtual*/ void updateColumns(); /*virtual*/ void mouseOverHighlightNthItem( S32 index ); private: void showInspector(const LLUUID& avatar_id, bool is_group); - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, LLHandle<LLNameListItem> item); private: S32 mNameColumnIndex; std::string mNameColumn; BOOL mAllowCallingCardDrop; bool mShortNames; // display name only, no SLID + boost::signals2::connection mAvatarNameCacheConnection; }; -/** - * LLNameListCtrl item - * - * We don't use LLScrollListItem to be able to override getUUID(), which is needed - * because the name list item value is not simply an UUID but a map (uuid, is_group). - */ -class LLNameListItem : public LLScrollListItem -{ -public: - LLUUID getUUID() const { return getValue()["uuid"].asUUID(); } - -protected: - friend class LLNameListCtrl; - - LLNameListItem( const LLScrollListItem::Params& p ) - : LLScrollListItem(p) - { - } -}; #endif diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 146bcbe47b..95caa2731a 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -267,7 +267,6 @@ LLNavigationBar::LLNavigationBar() mBtnForward(NULL), mBtnHome(NULL), mCmbLocation(NULL), - mPurgeTPHistoryItems(false), mSaveToLocationHistory(false) { buildFromFile( "panel_navigation_bar.xml"); @@ -317,7 +316,7 @@ BOOL LLNavigationBar::postBuild() LLTeleportHistory::getInstance()->setHistoryChangedCallback( boost::bind(&LLNavigationBar::onTeleportHistoryChanged, this)); - LLHints::registerHintTarget("nav_bar", LLView::getHandle()); + LLHints::registerHintTarget("nav_bar", getHandle()); return TRUE; } @@ -338,12 +337,6 @@ void LLNavigationBar::setVisible(BOOL visible) void LLNavigationBar::draw() { - if(mPurgeTPHistoryItems) - { - LLTeleportHistory::getInstance()->purgeItems(); - mPurgeTPHistoryItems = false; - } - if (isBackgroundVisible()) { static LLUICachedControl<S32> drop_shadow_floater ("DropShadowFloater", 0); @@ -687,7 +680,7 @@ void LLNavigationBar::clearHistoryCache() LLLocationHistory* lh = LLLocationHistory::getInstance(); lh->removeItems(); lh->save(); - mPurgeTPHistoryItems= true; + LLTeleportHistory::getInstance()->purgeItems(); } int LLNavigationBar::getDefNavBarHeight() diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index e4ce9e3998..7878bab24e 100644 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -145,7 +145,6 @@ private: boost::signals2::connection mTeleportFailedConnection; boost::signals2::connection mTeleportFinishConnection; boost::signals2::connection mHistoryMenuConnection; - bool mPurgeTPHistoryItems; // if true, save location to location history when teleport finishes bool mSaveToLocationHistory; }; diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp deleted file mode 100644 index a7303ad035..0000000000 --- a/indra/newview/llnearbychat.cpp +++ /dev/null @@ -1,338 +0,0 @@ -/** - * @file LLNearbyChat.cpp - * @brief Nearby chat history scrolling panel implementation - * - * $LicenseInfo:firstyear=2009&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 "llnearbychat.h" -#include "llviewercontrol.h" -#include "llviewerwindow.h" -#include "llrootview.h" -//#include "llchatitemscontainerctrl.h" -#include "lliconctrl.h" -#include "llfloatersidepanelcontainer.h" -#include "llfocusmgr.h" -#include "lllogchat.h" -#include "llresizebar.h" -#include "llresizehandle.h" -#include "llmenugl.h" -#include "llviewermenu.h"//for gMenuHolder - -#include "llnearbychathandler.h" -#include "llchannelmanager.h" - -#include "llagent.h" // gAgent -#include "llchathistory.h" -#include "llstylemap.h" - -#include "llavatarnamecache.h" - -#include "lldraghandle.h" - -#include "llnearbychatbar.h" -#include "llfloaterreg.h" -#include "lltrans.h" - -static const S32 RESIZE_BAR_THICKNESS = 3; - - -static LLRegisterPanelClassWrapper<LLNearbyChat> t_panel_nearby_chat("panel_nearby_chat"); - -LLNearbyChat::LLNearbyChat(const LLNearbyChat::Params& p) -: LLPanel(p), - mChatHistory(NULL) -{ -} - -BOOL LLNearbyChat::postBuild() -{ - //menu - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - - enable_registrar.add("NearbyChat.Check", boost::bind(&LLNearbyChat::onNearbyChatCheckContextMenuItem, this, _2)); - registrar.add("NearbyChat.Action", boost::bind(&LLNearbyChat::onNearbyChatContextMenuItemClicked, this, _2)); - - - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if(menu) - mPopupMenuHandle = menu->getHandle(); - - gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true); - - mChatHistory = getChild<LLChatHistory>("chat_history"); - - if(!LLPanel::postBuild()) - return false; - - return true; -} - -std::string appendTime() -{ - time_t utc_time; - utc_time = time_corrected(); - std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:[" - +LLTrans::getString("TimeMin")+"]"; - - LLSD substitution; - - substitution["datetime"] = (S32) utc_time; - LLStringUtil::format (timeStr, substitution); - - return timeStr; -} - - -void LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args) -{ - LLChat& tmp_chat = const_cast<LLChat&>(chat); - - if(tmp_chat.mTimeStr.empty()) - tmp_chat.mTimeStr = appendTime(); - - bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory"); - - if (!chat.mMuted) - { - tmp_chat.mFromName = chat.mFromName; - LLSD chat_args = args; - chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history; - mChatHistory->appendMessage(chat, chat_args); - } - - if(archive) - { - mMessageArchive.push_back(chat); - if(mMessageArchive.size()>200) - mMessageArchive.erase(mMessageArchive.begin()); - } - - if (args["do_not_log"].asBoolean()) - { - return; - } - - if (gSavedPerAccountSettings.getBOOL("LogNearbyChat")) - { - std::string from_name = chat.mFromName; - - if (chat.mSourceType == CHAT_SOURCE_AGENT) - { - // if the chat is coming from an agent, log the complete name - LLAvatarName av_name; - LLAvatarNameCache::get(chat.mFromID, &av_name); - - if (!av_name.mIsDisplayNameDefault) - { - from_name = av_name.getCompleteName(); - } - } - - LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText); - } -} - -void LLNearbyChat::onNearbySpeakers() -{ - LLSD param; - param["people_panel_tab_name"] = "nearby_panel"; - LLFloaterSidePanelContainer::showPanel("people", "panel_people", param); -} - - -void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata) -{ -} -bool LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata) -{ - std::string str = userdata.asString(); - if(str == "nearby_people") - onNearbySpeakers(); - return false; -} - -void LLNearbyChat::removeScreenChat() -{ - LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID"))); - if(chat_channel) - { - chat_channel->removeToastsFromChannel(); - } -} - -void LLNearbyChat::setVisible(BOOL visible) -{ - if(visible) - { - removeScreenChat(); - } - - LLPanel::setVisible(visible); -} - - -void LLNearbyChat::getAllowedRect(LLRect& rect) -{ - rect = gViewerWindow->getWorldViewRectScaled(); -} - -void LLNearbyChat::updateChatHistoryStyle() -{ - mChatHistory->clear(); - - LLSD do_not_log; - do_not_log["do_not_log"] = true; - for(std::vector<LLChat>::iterator it = mMessageArchive.begin();it!=mMessageArchive.end();++it) - { - // Update the messages without re-writing them to a log file. - addMessage(*it,false, do_not_log); - } -} - -//static -void LLNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue) -{ - LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar"); - LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat"); - if(nearby_chat) - nearby_chat->updateChatHistoryStyle(); -} - -bool isWordsName(const std::string& name) -{ - // checking to see if it's display name plus username in parentheses - S32 open_paren = name.find(" (", 0); - S32 close_paren = name.find(')', 0); - - if (open_paren != std::string::npos && - close_paren == name.length()-1) - { - return true; - } - else - { - //checking for a single space - S32 pos = name.find(' ', 0); - return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos; - } -} - -void LLNearbyChat::loadHistory() -{ - LLSD do_not_log; - do_not_log["do_not_log"] = true; - - std::list<LLSD> history; - LLLogChat::loadAllHistory("chat", history); - - std::list<LLSD>::const_iterator it = history.begin(); - while (it != history.end()) - { - const LLSD& msg = *it; - - std::string from = msg[IM_FROM]; - LLUUID from_id; - if (msg[IM_FROM_ID].isDefined()) - { - from_id = msg[IM_FROM_ID].asUUID(); - } - else - { - std::string legacy_name = gCacheName->buildLegacyName(from); - gCacheName->getUUID(legacy_name, from_id); - } - - LLChat chat; - chat.mFromName = from; - chat.mFromID = from_id; - chat.mText = msg[IM_TEXT].asString(); - chat.mTimeStr = msg[IM_TIME].asString(); - chat.mChatStyle = CHAT_STYLE_HISTORY; - - chat.mSourceType = CHAT_SOURCE_AGENT; - if (from_id.isNull() && SYSTEM_FROM == from) - { - chat.mSourceType = CHAT_SOURCE_SYSTEM; - - } - else if (from_id.isNull()) - { - chat.mSourceType = isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT; - } - - addMessage(chat, true, do_not_log); - - it++; - } -} - -//static -LLNearbyChat* LLNearbyChat::getInstance() -{ - LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar"); - return chat_bar->findChild<LLNearbyChat>("nearby_chat"); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLNearbyChat::onFocusReceived() -{ - setBackgroundOpaque(true); - LLPanel::onFocusReceived(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLNearbyChat::onFocusLost() -{ - setBackgroundOpaque(false); - LLPanel::onFocusLost(); -} - -BOOL LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask) -{ - //fix for EXT-6625 - //highlight NearbyChat history whenever mouseclick happen in NearbyChat - //setting focus to eidtor will force onFocusLost() call that in its turn will change - //background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change. - - if(mChatHistory) - mChatHistory->setFocus(TRUE); - return LLPanel::handleMouseDown(x, y, mask); -} - -void LLNearbyChat::draw() -{ - // *HACK: Update transparency type depending on whether our children have focus. - // This is needed because this floater is chrome and thus cannot accept focus, so - // the transparency type setting code from LLFloater::setFocus() isn't reached. - if (getTransparencyType() != TT_DEFAULT) - { - setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE); - } - - LLPanel::draw(); -} diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h deleted file mode 100644 index 7c5975cbc5..0000000000 --- a/indra/newview/llnearbychat.h +++ /dev/null @@ -1,83 +0,0 @@ - /** - * @file llnearbychat.h - * @brief nearby chat history scrolling panel implementation - * - * $LicenseInfo:firstyear=2004&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_LLNEARBYCHAT_H_ -#define LL_LLNEARBYCHAT_H_ - -#include "llscrollbar.h" -#include "llviewerchat.h" -#include "llfloater.h" - -class LLResizeBar; -class LLChatHistory; - -class LLNearbyChat: public LLPanel -{ -public: - LLNearbyChat(const Params& p = LLPanel::getDefaultParams()); - - BOOL postBuild (); - - /** @param archive true - to save a message to the chat history log */ - void addMessage (const LLChat& message,bool archive = true, const LLSD &args = LLSD()); - void onNearbyChatContextMenuItemClicked(const LLSD& userdata); - bool onNearbyChatCheckContextMenuItem(const LLSD& userdata); - - virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); - virtual void draw(); - - // focus overrides - /*virtual*/ void onFocusLost(); - /*virtual*/ void onFocusReceived(); - - /*virtual*/ void setVisible(BOOL visible); - - virtual void updateChatHistoryStyle(); - - static void processChatHistoryStyleUpdate(const LLSD& newvalue); - - void loadHistory(); - - static LLNearbyChat* getInstance(); - void removeScreenChat(); - -private: - - void getAllowedRect (LLRect& rect); - - void onNearbySpeakers (); - - -private: - LLHandle<LLView> mPopupMenuHandle; - LLChatHistory* mChatHistory; - - std::vector<LLChat> mMessageArchive; -}; - -#endif - - diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp deleted file mode 100644 index 114472ba56..0000000000 --- a/indra/newview/llnearbychatbar.cpp +++ /dev/null @@ -1,651 +0,0 @@ -/** - * @file llnearbychatbar.cpp - * @brief LLNearbyChatBar class implementation - * - * $LicenseInfo:firstyear=2002&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 "message.h" - -#include "llappviewer.h" -#include "llfloaterreg.h" -#include "lltrans.h" - -#include "llfirstuse.h" -#include "llnearbychatbar.h" -#include "llagent.h" -#include "llgesturemgr.h" -#include "llmultigesture.h" -#include "llkeyboard.h" -#include "llanimationstates.h" -#include "llviewerstats.h" -#include "llcommandhandler.h" -#include "llviewercontrol.h" -#include "llnavigationbar.h" -#include "llwindow.h" -#include "llviewerwindow.h" -#include "llrootview.h" -#include "llviewerchat.h" -#include "llnearbychat.h" - -#include "llresizehandle.h" - -S32 LLNearbyChatBar::sLastSpecialChatChannel = 0; - -const S32 EXPANDED_HEIGHT = 300; -const S32 COLLAPSED_HEIGHT = 60; -const S32 EXPANDED_MIN_HEIGHT = 150; - -// legacy callback glue -void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); - -struct LLChatTypeTrigger { - std::string name; - EChatType type; -}; - -static LLChatTypeTrigger sChatTypeTriggers[] = { - { "/whisper" , CHAT_TYPE_WHISPER}, - { "/shout" , CHAT_TYPE_SHOUT} -}; - -LLNearbyChatBar::LLNearbyChatBar(const LLSD& key) - : LLFloater(key), - mChatBox(NULL) -{ mSpeakerMgr = LLLocalSpeakerMgr::getInstance(); -} - -//virtual -BOOL LLNearbyChatBar::postBuild() -{ - mChatBox = getChild<LLLineEditor>("chat_box"); - - mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this)); - mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this); - mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this)); - mChatBox->setFocusReceivedCallback(boost::bind(&LLNearbyChatBar::onChatBoxFocusReceived, this)); - - mChatBox->setIgnoreArrowKeys( FALSE ); - mChatBox->setCommitOnFocusLost( FALSE ); - mChatBox->setRevertOnEsc( FALSE ); - mChatBox->setIgnoreTab(TRUE); - mChatBox->setPassDelete(TRUE); - mChatBox->setReplaceNewlinesWithSpaces(FALSE); - mChatBox->setEnableLineHistory(TRUE); - mChatBox->setFont(LLViewerChat::getChatFont()); - - - LLUICtrl* show_btn = getChild<LLUICtrl>("show_nearby_chat"); - show_btn->setCommitCallback(boost::bind(&LLNearbyChatBar::onToggleNearbyChatPanel, this)); - - mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator"); - mOutputMonitor->setVisible(FALSE); - - // Register for font change notifications - LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatBar::onChatFontChange, this, _1)); - - mExpandedHeight = COLLAPSED_HEIGHT + EXPANDED_HEIGHT; - - enableResizeCtrls(true, true, false); - - return TRUE; -} - -bool LLNearbyChatBar::applyRectControl() -{ - bool rect_controlled = LLFloater::applyRectControl(); - - LLView* nearby_chat = getChildView("nearby_chat"); - if (!nearby_chat->getVisible()) - { - reshape(getRect().getWidth(), getMinHeight()); - enableResizeCtrls(true, true, false); - } - else - { - enableResizeCtrls(true); - setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT); - } - - return rect_controlled; -} - -void LLNearbyChatBar::onChatFontChange(LLFontGL* fontp) -{ - // Update things with the new font whohoo - if (mChatBox) - { - mChatBox->setFont(fontp); - } -} - -//static -LLNearbyChatBar* LLNearbyChatBar::getInstance() -{ - return LLFloaterReg::getTypedInstance<LLNearbyChatBar>("chat_bar"); -} - -void LLNearbyChatBar::showHistory() -{ - openFloater(); - - if (!getChildView("nearby_chat")->getVisible()) - { - onToggleNearbyChatPanel(); - } -} - -void LLNearbyChatBar::draw() -{ - displaySpeakingIndicator(); - LLFloater::draw(); -} - -std::string LLNearbyChatBar::getCurrentChat() -{ - return mChatBox ? mChatBox->getText() : LLStringUtil::null; -} - -// virtual -BOOL LLNearbyChatBar::handleKeyHere( KEY key, MASK mask ) -{ - BOOL handled = FALSE; - - if( KEY_RETURN == key && mask == MASK_CONTROL) - { - // shout - sendChat(CHAT_TYPE_SHOUT); - handled = TRUE; - } - - return handled; -} - -BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::string* out_str) -{ - U32 in_len = in_str.length(); - S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); - - for (S32 n = 0; n < cnt; n++) - { - if (in_len > sChatTypeTriggers[n].name.length()) - continue; - - std::string trigger_trunc = sChatTypeTriggers[n].name; - LLStringUtil::truncate(trigger_trunc, in_len); - - if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc)) - { - *out_str = sChatTypeTriggers[n].name; - return TRUE; - } - } - - return FALSE; -} - -void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata) -{ - LLFirstUse::otherAvatarChatFirst(false); - - LLNearbyChatBar* self = (LLNearbyChatBar *)userdata; - - LLWString raw_text = self->mChatBox->getWText(); - - // Can't trim the end, because that will cause autocompletion - // to eat trailing spaces that might be part of a gesture. - LLWStringUtil::trimHead(raw_text); - - S32 length = raw_text.length(); - - if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences - { - gAgent.startTyping(); - } - else - { - gAgent.stopTyping(); - } - - /* Doesn't work -- can't tell the difference between a backspace - that killed the selection vs. backspace at the end of line. - if (length > 1 - && text[0] == '/' - && key == KEY_BACKSPACE) - { - // the selection will already be deleted, but we need to trim - // off the character before - std::string new_text = raw_text.substr(0, length-1); - self->mInputEditor->setText( new_text ); - self->mInputEditor->setCursorToEnd(); - length = length - 1; - } - */ - - KEY key = gKeyboard->currentKey(); - - // Ignore "special" keys, like backspace, arrows, etc. - if (length > 1 - && raw_text[0] == '/' - && key < KEY_SPECIAL) - { - // we're starting a gesture, attempt to autocomplete - - std::string utf8_trigger = wstring_to_utf8str(raw_text); - std::string utf8_out_str(utf8_trigger); - - if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str)) - { - std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); - self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part - S32 outlength = self->mChatBox->getLength(); // in characters - - // Select to end of line, starting from the character - // after the last one the user typed. - self->mChatBox->setSelection(length, outlength); - } - else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str)) - { - std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); - self->mChatBox->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part - self->mChatBox->setCursorToEnd(); - } - - //llinfos << "GESTUREDEBUG " << trigger - // << " len " << length - // << " outlen " << out_str.getLength() - // << llendl; - } -} - -// static -void LLNearbyChatBar::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata) -{ - // stop typing animation - gAgent.stopTyping(); -} - -void LLNearbyChatBar::onChatBoxFocusReceived() -{ - mChatBox->setEnabled(!gDisconnected); -} - -EChatType LLNearbyChatBar::processChatTypeTriggers(EChatType type, std::string &str) -{ - U32 length = str.length(); - S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); - - for (S32 n = 0; n < cnt; n++) - { - if (length >= sChatTypeTriggers[n].name.length()) - { - std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length()); - - if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name)) - { - U32 trigger_length = sChatTypeTriggers[n].name.length(); - - // It's to remove space after trigger name - if (length > trigger_length && str[trigger_length] == ' ') - trigger_length++; - - str = str.substr(trigger_length, length); - - if (CHAT_TYPE_NORMAL == type) - return sChatTypeTriggers[n].type; - else - break; - } - } - } - - return type; -} - -void LLNearbyChatBar::sendChat( EChatType type ) -{ - if (mChatBox) - { - LLWString text = mChatBox->getConvertedText(); - if (!text.empty()) - { - // store sent line in history, duplicates will get filtered - mChatBox->updateHistory(); - // Check if this is destined for another channel - S32 channel = 0; - stripChannelNumber(text, &channel); - - std::string utf8text = wstring_to_utf8str(text); - // Try to trigger a gesture, if not chat to a script. - std::string utf8_revised_text; - if (0 == channel) - { - // discard returned "found" boolean - LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text); - } - else - { - utf8_revised_text = utf8text; - } - - utf8_revised_text = utf8str_trim(utf8_revised_text); - - type = processChatTypeTriggers(type, utf8_revised_text); - - if (!utf8_revised_text.empty()) - { - // Chat with animation - sendChatFromViewer(utf8_revised_text, type, TRUE); - } - } - - mChatBox->setText(LLStringExplicit("")); - } - - gAgent.stopTyping(); - - // If the user wants to stop chatting on hitting return, lose focus - // and go out of chat mode. - if (gSavedSettings.getBOOL("CloseChatOnReturn")) - { - stopChat(); - } -} - - -void LLNearbyChatBar::onToggleNearbyChatPanel() -{ - LLView* nearby_chat = getChildView("nearby_chat"); - - if (nearby_chat->getVisible()) - { - if (!isMinimized()) - { - mExpandedHeight = getRect().getHeight(); - } - setResizeLimits(getMinWidth(), COLLAPSED_HEIGHT); - nearby_chat->setVisible(FALSE); - reshape(getRect().getWidth(), COLLAPSED_HEIGHT); - enableResizeCtrls(true, true, false); - storeRectControl(); - } - else - { - nearby_chat->setVisible(TRUE); - setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT); - reshape(getRect().getWidth(), mExpandedHeight); - enableResizeCtrls(true); - storeRectControl(); - } -} - -void LLNearbyChatBar::setMinimized(BOOL b) -{ - LLNearbyChat* nearby_chat = getChild<LLNearbyChat>("nearby_chat"); - // when unminimizing with nearby chat visible, go ahead and kill off screen chats - if (!b && nearby_chat->getVisible()) - { - nearby_chat->removeScreenChat(); - } - LLFloater::setMinimized(b); -} - -void LLNearbyChatBar::onChatBoxCommit() -{ - if (mChatBox->getText().length() > 0) - { - sendChat(CHAT_TYPE_NORMAL); - } - - gAgent.stopTyping(); -} - -void LLNearbyChatBar::displaySpeakingIndicator() -{ - LLSpeakerMgr::speaker_list_t speaker_list; - LLUUID id; - - id.setNull(); - mSpeakerMgr->update(TRUE); - mSpeakerMgr->getSpeakerList(&speaker_list, FALSE); - - for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i) - { - LLPointer<LLSpeaker> s = *i; - if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING) - { - id = s->mID; - break; - } - } - - if (!id.isNull()) - { - mOutputMonitor->setVisible(TRUE); - mOutputMonitor->setSpeakerId(id); - } - else - { - mOutputMonitor->setVisible(FALSE); - } -} - -void LLNearbyChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate) -{ - sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate); -} - -void LLNearbyChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate) -{ - // Look for "/20 foo" channel chats. - S32 channel = 0; - LLWString out_text = stripChannelNumber(wtext, &channel); - std::string utf8_out_text = wstring_to_utf8str(out_text); - std::string utf8_text = wstring_to_utf8str(wtext); - - utf8_text = utf8str_trim(utf8_text); - if (!utf8_text.empty()) - { - utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1); - } - - // Don't animate for chats people can't hear (chat to scripts) - if (animate && (channel == 0)) - { - if (type == CHAT_TYPE_WHISPER) - { - lldebugs << "You whisper " << utf8_text << llendl; - gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START); - } - else if (type == CHAT_TYPE_NORMAL) - { - lldebugs << "You say " << utf8_text << llendl; - gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START); - } - else if (type == CHAT_TYPE_SHOUT) - { - lldebugs << "You shout " << utf8_text << llendl; - gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START); - } - else - { - llinfos << "send_chat_from_viewer() - invalid volume" << llendl; - return; - } - } - else - { - if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP) - { - lldebugs << "Channel chat: " << utf8_text << llendl; - } - } - - send_chat_from_viewer(utf8_out_text, type, channel); -} - -// static -void LLNearbyChatBar::startChat(const char* line) -{ - LLNearbyChatBar* cb = LLNearbyChatBar::getInstance(); - - if (!cb ) - return; - - cb->setVisible(TRUE); - cb->setFocus(TRUE); - cb->mChatBox->setFocus(TRUE); - - if (line) - { - std::string line_string(line); - cb->mChatBox->setText(line_string); - } - - cb->mChatBox->setCursorToEnd(); -} - -// Exit "chat mode" and do the appropriate focus changes -// static -void LLNearbyChatBar::stopChat() -{ - LLNearbyChatBar* cb = LLNearbyChatBar::getInstance(); - - if (!cb) - return; - - cb->mChatBox->setFocus(FALSE); - - // stop typing animation - gAgent.stopTyping(); -} - -// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20. -// Otherwise returns input and channel 0. -LLWString LLNearbyChatBar::stripChannelNumber(const LLWString &mesg, S32* channel) -{ - if (mesg[0] == '/' - && mesg[1] == '/') - { - // This is a "repeat channel send" - *channel = sLastSpecialChatChannel; - return mesg.substr(2, mesg.length() - 2); - } - else if (mesg[0] == '/' - && mesg[1] - && LLStringOps::isDigit(mesg[1])) - { - // This a special "/20" speak on a channel - S32 pos = 0; - - // Copy the channel number into a string - LLWString channel_string; - llwchar c; - do - { - c = mesg[pos+1]; - channel_string.push_back(c); - pos++; - } - while(c && pos < 64 && LLStringOps::isDigit(c)); - - // Move the pointer forward to the first non-whitespace char - // Check isspace before looping, so we can handle "/33foo" - // as well as "/33 foo" - while(c && iswspace(c)) - { - c = mesg[pos+1]; - pos++; - } - - sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10); - *channel = sLastSpecialChatChannel; - return mesg.substr(pos, mesg.length() - pos); - } - else - { - // This is normal chat. - *channel = 0; - return mesg; - } -} - -void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) -{ - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ChatFromViewer); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ChatData); - msg->addStringFast(_PREHASH_Message, utf8_out_text); - msg->addU8Fast(_PREHASH_Type, type); - msg->addS32("Channel", channel); - - gAgent.sendReliableMessage(); - - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); -} - -class LLChatCommandHandler : public LLCommandHandler -{ -public: - // not allowed from outside the app - LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { } - - // Your code here - bool handle(const LLSD& tokens, const LLSD& query_map, - LLMediaCtrl* web) - { - bool retval = false; - // Need at least 2 tokens to have a valid message. - if (tokens.size() < 2) - { - retval = false; - } - else - { - S32 channel = tokens[0].asInteger(); - // VWR-19499 Restrict function to chat channels greater than 0. - if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG)) - { - retval = true; - // Send unescaped message, see EXT-6353. - std::string unescaped_mesg (LLURI::unescape(tokens[1].asString())); - send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel); - } - else - { - retval = false; - // Tell us this is an unsupported SLurl. - } - } - return retval; - } -}; - -// Creating the object registers with the dispatcher. -LLChatCommandHandler gChatHandler; - - diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 15d5d7c162..1bda7640bd 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -74,6 +74,8 @@ const F32 DOT_SCALE = 0.75f; const F32 MIN_PICK_SCALE = 2.f; const S32 MOUSE_DRAG_SLOP = 2; // How far the mouse needs to move before we think it's a drag +const F64 COARSEUPDATE_MAX_Z = 1020.0f; + LLNetMap::LLNetMap (const Params & p) : LLUICtrl (p), mBackgroundColor (p.bg_color()), @@ -300,7 +302,8 @@ void LLNetMap::draw() } LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); - map_center_agent -= gAgentCamera.getCameraPositionAgent(); + LLVector3 camera_position = gAgentCamera.getCameraPositionAgent(); + map_center_agent -= camera_position; map_center_agent.mV[VX] *= mScale/region_width; map_center_agent.mV[VY] *= mScale/region_width; @@ -321,9 +324,6 @@ void LLNetMap::draw() gGL.popMatrix(); - LLVector3d pos_global; - LLVector3 pos_map; - // Mouse pointer in local coordinates S32 local_mouse_x; S32 local_mouse_y; @@ -333,90 +333,67 @@ void LLNetMap::draw() F32 closest_dist_squared = F32_MAX; // value will be overridden in the loop F32 min_pick_dist_squared = (mDotRadius * MIN_PICK_SCALE) * (mDotRadius * MIN_PICK_SCALE); + LLVector3 pos_map; + uuid_vec_t avatar_ids; + std::vector<LLVector3d> positions; + bool unknown_relative_z; + + LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgentCamera.getCameraPositionGlobal()); + // Draw avatars - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + for (U32 i = 0; i < avatar_ids.size(); i++) { - LLViewerRegion* regionp = *iter; - const LLVector3d& origin_global = regionp->getOriginGlobal(); - - S32 count = regionp->mMapAvatars.count(); - S32 i; - LLVector3 pos_local; - U32 compact_local; - U8 bits; - // TODO: it'd be very cool to draw these in sorted order from lowest Z to highest. - // just be careful to sort the avatar IDs along with the positions. -MG - for (i = 0; i < count; i++) - { - compact_local = regionp->mMapAvatars.get(i); + pos_map = globalPosToView(positions[i]); + LLUUID uuid = avatar_ids[i]; - bits = compact_local & 0xFF; - pos_local.mV[VZ] = F32(bits) * 4.f; - compact_local >>= 8; + bool show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(uuid) != NULL); - bits = compact_local & 0xFF; - pos_local.mV[VY] = (F32)bits; - compact_local >>= 8; + LLColor4 color = show_as_friend ? map_avatar_friend_color : map_avatar_color; - bits = compact_local & 0xFF; - pos_local.mV[VX] = (F32)bits; + unknown_relative_z = positions[i].mdV[VZ] == COARSEUPDATE_MAX_Z && + camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z; - pos_global.setVec( pos_local ); - pos_global += origin_global; + LLWorldMapView::drawAvatar( + pos_map.mV[VX], pos_map.mV[VY], + color, + pos_map.mV[VZ], mDotRadius, + unknown_relative_z); - pos_map = globalPosToView(pos_global); - - LLUUID uuid(NULL); - BOOL show_as_friend = FALSE; - if( i < regionp->mMapAvatarIDs.count()) + if(uuid.notNull()) + { + bool selected = false; + uuid_vec_t::iterator sel_iter = gmSelected.begin(); + for (; sel_iter != gmSelected.end(); sel_iter++) { - uuid = regionp->mMapAvatarIDs.get(i); - show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(uuid) != NULL); + if(*sel_iter == uuid) + { + selected = true; + break; + } } - - LLColor4 color = show_as_friend ? map_avatar_friend_color : map_avatar_color; - LLWorldMapView::drawAvatar( - pos_map.mV[VX], pos_map.mV[VY], - color, - pos_map.mV[VZ], mDotRadius); - - if(uuid.notNull()) + if(selected) { - bool selected = false; - uuid_vec_t::iterator sel_iter = gmSelected.begin(); - for (; sel_iter != gmSelected.end(); sel_iter++) + if( (pos_map.mV[VX] < 0) || + (pos_map.mV[VY] < 0) || + (pos_map.mV[VX] >= getRect().getWidth()) || + (pos_map.mV[VY] >= getRect().getHeight()) ) { - if(*sel_iter == uuid) - { - selected = true; - break; - } - } - if(selected) + S32 x = llround( pos_map.mV[VX] ); + S32 y = llround( pos_map.mV[VY] ); + LLWorldMapView::drawTrackingCircle( getRect(), x, y, color, 1, 10); + } else { - if( (pos_map.mV[VX] < 0) || - (pos_map.mV[VY] < 0) || - (pos_map.mV[VX] >= getRect().getWidth()) || - (pos_map.mV[VY] >= getRect().getHeight()) ) - { - S32 x = llround( pos_map.mV[VX] ); - S32 y = llround( pos_map.mV[VY] ); - LLWorldMapView::drawTrackingCircle( getRect(), x, y, color, 1, 10); - } else - { - LLWorldMapView::drawTrackingDot(pos_map.mV[VX],pos_map.mV[VY],color,0.f); - } + LLWorldMapView::drawTrackingDot(pos_map.mV[VX],pos_map.mV[VY],color,0.f); } } + } - F32 dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), - LLVector2(local_mouse_x,local_mouse_y)); - if(dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared) - { - closest_dist_squared = dist_to_cursor_squared; - mClosestAgentToCursor = regionp->mMapAvatarIDs.get(i); - } + F32 dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), + LLVector2(local_mouse_x,local_mouse_y)); + if(dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared) + { + closest_dist_squared = dist_to_cursor_squared; + mClosestAgentToCursor = uuid; } } @@ -440,7 +417,7 @@ void LLNetMap::draw() } // Draw dot for self avatar position - pos_global = gAgent.getPositionGlobal(); + LLVector3d pos_global = gAgent.getPositionGlobal(); pos_map = globalPosToView(pos_global); S32 dot_width = llround(mDotRadius * 2.f); LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage; @@ -514,9 +491,11 @@ void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent) createObjectImage(); } -LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos ) +LLVector3 LLNetMap::globalPosToView(const LLVector3d& global_pos) { - LLVector3d relative_pos_global = global_pos - gAgentCamera.getCameraPositionGlobal(); + LLVector3d camera_position = gAgentCamera.getCameraPositionGlobal(); + + LLVector3d relative_pos_global = global_pos - camera_position; LLVector3 pos_local; pos_local.setVec(relative_pos_global); // convert to floats from doubles @@ -541,7 +520,7 @@ LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos ) void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color, BOOL draw_arrow ) { - LLVector3 pos_local = globalPosToView( pos_global ); + LLVector3 pos_local = globalPosToView(pos_global); if( (pos_local.mV[VX] < 0) || (pos_local.mV[VY] < 0) || (pos_local.mV[VX] >= getRect().getWidth()) || diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index 20fcee0814..1f7e7d68c6 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -33,9 +33,9 @@ #include "v3dmath.h" #include "v4color.h" #include "llpointer.h" +#include "llcoord.h" class LLColor4U; -class LLCoordGL; class LLImageRaw; class LLViewerTexture; class LLFloaterMap; diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp index cae7d02fed..58a9b01a45 100644 --- a/indra/newview/llnotificationalerthandler.cpp +++ b/indra/newview/llnotificationalerthandler.cpp @@ -29,6 +29,7 @@ #include "llnotificationhandler.h" +#include "llagentcamera.h" #include "llnotifications.h" #include "llprogressview.h" #include "lltoastnotifypanel.h" @@ -40,10 +41,10 @@ using namespace LLNotificationsUI; //-------------------------------------------------------------------------- -LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsModal(false) +LLAlertHandler::LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal) +: LLSystemNotificationHandler(name, notification_type), + mIsModal(is_modal) { - mType = type; - LLScreenChannelBase::Params p; p.id = LLUUID(gSavedSettings.getString("AlertChannelUUID")); p.display_toasts_always = true; @@ -51,8 +52,8 @@ LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsMo p.channel_align = CA_CENTRE; // Getting a Channel for our notifications - mChannel = LLChannelManager::getInstance()->getChannel(p); - mChannel->setCanStoreToasts(false); + mChannel = LLChannelManager::getInstance()->getChannel(p)->getHandle(); + mChannel.get()->setCanStoreToasts(false); } //-------------------------------------------------------------------------- @@ -64,83 +65,87 @@ LLAlertHandler::~LLAlertHandler() void LLAlertHandler::initChannel() { S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().getWidth() / 2; - mChannel->init(channel_right_bound, channel_right_bound); + mChannel.get()->init(channel_right_bound, channel_right_bound); } //-------------------------------------------------------------------------- -bool LLAlertHandler::processNotification(const LLSD& notify) +bool LLAlertHandler::processNotification(const LLNotificationPtr& notification) { - if(!mChannel) + if(mChannel.isDead()) { return false; } - LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - - if(!notification) - return false; - // arrange a channel on a screen - if(!mChannel->getVisible()) + if(!mChannel.get()->getVisible()) { initChannel(); } - if (notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "load") + if (notification->canLogToIM() && notification->hasFormElements()) { - if (LLHandlerUtil::canSpawnSessionAndLogToIM(notification)) - { - const std::string name = LLHandlerUtil::getSubstitutionName(notification); - - LLUUID from_id = notification->getPayload()["from_id"]; - - // firstly create session... - LLHandlerUtil::spawnIMSession(name, from_id); - - // ...then log message to have IM Well notified about new message - LLHandlerUtil::logToIMP2P(notification); - } - - LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal); - LLToast::Params p; - p.notif_id = notification->getID(); - p.notification = notification; - p.panel = dynamic_cast<LLToastPanel*>(alert_dialog); - p.enable_hide_btn = false; - p.can_fade = false; - p.is_modal = mIsModal; - p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1); - - // Show alert in middle of progress view (during teleport) (EXT-1093) - LLProgressView* progress = gViewerWindow->getProgressView(); - LLRect rc = progress && progress->getVisible() ? progress->getRect() : gViewerWindow->getWorldViewRectScaled(); - mChannel->updatePositionAndSize(rc); - - LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); - if(channel) - channel->addToast(p); - } - else if (notify["sigtype"].asString() == "change") - { - LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal); - LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); - if(channel) - channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog); - } - else - { - LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); - if(channel) - channel->killToastByNotificationID(notification->getID()); + const std::string name = LLHandlerUtil::getSubstitutionName(notification); + + LLUUID from_id = notification->getPayload()["from_id"]; + + // firstly create session... + LLHandlerUtil::spawnIMSession(name, from_id); + + // ...then log message to have IM Well notified about new message + LLHandlerUtil::logToIMP2P(notification); } + + LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal); + LLToast::Params p; + p.notif_id = notification->getID(); + p.notification = notification; + p.panel = dynamic_cast<LLToastPanel*>(alert_dialog); + p.enable_hide_btn = false; + p.can_fade = false; + p.is_modal = mIsModal; + p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1); + + // Show alert in middle of progress view (during teleport) (EXT-1093) + LLProgressView* progress = gViewerWindow->getProgressView(); + LLRect rc = progress && progress->getVisible() ? progress->getRect() : gViewerWindow->getWorldViewRectScaled(); + mChannel.get()->updatePositionAndSize(rc); + + LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get()); + if(channel) + channel->addToast(p); + return false; } +void LLAlertHandler::onChange( LLNotificationPtr notification ) +{ + LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal); + LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get()); + if(channel) + channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog); +} + //-------------------------------------------------------------------------- +LLViewerAlertHandler::LLViewerAlertHandler(const std::string& name, const std::string& notification_type) + : LLSystemNotificationHandler(name, notification_type) +{ +} -void LLAlertHandler::onDeleteToast(LLToast* toast) +bool LLViewerAlertHandler::processNotification(const LLNotificationPtr& p) { + if (gHeadlessClient) + { + LL_INFOS("LLViewerAlertHandler") << "Alert: " << p->getName() << LL_ENDL; + } + + // If we're in mouselook, the mouse is hidden and so the user can't click + // the dialog buttons. In that case, change to First Person instead. + if( gAgentCamera.cameraMouselook() ) + { + gAgentCamera.changeCameraToDefault(); + } + + return false; } -//-------------------------------------------------------------------------- diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp index 9b7fdaef82..8fef102cf8 100644 --- a/indra/newview/llnotificationgrouphandler.cpp +++ b/indra/newview/llnotificationgrouphandler.cpp @@ -37,15 +37,15 @@ using namespace LLNotificationsUI; //-------------------------------------------------------------------------- -LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id) +LLGroupHandler::LLGroupHandler() +: LLCommunicationNotificationHandler("Group Notifications", "groupnotify") { - mType = type; - // Getting a Channel for our notifications - mChannel = LLChannelManager::getInstance()->createNotificationChannel(); - LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); + LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel(); if(channel) - channel->setOnRejectToastCallback(boost::bind(&LLGroupHandler::onRejectToast, this, _1)); + { + mChannel = channel->getHandle(); + } } //-------------------------------------------------------------------------- @@ -58,76 +58,41 @@ void LLGroupHandler::initChannel() { S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); - mChannel->init(channel_right_bound - channel_width, channel_right_bound); + mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound); } //-------------------------------------------------------------------------- -bool LLGroupHandler::processNotification(const LLSD& notify) +bool LLGroupHandler::processNotification(const LLNotificationPtr& notification) { - if(!mChannel) + if(mChannel.isDead()) { return false; } - LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - - if(!notification) - return false; - // arrange a channel on a screen - if(!mChannel->getVisible()) + if(!mChannel.get()->getVisible()) { initChannel(); } - if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") - { - LLHandlerUtil::logGroupNoticeToIMGroup(notification); + LLHandlerUtil::logGroupNoticeToIMGroup(notification); - LLPanel* notify_box = new LLToastGroupNotifyPanel(notification); - LLToast::Params p; - p.notif_id = notification->getID(); - p.notification = notification; - p.panel = notify_box; - p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1); + LLPanel* notify_box = new LLToastGroupNotifyPanel(notification); + LLToast::Params p; + p.notif_id = notification->getID(); + p.notification = notification; + p.panel = notify_box; + p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1); - LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); - if(channel) - channel->addToast(p); + LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get()); + if(channel) + channel->addToast(p); - // send a signal to the counter manager - mNewNotificationSignal(); + LLGroupActions::refresh_notices(); - LLGroupActions::refresh_notices(); - } - else if (notify["sigtype"].asString() == "delete") - { - mChannel->killToastByNotificationID(notification->getID()); - } return false; } -//-------------------------------------------------------------------------- -void LLGroupHandler::onDeleteToast(LLToast* toast) -{ - // send a signal to the counter manager - mDelNotificationSignal(); - - // send a signal to a listener to let him perform some action - // in this case listener is a SysWellWindow and it will remove a corresponding item from its list - mNotificationIDSignal(toast->getNotificationID()); -} - -//-------------------------------------------------------------------------- -void LLGroupHandler::onRejectToast(LLUUID& id) -{ - LLNotificationPtr notification = LLNotifications::instance().find(id); - - if (notification && LLNotificationManager::getInstance()->getHandlerForNotification(notification->getType()) == this) - { - LLNotifications::instance().cancel(notification); - } -} //-------------------------------------------------------------------------- diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index 28a69f2373..bff4efa9ea 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -27,33 +27,20 @@ #ifndef LL_LLNOTIFICATIONHANDLER_H #define LL_LLNOTIFICATIONHANDLER_H +#include <boost/intrusive_ptr.hpp> #include "llwindow.h" -//#include "llnotificationsutil.h" +#include "llnotifications.h" #include "llchannelmanager.h" #include "llchat.h" #include "llinstantmessage.h" #include "llnotificationptr.h" -class LLIMFloater; +class LLFloaterIMSession; namespace LLNotificationsUI { -// ENotificationType enumerates all possible types of notifications that could be met -// -typedef enum e_notification_type -{ - NT_NOTIFY, - NT_NOTIFYTIP, - NT_GROUPNOTIFY, - NT_IMCHAT, - NT_GROUPCHAT, - NT_NEARBYCHAT, - NT_ALERT, - NT_ALERTMODAL, - NT_OFFER -} ENotificationType; /** * Handler of notification events. @@ -81,21 +68,8 @@ class LLEventHandler public: virtual ~LLEventHandler() {}; - // callbacks for counters - typedef boost::function<void (void)> notification_callback_t; - typedef boost::signals2::signal<void (void)> notification_signal_t; - notification_signal_t mNewNotificationSignal; - notification_signal_t mDelNotificationSignal; - boost::signals2::connection setNewNotificationCallback(notification_callback_t cb) { return mNewNotificationSignal.connect(cb); } - boost::signals2::connection setDelNotification(notification_callback_t cb) { return mDelNotificationSignal.connect(cb); } - // callback for notification/toast - typedef boost::function<void (const LLUUID id)> notification_id_callback_t; - typedef boost::signals2::signal<void (const LLUUID id)> notification_id_signal_t; - notification_id_signal_t mNotificationIDSignal; - boost::signals2::connection setNotificationIDCallback(notification_id_callback_t cb) { return mNotificationIDSignal.connect(cb); } - protected: - virtual void onDeleteToast(LLToast* toast)=0; + virtual void onDeleteToast(LLToast* toast) {} // arrange handler's channel on a screen // is necessary to unbind a moment of creation of a channel and a moment of positioning of it @@ -103,9 +77,7 @@ protected: // at the moment, when a handlers creates a channel. virtual void initChannel()=0; - LLScreenChannelBase* mChannel; - e_notification_type mType; - + LLHandle<LLScreenChannelBase> mChannel; }; // LLSysHandler and LLChatHandler are more specific base classes @@ -115,24 +87,37 @@ protected: /** * Handler for system notifications. */ -class LLSysHandler : public LLEventHandler +class LLNotificationHandler : public LLEventHandler, public LLNotificationChannel { public: - LLSysHandler(); - virtual ~LLSysHandler() {}; + LLNotificationHandler(const std::string& name, const std::string& notification_type, const std::string& parentName); + virtual ~LLNotificationHandler() {}; - virtual bool processNotification(const LLSD& notify)=0; + // base interface functions + virtual void onAdd(LLNotificationPtr p) { processNotification(p); } + virtual void onChange(LLNotificationPtr p) { processNotification(p); } + virtual void onLoad(LLNotificationPtr p) { processNotification(p); } + virtual void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->removeToastByNotificationID(p->getID());} -protected : - static void init(); - void removeExclusiveNotifications(const LLNotificationPtr& notif); + virtual bool processNotification(const LLNotificationPtr& notify) = 0; +}; - typedef std::list< std::set<std::string> > exclusive_notif_sets; - static exclusive_notif_sets sExclusiveNotificationGroups; +class LLSystemNotificationHandler : public LLNotificationHandler +{ +public: + LLSystemNotificationHandler(const std::string& name, const std::string& notification_type); + virtual ~LLSystemNotificationHandler() {}; +}; + +class LLCommunicationNotificationHandler : public LLNotificationHandler +{ +public: + LLCommunicationNotificationHandler(const std::string& name, const std::string& notification_type); + virtual ~LLCommunicationNotificationHandler() {}; }; /** - * Handler for chat message notifications. + * Handler for chat message notifications. */ class LLChatHandler : public LLEventHandler { @@ -146,17 +131,14 @@ public: * Handler for IM notifications. * It manages life time of IMs, group messages. */ -class LLIMHandler : public LLSysHandler +class LLIMHandler : public LLCommunicationNotificationHandler { public: - LLIMHandler(e_notification_type type, const LLSD& id); + LLIMHandler(); virtual ~LLIMHandler(); - - // base interface functions - virtual bool processNotification(const LLSD& notify); + bool processNotification(const LLNotificationPtr& p); protected: - virtual void onDeleteToast(LLToast* toast); virtual void initChannel(); }; @@ -164,18 +146,15 @@ protected: * Handler for system informational notices. * It manages life time of tip notices. */ -class LLTipHandler : public LLSysHandler +class LLTipHandler : public LLSystemNotificationHandler { public: - LLTipHandler(e_notification_type type, const LLSD& id); + LLTipHandler(); virtual ~LLTipHandler(); - // base interface functions - virtual bool processNotification(const LLSD& notify); + virtual bool processNotification(const LLNotificationPtr& p); protected: - virtual void onDeleteToast(LLToast* toast); - virtual void onRejectToast(const LLUUID& id); virtual void initChannel(); }; @@ -183,160 +162,144 @@ protected: * Handler for system informational notices. * It manages life time of script notices. */ -class LLScriptHandler : public LLSysHandler +class LLScriptHandler : public LLSystemNotificationHandler { public: - LLScriptHandler(e_notification_type type, const LLSD& id); + LLScriptHandler(); virtual ~LLScriptHandler(); - // base interface functions - virtual bool processNotification(const LLSD& notify); + virtual void onDelete(LLNotificationPtr p); + virtual bool processNotification(const LLNotificationPtr& p); protected: virtual void onDeleteToast(LLToast* toast); virtual void initChannel(); - - // own handlers - void onRejectToast(LLUUID& id); }; /** * Handler for group system notices. */ -class LLGroupHandler : public LLSysHandler +class LLGroupHandler : public LLCommunicationNotificationHandler { public: - LLGroupHandler(e_notification_type type, const LLSD& id); + LLGroupHandler(); virtual ~LLGroupHandler(); - // base interface functions - virtual bool processNotification(const LLSD& notify); + virtual bool processNotification(const LLNotificationPtr& p); protected: - virtual void onDeleteToast(LLToast* toast); virtual void initChannel(); - - // own handlers - void onRejectToast(LLUUID& id); }; /** * Handler for alert system notices. */ -class LLAlertHandler : public LLSysHandler +class LLAlertHandler : public LLSystemNotificationHandler { public: - LLAlertHandler(e_notification_type type, const LLSD& id); + LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal); virtual ~LLAlertHandler(); - void setAlertMode(bool is_modal) { mIsModal = is_modal; } - - // base interface functions - virtual bool processNotification(const LLSD& notify); + virtual void onChange(LLNotificationPtr p); + virtual bool processNotification(const LLNotificationPtr& p); protected: - virtual void onDeleteToast(LLToast* toast); virtual void initChannel(); bool mIsModal; }; +class LLViewerAlertHandler : public LLSystemNotificationHandler +{ + LOG_CLASS(LLViewerAlertHandler); +public: + LLViewerAlertHandler(const std::string& name, const std::string& notification_type); + virtual ~LLViewerAlertHandler() {}; + + virtual void onDelete(LLNotificationPtr p) {}; + virtual bool processNotification(const LLNotificationPtr& p); + +protected: + virtual void initChannel() {}; +}; + /** * Handler for offers notices. * It manages life time of offer notices. */ -class LLOfferHandler : public LLSysHandler +class LLOfferHandler : public LLCommunicationNotificationHandler { public: - LLOfferHandler(e_notification_type type, const LLSD& id); + LLOfferHandler(); virtual ~LLOfferHandler(); - // base interface functions - virtual bool processNotification(const LLSD& notify); + virtual void onChange(LLNotificationPtr p); + virtual void onDelete(LLNotificationPtr notification); + virtual bool processNotification(const LLNotificationPtr& p); protected: - virtual void onDeleteToast(LLToast* toast); virtual void initChannel(); - - // own handlers - void onRejectToast(LLUUID& id); }; /** * Handler for UI hints. */ -class LLHintHandler : public LLSingleton<LLHintHandler> +class LLHintHandler : public LLSystemNotificationHandler { public: LLHintHandler(); - virtual ~LLHintHandler(); + virtual ~LLHintHandler() {} - // base interface functions - virtual bool processNotification(const LLSD& notify); + virtual void onAdd(LLNotificationPtr p); + virtual void onLoad(LLNotificationPtr p); + virtual void onDelete(LLNotificationPtr p); + virtual bool processNotification(const LLNotificationPtr& p); + +protected: + virtual void initChannel() {}; }; /** * Handler for browser notifications */ -class LLBrowserNotification : public LLSingleton<LLBrowserNotification> +class LLBrowserNotification : public LLSystemNotificationHandler { public: - virtual bool processNotification(const LLSD& notify); - + LLBrowserNotification(); + virtual ~LLBrowserNotification() {} + + virtual bool processNotification(const LLNotificationPtr& p); + +protected: + virtual void initChannel() {}; }; + +/** + * Handler for outbox notifications + */ +class LLOutboxNotification : public LLSystemNotificationHandler +{ +public: + LLOutboxNotification(); + virtual ~LLOutboxNotification() {}; + virtual void onChange(LLNotificationPtr p) { } + virtual void onDelete(LLNotificationPtr p); + virtual bool processNotification(const LLNotificationPtr& p); +protected: + virtual void initChannel() {}; +}; + class LLHandlerUtil { public: /** - * Checks sufficient conditions to log notification message to IM session. - */ - static bool canLogToIM(const LLNotificationPtr& notification); - - /** - * Checks sufficient conditions to log notification message to nearby chat session. - */ - static bool canLogToNearbyChat(const LLNotificationPtr& notification); - - /** - * Checks sufficient conditions to spawn IM session. - */ - static bool canSpawnIMSession(const LLNotificationPtr& notification); - - /** - * Checks sufficient conditions to add notification toast panel IM floater. - */ - static bool canAddNotifPanelToIM(const LLNotificationPtr& notification); - - /** - * Checks whether notification can be used multiple times or not. - */ - static bool isNotificationReusable(const LLNotificationPtr& notification); - - /** - * Checks if passed notification can create IM session and be written into it. - * - * This method uses canLogToIM() & canSpawnIMSession(). - */ - static bool canSpawnSessionAndLogToIM(const LLNotificationPtr& notification); - - /** - * Checks if passed notification can create toast. - */ - static bool canSpawnToast(const LLNotificationPtr& notification); - - /** * Determines whether IM floater is opened. */ static bool isIMFloaterOpened(const LLNotificationPtr& notification); /** - * Determines whether IM floater is focused. - */ - static bool isIMFloaterFocused(const LLNotificationPtr& notification); - - /** * Writes notification message to IM session. */ static void logToIM(const EInstantMessage& session_type, @@ -347,12 +310,7 @@ public: /** * Writes notification message to IM p2p session. */ - static void logToIMP2P(const LLNotificationPtr& notification); - - /** - * Writes notification message to IM p2p session. - */ - static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only); + static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false); /** * Writes group notice notification message to IM group session. @@ -398,13 +356,6 @@ public: */ static void decIMMesageCounter(const LLNotificationPtr& notification); -private: - - /** - * Find IM floater based on "from_id" - */ - static LLIMFloater* findIMFloater(const LLNotificationPtr& notification); - }; } diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 1b767e80d4..eb4601a469 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -34,207 +34,34 @@ #include "llurlaction.h" #include "llagent.h" -#include "llimfloater.h" +#include "llfloaterimsession.h" #include "llimview.h" -#include "llnearbychat.h" +#include "llfloaterimnearbychat.h" #include "llnotificationhandler.h" using namespace LLNotificationsUI; -// static -std::list< std::set<std::string> > LLSysHandler::sExclusiveNotificationGroups; - -// static -void LLSysHandler::init() -{ - std::set<std::string> online_offline_group; - online_offline_group.insert("FriendOnline"); - online_offline_group.insert("FriendOffline"); +LLNotificationHandler::LLNotificationHandler(const std::string& name, const std::string& notification_type, const std::string& parentName) +: LLNotificationChannel(name, parentName, LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, notification_type)) +{} - sExclusiveNotificationGroups.push_back(online_offline_group); -} - -LLSysHandler::LLSysHandler() -{ - if(sExclusiveNotificationGroups.empty()) - { - init(); - } -} +LLSystemNotificationHandler::LLSystemNotificationHandler(const std::string& name, const std::string& notification_type) + : LLNotificationHandler(name, notification_type, "System") +{} -void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif) -{ - LLScreenChannel* channel = dynamic_cast<LLScreenChannel *>(mChannel); - if (channel == NULL) - { - return; - } - - class ExclusiveMatcher: public LLScreenChannel::Matcher - { - public: - ExclusiveMatcher(const std::set<std::string>& excl_group, - const std::string& from_name) : - mExclGroup(excl_group), mFromName(from_name) - { - } - bool matches(const LLNotificationPtr notification) const - { - for (std::set<std::string>::const_iterator it = mExclGroup.begin(); it - != mExclGroup.end(); it++) - { - std::string from_name = LLHandlerUtil::getSubstitutionName(notification); - if (notification->getName() == *it && from_name == mFromName) - { - return true; - } - } - return false; - } - private: - const std::set<std::string>& mExclGroup; - const std::string& mFromName; - }; - - - for (exclusive_notif_sets::iterator it = sExclusiveNotificationGroups.begin(); it - != sExclusiveNotificationGroups.end(); it++) - { - std::set<std::string> group = *it; - std::set<std::string>::iterator g_it = group.find(notif->getName()); - if (g_it != group.end()) - { - channel->killMatchedToasts(ExclusiveMatcher(group, - LLHandlerUtil::getSubstitutionName(notif))); - } - } -} - -const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"), - REVOKED_MODIFY_RIGHTS("RevokedModifyRights"), - OBJECT_GIVE_ITEM("ObjectGiveItem"), - OBJECT_GIVE_ITEM_UNKNOWN_USER("ObjectGiveItemUnknownUser"), - PAYMENT_RECEIVED("PaymentReceived"), - PAYMENT_SENT("PaymentSent"), - ADD_FRIEND_WITH_MESSAGE("AddFriendWithMessage"), - USER_GIVE_ITEM("UserGiveItem"), - INVENTORY_ACCEPTED("InventoryAccepted"), - INVENTORY_DECLINED("InventoryDeclined"), - OFFER_FRIENDSHIP("OfferFriendship"), - FRIENDSHIP_ACCEPTED("FriendshipAccepted"), - FRIENDSHIP_OFFERED("FriendshipOffered"), - FRIENDSHIP_ACCEPTED_BYME("FriendshipAcceptedByMe"), - FRIENDSHIP_DECLINED_BYME("FriendshipDeclinedByMe"), - FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"), - SERVER_OBJECT_MESSAGE("ServerObjectMessage"), - TELEPORT_OFFERED("TeleportOffered"), - TELEPORT_OFFER_SENT("TeleportOfferSent"), - IM_SYSTEM_MESSAGE_TIP("IMSystemMessageTip"); - - -// static -bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification) -{ - return GRANTED_MODIFY_RIGHTS == notification->getName() - || REVOKED_MODIFY_RIGHTS == notification->getName() - || PAYMENT_RECEIVED == notification->getName() - || PAYMENT_SENT == notification->getName() - || OFFER_FRIENDSHIP == notification->getName() - || FRIENDSHIP_OFFERED == notification->getName() - || FRIENDSHIP_ACCEPTED == notification->getName() - || FRIENDSHIP_ACCEPTED_BYME == notification->getName() - || FRIENDSHIP_DECLINED_BYME == notification->getName() - || SERVER_OBJECT_MESSAGE == notification->getName() - || INVENTORY_ACCEPTED == notification->getName() - || INVENTORY_DECLINED == notification->getName() - || USER_GIVE_ITEM == notification->getName() - || TELEPORT_OFFERED == notification->getName() - || TELEPORT_OFFER_SENT == notification->getName() - || IM_SYSTEM_MESSAGE_TIP == notification->getName(); -} - -// static -bool LLHandlerUtil::canLogToNearbyChat(const LLNotificationPtr& notification) -{ - return notification->getType() == "notifytip" - && FRIEND_ONLINE != notification->getName() - && FRIEND_OFFLINE != notification->getName() - && INVENTORY_ACCEPTED != notification->getName() - && INVENTORY_DECLINED != notification->getName() - && IM_SYSTEM_MESSAGE_TIP != notification->getName(); -} - -// static -bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification) -{ - return OFFER_FRIENDSHIP == notification->getName() - || USER_GIVE_ITEM == notification->getName() - || TELEPORT_OFFERED == notification->getName(); -} - -// static -bool LLHandlerUtil::canAddNotifPanelToIM(const LLNotificationPtr& notification) -{ - return OFFER_FRIENDSHIP == notification->getName() - || USER_GIVE_ITEM == notification->getName() - || TELEPORT_OFFERED == notification->getName(); -} - -// static -bool LLHandlerUtil::isNotificationReusable(const LLNotificationPtr& notification) -{ - return OFFER_FRIENDSHIP == notification->getName() - || USER_GIVE_ITEM == notification->getName() - || TELEPORT_OFFERED == notification->getName(); -} - -// static -bool LLHandlerUtil::canSpawnSessionAndLogToIM(const LLNotificationPtr& notification) -{ - return canLogToIM(notification) && canSpawnIMSession(notification); -} +LLCommunicationNotificationHandler::LLCommunicationNotificationHandler(const std::string& name, const std::string& notification_type) + : LLNotificationHandler(name, notification_type, "Communication") +{} // static -bool LLHandlerUtil::canSpawnToast(const LLNotificationPtr& notification) +bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification) { - if(INVENTORY_DECLINED == notification->getName() - || INVENTORY_ACCEPTED == notification->getName()) - { - // return false for inventory accepted/declined notifications if respective IM window is open (EXT-5909) - return ! isIMFloaterOpened(notification); - } - - if(FRIENDSHIP_ACCEPTED == notification->getName()) - { - // don't show FRIENDSHIP_ACCEPTED if IM window is opened and focused - EXT-6441 - return ! isIMFloaterFocused(notification); - } - - if(OFFER_FRIENDSHIP == notification->getName() - || USER_GIVE_ITEM == notification->getName() - || TELEPORT_OFFERED == notification->getName()) - { - // When ANY offer arrives, show toast, unless IM window is already open - EXT-5904 - return ! isIMFloaterOpened(notification); - } - - return true; -} + bool res = false; -// static -LLIMFloater* LLHandlerUtil::findIMFloater(const LLNotificationPtr& notification) -{ LLUUID from_id = notification->getPayload()["from_id"]; LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id); - return LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); -} - -// static -bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification) -{ - bool res = false; + LLFloaterIMSession* im_floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id); - LLIMFloater* im_floater = findIMFloater(notification); if (im_floater != NULL) { res = im_floater->getVisible() == TRUE; @@ -243,19 +70,6 @@ bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification) return res; } -bool LLHandlerUtil::isIMFloaterFocused(const LLNotificationPtr& notification) -{ - bool res = false; - - LLIMFloater* im_floater = findIMFloater(notification); - if (im_floater != NULL) - { - res = im_floater->hasFocus() == TRUE; - } - - return res; -} - // static void LLHandlerUtil::logToIM(const EInstantMessage& session_type, const std::string& session_name, const std::string& from_name, @@ -287,13 +101,6 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type, } else { - // store active session id - const LLUUID & active_session_id = - LLIMModel::instance().getActiveSessionID(); - - // set searched session as active to avoid IM toast popup - LLIMModel::instance().setActiveSessionID(session_id); - S32 unread = session->mNumUnread; S32 participant_unread = session->mParticipantUnreadMessageCount; LLIMModel::instance().addMessageSilently(session_id, from, from_id, @@ -304,25 +111,9 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type, // update IM floater messages updateIMFLoaterMesages(session_id); - - // restore active session id - if (active_session_id.isNull()) - { - LLIMModel::instance().resetActiveSessionID(); - } - else - { - LLIMModel::instance().setActiveSessionID(active_session_id); - } } } -// static -void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification) -{ - logToIMP2P(notification, false); -} - void log_name_callback(const std::string& full_name, const std::string& from_name, const std::string& message, const LLUUID& from_id) @@ -334,14 +125,12 @@ void log_name_callback(const std::string& full_name, const std::string& from_nam // static void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only) { - // don't create IM p2p session with objects, it's necessary condition to log - if (notification->getName() != OBJECT_GIVE_ITEM) - { LLUUID from_id = notification->getPayload()["from_id"]; if (from_id.isNull()) { - llwarns << " from_id for notification " << notification->getName() << " is null " << llendl; + // Normal behavior for system generated messages, don't spam. + // llwarns << " from_id for notification " << notification->getName() << " is null " << llendl; return; } @@ -354,7 +143,6 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id)); } } -} // static void LLHandlerUtil::logGroupNoticeToIMGroup( @@ -385,8 +173,8 @@ void LLHandlerUtil::logGroupNoticeToIMGroup( // static void LLHandlerUtil::logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type) { - LLNearbyChat* nearby_chat = LLNearbyChat::getInstance(); - if(nearby_chat) + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + if (nearby_chat) { LLChat chat_msg(notification->getMessage()); chat_msg.mSourceType = type; @@ -465,7 +253,7 @@ void LLHandlerUtil::addNotifPanelToIM(const LLNotificationPtr& notification) // static void LLHandlerUtil::updateIMFLoaterMesages(const LLUUID& session_id) { - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id); if (im_floater != NULL && im_floater->getVisible()) { im_floater->updateMessages(); @@ -489,14 +277,10 @@ void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification) LLUUID from_id = notification->getPayload()["from_id"]; LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id); - LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession( - session_id); + LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(session_id); - if (session == NULL) + if (session) { - return; - } - LLSD arg; arg["session_id"] = session_id; session->mNumUnread--; @@ -505,3 +289,5 @@ void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification) arg["participant_unread"] = session->mParticipantUnreadMessageCount; LLIMModel::getInstance()->mNewMsgSignal(arg); } +} + diff --git a/indra/newview/llnotificationhinthandler.cpp b/indra/newview/llnotificationhinthandler.cpp index f7163cb04f..f40369a2e0 100644 --- a/indra/newview/llnotificationhinthandler.cpp +++ b/indra/newview/llnotificationhinthandler.cpp @@ -34,25 +34,26 @@ using namespace LLNotificationsUI; LLHintHandler::LLHintHandler() + : LLSystemNotificationHandler("Hints", "hint") { } -LLHintHandler::~LLHintHandler() +void LLHintHandler::onAdd(LLNotificationPtr p) { + LLHints::show(p); } -bool LLHintHandler::processNotification(const LLSD& notify) +void LLHintHandler::onLoad(LLNotificationPtr p) +{ + LLHints::show(p); +} + +void LLHintHandler::onDelete(LLNotificationPtr p) +{ + LLHints::hide(p); +} + +bool LLHintHandler::processNotification(const LLNotificationPtr& p) { - LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - - std::string sigtype = notify["sigtype"].asString(); - if (sigtype == "add" || sigtype == "load") - { - LLHints::show(notification); - } - else if (sigtype == "delete") - { - LLHints::hide(notification); - } return false; } diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp index 6988227128..152581c5a0 100644 --- a/indra/newview/llnotificationmanager.cpp +++ b/indra/newview/llnotificationmanager.cpp @@ -31,17 +31,17 @@ #include "llnotificationmanager.h" -#include "llnearbychathandler.h" +#include "llfloaterimnearbychathandler.h" #include "llnotifications.h" #include <boost/bind.hpp> +#include <boost/foreach.hpp> using namespace LLNotificationsUI; //-------------------------------------------------------------------------- LLNotificationManager::LLNotificationManager() { - mNotifyHandlers.clear(); init(); } @@ -53,86 +53,24 @@ LLNotificationManager::~LLNotificationManager() //-------------------------------------------------------------------------- void LLNotificationManager::init() { - LLNotificationChannel::buildChannel("Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notify")); - LLNotificationChannel::buildChannel("NotificationTips", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytip")); - LLNotificationChannel::buildChannel("Group Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "groupnotify")); - LLNotificationChannel::buildChannel("Alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert")); - LLNotificationChannel::buildChannel("AlertModal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal")); - LLNotificationChannel::buildChannel("IM Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytoast")); - 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")); + mChannels.push_back(new LLScriptHandler()); + mChannels.push_back(new LLTipHandler()); + mChannels.push_back(new LLGroupHandler()); + mChannels.push_back(new LLAlertHandler("Alerts", "alert", false)); + mChannels.push_back(new LLAlertHandler("AlertModal", "alertmodal", true)); + mChannels.push_back(new LLOfferHandler()); + mChannels.push_back(new LLHintHandler()); + mChannels.push_back(new LLBrowserNotification()); + mChannels.push_back(new LLOutboxNotification()); + mChannels.push_back(new LLIMHandler()); - LLNotifications::instance().getChannel("Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); - LLNotifications::instance().getChannel("NotificationTips")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); - LLNotifications::instance().getChannel("Group Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); - LLNotifications::instance().getChannel("Alerts")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); - LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); - LLNotifications::instance().getChannel("IM Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); - 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)); - - mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLScriptHandler(NT_NOTIFY, LLSD())); - mNotifyHandlers["notifytip"] = boost::shared_ptr<LLEventHandler>(new LLTipHandler(NT_NOTIFY, LLSD())); - mNotifyHandlers["groupnotify"] = boost::shared_ptr<LLEventHandler>(new LLGroupHandler(NT_GROUPNOTIFY, LLSD())); - mNotifyHandlers["alert"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD())); - mNotifyHandlers["alertmodal"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD())); - static_cast<LLAlertHandler*>(mNotifyHandlers["alertmodal"].get())->setAlertMode(true); - mNotifyHandlers["notifytoast"] = boost::shared_ptr<LLEventHandler>(new LLIMHandler(NT_IMCHAT, LLSD())); - - mNotifyHandlers["nearbychat"] = boost::shared_ptr<LLEventHandler>(new LLNearbyChatHandler(NT_NEARBYCHAT, LLSD())); - mNotifyHandlers["offer"] = boost::shared_ptr<LLEventHandler>(new LLOfferHandler(NT_OFFER, LLSD())); -} - -//-------------------------------------------------------------------------- -bool LLNotificationManager::onNotification(const LLSD& notify) -{ - LLSysHandler* handle = NULL; - - LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - - if (!notification) - return false; - - std::string notification_type = notification->getType(); - handle = static_cast<LLSysHandler*>(mNotifyHandlers[notification_type].get()); - - if(!handle) - return false; - - return handle->processNotification(notify); + mChatHandler = boost::shared_ptr<LLFloaterIMNearbyChatHandler>(new LLFloaterIMNearbyChatHandler()); } //-------------------------------------------------------------------------- void LLNotificationManager::onChat(const LLChat& msg, const LLSD &args) { - // check ENotificationType argument - switch(args["type"].asInteger()) - { - case NT_NEARBYCHAT: - { - LLNearbyChatHandler* handle = dynamic_cast<LLNearbyChatHandler*>(mNotifyHandlers["nearbychat"].get()); - - if(handle) - handle->processChat(msg, args); + if(mChatHandler) + mChatHandler->processChat(msg, args); } - break; - default: //no need to handle all enum types - break; - } -} - -//-------------------------------------------------------------------------- -LLEventHandler* LLNotificationManager::getHandlerForNotification(std::string notification_type) -{ - std::map<std::string, boost::shared_ptr<LLEventHandler> >::iterator it = mNotifyHandlers.find(notification_type); - - if(it != mNotifyHandlers.end()) - return (*it).second.get(); - - return NULL; -} - -//-------------------------------------------------------------------------- diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h index 16e82e4cce..f37c6b833c 100644 --- a/indra/newview/llnotificationmanager.h +++ b/indra/newview/llnotificationmanager.h @@ -56,20 +56,12 @@ public: void init(void); //TODO: combine processing and storage (*) - // this method reacts on system notifications and calls an appropriate handler - bool onNotification(const LLSD& notification); - // this method reacts on chat notifications and calls an appropriate handler void onChat(const LLChat& msg, const LLSD &args); - // get a handler for a certain type of notification - LLEventHandler* getHandlerForNotification(std::string notification_type); - - private: - //TODO (*) - std::map<std::string, boost::shared_ptr<LLEventHandler> > mNotifyHandlers; - // cruft std::map<std::string, LLChatHandler*> mChatHandlers; + boost::shared_ptr<class LLFloaterIMNearbyChatHandler> mChatHandler; + std::vector<LLNotificationChannelPtr> mChannels; }; } diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index 68fd65be0f..2657b84ef3 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -40,17 +40,16 @@ using namespace LLNotificationsUI; //-------------------------------------------------------------------------- -LLOfferHandler::LLOfferHandler(e_notification_type type, const LLSD& id) +LLOfferHandler::LLOfferHandler() +: LLCommunicationNotificationHandler("Offer", "offer") { - mType = type; - // Getting a Channel for our notifications - mChannel = LLChannelManager::getInstance()->createNotificationChannel(); - mChannel->setControlHovering(true); - - LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); + LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel(); if(channel) - channel->setOnRejectToastCallback(boost::bind(&LLOfferHandler::onRejectToast, this, _1)); + { + channel->setControlHovering(true); + mChannel = channel->getHandle(); + } } //-------------------------------------------------------------------------- @@ -63,151 +62,128 @@ void LLOfferHandler::initChannel() { S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); - mChannel->init(channel_right_bound - channel_width, channel_right_bound); + mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound); } //-------------------------------------------------------------------------- -bool LLOfferHandler::processNotification(const LLSD& notify) +bool LLOfferHandler::processNotification(const LLNotificationPtr& notification) { - if(!mChannel) + if(mChannel.isDead()) { return false; } - LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - - if(!notification) - return false; - // arrange a channel on a screen - if(!mChannel->getVisible()) + if(!mChannel.get()->getVisible()) { initChannel(); } - if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") - { + if( notification->getPayload().has("give_inventory_notification") + && notification->getPayload()["give_inventory_notification"].asBoolean() == false) + { + // This is an original inventory offer, so add a script floater + LLScriptFloaterManager::instance().onAddNotification(notification->getID()); + } + else + { + bool add_notif_to_im = notification->canLogToIM() && notification->hasFormElements(); - if( notification->getPayload().has("give_inventory_notification") - && !notification->getPayload()["give_inventory_notification"] ) + if (add_notif_to_im) { - // This is an original inventory offer, so add a script floater - LLScriptFloaterManager::instance().onAddNotification(notification->getID()); + const std::string name = LLHandlerUtil::getSubstitutionName(notification); + + LLUUID from_id = notification->getPayload()["from_id"]; + + //Will not play a notification sound for inventory and teleport offer based upon chat preference + bool playSound = (!notification->isDND() + && ((notification->getName() == "UserGiveItem" + && gSavedSettings.getBOOL("PlaySoundInventoryOffer")) + || (notification->getName() == "TeleportOffered" + && gSavedSettings.getBOOL("PlaySoundTeleportOffer")))); + + if(playSound) + { + notification->playSound(); + } + + LLHandlerUtil::spawnIMSession(name, from_id); + LLHandlerUtil::addNotifPanelToIM(notification); + } - else + + if (!notification->canShowToast()) { - notification->setReusable(LLHandlerUtil::isNotificationReusable(notification)); - - LLUUID session_id; - if (LLHandlerUtil::canSpawnIMSession(notification)) - { - const std::string name = LLHandlerUtil::getSubstitutionName(notification); - - LLUUID from_id = notification->getPayload()["from_id"]; - - session_id = LLHandlerUtil::spawnIMSession(name, from_id); - } - - bool show_toast = LLHandlerUtil::canSpawnToast(notification); - bool add_notid_to_im = LLHandlerUtil::canAddNotifPanelToIM(notification); - if (add_notid_to_im) - { - LLHandlerUtil::addNotifPanelToIM(notification); - } - - if (notification->getPayload().has("SUPPRESS_TOAST") - && notification->getPayload()["SUPPRESS_TOAST"]) - { - LLNotificationsUtil::cancel(notification); - } - else if(show_toast) - { - LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification); - // don't close notification on panel destroy since it will be used by IM floater - notify_box->setCloseNotificationOnDestroy(!add_notid_to_im); - LLToast::Params p; - p.notif_id = notification->getID(); - p.notification = notification; - p.panel = notify_box; - p.on_delete_toast = boost::bind(&LLOfferHandler::onDeleteToast, this, _1); - // we not save offer notifications to the syswell floater that should be added to the IM floater - p.can_be_stored = !add_notid_to_im; - - LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); - if(channel) - channel->addToast(p); - - // if we not add notification to IM - add it to notification well - if (!add_notid_to_im) - { - // send a signal to the counter manager - mNewNotificationSignal(); - } - } - - if (LLHandlerUtil::canLogToIM(notification)) - { - // log only to file if notif panel can be embedded to IM and IM is opened - if (add_notid_to_im && LLHandlerUtil::isIMFloaterOpened(notification)) - { - LLHandlerUtil::logToIMP2P(notification, true); - } - else - { - LLHandlerUtil::logToIMP2P(notification); - } - } + LLNotificationsUtil::cancel(notification); } - } - else if (notify["sigtype"].asString() == "delete") - { - if( notification->getPayload().has("give_inventory_notification") - && !notification->getPayload()["give_inventory_notification"] ) + else if(!notification->canLogToIM() || !LLHandlerUtil::isIMFloaterOpened(notification)) { - // Remove original inventory offer script floater - LLScriptFloaterManager::instance().onRemoveNotification(notification->getID()); + LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification); + LLToast::Params p; + p.notif_id = notification->getID(); + p.notification = notification; + p.panel = notify_box; + // we not save offer notifications to the syswell floater that should be added to the IM floater + p.can_be_stored = !add_notif_to_im; + p.force_show = notification->getOfferFromAgent(); + + LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get()); + if(channel) + channel->addToast(p); + } - else + + if (notification->canLogToIM()) { - if (LLHandlerUtil::canAddNotifPanelToIM(notification) - && !LLHandlerUtil::isIMFloaterOpened(notification)) - { - LLHandlerUtil::decIMMesageCounter(notification); - } - mChannel->killToastByNotificationID(notification->getID()); + // log only to file if notif panel can be embedded to IM and IM is opened + bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification); + LLHandlerUtil::logToIMP2P(notification, file_only); } } return false; } -//-------------------------------------------------------------------------- - -void LLOfferHandler::onDeleteToast(LLToast* toast) +/*virtual*/ void LLOfferHandler::onChange(LLNotificationPtr p) { - if (!LLHandlerUtil::canAddNotifPanelToIM(toast->getNotification())) + LLToastNotifyPanel* panelp = LLToastNotifyPanel::getInstance(p->getID()); + if (panelp) { - // send a signal to the counter manager - mDelNotificationSignal(); + // + // HACK: if we're dealing with a notification embedded in IM, update it + // otherwise remove its toast + // + if (dynamic_cast<LLIMToastNotifyPanel*>(panelp)) + { + panelp->updateNotification(); + } + else + { + // if notification has changed, hide it + mChannel.get()->removeToastByNotificationID(p->getID()); + } } - - // send a signal to a listener to let him perform some action - // in this case listener is a SysWellWindow and it will remove a corresponding item from its list - mNotificationIDSignal(toast->getNotificationID()); } -//-------------------------------------------------------------------------- -void LLOfferHandler::onRejectToast(LLUUID& id) -{ - LLNotificationPtr notification = LLNotifications::instance().find(id); - if (notification - && LLNotificationManager::getInstance()->getHandlerForNotification( - notification->getType()) == this - // don't delete notification since it may be used by IM floater - && !LLHandlerUtil::canAddNotifPanelToIM(notification)) +/*virtual*/ void LLOfferHandler::onDelete(LLNotificationPtr notification) +{ + if( notification->getPayload().has("give_inventory_notification") + && !notification->getPayload()["give_inventory_notification"] ) { - LLNotifications::instance().cancel(notification); + // Remove original inventory offer script floater + LLScriptFloaterManager::instance().onRemoveNotification(notification->getID()); + } + else + { + if (notification->canLogToIM() + && notification->hasFormElements() + && !LLHandlerUtil::isIMFloaterOpened(notification)) + { + LLHandlerUtil::decIMMesageCounter(notification); + } + mChannel.get()->removeToastByNotificationID(notification->getID()); } } + diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp index bbb4d03768..08c98e4f28 100644 --- a/indra/newview/llnotificationscripthandler.cpp +++ b/indra/newview/llnotificationscripthandler.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" // must be first include +#include "llagent.h" #include "llnotificationhandler.h" #include "lltoastnotifypanel.h" #include "llviewercontrol.h" @@ -37,23 +38,17 @@ using namespace LLNotificationsUI; -static const std::string SCRIPT_DIALOG ("ScriptDialog"); -static const std::string SCRIPT_DIALOG_GROUP ("ScriptDialogGroup"); -static const std::string SCRIPT_LOAD_URL ("LoadWebPage"); - //-------------------------------------------------------------------------- -LLScriptHandler::LLScriptHandler(e_notification_type type, const LLSD& id) +LLScriptHandler::LLScriptHandler() +: LLSystemNotificationHandler("Notifications", "notify") { - mType = type; - // Getting a Channel for our notifications - mChannel = LLChannelManager::getInstance()->createNotificationChannel(); - mChannel->setControlHovering(true); - - LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); + LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel(); if(channel) - channel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1)); - + { + channel->setControlHovering(true); + mChannel = channel->getHandle(); + } } //-------------------------------------------------------------------------- @@ -66,108 +61,87 @@ void LLScriptHandler::initChannel() { S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); - mChannel->init(channel_right_bound - channel_width, channel_right_bound); + mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound); } //-------------------------------------------------------------------------- -bool LLScriptHandler::processNotification(const LLSD& notify) +bool LLScriptHandler::processNotification(const LLNotificationPtr& notification) { - if(!mChannel) + if(mChannel.isDead()) { return false; } - LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - - if(!notification) - return false; - // arrange a channel on a screen - if(!mChannel->getVisible()) + if(!mChannel.get()->getVisible()) { initChannel(); } - if(notify["sigtype"].asString() == "add") + if (notification->canLogToIM()) { - if (LLHandlerUtil::canLogToIM(notification)) - { - LLHandlerUtil::logToIMP2P(notification); - } + LLHandlerUtil::logToIMP2P(notification); + } - if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName()) - { - LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID()); + if(notification->hasFormElements() && !notification->canShowToast()) + { + LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID()); + } + else + { + LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification); + + LLToast::Params p; + p.notif_id = notification->getID(); + p.notification = notification; + p.panel = notify_box; + p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1); + if(gAgent.isDoNotDisturb()) + { + p.force_show = notification->getName() == "SystemMessage" + || notification->getName() == "GodMessage" + || notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH; } - else + + LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get()); + if(channel) { - LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification); - - LLToast::Params p; - p.notif_id = notification->getID(); - p.notification = notification; - p.panel = notify_box; - p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1); - - LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); - if(channel) - { - channel->addToast(p); - } - - // send a signal to the counter manager - mNewNotificationSignal(); + channel->addToast(p); } } - else if (notify["sigtype"].asString() == "delete") + + return false; +} + + +void LLScriptHandler::onDelete( LLNotificationPtr notification ) { - if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName()) + if(notification->hasFormElements() && !notification->canShowToast()) { LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID()); } else { - mChannel->killToastByNotificationID(notification->getID()); + mChannel.get()->removeToastByNotificationID(notification->getID()); } } - return false; -} + //-------------------------------------------------------------------------- void LLScriptHandler::onDeleteToast(LLToast* toast) { - // send a signal to the counter manager - mDelNotificationSignal(); - // send a signal to a listener to let him perform some action // in this case listener is a SysWellWindow and it will remove a corresponding item from its list - mNotificationIDSignal(toast->getNotificationID()); - LLNotificationPtr notification = LLNotifications::getInstance()->find(toast->getNotificationID()); - if( notification && - (SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName()) ) + if( notification && notification->hasFormElements() && !notification->canShowToast()) { LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID()); } -} - -//-------------------------------------------------------------------------- -void LLScriptHandler::onRejectToast(LLUUID& id) -{ - LLNotificationPtr notification = LLNotifications::instance().find(id); - if (notification - && LLNotificationManager::getInstance()->getHandlerForNotification( - notification->getType()) == this) - { - LLNotifications::instance().cancel(notification); - } } -//-------------------------------------------------------------------------- - diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp index fb1adc7ddf..b6184f09bf 100644 --- a/indra/newview/llnotificationstorage.cpp +++ b/indra/newview/llnotificationstorage.cpp @@ -25,197 +25,111 @@ */ #include "llviewerprecompiledheaders.h" // must be first include + #include "llnotificationstorage.h" -#include "llxmlnode.h" // for linux compilers +#include <string> +#include <map> -#include "llchannelmanager.h" -#include "llscreenchannel.h" -#include "llscriptfloater.h" +#include "llerror.h" +#include "llfile.h" +#include "llnotifications.h" +#include "llpointer.h" +#include "llsd.h" #include "llsdserialize.h" -#include "llviewermessage.h" +#include "llsingleton.h" +#include "llregistry.h" +#include "llviewermessage.h" -////////////////////////////////////////////////////////////////////////// +typedef boost::function<LLNotificationResponderInterface * (const LLSD& pParams)> responder_constructor_t; -class LLResponderRegistry +class LLResponderRegistry : public LLRegistrySingleton<std::string, responder_constructor_t, LLResponderRegistry> { -public: - - static void registerResponders(); - - static LLNotificationResponderInterface* createResponder(const std::string& notification_name, const LLSD& params); - -private: - - template<typename RESPONDER_TYPE> - static LLNotificationResponderInterface* create(const LLSD& params) - { - RESPONDER_TYPE* responder = new RESPONDER_TYPE(); - responder->fromLLSD(params); - return responder; - } - - typedef boost::function<LLNotificationResponderInterface* (const LLSD& params)> responder_constructor_t; + public: + template<typename RESPONDER_TYPE> static LLNotificationResponderInterface * create(const LLSD& pParams); + LLNotificationResponderInterface * createResponder(const std::string& pNotificationName, const LLSD& pParams); +}; - static void add(const std::string& notification_name, const responder_constructor_t& ctr); +template<typename RESPONDER_TYPE> LLNotificationResponderInterface * LLResponderRegistry::create(const LLSD& pParams) +{ + RESPONDER_TYPE* responder = new RESPONDER_TYPE(); + responder->fromLLSD(pParams); + return responder; +} -private: - typedef std::map<std::string, responder_constructor_t> build_map_t; +LLNotificationResponderInterface * LLResponderRegistry::createResponder(const std::string& pNotificationName, const LLSD& pParams) +{ + responder_constructor_t * factoryFunc = (LLResponderRegistry::getValue(pNotificationName)); + + if(factoryFunc) + { + return (*factoryFunc)(pParams); + } + + return NULL; +} - static build_map_t sBuildMap; -}; +LLResponderRegistry::StaticRegistrar sRegisterObjectGiveItem("ObjectGiveItem", &LLResponderRegistry::create<LLOfferInfo>); +LLResponderRegistry::StaticRegistrar sRegisterUserGiveItem("UserGiveItem", &LLResponderRegistry::create<LLOfferInfo>); +LLResponderRegistry::StaticRegistrar sRegisterOfferInfo("offer_info", &LLResponderRegistry::create<LLOfferInfo>); -////////////////////////////////////////////////////////////////////////// -LLPersistentNotificationStorage::LLPersistentNotificationStorage() +LLNotificationStorage::LLNotificationStorage(std::string pFileName) + : mFileName(pFileName) { - mFileName = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" ); } -bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload) +LLNotificationStorage::~LLNotificationStorage() { - // we ignore "load" messages, but rewrite the persistence file on any other - const std::string sigtype = payload["sigtype"].asString(); - if ("load" != sigtype) - { - saveNotifications(); - } - return false; } -void LLPersistentNotificationStorage::saveNotifications() +bool LLNotificationStorage::writeNotifications(const LLSD& pNotificationData) const { - // TODO - think about save optimization. - llofstream notify_file(mFileName.c_str()); - if (!notify_file.is_open()) + llofstream notifyFile(mFileName.c_str()); + bool didFileOpen = notifyFile.is_open(); + + if (!didFileOpen) { - llwarns << "Failed to open " << mFileName << llendl; - return; + LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL; } - - LLSD output; - LLSD& data = output["data"]; - - LLNotificationChannelPtr history_channel = LLNotifications::instance().getChannel("Persistent"); - LLNotificationSet::iterator it = history_channel->begin(); - - for ( ; history_channel->end() != it; ++it) + else { - LLNotificationPtr notification = *it; - - // After a notification was placed in Persist channel, it can become - // responded, expired or canceled - in this case we are should not save it - if(notification->isRespondedTo() || notification->isCancelled() - || notification->isExpired()) - { - continue; - } - - data.append(notification->asLLSD()); + LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter(); + formatter->format(pNotificationData, notifyFile, LLSDFormatter::OPTIONS_PRETTY); } - LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter(); - formatter->format(output, notify_file, LLSDFormatter::OPTIONS_PRETTY); + return didFileOpen; } -void LLPersistentNotificationStorage::loadNotifications() +bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const { - LLResponderRegistry::registerResponders(); + bool didFileRead; - LLNotifications::instance().getChannel("Persistent")-> - connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1)); + pNotificationData.clear(); - llifstream notify_file(mFileName.c_str()); - if (!notify_file.is_open()) + llifstream notifyFile(mFileName.c_str()); + didFileRead = notifyFile.is_open(); + if (!didFileRead) { - llwarns << "Failed to open " << mFileName << llendl; - return; + LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL; } - - LLSD input; - LLPointer<LLSDParser> parser = new LLSDXMLParser(); - if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0) + else { - llwarns << "Failed to parse open notifications" << llendl; - return; - } - - if (input.isUndefined()) - { - return; - } - - LLSD& data = input["data"]; - if (data.isUndefined()) - { - return; - } - - using namespace LLNotificationsUI; - LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()-> - findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); - - LLNotifications& instance = LLNotifications::instance(); - - for (LLSD::array_const_iterator notification_it = data.beginArray(); - notification_it != data.endArray(); - ++notification_it) - { - LLSD notification_params = *notification_it; - LLNotificationPtr notification(new LLNotification(notification_params)); - - LLNotificationResponderPtr responder(LLResponderRegistry:: - createResponder(notification_params["name"], notification_params["responder"])); - notification->setResponseFunctor(responder); - - instance.add(notification); - - // hide script floaters so they don't confuse the user and don't overlap startup toast - LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false); - - if(notification_channel) + LLPointer<LLSDParser> parser = new LLSDXMLParser(); + didFileRead = (parser->parse(notifyFile, pNotificationData, LLSDSerialize::SIZE_UNLIMITED) >= 0); + if (!didFileRead) { - // hide saved toasts so they don't confuse the user - notification_channel->hideToast(notification->getID()); + LL_WARNS("LLNotificationStorage") << "Failed to parse open notifications from file '" << mFileName + << "'" << LL_ENDL; } } -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -LLResponderRegistry::build_map_t LLResponderRegistry::sBuildMap; - -void LLResponderRegistry::registerResponders() -{ - sBuildMap.clear(); - - add("ObjectGiveItem", &create<LLOfferInfo>); - add("UserGiveItem", &create<LLOfferInfo>); + return didFileRead; } -LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& notification_name, const LLSD& params) +LLNotificationResponderInterface * LLNotificationStorage::createResponder(const std::string& pNotificationName, const LLSD& pParams) const { - build_map_t::const_iterator it = sBuildMap.find(notification_name); - if(sBuildMap.end() == it) - { - return NULL; - } - responder_constructor_t ctr = it->second; - return ctr(params); + return LLResponderRegistry::getInstance()->createResponder(pNotificationName, pParams); } - -void LLResponderRegistry::add(const std::string& notification_name, const responder_constructor_t& ctr) -{ - if(sBuildMap.find(notification_name) != sBuildMap.end()) - { - llwarns << "Responder is already registered : " << notification_name << llendl; - llassert(!"Responder already registered"); - } - sBuildMap[notification_name] = ctr; -} - -// EOF diff --git a/indra/newview/llnotificationstorage.h b/indra/newview/llnotificationstorage.h index 8635c797c0..7aabf7d09e 100644 --- a/indra/newview/llnotificationstorage.h +++ b/indra/newview/llnotificationstorage.h @@ -27,32 +27,27 @@ #ifndef LL_NOTIFICATIONSTORAGE_H #define LL_NOTIFICATIONSTORAGE_H -#include "llnotifications.h" - -// Class that saves not responded(unread) notifications. -// Unread notifications are saved in open_notifications.xml in SL account folder -// -// Notifications that should be saved(if unread) are marked with persist="true" in notifications.xml -// Notifications using functor responders are saved automatically (see llviewermessage.cpp -// lure_callback_reg for example). -// Notifications using object responders(LLOfferInfo) need additional tuning. Responder object should -// be a) serializable(implement LLNotificationResponderInterface), -// b) registered with LLResponderRegistry (found in llnotificationstorage.cpp). -class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage> -{ - LOG_CLASS(LLPersistentNotificationStorage); -public: +#include <string> - LLPersistentNotificationStorage(); +#include "llerror.h" - void saveNotifications(); +class LLNotificationResponderInterface; +class LLSD; - void loadNotifications(); +class LLNotificationStorage +{ + LOG_CLASS(LLNotificationStorage); +public: + LLNotificationStorage(std::string pFileName); + ~LLNotificationStorage(); -private: +protected: + bool writeNotifications(const LLSD& pNotificationData) const; + bool readNotifications(LLSD& pNotificationData) const; - bool onPersistentChannelChanged(const LLSD& payload); + LLNotificationResponderInterface* createResponder(const std::string& pNotificationName, const LLSD& pParams) const; +private: std::string mFileName; }; diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index aa009a76fa..a85335f1ba 100644 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -28,8 +28,8 @@ #include "llviewerprecompiledheaders.h" // must be first include #include "llfloaterreg.h" -#include "llnearbychat.h" -#include "llnearbychatbar.h" +#include "llfloaterimnearbychat.h" +#include "llfloaterimnearbychat.h" #include "llnotificationhandler.h" #include "llnotifications.h" #include "lltoastnotifypanel.h" @@ -41,16 +41,15 @@ using namespace LLNotificationsUI; //-------------------------------------------------------------------------- -LLTipHandler::LLTipHandler(e_notification_type type, const LLSD& id) +LLTipHandler::LLTipHandler() +: LLSystemNotificationHandler("NotificationTips", "notifytip") { - mType = type; - // Getting a Channel for our notifications - mChannel = LLChannelManager::getInstance()->createNotificationChannel(); - - LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); + LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel(); if(channel) - channel->setOnRejectToastCallback(boost::bind(&LLTipHandler::onRejectToast, this, _1)); + { + mChannel = channel->getHandle(); + } } //-------------------------------------------------------------------------- @@ -63,106 +62,71 @@ void LLTipHandler::initChannel() { S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); - mChannel->init(channel_right_bound - channel_width, channel_right_bound); + mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound); } //-------------------------------------------------------------------------- -bool LLTipHandler::processNotification(const LLSD& notify) +bool LLTipHandler::processNotification(const LLNotificationPtr& notification) { - if(!mChannel) + if(mChannel.isDead()) { return false; } - LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - - if(!notification) - return false; - // arrange a channel on a screen - if(!mChannel->getVisible()) + if(!mChannel.get()->getVisible()) { initChannel(); } - if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") - { // archive message in nearby chat - if (LLHandlerUtil::canLogToNearbyChat(notification)) - { - LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM); - - // don't show toast if Nearby Chat is opened - LLNearbyChat* nearby_chat = LLNearbyChat::getInstance(); - LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance(); - if (nearby_chat_bar->getVisible() && nearby_chat->getVisible()) - { - return false; - } - } - - std::string session_name = notification->getPayload()["SESSION_NAME"]; - const std::string name = notification->getSubstitutions()["NAME"]; - if (session_name.empty()) - { - session_name = name; - } - LLUUID from_id = notification->getPayload()["from_id"]; - if (LLHandlerUtil::canLogToIM(notification)) - { - LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, session_name, name, - notification->getMessage(), from_id, from_id); - } - - if (LLHandlerUtil::canSpawnIMSession(notification)) - { - LLHandlerUtil::spawnIMSession(name, from_id); - } + if (notification->canLogToChat()) + { + LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM); - // don't spawn toast for inventory accepted/declined offers if respective IM window is open (EXT-5909) - if (!LLHandlerUtil::canSpawnToast(notification)) + // don't show toast if Nearby Chat is opened + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + if (nearby_chat->isChatVisible()) { return false; } + } - LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification); - - LLToast::Params p; - p.notif_id = notification->getID(); - p.notification = notification; - p.lifetime_secs = gSavedSettings.getS32("NotificationTipToastLifeTime"); - p.panel = notify_box; - p.is_tip = true; - p.can_be_stored = false; - - removeExclusiveNotifications(notification); - - LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); - if(channel) - channel->addToast(p); + std::string session_name = notification->getPayload()["SESSION_NAME"]; + const std::string name = notification->getSubstitutions()["NAME"]; + if (session_name.empty()) + { + session_name = name; } - else if (notify["sigtype"].asString() == "delete") + LLUUID from_id = notification->getPayload()["from_id"]; + if (notification->canLogToIM()) { - mChannel->killToastByNotificationID(notification->getID()); + LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, session_name, name, + notification->getMessage(), from_id, from_id); } - return false; -} - -//-------------------------------------------------------------------------- -void LLTipHandler::onDeleteToast(LLToast* toast) -{ -} - -//-------------------------------------------------------------------------- -void LLTipHandler::onRejectToast(const LLUUID& id) -{ - LLNotificationPtr notification = LLNotifications::instance().find(id); + if (notification->canLogToIM() && notification->hasFormElements()) + { + LLHandlerUtil::spawnIMSession(name, from_id); + } - if (notification - && LLNotificationManager::getInstance()->getHandlerForNotification( - notification->getType()) == this) + if (notification->canLogToIM() && LLHandlerUtil::isIMFloaterOpened(notification)) { - LLNotifications::instance().cancel(notification); + return false; } + + LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification); + + LLToast::Params p; + p.notif_id = notification->getID(); + p.notification = notification; + p.lifetime_secs = gSavedSettings.getS32("NotificationTipToastLifeTime"); + p.panel = notify_box; + p.is_tip = true; + p.can_be_stored = false; + + LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get()); + if(channel) + channel->addToast(p); + return false; } diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 1dc4d796ab..c15b6bd0d3 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -117,6 +117,8 @@ public: registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenu::onRename, this)); registrar.add("Gear.Delete", boost::bind(&LLOutfitsList::removeSelected, mOutfitList)); registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2)); + registrar.add("Gear.Collapse", boost::bind(&LLOutfitsList::collapse_all_folders, mOutfitList)); + registrar.add("Gear.Expand", boost::bind(&LLOutfitsList::expand_all_folders, mOutfitList)); registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenu::onAdd, this)); @@ -640,7 +642,7 @@ void LLOutfitsList::onOutfitsRemovalConfirmation(const LLSD& notification, const if (mSelectedOutfitUUID.notNull()) { - remove_category(&gInventory, mSelectedOutfitUUID); + gInventory.removeCategory(mSelectedOutfitUUID); } } @@ -743,6 +745,34 @@ void LLOutfitsList::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const } } +void LLOutfitsList::collapse_all_folders() +{ + for (outfits_map_t::iterator iter = mOutfitsMap.begin(); + iter != mOutfitsMap.end(); + ++iter) + { + LLAccordionCtrlTab* tab = iter->second; + if(tab && tab->isExpanded()) + { + tab->changeOpenClose(true); + } + } +} + +void LLOutfitsList::expand_all_folders() +{ + for (outfits_map_t::iterator iter = mOutfitsMap.begin(); + iter != mOutfitsMap.end(); + ++iter) + { + LLAccordionCtrlTab* tab = iter->second; + if(tab && !tab->isExpanded()) + { + tab->changeOpenClose(false); + } + } +} + boost::signals2::connection LLOutfitsList::setSelectionChangeCallback(selection_change_callback_t cb) { return mSelectionChangeSignal.connect(cb); diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index a0598737f1..2e3fb3f488 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -108,6 +108,16 @@ public: */ bool hasItemSelected(); + /** + Collapses all outfit accordions. + */ + void collapse_all_folders(); + /** + Expands all outfit accordions. + */ + void expand_all_folders(); + + private: void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index 85626d8783..6c26073d5b 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -28,6 +28,7 @@ #include "lloutputmonitorctrl.h" // library includes +#include "llfloaterreg.h" #include "llui.h" // viewer includes @@ -72,8 +73,8 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p) mAutoUpdate(p.auto_update), mSpeakerId(p.speaker_id), mIsAgentControl(false), - mIsSwitchDirty(false), - mShouldSwitchOn(false) + mIndicatorToggled(false), + mShowParticipantsSpeaking(false) { //static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange); //static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red); @@ -114,26 +115,6 @@ void LLOutputMonitorCtrl::setPower(F32 val) void LLOutputMonitorCtrl::draw() { - // see also switchIndicator() - if (mIsSwitchDirty) - { - mIsSwitchDirty = false; - if (mShouldSwitchOn) - { - // just notify parent visibility may have changed - notifyParentVisibilityChanged(); - } - else - { - // make itself invisible and notify parent about this - setVisible(FALSE); - notifyParentVisibilityChanged(); - - // no needs to render for invisible element - return; - } - } - // Copied from llmediaremotectrl.cpp // *TODO: Give the LLOutputMonitorCtrl an agent-id to monitor, then // call directly into LLVoiceClient::getInstance() to ask if that agent-id is muted, is @@ -156,6 +137,24 @@ void LLOutputMonitorCtrl::draw() } } + if ((mPower == 0.f && !mIsTalking) && mShowParticipantsSpeaking) + { + std::set<LLUUID> participant_uuids; + LLVoiceClient::instance().getParticipantList(participant_uuids); + std::set<LLUUID>::const_iterator part_it = participant_uuids.begin(); + + F32 power = 0; + for (; part_it != participant_uuids.end(); ++part_it) + { + power = LLVoiceClient::instance().getCurrentPower(*part_it); + if (power) + { + mPower = power; + break; + } + } + } + LLPointer<LLUIImage> icon; if (mIsMuted) { @@ -241,14 +240,34 @@ void LLOutputMonitorCtrl::draw() gl_rect_2d(0, monh, monw, 0, sColorBound, FALSE); } -void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/) +// virtual +BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask) +{ + if (mSpeakerId != gAgentID && !mShowParticipantsSpeaking) + { + LLFloaterReg::showInstance("floater_voice_volume", LLSD().with("avatar_id", mSpeakerId)); + } + else if(mShowParticipantsSpeaking) + { + LLFloaterReg::showInstance("chat_voice", LLSD()); + } + + return TRUE; +} + +void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/, bool show_other_participants_speaking /* = false */) { if (speaker_id.isNull() && mSpeakerId.notNull()) { LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this); + switchIndicator(false); + mSpeakerId = speaker_id; } - if (speaker_id.isNull() || speaker_id == mSpeakerId) return; + if (speaker_id.isNull() || (speaker_id == mSpeakerId)) + { + return; + } if (mSpeakerId.notNull()) { @@ -256,6 +275,7 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this); } + mShowParticipantsSpeaking = show_other_participants_speaking; mSpeakerId = speaker_id; LLSpeakingIndicatorManager::registerSpeakingIndicator(mSpeakerId, this, session_id); @@ -264,12 +284,12 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s { if (speaker_id == gAgentID) { - setIsMuted(false); + mIsMuted = false; } else { // check only blocking on voice. EXT-3542 - setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat)); + mIsMuted = LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat); LLMuteList::getInstance()->addObserver(this); } } @@ -278,32 +298,34 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s void LLOutputMonitorCtrl::onChange() { // check only blocking on voice. EXT-3542 - setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat)); + mIsMuted = LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat); } // virtual void LLOutputMonitorCtrl::switchIndicator(bool switch_on) { - // ensure indicator is visible in case it is not in visible chain - // to be called when parent became visible next time to notify parent that visibility is changed. - setVisible(TRUE); - - // if parent is in visible chain apply switch_on state and notify it immediately - if (getParent() && getParent()->isInVisibleChain()) - { - LL_DEBUGS("SpeakingIndicator") << "Indicator is in visible chain, notifying parent: " << mSpeakerId << LL_ENDL; - setVisible((BOOL)switch_on); - notifyParentVisibilityChanged(); - } - // otherwise remember necessary state and mark itself as dirty. - // State will be applied in next draw when parents chain becomes visible. - else - { - LL_DEBUGS("SpeakingIndicator") << "Indicator is not in visible chain, parent won't be notified: " << mSpeakerId << LL_ENDL; - mIsSwitchDirty = true; - mShouldSwitchOn = switch_on; - } + if(getVisible() != (BOOL)switch_on) + { + setVisible(switch_on); + + //Let parent adjust positioning of icons adjacent to speaker indicator + //(when speaker indicator hidden, adjacent icons move to right and when speaker + //indicator visible, adjacent icons move to the left) + if (getParent() && getParent()->isInVisibleChain()) + { + notifyParentVisibilityChanged(); + //Ignore toggled state in case it was set when parent visibility was hidden + mIndicatorToggled = false; + } + else + { + //Makes sure to only adjust adjacent icons when parent becomes visible + //(!mIndicatorToggled ensures that changes of TFT and FTF are discarded, real state changes are TF or FT) + mIndicatorToggled = !mIndicatorToggled; + } + + } } ////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h index 2d23753d46..a346909027 100644 --- a/indra/newview/lloutputmonitorctrl.h +++ b/indra/newview/lloutputmonitorctrl.h @@ -28,10 +28,10 @@ #define LL_LLOUTPUTMONITORCTRL_H #include "v4color.h" -#include "llview.h" +#include "../llui/llview.h" #include "llmutelist.h" #include "llspeakingindicatormanager.h" -#include "lluiimage.h" +#include "../llui/lluiimage.h" class LLTextBox; class LLUICtrlFactory; @@ -68,19 +68,19 @@ public: // llview overrides virtual void draw(); + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); void setPower(F32 val); F32 getPower(F32 val) const { return mPower; } - bool getIsMuted() const { return mIsMuted; } - void setIsMuted(bool val) { mIsMuted = val; } - // For the current user, need to know the PTT state to show // correct button image. void setIsAgentControl(bool val) { mIsAgentControl = val; } void setIsTalking(bool val) { mIsTalking = val; } + void setShowParticipantsSpeaking(bool show) { mShowParticipantsSpeaking = show; } + /** * Sets avatar UUID to interact with voice channel. * @@ -89,7 +89,7 @@ public: * If this parameter is set registered indicator will be shown only in voice channel * which has the same session id (EXT-5562). */ - void setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id = LLUUID::null); + void setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id = LLUUID::null, bool show_other_participants_speaking = false); //called by mute list virtual void onChange(); @@ -105,6 +105,8 @@ public: * It will be applied in next draw and parent will be notified. */ virtual void switchIndicator(bool switch_on); + bool getIndicatorToggled() { return mIndicatorToggled;} + void setIndicatorToggled(bool value) { mIndicatorToggled = value;} private: @@ -131,6 +133,7 @@ private: bool mIsAgentControl; bool mIsMuted; bool mIsTalking; + bool mShowParticipantsSpeaking; LLPointer<LLUIImage> mImageMute; LLPointer<LLUIImage> mImageOff; LLPointer<LLUIImage> mImageOn; @@ -144,9 +147,7 @@ private: /** uuid of a speaker being monitored */ LLUUID mSpeakerId; - /** indicates if the instance is dirty and should notify parent */ - bool mIsSwitchDirty; - bool mShouldSwitchOn; + bool mIndicatorToggled; }; #endif diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp deleted file mode 100644 index c2bbec0470..0000000000 --- a/indra/newview/lloverlaybar.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/** - * @file lloverlaybar.cpp - * @brief LLOverlayBar class implementation - * - * $LicenseInfo:firstyear=2002&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$ - */ - -// Temporary buttons that appear at the bottom of the screen when you -// are in a mode. - -#include "llviewerprecompiledheaders.h" - -#include "lloverlaybar.h" - -#include "llaudioengine.h" -#include "llrender.h" -#include "llagent.h" -#include "llbutton.h" -#include "llfocusmgr.h" -#include "llimview.h" -#include "llmediaremotectrl.h" -#include "llparcel.h" -#include "lltextbox.h" -#include "llui.h" -#include "llviewercontrol.h" -#include "llviewertexturelist.h" -#include "llviewerjoystick.h" -#include "llviewermedia.h" -#include "llviewermenu.h" // handle_reset_view() -#include "llviewermedia.h" -#include "llviewerparcelmedia.h" -#include "llviewerparcelmgr.h" -#include "lluictrlfactory.h" -#include "llviewerwindow.h" -#include "llvoiceclient.h" -#include "llvoavatarself.h" -#include "llvoiceremotectrl.h" -#include "llmediactrl.h" -#include "llselectmgr.h" - -// -// Globals -// - -LLOverlayBar *gOverlayBar = NULL; - -extern S32 MENU_BAR_HEIGHT; - -// -// Functions -// - - - -void* LLOverlayBar::createMediaRemote(void* userdata) -{ - LLOverlayBar *self = (LLOverlayBar*)userdata; - self->mMediaRemote = new LLMediaRemoteCtrl (); - return self->mMediaRemote; -} - -void* LLOverlayBar::createVoiceRemote(void* userdata) -{ - LLOverlayBar *self = (LLOverlayBar*)userdata; - self->mVoiceRemote = new LLVoiceRemoteCtrl(); - return self->mVoiceRemote; -} - -LLOverlayBar::LLOverlayBar() - : LLPanel(), - mMediaRemote(NULL), - mVoiceRemote(NULL), - mMusicState(STOPPED) -{ - setMouseOpaque(FALSE); - setIsChrome(TRUE); - - mBuilt = false; - - mFactoryMap["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this); - mFactoryMap["voice_remote"] = LLCallbackMap(LLOverlayBar::createVoiceRemote, this); - - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_overlaybar.xml"); -} - -BOOL LLOverlayBar::postBuild() -{ - childSetAction("Set Not Busy",onClickSetNotBusy,this); - childSetAction("Mouselook",onClickMouselook,this); - childSetAction("Stand Up",onClickStandUp,this); - childSetAction("Flycam",onClickFlycam,this); - childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible")); - - mVoiceRemote->expandOrCollapse(); - mMediaRemote->expandOrCollapse(); - - setFocusRoot(TRUE); - mBuilt = true; - - layoutButtons(); - return TRUE; -} - -LLOverlayBar::~LLOverlayBar() -{ - // LLView destructor cleans up children -} - -// virtual -void LLOverlayBar::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - LLView::reshape(width, height, called_from_parent); - - if (mBuilt) - { - layoutButtons(); - } -} - -void LLOverlayBar::layoutButtons() -{ - LLView* state_buttons_panel = getChildView("state_buttons"); - - if (state_buttons_panel->getVisible()) - { - LLViewQuery query; - LLWidgetTypeFilter<LLButton> widget_filter; - query.addPreFilter(LLEnabledFilter::getInstance()); - query.addPreFilter(&widget_filter); - - child_list_t button_list = query(state_buttons_panel); - - const S32 MAX_BAR_WIDTH = 600; - S32 bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH); - - // calculate button widths - const S32 MAX_BUTTON_WIDTH = 150; - const S32 STATUS_BAR_PAD = 10; - S32 segment_width = llclamp(lltrunc((F32)(bar_width) / (F32)button_list.size()), 0, MAX_BUTTON_WIDTH); - S32 btn_width = segment_width - STATUS_BAR_PAD; - - // Evenly space all buttons, starting from left - S32 left = 0; - S32 bottom = 1; - - for (child_list_reverse_iter_t child_iter = button_list.rbegin(); - child_iter != button_list.rend(); ++child_iter) - { - LLView *view = *child_iter; - LLRect r = view->getRect(); - r.setOriginAndSize(left, bottom, btn_width, r.getHeight()); - view->setRect(r); - left += segment_width; - } - } -} - -// Per-frame updates of visibility -void LLOverlayBar::refresh() -{ - BOOL buttons_changed = FALSE; - - BOOL im_received = gIMMgr->getIMReceived(); - LLButton* button = getChild<LLButton>("IM Received"); - if (button && button->getVisible() != im_received) - { - button->setVisible(im_received); - sendChildToFront(button); - moveChildToBackOfTabGroup(button); - buttons_changed = TRUE; - } - - BOOL busy = gAgent.getBusy(); - button = getChild<LLButton>("Set Not Busy"); - if (button && button->getVisible() != busy) - { - button->setVisible(busy); - sendChildToFront(button); - moveChildToBackOfTabGroup(button); - buttons_changed = TRUE; - } - - BOOL flycam = LLViewerJoystick::getInstance()->getOverrideCamera(); - button = getChild<LLButton>("Flycam"); - if (button && button->getVisible() != flycam) - { - button->setVisible(flycam); - sendChildToFront(button); - moveChildToBackOfTabGroup(button); - buttons_changed = TRUE; - } - - BOOL mouselook_grabbed; - mouselook_grabbed = gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_DOWN_INDEX) - || gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX); - button = getChild<LLButton>("Mouselook"); - - if (button && button->getVisible() != mouselook_grabbed) - { - button->setVisible(mouselook_grabbed); - sendChildToFront(button); - moveChildToBackOfTabGroup(button); - buttons_changed = TRUE; - } - - BOOL sitting = FALSE; - if (gAgent.getAvatarObject()) - { - sitting = gAgent.getAvatarObject()->isSitting(); - } - button = getChild<LLButton>("Stand Up"); - - if (button && button->getVisible() != sitting) - { - button->setVisible(sitting); - sendChildToFront(button); - moveChildToBackOfTabGroup(button); - buttons_changed = TRUE; - } - - - moveChildToBackOfTabGroup(mMediaRemote); - moveChildToBackOfTabGroup(mVoiceRemote); - - // turn off the whole bar in mouselook - if (gAgent.cameraMouselook()) - { - childSetVisible("media_remote_container", FALSE); - childSetVisible("voice_remote_container", FALSE); - childSetVisible("state_buttons", FALSE); - } - else - { - // update "remotes" - childSetVisible("media_remote_container", TRUE); - childSetVisible("voice_remote_container", LLVoiceClient::getInstance()->voiceEnabled()); - childSetVisible("state_buttons", TRUE); - } - - // always let user toggle into and out of chatbar - childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible")); - - if (buttons_changed) - { - layoutButtons(); - } -} - -//----------------------------------------------------------------------- -// Static functions -//----------------------------------------------------------------------- - -// static -void LLOverlayBar::onClickSetNotBusy(void*) -{ - gAgent.clearBusy(); -} - - -// static -void LLOverlayBar::onClickFlycam(void*) -{ - LLViewerJoystick::getInstance()->toggleFlycam(); -} - -// static -void LLOverlayBar::onClickResetView(void* data) -{ - handle_reset_view(); -} - -//static -void LLOverlayBar::onClickMouselook(void*) -{ - gAgent.changeCameraToMouselook(); -} - -//static -void LLOverlayBar::onClickStandUp(void*) -{ - LLSelectMgr::getInstance()->deselectAllForStandingUp(); - gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); -} - -//////////////////////////////////////////////////////////////////////////////// -// static media helpers -// *TODO: Move this into an audio manager abstraction -//static -void LLOverlayBar::mediaStop(void*) -{ - if (!gOverlayBar) - { - // return; - } - LLViewerParcelMedia::stop(); -} -//static -void LLOverlayBar::toggleMediaPlay(void*) -{ - if (!gOverlayBar) - { - // return; - } - - - if (LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PAUSED) - { - LLViewerParcelMedia::start(); - } - else if(LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PLAYING) - { - LLViewerParcelMedia::pause(); - } - else - { - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if (parcel) - { - LLViewerParcelMedia::play(parcel); - } - } -} - -//static -void LLOverlayBar::toggleMusicPlay(void*) -{ - if (gAudiop->isInternetStreamPlaying() != 1) - { - if (gAudiop) - { - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if ( parcel ) - { - // this doesn't work properly when crossing parcel boundaries - even when the - // stream is stopped, it doesn't return the right thing - commenting out for now. - // if ( gAudiop->isInternetStreamPlaying() == 0 ) - { - gAudiop->startInternetStream(parcel->getMusicURL()); - } - } - } - } - //else - //{ - // gOverlayBar->mMusicState = PAUSED; // desired state - // if (gAudiop) - // { - // gAudiop->pauseInternetStream(1); - // } - //} - else - { - if (gAudiop) - { - gAudiop->stopInternetStream(); - } - } -} - diff --git a/indra/newview/lloverlaybar.h b/indra/newview/lloverlaybar.h deleted file mode 100644 index b36f5ebb73..0000000000 --- a/indra/newview/lloverlaybar.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @file lloverlaybar.h - * @brief LLOverlayBar class definition - * - * $LicenseInfo:firstyear=2002&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_LLOVERLAYBAR_H -#define LL_LLOVERLAYBAR_H - -#include "llpanel.h" - -// "Constants" loaded from settings.xml at start time -extern S32 STATUS_BAR_HEIGHT; - -class LLButton; -class LLLineEditor; -class LLMediaRemoteCtrl; -class LLMessageSystem; -class LLTextBox; -class LLTextEditor; -class LLUICtrl; -class LLUUID; -class LLFrameTimer; -class LLStatGraph; -class LLSlider; -class LLVoiceRemoteCtrl; - -class LLOverlayBar -: public LLPanel -{ -public: - LLOverlayBar(); - ~LLOverlayBar(); - - /*virtual*/ void refresh(); - /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); - /*virtual*/ BOOL postBuild(); - - void layoutButtons(); - - // helpers for returning desired state - BOOL musicPlaying() { return mMusicState == PLAYING; } - - static void onClickSetNotBusy(void* data); - static void onClickMouselook(void* data); - static void onClickStandUp(void* data); - static void onClickResetView(void* data); - static void onClickFlycam(void* data); - - //static media helper functions - static void toggleMediaPlay(void*); - static void toggleMusicPlay(void*); - static void musicPause(void*); - static void musicStop(void*); - static void mediaStop(void*); - - static void toggleAudioVolumeFloater(void*); - -protected: - static void* createMediaRemote(void* userdata); - static void* createVoiceRemote(void* userdata); - - void enableMediaButtons(); - -protected: - LLMediaRemoteCtrl* mMediaRemote; - LLVoiceRemoteCtrl* mVoiceRemote; - bool mBuilt; // dialog constructed yet? - enum { STOPPED=0, PLAYING=1, PAUSED=2 }; - S32 mMusicState; -}; - -extern LLOverlayBar* gOverlayBar; - -#endif diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 988e801b61..679b1bdcda 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -120,269 +120,6 @@ BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, static LLDefaultChildRegistry::Register<LLDropTarget> r("drop_target"); -static LLRegisterPanelClassWrapper<LLPanelAvatarProfile> t_panel_profile("panel_profile"); -static LLRegisterPanelClassWrapper<LLPanelMyProfile> t_panel_my_profile("panel_my_profile"); -static LLRegisterPanelClassWrapper<LLPanelAvatarNotes> t_panel_notes("panel_notes"); - -//----------------------------------------------------------------------------- -// LLPanelAvatarNotes() -//----------------------------------------------------------------------------- -LLPanelAvatarNotes::LLPanelAvatarNotes() -: LLPanelProfileTab() -{ - -} - -void LLPanelAvatarNotes::updateData() -{ - LLAvatarPropertiesProcessor::getInstance()-> - sendAvatarNotesRequest(getAvatarId()); -} - -BOOL LLPanelAvatarNotes::postBuild() -{ - childSetCommitCallback("status_check", boost::bind(&LLPanelAvatarNotes::onCommitRights, this), NULL); - childSetCommitCallback("map_check", boost::bind(&LLPanelAvatarNotes::onCommitRights, this), NULL); - childSetCommitCallback("objects_check", boost::bind(&LLPanelAvatarNotes::onCommitRights, this), NULL); - - childSetCommitCallback("add_friend", boost::bind(&LLPanelAvatarNotes::onAddFriendButtonClick, this),NULL); - childSetCommitCallback("im", boost::bind(&LLPanelAvatarNotes::onIMButtonClick, this), NULL); - childSetCommitCallback("call", boost::bind(&LLPanelAvatarNotes::onCallButtonClick, this), NULL); - childSetCommitCallback("teleport", boost::bind(&LLPanelAvatarNotes::onTeleportButtonClick, this), NULL); - childSetCommitCallback("share", boost::bind(&LLPanelAvatarNotes::onShareButtonClick, this), NULL); - childSetCommitCallback("show_on_map_btn", (boost::bind( - &LLPanelAvatarNotes::onMapButtonClick, this)), NULL); - - LLTextEditor* te = getChild<LLTextEditor>("notes_edit"); - te->setCommitCallback(boost::bind(&LLPanelAvatarNotes::onCommitNotes,this)); - te->setCommitOnFocusLost(TRUE); - - resetControls(); - resetData(); - - LLVoiceClient::getInstance()->addObserver((LLVoiceClientStatusObserver*)this); - - return TRUE; -} - -void LLPanelAvatarNotes::onOpen(const LLSD& key) -{ - LLPanelProfileTab::onOpen(key); - - fillRightsData(); - - //Disable "Add Friend" button for friends. - getChildView("add_friend")->setEnabled(!LLAvatarActions::isFriend(getAvatarId())); -} - -void LLPanelAvatarNotes::fillRightsData() -{ - getChild<LLUICtrl>("status_check")->setValue(FALSE); - getChild<LLUICtrl>("map_check")->setValue(FALSE); - getChild<LLUICtrl>("objects_check")->setValue(FALSE); - - const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - // If true - we are viewing friend's profile, enable check boxes and set values. - if(relation) - { - S32 rights = relation->getRightsGrantedTo(); - - getChild<LLUICtrl>("status_check")->setValue(LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE); - getChild<LLUICtrl>("map_check")->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); - getChild<LLUICtrl>("objects_check")->setValue(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); - - } - - enableCheckboxes(NULL != relation); -} - -void LLPanelAvatarNotes::onCommitNotes() -{ - std::string notes = getChild<LLUICtrl>("notes_edit")->getValue().asString(); - LLAvatarPropertiesProcessor::getInstance()-> sendNotes(getAvatarId(),notes); -} - -void LLPanelAvatarNotes::rightsConfirmationCallback(const LLSD& notification, - const LLSD& response, S32 rights) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option == 0) - { - LLAvatarPropertiesProcessor::getInstance()->sendFriendRights( - getAvatarId(), rights); - } - else - { - getChild<LLUICtrl>("objects_check")->setValue( - getChild<LLUICtrl>("objects_check")->getValue().asBoolean() ? FALSE : TRUE); - } -} - -void LLPanelAvatarNotes::confirmModifyRights(bool grant, S32 rights) -{ - LLSD args; - args["NAME"] = LLSLURL("agent", getAvatarId(), "displayname").getSLURLString(); - - if (grant) - { - LLNotificationsUtil::add("GrantModifyRights", args, LLSD(), - boost::bind(&LLPanelAvatarNotes::rightsConfirmationCallback, this, - _1, _2, rights)); - } - else - { - LLNotificationsUtil::add("RevokeModifyRights", args, LLSD(), - boost::bind(&LLPanelAvatarNotes::rightsConfirmationCallback, this, - _1, _2, rights)); - } -} - -void LLPanelAvatarNotes::onCommitRights() -{ - const LLRelationship* buddy_relationship = - LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - - if (NULL == buddy_relationship) - { - // Lets have a warning log message instead of having a crash. EXT-4947. - llwarns << "Trying to modify rights for non-friend avatar. Skipped." << llendl; - return; - } - - - S32 rights = 0; - - if(getChild<LLUICtrl>("status_check")->getValue().asBoolean()) - rights |= LLRelationship::GRANT_ONLINE_STATUS; - if(getChild<LLUICtrl>("map_check")->getValue().asBoolean()) - rights |= LLRelationship::GRANT_MAP_LOCATION; - if(getChild<LLUICtrl>("objects_check")->getValue().asBoolean()) - rights |= LLRelationship::GRANT_MODIFY_OBJECTS; - - bool allow_modify_objects = getChild<LLUICtrl>("objects_check")->getValue().asBoolean(); - - // if modify objects checkbox clicked - if (buddy_relationship->isRightGrantedTo( - LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects) - { - confirmModifyRights(allow_modify_objects, rights); - } - // only one checkbox can trigger commit, so store the rest of rights - else - { - LLAvatarPropertiesProcessor::getInstance()->sendFriendRights( - getAvatarId(), rights); - } -} - -void LLPanelAvatarNotes::processProperties(void* data, EAvatarProcessorType type) -{ - if(APT_NOTES == type) - { - LLAvatarNotes* avatar_notes = static_cast<LLAvatarNotes*>(data); - if(avatar_notes && getAvatarId() == avatar_notes->target_id) - { - getChild<LLUICtrl>("notes_edit")->setValue(avatar_notes->notes); - getChildView("notes edit")->setEnabled(true); - - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); - } - } -} - -void LLPanelAvatarNotes::resetData() -{ - getChild<LLUICtrl>("notes_edit")->setValue(LLStringUtil::null); - // Default value is TRUE - getChild<LLUICtrl>("status_check")->setValue(TRUE); -} - -void LLPanelAvatarNotes::resetControls() -{ - //Disable "Add Friend" button for friends. - getChildView("add_friend")->setEnabled(TRUE); - - enableCheckboxes(false); -} - -void LLPanelAvatarNotes::onAddFriendButtonClick() -{ - LLAvatarActions::requestFriendshipDialog(getAvatarId()); -} - -void LLPanelAvatarNotes::onIMButtonClick() -{ - LLAvatarActions::startIM(getAvatarId()); -} - -void LLPanelAvatarNotes::onTeleportButtonClick() -{ - LLAvatarActions::offerTeleport(getAvatarId()); -} - -void LLPanelAvatarNotes::onCallButtonClick() -{ - LLAvatarActions::startCall(getAvatarId()); -} - -void LLPanelAvatarNotes::onShareButtonClick() -{ - //*TODO not implemented. -} - -void LLPanelAvatarNotes::enableCheckboxes(bool enable) -{ - getChildView("status_check")->setEnabled(enable); - getChildView("map_check")->setEnabled(enable); - getChildView("objects_check")->setEnabled(enable); -} - -LLPanelAvatarNotes::~LLPanelAvatarNotes() -{ - if(getAvatarId().notNull()) - { - LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); - } - - if(LLVoiceClient::instanceExists()) - { - LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this); - } -} - -// virtual, called by LLAvatarTracker -void LLPanelAvatarNotes::changed(U32 mask) -{ - getChildView("teleport")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(getAvatarId())); - - // update rights to avoid have checkboxes enabled when friendship is terminated. EXT-4947. - fillRightsData(); -} - -// virtual -void LLPanelAvatarNotes::onChange(EStatusType status, const std::string &channelURI, bool proximal) -{ - if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) - { - return; - } - - getChildView("call")->setEnabled(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking()); -} - -void LLPanelAvatarNotes::setAvatarId(const LLUUID& id) -{ - if(id.notNull()) - { - if(getAvatarId().notNull()) - { - LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); - } - LLPanelProfileTab::setAvatarId(id); - LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this); - } -} - ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -461,449 +198,3 @@ void LLPanelProfileTab::updateButtons() || gAgent.isGodlike(); getChildView("show_on_map_btn")->setEnabled(enable_map_btn); } - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -bool enable_god() -{ - return gAgent.isGodlike(); -} - -LLPanelAvatarProfile::LLPanelAvatarProfile() -: LLPanelProfileTab() -{ -} - -BOOL LLPanelAvatarProfile::postBuild() -{ - childSetCommitCallback("see_profile_btn",(boost::bind(&LLPanelAvatarProfile::onSeeProfileBtnClick,this)),NULL); - childSetCommitCallback("add_friend",(boost::bind(&LLPanelAvatarProfile::onAddFriendButtonClick,this)),NULL); - childSetCommitCallback("im",(boost::bind(&LLPanelAvatarProfile::onIMButtonClick,this)),NULL); - childSetCommitCallback("call",(boost::bind(&LLPanelAvatarProfile::onCallButtonClick,this)),NULL); - childSetCommitCallback("teleport",(boost::bind(&LLPanelAvatarProfile::onTeleportButtonClick,this)),NULL); - childSetCommitCallback("share",(boost::bind(&LLPanelAvatarProfile::onShareButtonClick,this)),NULL); - childSetCommitCallback("show_on_map_btn", (boost::bind( - &LLPanelAvatarProfile::onMapButtonClick, this)), NULL); - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - registrar.add("Profile.ShowOnMap", boost::bind(&LLPanelAvatarProfile::onMapButtonClick, this)); - registrar.add("Profile.Pay", boost::bind(&LLPanelAvatarProfile::pay, this)); - registrar.add("Profile.Share", boost::bind(&LLPanelAvatarProfile::share, this)); - registrar.add("Profile.BlockUnblock", boost::bind(&LLPanelAvatarProfile::toggleBlock, this)); - registrar.add("Profile.Kick", boost::bind(&LLPanelAvatarProfile::kick, this)); - registrar.add("Profile.Freeze", boost::bind(&LLPanelAvatarProfile::freeze, this)); - registrar.add("Profile.Unfreeze", boost::bind(&LLPanelAvatarProfile::unfreeze, this)); - registrar.add("Profile.CSR", boost::bind(&LLPanelAvatarProfile::csr, this)); - - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable; - enable.add("Profile.EnableShowOnMap", boost::bind(&LLPanelAvatarProfile::enableShowOnMap, this)); - enable.add("Profile.EnableGod", boost::bind(&enable_god)); - enable.add("Profile.EnableBlock", boost::bind(&LLPanelAvatarProfile::enableBlock, this)); - enable.add("Profile.EnableUnblock", boost::bind(&LLPanelAvatarProfile::enableUnblock, this)); - - LLToggleableMenu* profile_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_profile_overflow.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - getChild<LLMenuButton>("overflow_btn")->setMenu(profile_menu, LLMenuButton::MP_TOP_RIGHT); - - LLVoiceClient::getInstance()->addObserver((LLVoiceClientStatusObserver*)this); - - resetControls(); - resetData(); - - return TRUE; -} - -void LLPanelAvatarProfile::onOpen(const LLSD& key) -{ - LLPanelProfileTab::onOpen(key); - - mGroups.clear(); - - //Disable "Add Friend" button for friends. - getChildView("add_friend")->setEnabled(!LLAvatarActions::isFriend(getAvatarId())); -} - -void LLPanelAvatarProfile::updateData() -{ - if (getAvatarId().notNull()) - { - LLAvatarPropertiesProcessor::getInstance()-> - sendAvatarPropertiesRequest(getAvatarId()); - LLAvatarPropertiesProcessor::getInstance()-> - sendAvatarGroupsRequest(getAvatarId()); - } -} - -void LLPanelAvatarProfile::resetControls() -{ - getChildView("status_panel")->setVisible( true); - getChildView("profile_buttons_panel")->setVisible( true); - getChildView("title_groups_text")->setVisible( true); - getChildView("sl_groups")->setVisible( true); - getChildView("add_friend")->setEnabled(true); - - getChildView("status_me_panel")->setVisible( false); - getChildView("profile_me_buttons_panel")->setVisible( false); - getChildView("account_actions_panel")->setVisible( false); -} - -void LLPanelAvatarProfile::resetData() -{ - mGroups.clear(); - getChild<LLUICtrl>("2nd_life_pic")->setValue(LLUUID::null); - getChild<LLUICtrl>("real_world_pic")->setValue(LLUUID::null); - getChild<LLUICtrl>("online_status")->setValue(LLStringUtil::null); - getChild<LLUICtrl>("status_message")->setValue(LLStringUtil::null); - getChild<LLUICtrl>("sl_description_edit")->setValue(LLStringUtil::null); - getChild<LLUICtrl>("fl_description_edit")->setValue(LLStringUtil::null); - getChild<LLUICtrl>("sl_groups")->setValue(LLStringUtil::null); - getChild<LLUICtrl>("homepage_edit")->setValue(LLStringUtil::null); - getChild<LLUICtrl>("register_date")->setValue(LLStringUtil::null); - getChild<LLUICtrl>("acc_status_text")->setValue(LLStringUtil::null); - getChild<LLUICtrl>("partner_text")->setValue(LLStringUtil::null); -} - -void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType type) -{ - if(APT_PROPERTIES == type) - { - const LLAvatarData* avatar_data = static_cast<const LLAvatarData*>(data); - if(avatar_data && getAvatarId() == avatar_data->avatar_id) - { - processProfileProperties(avatar_data); - } - } - else if(APT_GROUPS == type) - { - LLAvatarGroups* avatar_groups = static_cast<LLAvatarGroups*>(data); - if(avatar_groups && getAvatarId() == avatar_groups->avatar_id) - { - processGroupProperties(avatar_groups); - } - } -} - -void LLPanelAvatarProfile::processProfileProperties(const LLAvatarData* avatar_data) -{ - fillCommonData(avatar_data); - - fillPartnerData(avatar_data); - - fillAccountStatus(avatar_data); -} - -void LLPanelAvatarProfile::processGroupProperties(const LLAvatarGroups* avatar_groups) -{ - // *NOTE dzaporozhan - // Group properties may arrive in two callbacks, we need to save them across - // different calls. We can't do that in textbox as textbox may change the text. - - LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin(); - const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end(); - - for(; it_end != it; ++it) - { - LLAvatarGroups::LLGroupData group_data = *it; - mGroups[group_data.group_name] = group_data.group_id; - } - - // Creating string, containing group list - std::string groups = ""; - for (group_map_t::iterator it = mGroups.begin(); it != mGroups.end(); ++it) - { - if (it != mGroups.begin()) - groups += ", "; - - std::string group_name = LLURI::escape(it->first); - std::string group_url= it->second.notNull() - ? "[secondlife:///app/group/" + it->second.asString() + "/about " + group_name + "]" - : getString("no_group_text"); - - groups += group_url; - } - - getChild<LLUICtrl>("sl_groups")->setValue(groups); -} - -static void got_full_name_callback( LLHandle<LLPanel> profile_panel_handle, const std::string& full_name ) -{ - if (profile_panel_handle.isDead() ) return; - - LLPanelAvatarProfile* profile_panel = dynamic_cast<LLPanelAvatarProfile*>(profile_panel_handle.get()); - if ( ! profile_panel ) return; - - LLStringUtil::format_map_t args; - - std::string name; - if (LLAvatarNameCache::useDisplayNames()) - { - name = LLCacheName::buildUsername(full_name); - } - else - { - name = full_name; - } - - args["[NAME]"] = name; - - std::string linden_name = profile_panel->getString("name_text_args", args); - profile_panel->getChild<LLUICtrl>("name_descr_text")->setValue(linden_name); -} - -void LLPanelAvatarProfile::onNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) -{ - LLStringUtil::format_map_t args; - args["[DISPLAY_NAME]"] = av_name.mDisplayName; - - std::string display_name = getString("display_name_text_args", args); - getChild<LLUICtrl>("display_name_descr_text")->setValue(display_name); -} - -void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data) -{ - //remove avatar id from cache to get fresh info - LLAvatarIconIDCache::getInstance()->remove(avatar_data->avatar_id); - - LLStringUtil::format_map_t args; - { - std::string birth_date = LLTrans::getString("AvatarBirthDateFormat"); - LLStringUtil::format(birth_date, LLSD().with("datetime", (S32) avatar_data->born_on.secondsSinceEpoch())); - args["[REG_DATE]"] = birth_date; - } - - // ask (asynchronously) for the avatar name - LLHandle<LLPanel> profile_panel_handle = getHandle(); - std::string full_name; - if (gCacheName->getFullName(avatar_data->agent_id, full_name)) - { - // name in cache, call callback directly - got_full_name_callback( profile_panel_handle, full_name ); - } - else - { - // not in cache, lookup name - gCacheName->get(avatar_data->agent_id, false, boost::bind( got_full_name_callback, profile_panel_handle, _2 )); - } - - // get display name - LLAvatarNameCache::get(avatar_data->avatar_id, - boost::bind(&LLPanelAvatarProfile::onNameCache, this, _1, _2)); - - args["[AGE]"] = LLDateUtil::ageFromDate( avatar_data->born_on, LLDate::now()); - std::string register_date = getString("RegisterDateFormat", args); - getChild<LLUICtrl>("register_date")->setValue(register_date ); - getChild<LLUICtrl>("sl_description_edit")->setValue(avatar_data->about_text); - getChild<LLUICtrl>("fl_description_edit")->setValue(avatar_data->fl_about_text); - getChild<LLUICtrl>("2nd_life_pic")->setValue(avatar_data->image_id); - getChild<LLUICtrl>("real_world_pic")->setValue(avatar_data->fl_image_id); - getChild<LLUICtrl>("homepage_edit")->setValue(avatar_data->profile_url); - - // Hide home page textbox if no page was set to fix "homepage URL appears clickable without URL - EXT-4734" - getChildView("homepage_edit")->setVisible( !avatar_data->profile_url.empty()); -} - -void LLPanelAvatarProfile::fillPartnerData(const LLAvatarData* avatar_data) -{ - LLTextBox* partner_text = getChild<LLTextBox>("partner_text"); - if (avatar_data->partner_id.notNull()) - { - partner_text->setText(LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString()); - } - else - { - partner_text->setText(getString("no_partner_text")); - } -} - -void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data) -{ - LLStringUtil::format_map_t args; - args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(avatar_data); - args["[PAYMENTINFO]"] = LLAvatarPropertiesProcessor::paymentInfo(avatar_data); - // *NOTE: AVATAR_AGEVERIFIED not currently getting set in - // dataserver/lldataavatar.cpp for privacy considerations - args["[AGEVERIFICATION]"] = ""; - std::string caption_text = getString("CaptionTextAcctInfo", args); - getChild<LLUICtrl>("acc_status_text")->setValue(caption_text); -} - -void LLPanelAvatarProfile::pay() -{ - LLAvatarActions::pay(getAvatarId()); -} - -void LLPanelAvatarProfile::share() -{ - LLAvatarActions::share(getAvatarId()); -} - -void LLPanelAvatarProfile::toggleBlock() -{ - LLAvatarActions::toggleBlock(getAvatarId()); -} - -bool LLPanelAvatarProfile::enableShowOnMap() -{ - bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId()); - - bool enable_map_btn = (is_buddy_online && is_agent_mappable(getAvatarId())) - || gAgent.isGodlike(); - return enable_map_btn; -} - -bool LLPanelAvatarProfile::enableBlock() -{ - return LLAvatarActions::canBlock(getAvatarId()) && !LLAvatarActions::isBlocked(getAvatarId()); -} - -bool LLPanelAvatarProfile::enableUnblock() -{ - return LLAvatarActions::isBlocked(getAvatarId()); -} - -void LLPanelAvatarProfile::kick() -{ - LLAvatarActions::kick(getAvatarId()); -} - -void LLPanelAvatarProfile::freeze() -{ - LLAvatarActions::freeze(getAvatarId()); -} - -void LLPanelAvatarProfile::unfreeze() -{ - LLAvatarActions::unfreeze(getAvatarId()); -} - -void LLPanelAvatarProfile::csr() -{ - std::string name; - gCacheName->getFullName(getAvatarId(), name); - LLAvatarActions::csr(getAvatarId(), name); -} - -void LLPanelAvatarProfile::onAddFriendButtonClick() -{ - LLAvatarActions::requestFriendshipDialog(getAvatarId()); -} - -void LLPanelAvatarProfile::onSeeProfileBtnClick() -{ - LLAvatarActions::showProfile(getAvatarId()); -} - -void LLPanelAvatarProfile::onIMButtonClick() -{ - LLAvatarActions::startIM(getAvatarId()); -} - -void LLPanelAvatarProfile::onTeleportButtonClick() -{ - LLAvatarActions::offerTeleport(getAvatarId()); -} - -void LLPanelAvatarProfile::onCallButtonClick() -{ - LLAvatarActions::startCall(getAvatarId()); -} - -void LLPanelAvatarProfile::onShareButtonClick() -{ - //*TODO not implemented -} - -LLPanelAvatarProfile::~LLPanelAvatarProfile() -{ - if(getAvatarId().notNull()) - { - LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); - } - - if(LLVoiceClient::instanceExists()) - { - LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this); - } -} - -// virtual, called by LLAvatarTracker -void LLPanelAvatarProfile::changed(U32 mask) -{ - getChildView("teleport")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(getAvatarId())); -} - -// virtual -void LLPanelAvatarProfile::onChange(EStatusType status, const std::string &channelURI, bool proximal) -{ - if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) - { - return; - } - - getChildView("call")->setEnabled(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking()); -} - -void LLPanelAvatarProfile::setAvatarId(const LLUUID& id) -{ - if(id.notNull()) - { - if(getAvatarId().notNull()) - { - LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); - } - LLPanelProfileTab::setAvatarId(id); - LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this); - } -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -LLPanelMyProfile::LLPanelMyProfile() -: LLPanelAvatarProfile() -{ -} - -BOOL LLPanelMyProfile::postBuild() -{ - LLPanelAvatarProfile::postBuild(); - - childSetCommitCallback("status_me_message_text", boost::bind(&LLPanelMyProfile::onStatusMessageChanged, this), NULL); - - resetControls(); - resetData(); - - return TRUE; -} - -void LLPanelMyProfile::onOpen(const LLSD& key) -{ - LLPanelProfileTab::onOpen(key); -} - -void LLPanelMyProfile::processProfileProperties(const LLAvatarData* avatar_data) -{ - fillCommonData(avatar_data); - - fillPartnerData(avatar_data); - - fillAccountStatus(avatar_data); -} - -void LLPanelMyProfile::resetControls() -{ - getChildView("status_panel")->setVisible( false); - getChildView("profile_buttons_panel")->setVisible( false); - getChildView("title_groups_text")->setVisible( false); - getChildView("sl_groups")->setVisible( false); - getChildView("status_me_panel")->setVisible( true); - getChildView("profile_me_buttons_panel")->setVisible( true); -} - - -void LLPanelMyProfile::onStatusMessageChanged() -{ - updateData(); -} diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index e95441cd58..e33a850cfa 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -36,14 +36,8 @@ class LLComboBox; class LLLineEditor; -enum EOnlineStatus -{ - ONLINE_STATUS_NO = 0, - ONLINE_STATUS_YES = 1 -}; - /** -* Base class for any Profile View or My Profile Panel. +* Base class for any Profile View. */ class LLPanelProfileTab : public LLPanel @@ -111,187 +105,4 @@ private: LLUUID mAvatarId; }; -/** -* Panel for displaying Avatar's first and second life related info. -*/ -class LLPanelAvatarProfile - : public LLPanelProfileTab - , public LLFriendObserver - , public LLVoiceClientStatusObserver -{ -public: - LLPanelAvatarProfile(); - /*virtual*/ ~LLPanelAvatarProfile(); - - /*virtual*/ void onOpen(const LLSD& key); - - /** - * LLFriendObserver trigger - */ - virtual void changed(U32 mask); - - // Implements LLVoiceClientStatusObserver::onChange() to enable the call - // button when voice is available - /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); - - /*virtual*/ void setAvatarId(const LLUUID& id); - - /** - * Processes data received from server. - */ - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - - /*virtual*/ BOOL postBuild(); - - /*virtual*/ void updateData(); - - /*virtual*/ void resetControls(); - - /*virtual*/ void resetData(); - -protected: - - /** - * Process profile related data received from server. - */ - virtual void processProfileProperties(const LLAvatarData* avatar_data); - - /** - * Processes group related data received from server. - */ - virtual void processGroupProperties(const LLAvatarGroups* avatar_groups); - - /** - * Fills common for Avatar profile and My Profile fields. - */ - virtual void fillCommonData(const LLAvatarData* avatar_data); - - /** - * Fills partner data. - */ - virtual void fillPartnerData(const LLAvatarData* avatar_data); - - /** - * Fills account status. - */ - virtual void fillAccountStatus(const LLAvatarData* avatar_data); - - /** - * Opens "Pay Resident" dialog. - */ - void pay(); - - /** - * opens inventory and IM for sharing items - */ - void share(); - - /** - * Add/remove resident to/from your block list. - */ - void toggleBlock(); - - void kick(); - void freeze(); - void unfreeze(); - void csr(); - - bool enableShowOnMap(); - bool enableBlock(); - bool enableUnblock(); - bool enableGod(); - - void onSeeProfileBtnClick(); - void onAddFriendButtonClick(); - void onIMButtonClick(); - void onCallButtonClick(); - void onTeleportButtonClick(); - void onShareButtonClick(); - -private: - void onNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); - - typedef std::map< std::string,LLUUID> group_map_t; - group_map_t mGroups; -}; - -/** - * Panel for displaying own first and second life related info. - */ -class LLPanelMyProfile - : public LLPanelAvatarProfile -{ -public: - LLPanelMyProfile(); - - /*virtual*/ BOOL postBuild(); - -protected: - - /*virtual*/ void onOpen(const LLSD& key); - - /*virtual*/ void processProfileProperties(const LLAvatarData* avatar_data); - - /*virtual*/ void resetControls(); - -protected: - void onStatusMessageChanged(); -}; - -/** - * Panel for displaying Avatar's notes and modifying friend's rights. - */ -class LLPanelAvatarNotes - : public LLPanelProfileTab - , public LLFriendObserver - , public LLVoiceClientStatusObserver -{ -public: - LLPanelAvatarNotes(); - /*virtual*/ ~LLPanelAvatarNotes(); - - virtual void setAvatarId(const LLUUID& id); - - /** - * LLFriendObserver trigger - */ - virtual void changed(U32 mask); - - // Implements LLVoiceClientStatusObserver::onChange() to enable the call - // button when voice is available - /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); - - /*virtual*/ void onOpen(const LLSD& key); - - /*virtual*/ BOOL postBuild(); - - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - - /*virtual*/ void updateData(); - -protected: - - /*virtual*/ void resetControls(); - - /*virtual*/ void resetData(); - - /** - * Fills rights data for friends. - */ - void fillRightsData(); - - void rightsConfirmationCallback(const LLSD& notification, - const LLSD& response, S32 rights); - void confirmModifyRights(bool grant, S32 rights); - void onCommitRights(); - void onCommitNotes(); - - void onAddFriendButtonClick(); - void onIMButtonClick(); - void onCallButtonClick(); - void onTeleportButtonClick(); - void onShareButtonClick(); - void enableCheckboxes(bool enable); -}; - #endif // LL_LLPANELAVATAR_H diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp index 5c85ec438c..115114bb53 100644 --- a/indra/newview/llpanelblockedlist.cpp +++ b/indra/newview/llpanelblockedlist.cpp @@ -30,15 +30,23 @@ // library include #include "llavatarname.h" +#include "llfiltereditor.h" #include "llfloater.h" #include "llfloaterreg.h" #include "llnotificationsutil.h" #include "llscrolllistctrl.h" +#include "llmenubutton.h" // project include +#include "llavatarlistitem.h" +#include "llblocklist.h" +#include "llblockedlistitem.h" #include "llfloateravatarpicker.h" #include "llfloatersidepanelcontainer.h" +#include "llinventorylistitem.h" +#include "llinventorymodel.h" #include "llsidetraypanelcontainer.h" +#include "llviewercontrol.h" static LLRegisterPanelClassWrapper<LLPanelBlockedList> t_panel_blocked_list("panel_block_list_sidetray"); @@ -54,26 +62,47 @@ const std::string BLOCKED_PARAM_NAME = "blocked_to_select"; LLPanelBlockedList::LLPanelBlockedList() : LLPanel() { - mCommitCallbackRegistrar.add("Block.ClickPick", boost::bind(&LLPanelBlockedList::onPickBtnClick, this)); - mCommitCallbackRegistrar.add("Block.ClickBlockByName", boost::bind(&LLPanelBlockedList::onBlockByNameClick, this)); - mCommitCallbackRegistrar.add("Block.ClickRemove", boost::bind(&LLPanelBlockedList::onRemoveBtnClick, this)); + mCommitCallbackRegistrar.add("Block.Action", boost::bind(&LLPanelBlockedList::onCustomAction, this, _2)); + mEnableCallbackRegistrar.add("Block.Check", boost::bind(&LLPanelBlockedList::isActionChecked, this, _2)); } -LLPanelBlockedList::~LLPanelBlockedList() +void LLPanelBlockedList::removePicker() { - LLMuteList::getInstance()->removeObserver(this); + if(mPicker.get()) + { + mPicker.get()->closeFloater(); + } } BOOL LLPanelBlockedList::postBuild() { - mBlockedList = getChild<LLScrollListCtrl>("blocked"); + mBlockedList = getChild<LLBlockList>("blocked"); mBlockedList->setCommitOnSelectionChange(TRUE); + this->setVisibleCallback(boost::bind(&LLPanelBlockedList::removePicker, this)); - childSetCommitCallback("back", boost::bind(&LLPanelBlockedList::onBackBtnClick, this), NULL); + switch (gSavedSettings.getU32("BlockPeopleSortOrder")) + { + case E_SORT_BY_NAME: + mBlockedList->sortByName(); + break; + + case E_SORT_BY_TYPE: + mBlockedList->sortByType(); + break; + default: + llwarns << "Unrecognized sort order for blocked list" << llendl; + break; + } + + // Use the context menu of the Block list for the Block tab gear menu. + LLToggleableMenu* blocked_gear_menu = mBlockedList->getContextMenu(); + if (blocked_gear_menu) + { + getChild<LLMenuButton>("blocked_gear_btn")->setMenu(blocked_gear_menu, LLMenuButton::MP_BOTTOM_LEFT); + } - LLMuteList::getInstance()->addObserver(this); - - refreshBlockedList(); + getChild<LLButton>("unblock_btn")->setCommitCallback(boost::bind(&LLPanelBlockedList::unblockItem, this)); + getChild<LLFilterEditor>("blocked_filter_input")->setCommitCallback(boost::bind(&LLPanelBlockedList::onFilterEdit, this, _2)); return LLPanel::postBuild(); } @@ -94,97 +123,112 @@ void LLPanelBlockedList::onOpen(const LLSD& key) void LLPanelBlockedList::selectBlocked(const LLUUID& mute_id) { - mBlockedList->selectByID(mute_id); + mBlockedList->selectItemByUUID(mute_id); } void LLPanelBlockedList::showPanelAndSelect(const LLUUID& idToSelect) { - LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with(BLOCKED_PARAM_NAME, idToSelect)); + LLFloaterSidePanelContainer::showPanel("people", "panel_people", + LLSD().with("people_panel_tab_name", "blocked_panel").with(BLOCKED_PARAM_NAME, idToSelect)); } ////////////////////////////////////////////////////////////////////////// // Private Section ////////////////////////////////////////////////////////////////////////// -void LLPanelBlockedList::refreshBlockedList() +void LLPanelBlockedList::updateButtons() { - mBlockedList->deleteAllItems(); + bool hasSelected = NULL != mBlockedList->getSelectedItem(); + getChildView("unblock_btn")->setEnabled(hasSelected); + getChildView("blocked_gear_btn")->setEnabled(hasSelected); +} - std::vector<LLMute> mutes = LLMuteList::getInstance()->getMutes(); - std::vector<LLMute>::iterator it; - for (it = mutes.begin(); it != mutes.end(); ++it) +void LLPanelBlockedList::unblockItem() +{ + LLBlockedListItem* item = mBlockedList->getBlockedItem(); + if (item) { - LLScrollListItem::Params item_p; - item_p.enabled(TRUE); - item_p.value(it->mID); // link UUID of blocked item with ScrollListItem - item_p.columns.add().column("item_name").value(it->mName);//.type("text"); - item_p.columns.add().column("item_type").value(it->getDisplayType());//.type("text").width(111); - - mBlockedList->addRow(item_p, ADD_BOTTOM); + LLMute mute(item->getUUID(), item->getName()); + LLMuteList::instance().remove(mute); } } -void LLPanelBlockedList::updateButtons() +void LLPanelBlockedList::onCustomAction(const LLSD& userdata) { - bool hasSelected = NULL != mBlockedList->getFirstSelected(); - getChildView("Unblock")->setEnabled(hasSelected); -} - + const std::string command_name = userdata.asString(); - -void LLPanelBlockedList::onBackBtnClick() -{ - LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent()); - if(parent) + if ("block_obj_by_name" == command_name) + { + blockObjectByName(); + } + else if ("block_res_by_name" == command_name) + { + blockResidentByName(); + } + else if ("sort_by_name" == command_name) + { + mBlockedList->sortByName(); + gSavedSettings.setU32("BlockPeopleSortOrder", E_SORT_BY_NAME); + } + else if ("sort_by_type" == command_name) { - parent->openPreviousPanel(); + mBlockedList->sortByType(); + gSavedSettings.setU32("BlockPeopleSortOrder", E_SORT_BY_TYPE); } } -void LLPanelBlockedList::onRemoveBtnClick() +BOOL LLPanelBlockedList::isActionChecked(const LLSD& userdata) { - std::string name = mBlockedList->getSelectedItemLabel(); - LLUUID id = mBlockedList->getStringUUIDSelectedItem(); - LLMute mute(id, name); - - S32 last_selected = mBlockedList->getFirstSelectedIndex(); - if (LLMuteList::getInstance()->remove(mute)) + std::string item = userdata.asString(); + U32 sort_order = gSavedSettings.getU32("BlockPeopleSortOrder"); + + if ("sort_by_name" == item) + { + return E_SORT_BY_NAME == sort_order; + } + else if ("sort_by_type" == item) { - // Above removals may rebuild this dialog. - - if (last_selected == mBlockedList->getItemCount()) - { - // we were on the last item, so select the last item again - mBlockedList->selectNthItem(last_selected - 1); - } - else - { - // else select the item after the last item previously selected - mBlockedList->selectNthItem(last_selected); - } + return E_SORT_BY_TYPE == sort_order; } + + return false; } -void LLPanelBlockedList::onPickBtnClick() +void LLPanelBlockedList::blockResidentByName() { const BOOL allow_multiple = FALSE; const BOOL close_on_select = TRUE; - /*LLFloaterAvatarPicker* picker = */LLFloaterAvatarPicker::show(boost::bind(&LLPanelBlockedList::callbackBlockPicked, this, _1, _2), allow_multiple, close_on_select); - - // *TODO: mantipov: should LLFloaterAvatarPicker be closed when panel is closed? - // old Floater dependency is not enable in panel - // addDependentFloater(picker); + + LLView * button = findChild<LLButton>("plus_btn", TRUE); + LLFloater* root_floater = gFloaterView->getParentFloater(this); + LLFloaterAvatarPicker * picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelBlockedList::callbackBlockPicked, this, _1, _2), + allow_multiple, close_on_select, FALSE, root_floater->getName(), button); + + if (root_floater) + { + root_floater->addDependentFloater(picker); + } + + mPicker = picker->getHandle(); } -void LLPanelBlockedList::onBlockByNameClick() +void LLPanelBlockedList::blockObjectByName() { LLFloaterGetBlockedObjectName::show(&LLPanelBlockedList::callbackBlockByName); } +void LLPanelBlockedList::onFilterEdit(const std::string& search_string) +{ + std::string filter = search_string; + LLStringUtil::trimHead(filter); + + mBlockedList->setNameFilter(filter); +} + void LLPanelBlockedList::callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names) { if (names.empty() || ids.empty()) return; - LLMute mute(ids[0], names[0].getLegacyName(), LLMute::AGENT); + LLMute mute(ids[0], names[0].getAccountName(), LLMute::AGENT); LLMuteList::getInstance()->add(mute); showPanelAndSelect(mute.mID); } diff --git a/indra/newview/llpanelblockedlist.h b/indra/newview/llpanelblockedlist.h index 74ad82e32d..07f0437656 100644 --- a/indra/newview/llpanelblockedlist.h +++ b/indra/newview/llpanelblockedlist.h @@ -30,21 +30,15 @@ #include "llpanel.h" #include "llmutelist.h" #include "llfloater.h" -// #include <vector> -// class LLButton; -// class LLLineEditor; -// class LLMessageSystem; -// class LLUUID; class LLAvatarName; -class LLScrollListCtrl; +class LLBlockList; -class LLPanelBlockedList - : public LLPanel, public LLMuteListObserver +class LLPanelBlockedList : public LLPanel { public: LLPanelBlockedList(); - ~LLPanelBlockedList(); + ~LLPanelBlockedList(){}; virtual BOOL postBuild(); virtual void draw(); @@ -59,25 +53,33 @@ public: * If it is LLUUID::null, nothing will be selected. */ static void showPanelAndSelect(const LLUUID& idToSelect); - - // LLMuteListObserver callback interface implementation. - /* virtual */ void onChange() { refreshBlockedList();} private: - void refreshBlockedList(); + + typedef enum e_sort_oder{ + E_SORT_BY_NAME = 0, + E_SORT_BY_TYPE = 1, + } ESortOrder; + + void removePicker(); void updateButtons(); // UI callbacks - void onBackBtnClick(); - void onRemoveBtnClick(); - void onPickBtnClick(); - void onBlockByNameClick(); + void unblockItem(); + void blockResidentByName(); + void blockObjectByName(); + void onFilterEdit(const std::string& search_string); + + // List commnads + void onCustomAction(const LLSD& userdata); + BOOL isActionChecked(const LLSD& userdata); void callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names); static void callbackBlockByName(const std::string& text); private: - LLScrollListCtrl* mBlockedList; + LLBlockList* mBlockedList; + LLHandle<LLFloater> mPicker; }; //----------------------------------------------------------------------------- diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index a64b4ec94d..77e1487f38 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -116,7 +116,7 @@ void LLPanelContents::getState(LLViewerObject *objectp ) // BUG? Check for all objects being editable? bool editable = gAgent.isGodlike() - || (objectp->permModify() + || (objectp->permModify() && !objectp->isPermanentEnforced() && ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) ))); // solves SL-23488 BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ); @@ -127,6 +127,8 @@ void LLPanelContents::getState(LLViewerObject *objectp ) ((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1) || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1))); + getChildView("button permissions")->setEnabled(!objectp->isPermanentEnforced()); + mPanelInventoryObject->setEnabled(!objectp->isPermanentEnforced()); } void LLPanelContents::refresh() diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index b73d97e4c4..6b9edcb07c 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -356,9 +356,9 @@ LLEditWearableDictionary::ColorSwatchCtrls::ColorSwatchCtrls() LLEditWearableDictionary::TextureCtrls::TextureCtrls() { - addEntry ( TEX_HEAD_BODYPAINT, new PickerControlEntry (TEX_HEAD_BODYPAINT, "Head Tattoos", LLUUID::null, TRUE )); - addEntry ( TEX_UPPER_BODYPAINT, new PickerControlEntry (TEX_UPPER_BODYPAINT, "Upper Tattoos", LLUUID::null, TRUE )); - addEntry ( TEX_LOWER_BODYPAINT, new PickerControlEntry (TEX_LOWER_BODYPAINT, "Lower Tattoos", LLUUID::null, TRUE )); + addEntry ( TEX_HEAD_BODYPAINT, new PickerControlEntry (TEX_HEAD_BODYPAINT, "Head", LLUUID::null, TRUE )); + addEntry ( TEX_UPPER_BODYPAINT, new PickerControlEntry (TEX_UPPER_BODYPAINT, "Upper Body", LLUUID::null, TRUE )); + addEntry ( TEX_LOWER_BODYPAINT, new PickerControlEntry (TEX_LOWER_BODYPAINT, "Lower Body", LLUUID::null, TRUE )); addEntry ( TEX_HAIR, new PickerControlEntry (TEX_HAIR, "Texture", LLUUID( gSavedSettings.getString( "UIImgDefaultHairUUID" ) ), FALSE )); addEntry ( TEX_EYES_IRIS, new PickerControlEntry (TEX_EYES_IRIS, "Iris", LLUUID( gSavedSettings.getString( "UIImgDefaultEyesUUID" ) ), FALSE )); addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShirtUUID" ) ), FALSE )); @@ -574,6 +574,7 @@ static void init_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const L texture_ctrl->setAllowNoTexture(entry->mAllowNoTexture); // Don't allow (no copy) or (notransfer) textures to be selected. texture_ctrl->setImmediateFilterPermMask(PERM_NONE); + texture_ctrl->setDnDFilterPermMask(PERM_NONE); texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE); } } @@ -834,11 +835,11 @@ BOOL LLPanelEditWearable::isDirty() const BOOL isDirty = FALSE; if (mWearablePtr) { - if (mWearablePtr->isDirty() || - mWearableItem->getName().compare(mNameEditor->getText()) != 0) - { - isDirty = TRUE; - } + if (mWearablePtr->isDirty() || + ( mWearableItem && mNameEditor && mWearableItem->getName().compare(mNameEditor->getText()) != 0 )) + { + isDirty = TRUE; + } } return isDirty; } @@ -1185,7 +1186,7 @@ void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show, BOOL dis void LLPanelEditWearable::showDefaultSubpart() { - changeCamera(3); + changeCamera(0); } void LLPanelEditWearable::onTabExpandedCollapsed(const LLSD& param, U8 index) diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index a4f6921f98..202be9671b 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -38,6 +38,7 @@ #include "llfontgl.h" // project includes +#include "llagentdata.h" #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcolorswatch.h" @@ -46,6 +47,7 @@ #include "llface.h" #include "lllineeditor.h" #include "llmediaentry.h" +#include "llnotificationsutil.h" #include "llresmgr.h" #include "llselectmgr.h" #include "llspinctrl.h" @@ -104,27 +106,11 @@ BOOL LLPanelFace::postBuild() mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) ); mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) ); mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); + mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); mTextureCtrl->setFollowsTop(); mTextureCtrl->setFollowsLeft(); - // Don't allow (no copy) or (no transfer) textures to be selected during immediate mode - mTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); - // Allow any texture to be used during non-immediate mode. - mTextureCtrl->setNonImmediateFilterPermMask(PERM_NONE); - LLAggregatePermissions texture_perms; - if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms)) - { - BOOL can_copy = - texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY || - texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL; - BOOL can_transfer = - texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY || - texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL; - mTextureCtrl->setCanApplyImmediately(can_copy && can_transfer); - } - else - { - mTextureCtrl->setCanApplyImmediately(FALSE); - } + mTextureCtrl->setImmediateFilterPermMask(PERM_NONE); + mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); } mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch"); @@ -504,7 +490,7 @@ void LLPanelFace::getState() && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify()) { - BOOL editable = objectp->permModify(); + BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced(); // only turn on auto-adjust button if there is a media renderer and the media is loaded getChildView("textbox autofix")->setEnabled(editable); @@ -595,28 +581,6 @@ void LLPanelFace::getState() } - LLAggregatePermissions texture_perms; - if(texture_ctrl) - { -// texture_ctrl->setValid( editable ); - - if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms)) - { - BOOL can_copy = - texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY || - texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL; - BOOL can_transfer = - texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY || - texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL; - texture_ctrl->setCanApplyImmediately(can_copy && can_transfer); - } - else - { - texture_ctrl->setCanApplyImmediately(FALSE); - } - } - - // planar align bool align_planar = false; bool identical_planar_aligned = false; @@ -875,8 +839,15 @@ void LLPanelFace::getState() { getChild<LLUICtrl>("TexScaleU")->setValue(2.0f * getChild<LLUICtrl>("TexScaleU")->getValue().asReal() ); getChild<LLUICtrl>("TexScaleV")->setValue(2.0f * getChild<LLUICtrl>("TexScaleV")->getValue().asReal() ); - } + // EXP-1507 (change label based on the mapping mode) + getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per meter")); + } + else + if (selected_texgen == 0) // FIXME: should not be magic numbers + { + getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per face")); + } } { @@ -1183,3 +1154,35 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata) self->sendTextureInfo(); } +void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp) +{ + LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control"); + if (texture_ctrl) + { + LLUUID obj_owner_id; + std::string obj_owner_name; + LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name); + + LLSaleInfo sale_info; + LLSelectMgr::instance().selectGetSaleInfo(sale_info); + + bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture? + bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture? + bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent? + bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale? + + if (can_copy && can_transfer) + { + texture_ctrl->setCanApply(true, true); + return; + } + + // if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale + texture_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale); + + if (gSavedSettings.getBOOL("TextureLivePreview")) + { + LLNotificationsUtil::add("LivePreviewUnavailable"); + } + } +} diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 42be9b257f..3b5a9b1398 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -91,6 +91,15 @@ protected: static void onClickAutoFix(void*); static F32 valueGlow(LLViewerObject* object, S32 face); +private: + + /* + * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object. + * If agent selects texture which is not allowed to be applied for the currently selected object, + * all controls of the floater texture picker which allow to apply the texture will be disabled. + */ + void onTextureSelectionChanged(LLInventoryItem* itemp); + }; #endif diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index b494c7d403..0e6f5b8924 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -33,7 +33,7 @@ class LLOfferInfo; -const S32 UPDATE_MEMBERS_PER_FRAME = 500; +const F32 UPDATE_MEMBERS_SECONDS_PER_FRAME = 0.005; // 5ms // Forward declares class LLPanelGroupTab; diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index bc594b5517..0cd93b330a 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -28,8 +28,10 @@ #include "llpanelgroupgeneral.h" -#include "lluictrlfactory.h" +#include "llavatarnamecache.h" #include "llagent.h" +#include "llsdparam.h" +#include "lluictrlfactory.h" #include "roles_constants.h" // UI elements @@ -77,13 +79,18 @@ LLPanelGroupGeneral::LLPanelGroupGeneral() mCtrlReceiveNotices(NULL), mCtrlListGroup(NULL), mActiveTitleLabel(NULL), - mComboActiveTitle(NULL) + mComboActiveTitle(NULL), + mAvatarNameCacheConnection() { } LLPanelGroupGeneral::~LLPanelGroupGeneral() { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } } BOOL LLPanelGroupGeneral::postBuild() @@ -313,11 +320,10 @@ void LLPanelGroupGeneral::activate() { LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID); LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID); - if (!gdatap || !gdatap->isMemberDataComplete() ) { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } mFirstUse = FALSE; @@ -697,76 +703,48 @@ void LLPanelGroupGeneral::updateMembers() LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); - if (!mListVisibleMembers || !gdatap + if (!mListVisibleMembers + || !gdatap || !gdatap->isMemberDataComplete() || gdatap->mMembers.empty()) { return; } - static LLTimer all_timer; - static LLTimer sd_timer; - static LLTimer element_timer; + LLTimer update_time; + update_time.setTimerExpirySec(UPDATE_MEMBERS_SECONDS_PER_FRAME); - all_timer.reset(); - S32 i = 0; + LLAvatarName av_name; - for( ; mMemberProgress != gdatap->mMembers.end() && i<UPDATE_MEMBERS_PER_FRAME; - ++mMemberProgress, ++i) + for( ; mMemberProgress != gdatap->mMembers.end() && !update_time.hasExpired(); + ++mMemberProgress) { - //llinfos << "Adding " << iter->first << ", " << iter->second->getTitle() << llendl; LLGroupMemberData* member = mMemberProgress->second; if (!member) { continue; } - // Owners show up in bold. - std::string style = "NORMAL"; - sd_timer.reset(); - LLSD row; - row["id"] = member->getID(); - - row["columns"][0]["column"] = "name"; - row["columns"][0]["font"]["name"] = "SANSSERIF_SMALL"; - row["columns"][0]["font"]["style"] = style; - // value is filled in by name list control - - row["columns"][1]["column"] = "title"; - row["columns"][1]["value"] = member->getTitle(); - row["columns"][1]["font"]["name"] = "SANSSERIF_SMALL"; - row["columns"][1]["font"]["style"] = style; - - std::string status = member->getOnlineStatus(); - - row["columns"][2]["column"] = "status"; - row["columns"][2]["value"] = status; - row["columns"][2]["font"]["name"] = "SANSSERIF_SMALL"; - row["columns"][2]["font"]["style"] = style; - - sSDTime += sd_timer.getElapsedTimeF32(); - element_timer.reset(); - LLScrollListItem* member_row = mListVisibleMembers->addElement(row); - - if ( member->isOwner() ) + if (LLAvatarNameCache::get(mMemberProgress->first, &av_name)) + { + addMember(mMemberProgress->second); + } + else { - LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0)); - if (name_textp) - name_textp->setFontStyle(LLFontGL::BOLD); + // If name is not cached, onNameCache() should be called when it is cached and add this member to list. + // *TODO : Use a callback per member, not for the panel group. + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupGeneral::onNameCache, this, gdatap->getMemberVersion(), member, _2)); } - sElementTime += element_timer.getElapsedTimeF32(); } - sAllTime += all_timer.getElapsedTimeF32(); - llinfos << "Updated " << i << " of " << UPDATE_MEMBERS_PER_FRAME << "members in the list." << llendl; if (mMemberProgress == gdatap->mMembers.end()) { - llinfos << " member list completed." << llendl; + lldebugs << " member list completed." << llendl; mListVisibleMembers->setEnabled(TRUE); - - llinfos << "All Time: " << sAllTime << llendl; - llinfos << "SD Time: " << sSDTime << llendl; - llinfos << "Element Time: " << sElementTime << llendl; } else { @@ -775,6 +753,45 @@ void LLPanelGroupGeneral::updateMembers() } } +void LLPanelGroupGeneral::addMember(LLGroupMemberData* member) +{ + LLNameListCtrl::NameItem item_params; + item_params.value = member->getID(); + + LLScrollListCell::Params column; + item_params.columns.add().column("name").font.name("SANSSERIF_SMALL"); + + item_params.columns.add().column("title").value(member->getTitle()).font.name("SANSSERIF_SMALL"); + + item_params.columns.add().column("status").value(member->getOnlineStatus()).font.name("SANSSERIF_SMALL"); + + LLScrollListItem* member_row = mListVisibleMembers->addNameItemRow(item_params); + + if ( member->isOwner() ) + { + LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0)); + if (name_textp) + name_textp->setFontStyle(LLFontGL::BOLD); + } +} + +void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name) +{ + mAvatarNameCacheConnection.disconnect(); + + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + + if (!gdatap + || !gdatap->isMemberDataComplete() + || gdatap->getMemberVersion() != update_id) + { + // Stale data + return; + } + + addMember(member); +} + void LLPanelGroupGeneral::updateChanged() { // List all the controls we want to check for changes... diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h index 88c092c461..b7f4a01139 100644 --- a/indra/newview/llpanelgroupgeneral.h +++ b/indra/newview/llpanelgroupgeneral.h @@ -38,6 +38,7 @@ class LLNameListCtrl; class LLCheckBoxCtrl; class LLComboBox; class LLSpinCtrl; +class LLAvatarName; class LLPanelGroupGeneral : public LLPanelGroupTab { @@ -62,6 +63,7 @@ public: virtual void setupCtrls (LLPanel* parent); + void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name); private: void reset(); @@ -75,7 +77,8 @@ private: static void onReceiveNotices(LLUICtrl* ctrl, void* data); static void openProfile(void* data); - S32 sortMembersList(S32,const LLScrollListItem*,const LLScrollListItem*); + S32 sortMembersList(S32,const LLScrollListItem*,const LLScrollListItem*); + void addMember(LLGroupMemberData* member); static bool joinDlgCB(const LLSD& notification, const LLSD& response); @@ -108,6 +111,7 @@ private: LLComboBox *mComboMature; LLGroupMgrGroupData::member_list_t::iterator mMemberProgress; + boost::signals2::connection mAvatarNameCacheConnection; }; #endif diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index ca48e8561b..133b269c11 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -83,11 +83,14 @@ public: LLTextBox *mGroupName; std::string mOwnerWarning; std::string mAlreadyInGroup; + std::string mTooManySelected; bool mConfirmedOwnerInvite; void (*mCloseCallback)(void* data); void* mCloseCallbackUserData; + + boost::signals2::connection mAvatarNameCacheConnection; }; @@ -101,12 +104,17 @@ LLPanelGroupInvite::impl::impl(const LLUUID& group_id): mGroupName( NULL ), mConfirmedOwnerInvite( false ), mCloseCallback( NULL ), - mCloseCallbackUserData( NULL ) + mCloseCallbackUserData( NULL ), + mAvatarNameCacheConnection() { } LLPanelGroupInvite::impl::~impl() { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } } void LLPanelGroupInvite::impl::addUsers(const std::vector<std::string>& names, @@ -185,6 +193,17 @@ void LLPanelGroupInvite::impl::submitInvitations() role_member_pairs[item->getUUID()] = role_id; } + const S32 MAX_GROUP_INVITES = 100; // Max invites per request. 100 to match server cap. + if (role_member_pairs.size() > MAX_GROUP_INVITES) + { + // Fail! + LLSD msg; + msg["MESSAGE"] = mTooManySelected; + LLNotificationsUtil::add("GenericAlert", msg); + (*mCloseCallback)(mCloseCallbackUserData); + return; + } + LLGroupMgr::getInstance()->sendGroupMemberInvites(mGroupID, role_member_pairs); if(already_in_group) @@ -289,12 +308,14 @@ void LLPanelGroupInvite::impl::callbackClickAdd(void* userdata) //Soon the avatar picker will be embedded into this panel //instead of being it's own separate floater. But that is next week. //This will do for now. -jwolk May 10, 2006 - LLFloater* parentp; - - parentp = gFloaterView->getParentFloater(panelp); - parentp->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(impl::callbackAddUsers, _1, - panelp->mImplementation), - TRUE)); + LLView * button = panelp->findChild<LLButton>("add_button"); + LLFloater * root_floater = gFloaterView->getParentFloater(panelp); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( + boost::bind(impl::callbackAddUsers, _1, panelp->mImplementation), TRUE, FALSE, FALSE, root_floater->getName(), button); + if (picker) + { + root_floater->addDependentFloater(picker); + } } } @@ -366,8 +387,24 @@ void LLPanelGroupInvite::impl::callbackAddUsers(const uuid_vec_t& agent_ids, voi std::vector<std::string> names; for (S32 i = 0; i < (S32)agent_ids.size(); i++) { - LLAvatarNameCache::get(agent_ids[i], - boost::bind(&LLPanelGroupInvite::impl::onAvatarNameCache, _1, _2, user_data)); + LLAvatarName av_name; + if (LLAvatarNameCache::get(agent_ids[i], &av_name)) + { + LLPanelGroupInvite::impl::onAvatarNameCache(agent_ids[i], av_name, user_data); + } + else + { + impl* selfp = (impl*) user_data; + if (selfp) + { + if (selfp->mAvatarNameCacheConnection.connected()) + { + selfp->mAvatarNameCacheConnection.disconnect(); + } + // *TODO : Add a callback per avatar name being fetched. + selfp->mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_ids[i],boost::bind(&LLPanelGroupInvite::impl::onAvatarNameCache, _1, _2, user_data)); + } + } } } @@ -380,6 +417,10 @@ void LLPanelGroupInvite::impl::onAvatarNameCache(const LLUUID& agent_id, if (selfp) { + if (selfp->mAvatarNameCacheConnection.connected()) + { + selfp->mAvatarNameCacheConnection.disconnect(); + } std::vector<std::string> names; uuid_vec_t agent_ids; agent_ids.push_back(agent_id); @@ -455,11 +496,11 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids) //so we need to do this additional search in avatar tracker, see EXT-4732 if (LLAvatarTracker::instance().isBuddy(agent_id)) { - if (!gCacheName->getFullName(agent_id, fullname)) + LLAvatarName av_name; + if (!LLAvatarNameCache::get(agent_id, &av_name)) { // actually it should happen, just in case - gCacheName->get(LLUUID(agent_id), false, boost::bind( - &LLPanelGroupInvite::addUserCallback, this, _1, _2)); + //LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(&LLPanelGroupInvite::addUserCallback, this, _1, _2)); // for this special case! //when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence // removed id will be added in callback @@ -467,7 +508,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids) } else { - names.push_back(fullname); + names.push_back(av_name.getAccountName()); } } } @@ -475,12 +516,12 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids) mImplementation->addUsers(names, agent_ids); } -void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const std::string& full_name) +void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const LLAvatarName& av_name) { std::vector<std::string> names; uuid_vec_t agent_ids; agent_ids.push_back(id); - names.push_back(full_name); + names.push_back(av_name.getAccountName()); mImplementation->addUsers(names, agent_ids); } @@ -558,8 +599,8 @@ void LLPanelGroupInvite::updateLists() if (!mPendingUpdate) { LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); - LLGroupMgr::getInstance()->sendGroupMembersRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); } mPendingUpdate = TRUE; } @@ -621,6 +662,7 @@ BOOL LLPanelGroupInvite::postBuild() mImplementation->mOwnerWarning = getString("confirm_invite_owner_str"); mImplementation->mAlreadyInGroup = getString("already_in_group"); + mImplementation->mTooManySelected = getString("invite_selection_too_large"); update(); diff --git a/indra/newview/llpanelgroupinvite.h b/indra/newview/llpanelgroupinvite.h index a7bfd2226e..9f7b5ae9be 100644 --- a/indra/newview/llpanelgroupinvite.h +++ b/indra/newview/llpanelgroupinvite.h @@ -29,6 +29,8 @@ #include "llpanel.h" #include "lluuid.h" +class LLAvatarName; + class LLPanelGroupInvite : public LLPanel { @@ -40,7 +42,7 @@ public: /** * this callback is being used to add a user whose fullname isn't been loaded before invoking of addUsers(). */ - void addUserCallback(const LLUUID& id, const std::string& full_name); + void addUserCallback(const LLUUID& id, const LLAvatarName& av_name); void clear(); void update(); diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index e66dd5690c..37755fb851 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -517,7 +517,7 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg) row["columns"][3]["column"] = "type"; row["columns"][3]["value"] = land_type; - row["columns"][3]["font"] = "SANSSERIFSMALL"; + row["columns"][3]["font"] = "SANSSERIF_SMALL"; // hidden is always last column row["columns"][4]["column"] = "hidden"; @@ -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/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 31c0e3d01a..93b108efcc 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -543,10 +543,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg) msg->getU32("Data","Timestamp",timestamp,i); // we only have the legacy name here, convert it to a username - if (LLAvatarNameCache::useDisplayNames()) - { - name = LLCacheName::buildUsername(name); - } + name = LLCacheName::buildUsername(name); LLSD row; row["id"] = id; diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index fbe331c7ab..cfdac11d26 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -29,6 +29,7 @@ #include "llcheckboxctrl.h" #include "llagent.h" +#include "llavatarnamecache.h" #include "llbutton.h" #include "llfiltereditor.h" #include "llfloatergroupinvite.h" @@ -356,7 +357,7 @@ void LLPanelGroupRoles::activate() if (!gdatap || !gdatap->isMemberDataComplete() ) { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } // Check role data. @@ -742,14 +743,21 @@ LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab() mChanged(FALSE), mPendingMemberUpdate(FALSE), mHasMatch(FALSE), - mNumOwnerAdditions(0) + mNumOwnerAdditions(0), + mAvatarNameCacheConnection() { - mUdpateSessionID = LLUUID::null; } LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab() { - gSavedSettings.setString("GroupMembersSortOrder", mMembersList->getSortColumnName()); + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + if (mMembersList) + { + gSavedSettings.setString("GroupMembersSortOrder", mMembersList->getSortColumnName()); + } } BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) @@ -1423,13 +1431,20 @@ U64 LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges(const LLUUID& ag return GP_NO_POWERS; } - LLGroupMemberData* member_data = gdatap->mMembers[agent_id]; - if ( !member_data ) + LLGroupMgrGroupData::member_list_t::iterator iter = gdatap->mMembers.find(agent_id); + if ( iter == gdatap->mMembers.end() ) { llwarns << "LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges() -- No member data for member with UUID " << agent_id << llendl; return GP_NO_POWERS; } + LLGroupMemberData* member_data = (*iter).second; + if (!member_data) + { + llwarns << "LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges() -- Null member data for member with UUID " << agent_id << llendl; + return GP_NO_POWERS; + } + //see if there are unsaved role changes for this agent role_change_data_map_t* role_change_datap = NULL; member_role_changes_map_t::iterator member = mMemberRoleChangeData.find(agent_id); @@ -1544,10 +1559,6 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc) mMemberProgress = gdatap->mMembers.begin(); mPendingMemberUpdate = TRUE; mHasMatch = FALSE; - // Generate unique ID for current updateMembers()- see onNameCache for details. - // Using unique UUID is perhaps an overkill but this way we are perfectly safe - // from coincidences. - mUdpateSessionID.generate(); } else { @@ -1575,55 +1586,43 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc) } } -void LLPanelGroupMembersSubTab::addMemberToList(LLUUID id, LLGroupMemberData* data) +void LLPanelGroupMembersSubTab::addMemberToList(LLGroupMemberData* data) { if (!data) return; LLUIString donated = getString("donation_area"); donated.setArg("[AREA]", llformat("%d", data->getContribution())); - LLSD row; - row["id"] = id; + LLNameListCtrl::NameItem item_params; + item_params.value = data->getID(); - row["columns"][0]["column"] = "name"; - // value is filled in by name list control + item_params.columns.add().column("name").font.name("SANSSERIF_SMALL").style("NORMAL"); - row["columns"][1]["column"] = "donated"; - row["columns"][1]["value"] = donated.getString(); + item_params.columns.add().column("donated").value(donated.getString()) + .font.name("SANSSERIF_SMALL").style("NORMAL"); - row["columns"][2]["column"] = "online"; - row["columns"][2]["value"] = data->getOnlineStatus(); - row["columns"][2]["font"] = "SANSSERIF_SMALL"; - - mMembersList->addElement(row); + item_params.columns.add().column("online").value(data->getOnlineStatus()) + .font.name("SANSSERIF_SMALL").style("NORMAL"); + mMembersList->addNameItemRow(item_params); mHasMatch = TRUE; } -void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, const LLUUID& id) +void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name) { - // Update ID is used to determine whether member whose id is passed - // into onNameCache() was passed after current or previous user-initiated update. - // This is needed to avoid probable duplication of members in list after changing filter - // or adding of members of another group if gets for their names were called on - // previous update. If this id is from get() called from older update, - // we do nothing. - if (mUdpateSessionID != update_id) return; - + mAvatarNameCacheConnection.disconnect(); + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); - if (!gdatap) + if (!gdatap + || gdatap->getMemberVersion() != update_id + || !member) { - llwarns << "LLPanelGroupMembersSubTab::updateMembers() -- No group data!" << llendl; return; } - std::string fullname; - gCacheName->getFullName(id, fullname); - - LLGroupMemberData* data; // trying to avoid unnecessary hash lookups - if (matchesSearchFilter(fullname) && ((data = gdatap->mMembers[id]) != NULL)) + if (matchesSearchFilter(av_name.getAccountName())) { - addMemberToList(id, data); + addMemberToList(member); if(!mMembersList->getEnabled()) { mMembersList->setEnabled(TRUE); @@ -1662,27 +1661,33 @@ void LLPanelGroupMembersSubTab::updateMembers() LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end(); - - S32 i = 0; - for( ; mMemberProgress != end && i<UPDATE_MEMBERS_PER_FRAME; - ++mMemberProgress, ++i) + + LLTimer update_time; + update_time.setTimerExpirySec(UPDATE_MEMBERS_SECONDS_PER_FRAME); + + for( ; mMemberProgress != end && !update_time.hasExpired(); ++mMemberProgress) { if (!mMemberProgress->second) continue; + // Do filtering on name if it is already in the cache. - std::string fullname; - if (gCacheName->getFullName(mMemberProgress->first, fullname)) + LLAvatarName av_name; + if (LLAvatarNameCache::get(mMemberProgress->first, &av_name)) { - if (matchesSearchFilter(fullname)) + if (matchesSearchFilter(av_name.getAccountName())) { - addMemberToList(mMemberProgress->first, mMemberProgress->second); + addMemberToList(mMemberProgress->second); } } else { // If name is not cached, onNameCache() should be called when it is cached and add this member to list. - gCacheName->get(mMemberProgress->first, FALSE, boost::bind(&LLPanelGroupMembersSubTab::onNameCache, - this, mUdpateSessionID, _1)); + // *TODO : Add one callback per fetched avatar name + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache, this, gdatap->getMemberVersion(), mMemberProgress->second, _2)); } } @@ -1984,7 +1989,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc) if (!gdatap || !gdatap->isMemberDataComplete()) { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } if (!gdatap || !gdatap->isRoleMemberDataComplete()) @@ -2577,7 +2582,7 @@ void LLPanelGroupActionsSubTab::handleActionSelect() } else { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } if (gdatap->isRoleDataComplete()) @@ -2601,6 +2606,7 @@ void LLPanelGroupActionsSubTab::handleActionSelect() LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID); } } + void LLPanelGroupRoles::setGroupID(const LLUUID& id) { LLPanelGroupTab::setGroupID(id); diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index a55e264150..78bb3c57a1 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -187,8 +187,8 @@ public: virtual void setGroupID(const LLUUID& id); - void addMemberToList(LLUUID id, LLGroupMemberData* data); - void onNameCache(const LLUUID& update_id, const LLUUID& id); + void addMemberToList(LLGroupMemberData* data); + void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name); protected: typedef std::map<LLUUID, LLRoleMemberChangeType> role_change_data_map_t; @@ -210,13 +210,11 @@ protected: BOOL mPendingMemberUpdate; BOOL mHasMatch; - // This id is generated after each user initiated member list update(opening Roles or changing filter) - LLUUID mUdpateSessionID; - member_role_changes_map_t mMemberRoleChangeData; U32 mNumOwnerAdditions; LLGroupMgrGroupData::member_list_t::iterator mMemberProgress; + boost::signals2::connection mAvatarNameCacheConnection; }; class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index 0295ad151f..389baa86cd 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -1,31 +1,30 @@ -/** +/** * @file llpanelavatar.cpp * @brief LLPanelAvatar and related class implementations * * $LicenseInfo:firstyear=2004&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 "llfloaterreg.h" #include "llpanelimcontrolpanel.h" @@ -39,393 +38,7 @@ #include "llavatarlist.h" #include "llparticipantlist.h" #include "llimview.h" -#include "llvoicechannel.h" #include "llspeakers.h" #include "lltrans.h" -void LLPanelChatControlPanel::onCallButtonClicked() -{ - gIMMgr->startCall(mSessionId); -} - -void LLPanelChatControlPanel::onEndCallButtonClicked() -{ - gIMMgr->endCall(mSessionId); -} - -void LLPanelChatControlPanel::onOpenVoiceControlsClicked() -{ - LLFloaterReg::showInstance("voice_controls"); -} - -void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &channelURI, bool proximal) -{ - if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) - { - return; - } - - updateCallButton(); -} - -void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state) -{ - updateButtons(new_state); -} - -void LLPanelChatControlPanel::updateCallButton() -{ - // hide/show call button - bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking(); - - LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId); - - if (!session) - { - getChildView("call_btn")->setEnabled(false); - return; - } - - bool session_initialized = session->mSessionInitialized; - bool callback_enabled = session->mCallBackEnabled; - - BOOL enable_connect = session_initialized - && voice_enabled - && callback_enabled; - getChildView("call_btn")->setEnabled(enable_connect); -} - -void LLPanelChatControlPanel::updateButtons(LLVoiceChannel::EState state) -{ - bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED; - getChildView("end_call_btn_panel")->setVisible( is_call_started); - getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started && findChild<LLView>("voice_ctrls_btn_panel")); - getChildView("call_btn_panel")->setVisible( ! is_call_started); - - getChildView("volume_ctrl_panel")->setVisible(state == LLVoiceChannel::STATE_CONNECTED); - - updateCallButton(); - -} - -LLPanelChatControlPanel::~LLPanelChatControlPanel() -{ - mVoiceChannelStateChangeConnection.disconnect(); - if(LLVoiceClient::instanceExists()) - { - LLVoiceClient::getInstance()->removeObserver(this); - } -} - -BOOL LLPanelChatControlPanel::postBuild() -{ - childSetAction("call_btn", boost::bind(&LLPanelChatControlPanel::onCallButtonClicked, this)); - childSetAction("end_call_btn", boost::bind(&LLPanelChatControlPanel::onEndCallButtonClicked, this)); - childSetAction("voice_ctrls_btn", boost::bind(&LLPanelChatControlPanel::onOpenVoiceControlsClicked, this)); - - LLVoiceClient::getInstance()->addObserver(this); - - return TRUE; -} - -void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id) -{ - //Method is called twice for AdHoc and Group chat. Second time when server init reply received - mSessionId = session_id; - LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionId); - if(voice_channel) - { - mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(boost::bind(&LLPanelChatControlPanel::onVoiceChannelStateChanged, this, _1, _2)); - - //call (either p2p, group or ad-hoc) can be already in started state - updateButtons(voice_channel->getState()); - } -} - -LLPanelIMControlPanel::LLPanelIMControlPanel() -{ -} - -LLPanelIMControlPanel::~LLPanelIMControlPanel() -{ - LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this); -} - -BOOL LLPanelIMControlPanel::postBuild() -{ - childSetAction("view_profile_btn", boost::bind(&LLPanelIMControlPanel::onViewProfileButtonClicked, this)); - childSetAction("add_friend_btn", boost::bind(&LLPanelIMControlPanel::onAddFriendButtonClicked, this)); - - childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this)); - childSetAction("teleport_btn", boost::bind(&LLPanelIMControlPanel::onTeleportButtonClicked, this)); - childSetAction("pay_btn", boost::bind(&LLPanelIMControlPanel::onPayButtonClicked, this)); - - childSetAction("mute_btn", boost::bind(&LLPanelIMControlPanel::onClickMuteVolume, this)); - childSetAction("block_btn", boost::bind(&LLPanelIMControlPanel::onClickBlock, this)); - childSetAction("unblock_btn", boost::bind(&LLPanelIMControlPanel::onClickUnblock, this)); - - getChild<LLUICtrl>("volume_slider")->setCommitCallback(boost::bind(&LLPanelIMControlPanel::onVolumeChange, this, _2)); - - getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId())); - - setFocusReceivedCallback(boost::bind(&LLPanelIMControlPanel::onFocusReceived, this)); - - return LLPanelChatControlPanel::postBuild(); -} - -void LLPanelIMControlPanel::draw() -{ - bool is_muted = LLMuteList::getInstance()->isMuted(mAvatarID); - - getChild<LLUICtrl>("block_btn_panel")->setVisible(!is_muted); - getChild<LLUICtrl>("unblock_btn_panel")->setVisible(is_muted); - - if (getChildView("volume_ctrl_panel")->getVisible()) - { - - bool is_muted_voice = LLMuteList::getInstance()->isMuted(mAvatarID, LLMute::flagVoiceChat); - - LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn"); - mute_btn->setValue( is_muted_voice ); - - LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider"); - volume_slider->setEnabled( !is_muted_voice ); - - F32 volume; - - if (is_muted_voice) - { - // it's clearer to display their volume as zero - volume = 0.f; - } - else - { - // actual volume - volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID); - } - volume_slider->setValue( (F64)volume ); - } - - LLPanelChatControlPanel::draw(); -} - -void LLPanelIMControlPanel::onClickMuteVolume() -{ - // By convention, we only display and toggle voice mutes, not all mutes - LLMuteList* mute_list = LLMuteList::getInstance(); - bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat); - - LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT); - if (!is_muted) - { - mute_list->add(mute, LLMute::flagVoiceChat); - } - else - { - mute_list->remove(mute, LLMute::flagVoiceChat); - } -} - -void LLPanelIMControlPanel::onClickBlock() -{ - LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT); - - LLMuteList::getInstance()->add(mute); -} - -void LLPanelIMControlPanel::onClickUnblock() -{ - LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT); - - LLMuteList::getInstance()->remove(mute); -} - -void LLPanelIMControlPanel::onVolumeChange(const LLSD& data) -{ - F32 volume = (F32)data.asReal(); - LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume); -} - -void LLPanelIMControlPanel::onTeleportButtonClicked() -{ - LLAvatarActions::offerTeleport(mAvatarID); -} -void LLPanelIMControlPanel::onPayButtonClicked() -{ - LLAvatarActions::pay(mAvatarID); -} - -void LLPanelIMControlPanel::onViewProfileButtonClicked() -{ - LLAvatarActions::showProfile(mAvatarID); -} - -void LLPanelIMControlPanel::onAddFriendButtonClicked() -{ - LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon"); - std::string full_name = avatar_icon->getFullName(); - LLAvatarActions::requestFriendshipDialog(mAvatarID, full_name); -} - -void LLPanelIMControlPanel::onShareButtonClicked() -{ - LLAvatarActions::share(mAvatarID); -} - -void LLPanelIMControlPanel::onFocusReceived() -{ - // Disable all the buttons (Call, Teleport, etc) if disconnected. - if (gDisconnected) - { - setAllChildrenEnabled(FALSE); - } -} - -void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id) -{ - LLPanelChatControlPanel::setSessionId(session_id); - - LLIMModel& im_model = LLIMModel::instance(); - - LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this); - mAvatarID = im_model.getOtherParticipantID(session_id); - LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this); - - // Disable "Add friend" button for friends. - getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(mAvatarID)); - - // Disable "Teleport" button if friend is offline - if(LLAvatarActions::isFriend(mAvatarID)) - { - getChildView("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mAvatarID)); - } - - getChild<LLAvatarIconCtrl>("avatar_icon")->setValue(mAvatarID); - - // Disable most profile buttons if the participant is - // not really an SL avatar (e.g., an Avaline caller). - LLIMModel::LLIMSession* im_session = - im_model.findIMSession(session_id); - if( im_session && !im_session->mOtherParticipantIsAvatar ) - { - getChildView("view_profile_btn")->setEnabled(FALSE); - getChildView("add_friend_btn")->setEnabled(FALSE); - - getChildView("share_btn")->setEnabled(FALSE); - getChildView("teleport_btn")->setEnabled(FALSE); - getChildView("pay_btn")->setEnabled(FALSE); - - getChild<LLTextBox>("avatar_name")->setValue(im_session->mName); - getChild<LLTextBox>("avatar_name")->setToolTip(im_session->mName); - } - else - { - // If the participant is an avatar, fetch the currect name - gCacheName->get(mAvatarID, false, - boost::bind(&LLPanelIMControlPanel::onNameCache, this, _1, _2, _3)); - } -} - -//virtual -void LLPanelIMControlPanel::changed(U32 mask) -{ - getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(mAvatarID)); - - // Disable "Teleport" button if friend is offline - if(LLAvatarActions::isFriend(mAvatarID)) - { - getChildView("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mAvatarID)); - } -} - -void LLPanelIMControlPanel::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group) -{ - if ( id == mAvatarID ) - { - std::string avatar_name = full_name; - getChild<LLTextBox>("avatar_name")->setValue(avatar_name); - getChild<LLTextBox>("avatar_name")->setToolTip(avatar_name); - - bool is_linden = LLStringUtil::endsWith(full_name, " Linden"); - getChild<LLUICtrl>("mute_btn")->setEnabled( !is_linden); - } -} - -LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id): -mParticipantList(NULL) -{ -} - -BOOL LLPanelGroupControlPanel::postBuild() -{ - childSetAction("group_info_btn", boost::bind(&LLPanelGroupControlPanel::onGroupInfoButtonClicked, this)); - - return LLPanelChatControlPanel::postBuild(); -} - -LLPanelGroupControlPanel::~LLPanelGroupControlPanel() -{ - delete mParticipantList; - mParticipantList = NULL; -} - -// virtual -void LLPanelGroupControlPanel::draw() -{ - // Need to resort the participant list if it's in sort by recent speaker order. - if (mParticipantList) - mParticipantList->updateRecentSpeakersOrder(); - LLPanelChatControlPanel::draw(); -} - -void LLPanelGroupControlPanel::onGroupInfoButtonClicked() -{ - LLGroupActions::show(mGroupID); -} - -void LLPanelGroupControlPanel::onSortMenuItemClicked(const LLSD& userdata) -{ - // TODO: Check this code when when sort order menu will be added. (EM) - if (false && !mParticipantList) - return; - - std::string chosen_item = userdata.asString(); - - if (chosen_item == "sort_name") - { - mParticipantList->setSortOrder(LLParticipantList::E_SORT_BY_NAME); - } - -} - -void LLPanelGroupControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state) -{ - LLPanelChatControlPanel::onVoiceChannelStateChanged(old_state, new_state); - mParticipantList->setSpeakingIndicatorsVisible(new_state >= LLVoiceChannel::STATE_CALL_STARTED); -} - -void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id) -{ - LLPanelChatControlPanel::setSessionId(session_id); - - mGroupID = session_id; - - // for group and Ad-hoc chat we need to include agent into list - if(!mParticipantList) - { - LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id); - mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true,false); - } -} - - -LLPanelAdHocControlPanel::LLPanelAdHocControlPanel(const LLUUID& session_id):LLPanelGroupControlPanel(session_id) -{ -} - -BOOL LLPanelAdHocControlPanel::postBuild() -{ - //We don't need LLPanelGroupControlPanel::postBuild() to be executed as there is no group_info_btn at AdHoc chat - return LLPanelChatControlPanel::postBuild(); -} diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index bba847b5d4..02915ec4bb 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -28,14 +28,12 @@ #define LL_LLPANELIMCONTROLPANEL_H #include "llpanel.h" -#include "llvoicechannel.h" #include "llcallingcard.h" class LLParticipantList; -class LLPanelChatControlPanel +class LLPanelChatControlPanel : public LLPanel - , public LLVoiceClientStatusObserver { public: LLPanelChatControlPanel() : @@ -44,21 +42,6 @@ public: virtual BOOL postBuild(); - void onCallButtonClicked(); - void onEndCallButtonClicked(); - void onOpenVoiceControlsClicked(); - - // Implements LLVoiceClientStatusObserver::onChange() to enable the call - // button when voice is available - /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); - - virtual void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state); - - void updateButtons(LLVoiceChannel::EState state); - - // Enables/disables call button depending on voice availability - void updateCallButton(); - virtual void setSessionId(const LLUUID& session_id); const LLUUID& getSessionId() { return mSessionId; } @@ -69,41 +52,6 @@ private: boost::signals2::connection mVoiceChannelStateChangeConnection; }; - -class LLPanelIMControlPanel : public LLPanelChatControlPanel, LLFriendObserver -{ -public: - LLPanelIMControlPanel(); - ~LLPanelIMControlPanel(); - - BOOL postBuild(); - - void setSessionId(const LLUUID& session_id); - - // LLFriendObserver trigger - virtual void changed(U32 mask); - -protected: - void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group); - -private: - void onViewProfileButtonClicked(); - void onAddFriendButtonClicked(); - void onShareButtonClicked(); - void onTeleportButtonClicked(); - void onPayButtonClicked(); - void onFocusReceived(); - - void onClickMuteVolume(); - void onClickBlock(); - void onClickUnblock(); - /*virtual*/ void draw(); - void onVolumeChange(const LLSD& data); - - LLUUID mAvatarID; -}; - - class LLPanelGroupControlPanel : public LLPanelChatControlPanel { public: @@ -121,9 +69,7 @@ protected: LLParticipantList* mParticipantList; private: - void onGroupInfoButtonClicked(); void onSortMenuItemClicked(const LLSD& userdata); - /*virtual*/ void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state); }; class LLPanelAdHocControlPanel : public LLPanelGroupControlPanel diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index c7454e85a9..88400e4ef2 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -52,6 +52,7 @@ #include "llmenubutton.h" #include "llplacesinventorybridge.h" #include "llplacesinventorypanel.h" +#include "llplacesfolderview.h" #include "lltoggleablemenu.h" #include "llviewermenu.h" #include "llviewerregion.h" @@ -102,7 +103,7 @@ void LLCheckFolderState::doFolder(LLFolderViewFolder* folder) // Counting only folders that pass the filter. // The listener check allow us to avoid counting the folder view // object itself because it has no listener assigned. - if (folder->hasFilteredDescendants() && folder->getListener()) + if (folder->getViewModelItem()->descendantsPassedFilter()) { if (folder->isOpen()) { @@ -138,7 +139,7 @@ private: // virtual void LLOpenFolderByID::doFolder(LLFolderViewFolder* folder) { - if (folder->getListener() && folder->getListener()->getUUID() == mFolderID) + if (folder->getViewModelItem() && static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem())->getUUID() == mFolderID) { if (!folder->isOpen()) { @@ -177,7 +178,7 @@ void LLLandmarksPanelObserver::changed(U32 mask) if (!mIsLibraryLandmarksOpen && library) { // Search for "Landmarks" folder in the Library and open it once on start up. See EXT-4827. - const LLUUID &landmarks_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false, true); + const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); if (landmarks_cat.notNull()) { LLOpenFolderByID opener(landmarks_cat); @@ -247,10 +248,7 @@ void LLLandmarksPanel::onSearchEdit(const std::string& string) LLPlacesInventoryPanel* inventory_list = dynamic_cast<LLPlacesInventoryPanel*>(tab->getAccordionView()); if (NULL == inventory_list) continue; - if (inventory_list->getFilter()) - { - filter_list(inventory_list, string); - } + filter_list(inventory_list, string); } if (sFilterSubString != string) @@ -281,28 +279,21 @@ void LLLandmarksPanel::onShowOnMap() //virtual void LLLandmarksPanel::onShowProfile() { - LLFolderViewItem* cur_item = getCurSelectedItem(); + LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem(); if(!cur_item) return; - cur_item->getListener()->performAction(mCurrentSelectedList->getModel(),"about"); + cur_item->performAction(mCurrentSelectedList->getModel(),"about"); } // virtual void LLLandmarksPanel::onTeleport() { - LLFolderViewItem* current_item = getCurSelectedItem(); - if (!current_item) - { - llwarns << "There are no selected list. No actions are performed." << llendl; - return; - } - - LLFolderViewEventListener* listenerp = current_item->getListener(); - if (listenerp && listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) + LLFolderViewModelItemInventory* view_model_item = getCurSelectedViewModelItem(); + if (view_model_item && view_model_item->getInventoryType() == LLInventoryType::IT_LANDMARK) { - listenerp->openItem(); + view_model_item->openItem(); } } @@ -313,8 +304,7 @@ bool LLLandmarksPanel::isSingleItemSelected() if (mCurrentSelectedList != NULL) { - LLPlacesFolderView* root_view = - static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder()); + LLFolderView* root_view = mCurrentSelectedList->getRootFolder(); if (root_view->getSelectedCount() == 1) { @@ -360,7 +350,7 @@ void LLLandmarksPanel::onSelectorButtonClicked() LLFolderViewItem* cur_item = mFavoritesInventoryPanel->getRootFolder()->getCurSelectedItem(); if (!cur_item) return; - LLFolderViewEventListener* listenerp = cur_item->getListener(); + LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem()); if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) { LLSD key; @@ -373,10 +363,7 @@ void LLLandmarksPanel::onSelectorButtonClicked() void LLLandmarksPanel::updateShowFolderState() { - if (!mLandmarksInventoryPanel->getFilter()) - return; - - bool show_all_folders = mLandmarksInventoryPanel->getRootFolder()->getFilterSubString().empty(); + bool show_all_folders = mLandmarksInventoryPanel->getFilterSubString().empty(); if (show_all_folders) { show_all_folders = category_has_descendents(mLandmarksInventoryPanel); @@ -417,13 +404,14 @@ void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_ bool LLLandmarksPanel::isLandmarkSelected() const { - LLFolderViewItem* current_item = getCurSelectedItem(); - if(current_item && current_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) - { - return true; - } + LLFolderViewModelItemInventory* current_item = getCurSelectedViewModelItem(); + return current_item && (current_item->getInventoryType() == LLInventoryType::IT_LANDMARK); +} - return false; +bool LLLandmarksPanel::isFolderSelected() const +{ + LLFolderViewModelItemInventory* current_item = getCurSelectedViewModelItem(); + return current_item && (current_item->getInventoryType() == LLInventoryType::IT_CATEGORY); } bool LLLandmarksPanel::isReceivedFolderSelected() const @@ -440,10 +428,10 @@ bool LLLandmarksPanel::isReceivedFolderSelected() const void LLLandmarksPanel::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb) { - LLFolderViewItem* cur_item = getCurSelectedItem(); - if(cur_item && cur_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) + LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem(); + if(cur_item && cur_item->getInventoryType() == LLInventoryType::IT_LANDMARK) { - LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getListener()->getUUID(), cb); + LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getUUID(), cb); if (landmark) { cb(landmark); @@ -456,6 +444,17 @@ LLFolderViewItem* LLLandmarksPanel::getCurSelectedItem() const return mCurrentSelectedList ? mCurrentSelectedList->getRootFolder()->getCurSelectedItem() : NULL; } +LLFolderViewModelItemInventory* LLLandmarksPanel::getCurSelectedViewModelItem() const +{ + LLFolderViewItem* cur_item = getCurSelectedItem(); + if (cur_item) + { + return static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem()); + } + return NULL; +} + + LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list, const std::string& tab_name, const LLUUID& obj_id, @@ -466,7 +465,7 @@ LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPa LLFolderView* root = inventory_list->getRootFolder(); - LLFolderViewItem* item = root->getItemByID(obj_id); + LLFolderViewItem* item = inventory_list->getItemByID(obj_id); if (!item) return NULL; @@ -508,12 +507,12 @@ void LLLandmarksPanel::processParcelInfo(const LLParcelData& parcel_data) // We have to make request to sever to get parcel_id and snaption_id. if(isLandmarkSelected()) { - LLFolderViewItem* cur_item = getCurSelectedItem(); + LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem(); if (!cur_item) return; - LLUUID id = cur_item->getListener()->getUUID(); + LLUUID id = cur_item->getUUID(); LLInventoryItem* inv_item = mCurrentSelectedList->getModel()->getItem(id); doActionOnCurSelectedLandmark(boost::bind( - &LLLandmarksPanel::doProcessParcelInfo, this, _1, cur_item, inv_item, parcel_data)); + &LLLandmarksPanel::doProcessParcelInfo, this, _1, getCurSelectedItem(), inv_item, parcel_data)); } } @@ -543,7 +542,7 @@ void LLLandmarksPanel::initFavoritesInventoryPanel() mFavoritesInventoryPanel = getChild<LLPlacesInventoryPanel>("favorites_list"); initLandmarksPanel(mFavoritesInventoryPanel); - mFavoritesInventoryPanel->getFilter()->setEmptyLookupMessage("FavoritesNoMatchingItems"); + mFavoritesInventoryPanel->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems"); initAccordion("tab_favorites", mFavoritesInventoryPanel, true); } @@ -554,12 +553,7 @@ void LLLandmarksPanel::initLandmarksInventoryPanel() initLandmarksPanel(mLandmarksInventoryPanel); - // Check if mLandmarksInventoryPanel is properly initialized and has a Filter created. - // In case of a dummy widget getFilter() will return NULL. - if (mLandmarksInventoryPanel->getFilter()) - { - mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); - } + mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); // subscribe to have auto-rename functionality while creating New Folder mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2)); @@ -583,7 +577,7 @@ void LLLandmarksPanel::initLibraryInventoryPanel() initLandmarksPanel(mLibraryInventoryPanel); // We want to fetch only "Landmarks" category from the library. - const LLUUID &landmarks_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false, true); + const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); if (landmarks_cat.notNull()) { LLInventoryModelBackgroundFetch::instance().start(landmarks_cat); @@ -595,12 +589,7 @@ void LLLandmarksPanel::initLibraryInventoryPanel() void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list) { - // In case of a dummy widget further we have no Folder View widget and no Filter, - // so further initialization leads to crash. - if (!inventory_list->getFilter()) - return; - - inventory_list->getFilter()->setEmptyLookupMessage("PlacesNoMatchingItems"); + inventory_list->getFilter().setEmptyLookupMessage("PlacesNoMatchingItems"); inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK); inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2)); @@ -665,20 +654,20 @@ void LLLandmarksPanel::deselectOtherThan(const LLPlacesInventoryPanel* inventory { if (inventory_list != mFavoritesInventoryPanel) { - mFavoritesInventoryPanel->getRootFolder()->clearSelection(); + mFavoritesInventoryPanel->clearSelection(); } if (inventory_list != mLandmarksInventoryPanel) { - mLandmarksInventoryPanel->getRootFolder()->clearSelection(); + mLandmarksInventoryPanel->clearSelection(); } if (inventory_list != mMyInventoryPanel) { - mMyInventoryPanel->getRootFolder()->clearSelection(); + mMyInventoryPanel->clearSelection(); } if (inventory_list != mLibraryInventoryPanel) { - mLibraryInventoryPanel->getRootFolder()->clearSelection(); + mLibraryInventoryPanel->clearSelection(); } } @@ -720,7 +709,7 @@ void LLLandmarksPanel::initListCommandsHandlers() void LLLandmarksPanel::updateListCommands() { bool add_folder_enabled = isActionEnabled("category"); - bool trash_enabled = isActionEnabled("delete"); + bool trash_enabled = isActionEnabled("delete") && (isFolderSelected() || isLandmarkSelected()); // keep Options & Add Landmark buttons always enabled mListCommands->getChildView(ADD_FOLDER_BUTTON_NAME)->setEnabled(add_folder_enabled); @@ -731,14 +720,9 @@ void LLLandmarksPanel::onActionsButtonClick() { LLToggleableMenu* menu = mGearFolderMenu; - LLFolderViewItem* cur_item = NULL; if(mCurrentSelectedList) { - cur_item = mCurrentSelectedList->getRootFolder()->getCurSelectedItem(); - if(!cur_item) - return; - - LLFolderViewEventListener* listenerp = cur_item->getListener(); + LLFolderViewModelItemInventory* listenerp = getCurSelectedViewModelItem(); if(!listenerp) return; @@ -776,6 +760,9 @@ void LLLandmarksPanel::onTrashButtonClick() const void LLLandmarksPanel::onAddAction(const LLSD& userdata) const { + LLFolderViewModelItemInventory* view_model = getCurSelectedViewModelItem(); + LLFolderViewItem* item = getCurSelectedItem(); + std::string command_name = userdata.asString(); if("add_landmark" == command_name) { @@ -791,24 +778,24 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const } else if ("category" == command_name) { - LLFolderViewItem* item = getCurSelectedItem(); if (item && mCurrentSelectedList == mLandmarksInventoryPanel) { - LLFolderViewEventListener* folder_bridge = NULL; - if (item-> getListener()->getInventoryType() + LLFolderViewModelItem* folder_bridge = NULL; + + if (view_model->getInventoryType() == LLInventoryType::IT_LANDMARK) { // for a landmark get parent folder bridge - folder_bridge = item->getParentFolder()->getListener(); + folder_bridge = item->getParentFolder()->getViewModelItem(); } - else if (item-> getListener()->getInventoryType() + else if (view_model->getInventoryType() == LLInventoryType::IT_CATEGORY) { // for a folder get its own bridge - folder_bridge = item->getListener(); + folder_bridge = view_model; } - menu_create_inventory_item(mCurrentSelectedList->getRootFolder(), + menu_create_inventory_item(mCurrentSelectedList, dynamic_cast<LLFolderBridge*> (folder_bridge), LLSD( "category"), gInventory.findCategoryUUIDForType( LLFolderType::FT_LANDMARK)); @@ -816,7 +803,7 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const else { //in case My Landmarks tab is completely empty (thus cannot be determined as being selected) - menu_create_inventory_item(mLandmarksInventoryPanel->getRootFolder(), NULL, LLSD("category"), + menu_create_inventory_item(mLandmarksInventoryPanel, NULL, LLSD("category"), gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK)); if (mMyLandmarksAccordionTab) @@ -834,9 +821,9 @@ void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const std::string command_name = userdata.asString(); if("copy_slurl" == command_name) { - LLFolderViewItem* cur_item = getCurSelectedItem(); + LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem(); if(cur_item) - LLLandmarkActions::copySLURLtoClipboard(cur_item->getListener()->getUUID()); + LLLandmarkActions::copySLURLtoClipboard(cur_item->getUUID()); } else if ( "paste" == command_name) { @@ -848,7 +835,7 @@ void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const } else { - mCurrentSelectedList->getRootFolder()->doToSelected(mCurrentSelectedList->getModel(),command_name); + mCurrentSelectedList->doToSelected(command_name); } } @@ -893,7 +880,7 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata) { if(mCurrentSelectedList) { - mCurrentSelectedList->getRootFolder()->doToSelected(&gInventory, userdata); + mCurrentSelectedList->doToSelected(userdata); } } } @@ -915,8 +902,9 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const { std::string command_name = userdata.asString(); - LLPlacesFolderView* root_folder_view = mCurrentSelectedList ? - static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder()) : NULL; + LLFolderView* root_folder_view = mCurrentSelectedList + ? mCurrentSelectedList->getRootFolder() + : NULL; if ("collapse_all" == command_name) { @@ -977,18 +965,13 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const { if (!root_folder_view) return false; - std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList(); + std::set<LLFolderViewItem*> selected_uuids = root_folder_view->getSelectionList(); // Allow to execute the command only if it can be applied to all selected items. - for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) + for (std::set<LLFolderViewItem*>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) { - LLFolderViewItem* item = root_folder_view->getItemByID(*iter); + LLFolderViewItem* item = *iter; - // If no item is found it might be a folder id. - if (!item) - { - item = root_folder_view->getFolderByID(*iter); - } if (!item) return false; if (!canItemBeModified(command_name, item)) return false; @@ -1012,10 +995,10 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const if ("show_on_map" == command_name) { - LLFolderViewItem* cur_item = root_folder_view->getCurSelectedItem(); + LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem(); if (!cur_item) return false; - LLViewerInventoryItem* inv_item = cur_item->getInventoryItem(); + LLViewerInventoryItem* inv_item = dynamic_cast<LLViewerInventoryItem*>(cur_item->getInventoryObject()); if (!inv_item) return false; LLUUID asset_uuid = inv_item->getAssetUUID(); @@ -1049,7 +1032,7 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const { if (mCurrentSelectedList) { - std::set<LLUUID> selection = mCurrentSelectedList->getRootFolder()->getSelectionList(); + std::set<LLFolderViewItem*> selection = mCurrentSelectedList->getRootFolder()->getSelectionList(); if (!selection.empty()) { return ( 1 == selection.size() && !LLAgentPicksInfo::getInstance()->isPickLimitReached() ); @@ -1105,27 +1088,23 @@ void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param) { const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList(); + std::set<LLFolderViewItem*> selected_items = root_folder_view->getSelectionList(); // Iterate through selected items to find out if any of these items are in Trash // or all the items are in Trash category. - for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) + for (std::set<LLFolderViewItem*>::const_iterator iter = selected_items.begin(); iter != selected_items.end(); ++iter) { - LLFolderViewItem* item = root_folder_view->getItemByID(*iter); + LLFolderViewItem* item = *iter; // If no item is found it might be a folder id. - if (!item) - { - item = root_folder_view->getFolderByID(*iter); - } if (!item) continue; - LLFolderViewEventListener* listenerp = item->getListener(); + LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem()); if(!listenerp) continue; // Trash category itself should not be included because it can't be // actually restored from trash. - are_all_items_in_trash &= listenerp->isItemInTrash() && *iter != trash_id; + are_all_items_in_trash &= listenerp->isItemInTrash() && listenerp->getUUID() != trash_id; // If there are any selected items in Trash including the Trash category itself // we show "Restore Item" in context menu and hide other irrelevant items. @@ -1149,7 +1128,7 @@ Rules: - cut/rename/delete in any other accordions - paste - only in Favorites, Landmarks accordions 3. For Folders we can: perform any action in Landmarks accordion, except Received folder - 4. We can not paste folders from Clipboard (processed by LLFolderView::canPaste()) + 4. We can paste folders from Clipboard (processed by LLFolderView::canPaste()) 5. Check LLFolderView/Inventory Bridges rules */ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const @@ -1164,7 +1143,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold bool can_be_modified = false; // landmarks can be modified in any other accordion... - if (item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) + if (static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem())->getInventoryType() == LLInventoryType::IT_LANDMARK) { can_be_modified = true; @@ -1202,12 +1181,11 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold if (can_be_modified) { - LLFolderViewEventListener* listenerp = item->getListener(); + LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem()); if ("cut" == command_name) { - // "Cut" disabled for folders. See EXT-8697. - can_be_modified = root_folder->canCut() && listenerp->getInventoryType() != LLInventoryType::IT_CATEGORY; + can_be_modified = root_folder->canCut(); } else if ("rename" == command_name) { @@ -1263,8 +1241,9 @@ bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType carg LLInventoryItem* item = static_cast<LLInventoryItem*>(cargo_data); if (item) { - LLFolderViewItem* fv_item = (mCurrentSelectedList && mCurrentSelectedList->getRootFolder()) ? - mCurrentSelectedList->getRootFolder()->getItemByID(item->getUUID()) : NULL; + LLFolderViewItem* fv_item = mCurrentSelectedList + ? mCurrentSelectedList->getItemByID(item->getUUID()) + : NULL; if (fv_item) { @@ -1392,7 +1371,7 @@ void LLLandmarksPanel::doCreatePick(LLLandmark* landmark) static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string) { // When search is cleared, restore the old folder state. - if (!inventory_list->getRootFolder()->getFilterSubString().empty() && string == "") + if (!inventory_list->getFilterSubString().empty() && string == "") { inventory_list->setFilterSubString(LLStringUtil::null); // Re-open folders that were open before @@ -1406,7 +1385,7 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin } // save current folder open state if no filter currently applied - if (inventory_list->getRootFolder()->getFilterSubString().empty()) + if (inventory_list->getFilterSubString().empty()) { inventory_list->saveFolderState(); } diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index b2f4e92473..8fae0f0b67 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -44,6 +44,7 @@ class LLMenuGL; class LLToggleableMenu; class LLInventoryPanel; class LLPlacesInventoryPanel; +class LLFolderViewModelItemInventory; class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver { @@ -84,9 +85,11 @@ protected: * @return true - if current selected panel is not null and selected item is a landmark */ bool isLandmarkSelected() const; + bool isFolderSelected() const; bool isReceivedFolderSelected() const; void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb); LLFolderViewItem* getCurSelectedItem() const; + LLFolderViewModelItemInventory* getCurSelectedViewModelItem() const; /** * Selects item with "obj_id" in "inventory_list" and scrolls accordion diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp index b3adfac8a2..26cd3ff1c1 100644 --- a/indra/newview/llpanellandmedia.cpp +++ b/indra/newview/llpanellandmedia.cpp @@ -85,6 +85,7 @@ BOOL LLPanelLandMedia::postBuild() mMediaTextureCtrl->setCommitCallback( onCommitAny, this ); mMediaTextureCtrl->setAllowNoTexture ( TRUE ); mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + mMediaTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); mMediaAutoScaleCheck = getChild<LLCheckBoxCtrl>("media_auto_scale"); diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 058d1ad6bc..bcb90bcb56 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "llpanellogin.h" +#include "lllayoutstack.h" #include "indra_constants.h" // for key and mask constants #include "llfloaterreg.h" @@ -104,7 +105,6 @@ public: // Public methods //--------------------------------------------------------------------------- LLPanelLogin::LLPanelLogin(const LLRect &rect, - BOOL show_server, void (*callback)(S32 option, void* user_data), void *cb_data) : LLPanel(), @@ -119,7 +119,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, // instance management if (LLPanelLogin::sInstance) { - llwarns << "Duplicate instance of login view deleted" << llendl; + LL_WARNS("AppInit") << "Duplicate instance of login view deleted" << LL_ENDL; // Don't leave bad pointer in gFocusMgr gFocusMgr.setDefaultKeyboardFocus(NULL); @@ -139,44 +139,83 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, mLogoImage = LLUI::getUIImage("startup_logo"); buildFromFile( "panel_login.xml"); - + reshape(rect.getWidth(), rect.getHeight()); - getChild<LLLineEditor>("password_edit")->setKeystrokeCallback(onPassKey, this); + LLLineEditor* password_edit(getChild<LLLineEditor>("password_edit")); + password_edit->setKeystrokeCallback(onPassKey, this); + // STEAM-14: When user presses Enter with this field in focus, initiate login + password_edit->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this)); // change z sort of clickable text to be behind buttons sendChildToBack(getChildView("forgot_password_text")); - if(LLStartUp::getStartSLURL().getType() != LLSLURL::LOCATION) + LLComboBox* location_combo = getChild<LLComboBox>("start_location_combo"); + updateLocationSelectorsVisibility(); // separate so that it can be called from preferences + location_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this)); + + LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo"); + server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this)); + + // Load all of the grids, sorted, and then add a bar and the current grid at the top + server_choice_combo->removeall(); + + std::string current_grid = LLGridManager::getInstance()->getGrid(); + std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); + for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin(); + grid_choice != known_grids.end(); + grid_choice++) { - LLSLURL slurl(gSavedSettings.getString("LoginLocation")); - LLStartUp::setStartSLURL(slurl); + if (!grid_choice->first.empty() && current_grid != grid_choice->first) + { + LL_DEBUGS("AppInit")<<"adding "<<grid_choice->first<<LL_ENDL; + server_choice_combo->add(grid_choice->second, grid_choice->first); + } } - updateLocationCombo(false); - - LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo"); - server_choice_combo->setCommitCallback(onSelectServer, NULL); - server_choice_combo->setFocusLostCallback(boost::bind(onServerComboLostFocus, _1)); - updateServerCombo(); + server_choice_combo->sortByName(); + server_choice_combo->addSeparator(ADD_TOP); + LL_DEBUGS("AppInit")<<"adding current "<<current_grid<<LL_ENDL; + server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(), + current_grid, + ADD_TOP); + server_choice_combo->selectFirstItem(); + LLSLURL start_slurl(LLStartUp::getStartSLURL()); + if ( !start_slurl.isSpatial() ) // has a start been established by the command line or NextLoginLocation ? + { + // no, so get the preference setting + std::string defaultStartLocation = gSavedSettings.getString("LoginLocation"); + LL_INFOS("AppInit")<<"default LoginLocation '"<<defaultStartLocation<<"'"<<LL_ENDL; + LLSLURL defaultStart(defaultStartLocation); + if ( defaultStart.isSpatial() ) + { + LLStartUp::setStartSLURL(defaultStart); + } + else + { + LL_INFOS("AppInit")<<"no valid LoginLocation, using home"<<LL_ENDL; + LLSLURL homeStart(LLSLURL::SIM_LOCATION_HOME); + LLStartUp::setStartSLURL(homeStart); + } + } + else + { + LLPanelLogin::onUpdateStartSLURL(start_slurl); // updates grid if needed + } + childSetAction("connect_btn", onClickConnect, this); - getChild<LLPanel>("login")->setDefaultBtn("connect_btn"); + getChild<LLPanel>("links_login_panel")->setDefaultBtn("connect_btn"); std::string channel = LLVersionInfo::getChannel(); std::string version = llformat("%s (%d)", LLVersionInfo::getShortVersion().c_str(), LLVersionInfo::getBuild()); - //LLTextBox* channel_text = getChild<LLTextBox>("channel_text"); - //channel_text->setTextArg("[CHANNEL]", channel); // though not displayed - //channel_text->setTextArg("[VERSION]", version); - //channel_text->setClickedCallback(onClickVersion, this); LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text"); forgot_password_text->setClickedCallback(onClickForgotPassword, NULL); - LLTextBox* create_new_account_text = getChild<LLTextBox>("create_new_account_text"); - create_new_account_text->setClickedCallback(onClickNewAccount, NULL); + childSetAction("create_new_account_btn", onClickNewAccount, NULL); LLTextBox* need_help_text = getChild<LLTextBox>("login_help"); need_help_text->setClickedCallback(onClickHelp, NULL); @@ -184,17 +223,17 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, // get the web browser control LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html"); web_browser->addObserver(this); - + reshapeBrowser(); loadLoginPage(); - + // Show last logged in user favorites in "Start at" combo. addUsersWithFavoritesToUsername(); - getChild<LLComboBox>("username_combo")->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this)); - - updateLocationCombo(false); - + LLComboBox* username_combo(getChild<LLComboBox>("username_combo")); + username_combo->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this)); + // STEAM-14: When user presses Enter with this field in focus, initiate login + username_combo->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this)); } void LLPanelLogin::addUsersWithFavoritesToUsername() @@ -216,6 +255,7 @@ void LLPanelLogin::addUsersWithFavoritesToUsername() void LLPanelLogin::addFavoritesToStartLocation() { + // Clear the combo. LLComboBox* combo = getChild<LLComboBox>("start_location_combo"); if (!combo) return; int num_items = combo->getItemCount(); @@ -223,6 +263,10 @@ void LLPanelLogin::addFavoritesToStartLocation() { combo->remove(i); } + + // Load favorites into the combo. + std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple(); + std::string canonical_user_name = canonicalize_username(user_defined_name); std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); LLSD fav_llsd; llifstream file; @@ -232,15 +276,18 @@ void LLPanelLogin::addFavoritesToStartLocation() for (LLSD::map_const_iterator iter = fav_llsd.beginMap(); iter != fav_llsd.endMap(); ++iter) { - std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple(); - // The account name in stored_favorites.xml has Resident last name even if user has // a single word account name, so it can be compared case-insensitive with the // user defined "firstname lastname". - S32 res = LLStringUtil::compareInsensitive(canonicalize_username(user_defined_name), iter->first); - if (res != 0) continue; + S32 res = LLStringUtil::compareInsensitive(canonical_user_name, iter->first); + if (res != 0) + { + lldebugs << "Skipping favorites for " << iter->first << llendl; + continue; + } combo->addSeparator(); + lldebugs << "Loading favorites for " << iter->first << llendl; LLSD user_llsd = iter->second; for (LLSD::array_const_iterator iter1 = user_llsd.beginArray(); iter1 != user_llsd.endArray(); ++iter1) @@ -381,25 +428,27 @@ void LLPanelLogin::giveFocus() // static void LLPanelLogin::showLoginWidgets() { - // *NOTE: Mani - This may or may not be obselete code. - // It seems to be part of the defunct? reg-in-client project. - sInstance->getChildView("login_widgets")->setVisible( true); - LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); - sInstance->reshapeBrowser(); - // *TODO: Append all the usual login parameters, like first_login=Y etc. - std::string splash_screen_url = LLGridManager::getInstance()->getLoginPage(); - web_browser->navigateTo( splash_screen_url, "text/html" ); - LLUICtrl* username_combo = sInstance->getChild<LLUICtrl>("username_combo"); - username_combo->setFocus(TRUE); + if (sInstance) + { + // *NOTE: Mani - This may or may not be obselete code. + // It seems to be part of the defunct? reg-in-client project. + sInstance->getChildView("login_widgets")->setVisible( true); + LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); + sInstance->reshapeBrowser(); + // *TODO: Append all the usual login parameters, like first_login=Y etc. + std::string splash_screen_url = LLGridManager::getInstance()->getLoginPage(); + web_browser->navigateTo( splash_screen_url, "text/html" ); + LLUICtrl* username_combo = sInstance->getChild<LLUICtrl>("username_combo"); + username_combo->setFocus(TRUE); + } } // static void LLPanelLogin::show(const LLRect &rect, - BOOL show_server, void (*callback)(S32 option, void* user_data), void* callback_data) { - new LLPanelLogin(rect, show_server, callback, callback_data); + new LLPanelLogin(rect, callback, callback_data); if( !gFocusMgr.getKeyboardFocus() ) { @@ -559,21 +608,6 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential, remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue(); } -// static -BOOL LLPanelLogin::isGridComboDirty() -{ - BOOL user_picked = FALSE; - if (!sInstance) - { - llwarns << "Attempted getServer with no login view shown" << llendl; - } - else - { - LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo"); - user_picked = combo->isDirty(); - } - return user_picked; -} // static BOOL LLPanelLogin::areCredentialFieldsDirty() @@ -603,83 +637,86 @@ BOOL LLPanelLogin::areCredentialFieldsDirty() // static -void LLPanelLogin::updateLocationCombo( bool force_visible ) +void LLPanelLogin::updateLocationSelectorsVisibility() { - if (!sInstance) + if (sInstance) { - return; + BOOL show_start = gSavedSettings.getBOOL("ShowStartLocation"); + sInstance->getChild<LLLayoutPanel>("start_location_panel")->setVisible(show_start); + + BOOL show_server = gSavedSettings.getBOOL("ForceShowGrid"); + sInstance->getChild<LLLayoutPanel>("grid_panel")->setVisible(show_server); } - - LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo"); - - switch(LLStartUp::getStartSLURL().getType()) - { - case LLSLURL::LOCATION: - { - - combo->setCurrentByIndex( 2 ); - combo->setTextEntry(LLStartUp::getStartSLURL().getLocationString()); - break; - } - case LLSLURL::HOME_LOCATION: - combo->setCurrentByIndex(1); - break; - default: - combo->setCurrentByIndex(0); - break; - } - - BOOL show_start = TRUE; - - if ( ! force_visible ) - show_start = gSavedSettings.getBOOL("ShowStartLocation"); - - sInstance->getChildView("start_location_combo")->setVisible( show_start); - sInstance->getChildView("start_location_text")->setVisible( show_start); - - BOOL show_server = gSavedSettings.getBOOL("ForceShowGrid"); - sInstance->getChildView("server_combo_text")->setVisible( show_server); - sInstance->getChildView("server_combo")->setVisible( show_server); } -// static -void LLPanelLogin::updateStartSLURL() +// static - called from LLStartUp::setStartSLURL +void LLPanelLogin::onUpdateStartSLURL(const LLSLURL& new_start_slurl) { if (!sInstance) return; - - LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo"); - S32 index = combo->getCurrentIndex(); - - switch (index) + + LL_DEBUGS("AppInit")<<new_start_slurl.asString()<<LL_ENDL; + + LLComboBox* location_combo = sInstance->getChild<LLComboBox>("start_location_combo"); + /* + * Determine whether or not the new_start_slurl modifies the grid. + * + * Note that some forms that could be in the slurl are grid-agnostic., + * such as "home". Other forms, such as + * https://grid.example.com/region/Party%20Town/20/30/5 + * specify a particular grid; in those cases we want to change the grid + * and the grid selector to match the new value. + */ + enum LLSLURL::SLURL_TYPE new_slurl_type = new_start_slurl.getType(); + switch ( new_slurl_type ) { - case 0: - { - LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_LAST)); - break; - } - case 1: - { - LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME)); - break; - } - default: + case LLSLURL::LOCATION: + { + std::string slurl_grid = LLGridManager::getInstance()->getGrid(new_start_slurl.getGrid()); + if ( ! slurl_grid.empty() ) // is that a valid grid? { - LLSLURL slurl = LLSLURL(combo->getValue().asString()); - if(slurl.getType() == LLSLURL::LOCATION) + if ( slurl_grid != LLGridManager::getInstance()->getGrid() ) // new grid? { - // we've changed the grid, so update the grid selection - LLStartUp::setStartSLURL(slurl); + // the slurl changes the grid, so update everything to match + LLGridManager::getInstance()->setGridChoice(slurl_grid); + + // update the grid selector to match the slurl + LLComboBox* server_combo = sInstance->getChild<LLComboBox>("server_combo"); + std::string server_label(LLGridManager::getInstance()->getGridLabel(slurl_grid)); + server_combo->setSimple(server_label); + + updateServer(); // to change the links and splash screen } - break; - } + location_combo->setTextEntry(new_start_slurl.getLocationString()); + } + else + { + // the grid specified by the slurl is not known + LLNotificationsUtil::add("InvalidLocationSLURL"); + LL_WARNS("AppInit")<<"invalid LoginLocation:"<<new_start_slurl.asString()<<LL_ENDL; + location_combo->setTextEntry(LLStringUtil::null); + } + } + break; + + case LLSLURL::HOME_LOCATION: + location_combo->setCurrentByIndex(1); // home location + break; + + case LLSLURL::LAST_LOCATION: + location_combo->setCurrentByIndex(0); // last location + break; + + default: + LL_WARNS("AppInit")<<"invalid login slurl, using home"<<LL_ENDL; + location_combo->setCurrentByIndex(1); // home location + break; } } - void LLPanelLogin::setLocation(const LLSLURL& slurl) { - LLStartUp::setStartSLURL(slurl); - updateServer(); + LL_DEBUGS("AppInit")<<"setting Location "<<slurl.asString()<<LL_ENDL; + LLStartUp::setStartSLURL(slurl); // calls onUpdateStartSLURL, above } // static @@ -697,13 +734,14 @@ void LLPanelLogin::closePanel() // static void LLPanelLogin::setAlwaysRefresh(bool refresh) { - if (LLStartUp::getStartupState() >= STATE_LOGIN_CLEANUP) return; - - LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); - - if (web_browser) + if (sInstance && LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) { - web_browser->setAlwaysRefresh(refresh); + LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); + + if (web_browser) + { + web_browser->setAlwaysRefresh(refresh); + } } } @@ -712,82 +750,53 @@ void LLPanelLogin::setAlwaysRefresh(bool refresh) void LLPanelLogin::loadLoginPage() { if (!sInstance) return; - - std::ostringstream oStr; - std::string login_page = LLGridManager::getInstance()->getLoginPage(); + LLURI login_page = LLURI(LLGridManager::getInstance()->getLoginPage()); + LLSD params(login_page.queryMap()); - oStr << login_page; - - // Use the right delimeter depending on how LLURI parses the URL - LLURI login_page_uri = LLURI(login_page); - - std::string first_query_delimiter = "&"; - if (login_page_uri.queryMap().size() == 0) - { - first_query_delimiter = "?"; - } + LL_DEBUGS("AppInit") << "login_page: " << login_page << LL_ENDL; // Language - std::string language = LLUI::getLanguage(); - oStr << first_query_delimiter<<"lang=" << language; - + params["lang"] = LLUI::getLanguage(); + // First Login? if (gSavedSettings.getBOOL("FirstLoginThisInstall")) { - oStr << "&firstlogin=TRUE"; + params["firstlogin"] = "TRUE"; // not bool: server expects string TRUE } // Channel and Version - std::string version = llformat("%s (%d)", - LLVersionInfo::getShortVersion().c_str(), - LLVersionInfo::getBuild()); + params["version"] = llformat("%s (%d)", + LLVersionInfo::getShortVersion().c_str(), + LLVersionInfo::getBuild()); + params["channel"] = LLVersionInfo::getChannel(); - char* curl_channel = curl_escape(LLVersionInfo::getChannel().c_str(), 0); - char* curl_version = curl_escape(version.c_str(), 0); + // Grid + params["grid"] = LLGridManager::getInstance()->getGridId(); - oStr << "&channel=" << curl_channel; - oStr << "&version=" << curl_version; + // add OS info + params["os"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple(); - curl_free(curl_channel); - curl_free(curl_version); + // sourceid + params["sourceid"] = gSavedSettings.getString("sourceid"); + + // Make an LLURI with this augmented info + LLURI login_uri(LLURI::buildHTTP(login_page.authority(), + login_page.path(), + params)); - // Grid - char* curl_grid = curl_escape(LLGridManager::getInstance()->getGridLabel().c_str(), 0); - oStr << "&grid=" << curl_grid; - curl_free(curl_grid); - - // add OS info - char * os_info = curl_escape(LLAppViewer::instance()->getOSInfo().getOSStringSimple().c_str(), 0); - oStr << "&os=" << os_info; - curl_free(os_info); - gViewerWindow->setMenuBackgroundColor(false, !LLGridManager::getInstance()->isInProductionGrid()); - + LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); - if (web_browser->getCurrentNavUrl() != oStr.str()) + if (web_browser->getCurrentNavUrl() != login_uri.asString()) { - web_browser->navigateTo( oStr.str(), "text/html" ); + LL_DEBUGS("AppInit") << "loading: " << login_uri << LL_ENDL; + web_browser->navigateTo( login_uri.asString(), "text/html" ); } } void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event) { - if(event == MEDIA_EVENT_NAVIGATE_COMPLETE) - { - LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); - if (web_browser) - { - // *HACK HACK HACK HACK! - /* Stuff a Tab key into the browser now so that the first field will - ** get the focus! The embedded javascript on the page that properly - ** sets the initial focus in a real web browser is not working inside - ** the viewer, so this is an UGLY HACK WORKAROUND for now. - */ - // Commented out as it's not reliable - //web_browser->handleKey(KEY_TAB, MASK_NONE, false); - } - } } //--------------------------------------------------------------------------- @@ -804,15 +813,9 @@ void LLPanelLogin::onClickConnect(void *) LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo"); LLSD combo_val = combo->getSelectedValue(); - if (combo_val.isUndefined()) - { - combo_val = combo->getValue(); - } - if(combo_val.isUndefined()) - { - LLNotificationsUtil::add("StartRegionEmpty"); - return; - } + + // the grid definitions may come from a user-supplied grids.xml, so they may not be good + LL_DEBUGS("AppInit")<<"grid "<<combo_val.asString()<<LL_ENDL; try { LLGridManager::getInstance()->setGridChoice(combo_val.asString()); @@ -820,13 +823,14 @@ void LLPanelLogin::onClickConnect(void *) catch (LLInvalidGridName ex) { LLSD args; - args["GRID"] = combo_val.asString(); + args["GRID"] = ex.name(); LLNotificationsUtil::add("InvalidGrid", args); return; } - updateStartSLURL(); - std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString(); + // The start location SLURL has already been sent to LLStartUp::setStartSLURL + + std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString(); if(username.empty()) { @@ -869,7 +873,10 @@ void LLPanelLogin::onClickConnect(void *) // static void LLPanelLogin::onClickNewAccount(void*) { - LLWeb::loadURLExternal(sInstance->getString("create_account_url")); + if (sInstance) + { + LLWeb::loadURLExternal(LLTrans::getString("create_account_url")); + } } @@ -905,7 +912,7 @@ void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data) This->mPasswordModified = TRUE; if (gKeyboard->getKeyDown(KEY_CAPSLOCK) && sCapslockDidNotification == FALSE) { -// *TODO: use another way to notify user about enabled caps lock, see EXT-6858 + // *TODO: use another way to notify user about enabled caps lock, see EXT-6858 sCapslockDidNotification = TRUE; } } @@ -913,113 +920,99 @@ void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data) void LLPanelLogin::updateServer() { - try + if (sInstance) { - - updateServerCombo(); - // if they've selected another grid, we should load the credentials - // for that grid and set them to the UI. - if(sInstance && !sInstance->areCredentialFieldsDirty()) + try { - LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid()); - bool remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue(); - sInstance->setFields(credential, remember); - } - // grid changed so show new splash screen (possibly) - loadLoginPage(); - updateLocationCombo(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION); - } - catch (LLInvalidGridName ex) - { - // do nothing - } -} + // if they've selected another grid, we should load the credentials + // for that grid and set them to the UI. + if(!sInstance->areCredentialFieldsDirty()) + { + LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid()); + bool remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue(); + sInstance->setFields(credential, remember); + } -void LLPanelLogin::updateServerCombo() -{ - if (!sInstance) - { - return; - } - // We add all of the possible values, sorted, and then add a bar and the current value at the top - LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo"); - server_choice_combo->removeall(); + // update the login panel links + bool system_grid = LLGridManager::getInstance()->isSystemGrid(); - std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(!gSavedSettings.getBOOL("ShowBetaGrids")); + // Want to vanish not only create_new_account_btn, but also the + // title text over it, so turn on/off the whole layout_panel element. + sInstance->getChild<LLLayoutPanel>("links")->setVisible(system_grid); + sInstance->getChildView("forgot_password_text")->setVisible(system_grid); - for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin(); - grid_choice != known_grids.end(); - grid_choice++) - { - if (!grid_choice->first.empty()) + // grid changed so show new splash screen (possibly) + loadLoginPage(); + } + catch (LLInvalidGridName ex) { - server_choice_combo->add(grid_choice->second, grid_choice->first); + LL_WARNS("AppInit")<<"server '"<<ex.name()<<"' selection failed"<<LL_ENDL; + LLSD args; + args["GRID"] = ex.name(); + LLNotificationsUtil::add("InvalidGrid", args); + return; } } - server_choice_combo->sortByName(); - - server_choice_combo->addSeparator(ADD_TOP); - - server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(), - LLGridManager::getInstance()->getGrid(), ADD_TOP); - - server_choice_combo->selectFirstItem(); } -// static -void LLPanelLogin::onSelectServer(LLUICtrl*, void*) +void LLPanelLogin::onSelectServer() { - // *NOTE: The paramters for this method are ignored. - // LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe, void*) - // calls this method. - LL_INFOS("AppInit") << "onSelectServer" << LL_ENDL; // The user twiddled with the grid choice ui. // apply the selection to the grid setting. LLPointer<LLCredential> credential; - LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo"); - LLSD combo_val = combo->getSelectedValue(); - if (combo_val.isUndefined()) + LLComboBox* server_combo = getChild<LLComboBox>("server_combo"); + LLSD server_combo_val = server_combo->getSelectedValue(); + LL_INFOS("AppInit") << "grid "<<server_combo_val.asString()<< LL_ENDL; + LLGridManager::getInstance()->setGridChoice(server_combo_val.asString()); + + /* + * Determine whether or not the value in the start_location_combo makes sense + * with the new grid value. + * + * Note that some forms that could be in the location combo are grid-agnostic, + * such as "MyRegion/128/128/0". There could be regions with that name on any + * number of grids, so leave them alone. Other forms, such as + * https://grid.example.com/region/Party%20Town/20/30/5 specify a particular + * grid; in those cases we want to clear the location. + */ + LLComboBox* location_combo = getChild<LLComboBox>("start_location_combo"); + S32 index = location_combo->getCurrentIndex(); + switch (index) { - combo_val = combo->getValue(); + case 0: // last location + case 1: // home location + // do nothing - these are grid-agnostic locations + break; + + default: + { + std::string location = location_combo->getValue().asString(); + LLSLURL slurl(location); // generata a slurl from the location combo contents + if ( slurl.getType() == LLSLURL::LOCATION + && slurl.getGrid() != LLGridManager::getInstance()->getGrid() + ) + { + // the grid specified by the location is not this one, so clear the combo + location_combo->setCurrentByIndex(0); // last location on the new grid + location_combo->setTextEntry(LLStringUtil::null); + } + } + break; } - - combo = sInstance->getChild<LLComboBox>("start_location_combo"); - combo->setCurrentByIndex(1); - LLStartUp::setStartSLURL(LLSLURL(gSavedSettings.getString("LoginLocation"))); - LLGridManager::getInstance()->setGridChoice(combo_val.asString()); - // This new selection will override preset uris - // from the command line. + updateServer(); - updateLocationCombo(false); - updateLoginPanelLinks(); } -void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe) +void LLPanelLogin::onLocationSLURL() { - if (!sInstance) - { - return; - } + LLComboBox* location_combo = getChild<LLComboBox>("start_location_combo"); + std::string location = location_combo->getValue().asString(); + LL_DEBUGS("AppInit")<<location<<LL_ENDL; - LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo"); - if(fe == combo) - { - onSelectServer(combo, NULL); - } + LLStartUp::setStartSLURL(location); // calls onUpdateStartSLURL, above } -void LLPanelLogin::updateLoginPanelLinks() -{ - LLSD grid_data; - LLGridManager::getInstance()->getGridInfo(grid_data); - bool system_grid = grid_data.has(GRID_IS_SYSTEM_GRID_VALUE); - - // need to call through sInstance, as it's called from onSelectServer, which - // is static. - sInstance->getChildView("create_new_account_text")->setVisible( system_grid); - sInstance->getChildView("forgot_password_text")->setVisible( system_grid); -} std::string canonicalize_username(const std::string& name) { diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index a439c4ff6b..c71cfc3783 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -44,7 +44,7 @@ class LLPanelLogin: { LOG_CLASS(LLPanelLogin); public: - LLPanelLogin(const LLRect &rect, BOOL show_server, + LLPanelLogin(const LLRect &rect, void (*callback)(S32 option, void* user_data), void *callback_data); ~LLPanelLogin(); @@ -57,7 +57,7 @@ public: // hidden on startup for reg-in-client static void showLoginWidgets(); - static void show(const LLRect &rect, BOOL show_server, + static void show(const LLRect &rect, void (*callback)(S32 option, void* user_data), void* callback_data); @@ -65,11 +65,12 @@ public: static void getFields(LLPointer<LLCredential>& credential, BOOL& remember); - static BOOL isGridComboDirty(); static BOOL areCredentialFieldsDirty(); static void setLocation(const LLSLURL& slurl); - static void updateLocationCombo(bool force_visible); // simply update the combo box + /// Call when preferences that control visibility may have changed + static void updateLocationSelectorsVisibility(); + static void closePanel(); void setSiteIsAlive( bool alive ); @@ -82,22 +83,24 @@ public: /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); static void updateServer(); // update the combo box, change the login page to the new server, clear the combo + /// to be called from LLStartUp::setStartSLURL + static void onUpdateStartSLURL(const LLSLURL& new_start_slurl); + private: friend class LLPanelLoginListener; void reshapeBrowser(); void addFavoritesToStartLocation(); void addUsersWithFavoritesToUsername(); + void onSelectServer(); + void onLocationSLURL(); + static void onClickConnect(void*); static void onClickNewAccount(void*); static void onClickVersion(void*); static void onClickForgotPassword(void*); static void onClickHelp(void*); static void onPassKey(LLLineEditor* caller, void* user_data); - static void onSelectServer(LLUICtrl*, void*); - static void onServerComboLostFocus(LLFocusableElement*); static void updateServerCombo(); - static void updateStartSLURL(); - static void updateLoginPanelLinks(); private: LLPointer<LLUIImage> mLogoImage; diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 9944b51902..d6535c88e9 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" @@ -46,12 +47,14 @@ #include "llresmgr.h" #include "llscrollcontainer.h" #include "llsdserialize.h" +#include "llsdparam.h" #include "llspinctrl.h" #include "lltoggleablemenu.h" #include "lltooldraganddrop.h" #include "llviewermenu.h" #include "llviewertexturelist.h" #include "llsidepanelinventory.h" +#include "llfolderview.h" const std::string FILTERS_FILENAME("filters.xml"); @@ -104,7 +107,6 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p) mMenuAdd(NULL), mNeedUploadCost(true) { - LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_INIT); // Menu Callbacks (non contex menus) mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2)); mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLPanelMainInventory::closeAllFolders, this)); @@ -115,7 +117,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p) mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this)); mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this)); mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2)); - mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars)); + mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this)); mSavedFolderState = new LLSaveFolderState(); mSavedFolderState->setApply(FALSE); @@ -128,7 +130,7 @@ BOOL LLPanelMainInventory::postBuild() mFilterTabs = getChild<LLTabContainer>("inventory filter tabs"); mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this)); - //panel->getFilter()->markDefault(); + //panel->getFilter().markDefault(); // Set up the default inv. panel/filter settings. mActivePanel = getChild<LLInventoryPanel>("All Items"); @@ -136,7 +138,7 @@ BOOL LLPanelMainInventory::postBuild() { // "All Items" is the previous only view, so it gets the InventorySortOrder mActivePanel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER)); - mActivePanel->getFilter()->markDefault(); + mActivePanel->getFilter().markDefault(); mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); mActivePanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mActivePanel, _1, _2)); mResortActivePanel = true; @@ -147,7 +149,7 @@ BOOL LLPanelMainInventory::postBuild() recent_items_panel->setSinceLogoff(TRUE); recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE); recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - recent_items_panel->getFilter()->markDefault(); + recent_items_panel->getFilter().markDefault(); recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2)); } @@ -166,11 +168,14 @@ BOOL LLPanelMainInventory::postBuild() // Note that the "All Items" settings do not persist. if(recent_items_panel) { - if(savedFilterState.has(recent_items_panel->getFilter()->getName())) + if(savedFilterState.has(recent_items_panel->getFilter().getName())) { LLSD recent_items = savedFilterState.get( - recent_items_panel->getFilter()->getName()); - recent_items_panel->getFilter()->fromLLSD(recent_items); + recent_items_panel->getFilter().getName()); + LLInventoryFilter::Params p; + LLParamSDParser parser; + parser.readSD(recent_items, p); + recent_items_panel->getFilter().fromParams(p); } } @@ -207,24 +212,28 @@ LLPanelMainInventory::~LLPanelMainInventory( void ) LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items"); if (all_items_panel) { - LLInventoryFilter* filter = all_items_panel->getFilter(); - if (filter) + LLSD filterState; + LLInventoryPanel::InventoryState p; + all_items_panel->getFilter().toParams(p.filter); + all_items_panel->getRootViewModel().getSorter().toParams(p.sort); + if (p.validateBlock(false)) { - LLSD filterState; - filter->toLLSD(filterState); - filterRoot[filter->getName()] = filterState; + LLParamSDParser().writeSD(filterState, p); + filterRoot[all_items_panel->getName()] = filterState; } } - LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items"); - if (recent_items_panel) + LLInventoryPanel* panel = findChild<LLInventoryPanel>("Recent Items"); + if (panel) { - LLInventoryFilter* filter = recent_items_panel->getFilter(); - if (filter) + LLSD filterState; + LLInventoryPanel::InventoryState p; + panel->getFilter().toParams(p.filter); + panel->getRootViewModel().getSorter().toParams(p.sort); + if (p.validateBlock(false)) { - LLSD filterState; - filter->toLLSD(filterState); - filterRoot[filter->getName()] = filterState; + LLParamSDParser().writeSD(filterState, p); + filterRoot[panel->getName()] = filterState; } } @@ -284,7 +293,7 @@ BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask) void LLPanelMainInventory::doToSelected(const LLSD& userdata) { - getPanel()->getRootFolder()->doToSelected(&gInventory, userdata); + getPanel()->doToSelected(userdata); } void LLPanelMainInventory::closeAllFolders() @@ -294,18 +303,25 @@ 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) { - menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata); + reset_inventory_filter(); + menu_create_inventory_item(getPanel(), NULL, userdata); } void LLPanelMainInventory::resetFilters() { LLFloaterInventoryFinder *finder = getFinder(); - getActivePanel()->getFilter()->resetDefault(); + getActivePanel()->getFilter().resetDefault(); if (finder) { finder->updateElementsFromFilter(); @@ -368,7 +384,7 @@ void LLPanelMainInventory::onClearSearch() if (mActivePanel) { mActivePanel->setFilterSubString(LLStringUtil::null); - mActivePanel->setFilterTypes(0xffffffff); + mActivePanel->setFilterTypes(0xffffffffffffffffULL); mActivePanel->setFilterLinks(LLInventoryFilter::FILTERLINK_INCLUDE_LINKS); } @@ -410,7 +426,7 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string ) } // save current folder open state if no filter currently applied - if (!mActivePanel->getRootFolder()->isFilterModified()) + if (!mActivePanel->getFilter().isNotDefault()) { mSavedFolderState->setApply(FALSE); mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); @@ -472,13 +488,13 @@ void LLPanelMainInventory::onFilterSelected() } setFilterSubString(mFilterSubString); - LLInventoryFilter* filter = mActivePanel->getFilter(); + LLInventoryFilter& filter = mActivePanel->getFilter(); LLFloaterInventoryFinder *finder = getFinder(); if (finder) { - finder->changeFilter(filter); + finder->changeFilter(&filter); } - if (filter->isActive()) + if (filter.isActive()) { // If our filter is active we may be the first thing requiring a fetch so we better start it here. LLInventoryModelBackgroundFetch::instance().start(); @@ -560,7 +576,7 @@ void LLPanelMainInventory::updateItemcountText() std::string text = ""; - if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive()) + if (LLInventoryModelBackgroundFetch::instance().folderFetchActive()) { text = getString("ItemcountFetching", string_args); } @@ -586,17 +602,16 @@ void LLPanelMainInventory::onFocusReceived() return; } - sidepanel_inventory->clearSelections(false, true, true); + sidepanel_inventory->clearSelections(false, true); } void LLPanelMainInventory::setFilterTextFromFilter() { - mFilterText = mActivePanel->getFilter()->getFilterText(); + mFilterText = mActivePanel->getFilter().getFilterText(); } void LLPanelMainInventory::toggleFindOptions() { - LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE); LLFloater *floater = getFinder(); if (!floater) { @@ -641,7 +656,7 @@ LLFloaterInventoryFinder* LLPanelMainInventory::getFinder() LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) : LLFloater(LLSD()), mPanelMainInventory(inventory_view), - mFilter(inventory_view->getPanel()->getFilter()) + mFilter(&inventory_view->getPanel()->getFilter()) { buildFromFile("floater_inventory_view_finder.xml"); updateElementsFromFilter(); @@ -718,8 +733,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter() void LLFloaterInventoryFinder::draw() { - LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW); - U32 filter = 0xffffffff; + U64 filter = 0xffffffffffffffffULL; BOOL filtered_by_all_types = TRUE; if (!getChild<LLUICtrl>("check_animation")->getValue()) @@ -954,7 +968,7 @@ void LLPanelMainInventory::onTrashButtonClick() void LLPanelMainInventory::onClipboardAction(const LLSD& userdata) { std::string command_name = userdata.asString(); - getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name); + getActivePanel()->doToSelected(command_name); } void LLPanelMainInventory::saveTexture(const LLSD& userdata) @@ -965,7 +979,7 @@ void LLPanelMainInventory::saveTexture(const LLSD& userdata) return; } - const LLUUID& item_id = current_item->getListener()->getUUID(); + const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID(); LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES); if (preview_texture) { @@ -1038,7 +1052,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata) { return; } - const LLUUID item_id = current_item->getListener()->getUUID(); + const LLUUID item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID(); LLViewerInventoryItem *item = gInventory.getItem(item_id); if (item) { @@ -1053,7 +1067,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata) { return; } - current_item->getListener()->performAction(getActivePanel()->getModel(), "goto"); + static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(getActivePanel()->getModel(), "goto"); } if (command_name == "find_links") @@ -1063,17 +1077,17 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata) { return; } - const LLUUID& item_id = current_item->getListener()->getUUID(); - const std::string &item_name = current_item->getListener()->getName(); + const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID(); + const std::string &item_name = current_item->getViewModelItem()->getName(); mFilterSubString = item_name; - LLInventoryFilter *filter = mActivePanel->getFilter(); - filter->setFilterSubString(item_name); + LLInventoryFilter &filter = mActivePanel->getFilter(); + filter.setFilterSubString(item_name); mFilterEditor->setText(item_name); mFilterEditor->setFocus(TRUE); - filter->setFilterUUID(item_id); - filter->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - filter->setFilterLinks(LLInventoryFilter::FILTERLINK_ONLY_LINKS); + filter.setFilterUUID(item_id); + filter.setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); + filter.setFilterLinks(LLInventoryFilter::FILTERLINK_ONLY_LINKS); } } @@ -1082,11 +1096,11 @@ bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata) LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); if (current_item) { - LLViewerInventoryItem *inv_item = current_item->getInventoryItem(); + LLViewerInventoryItem *inv_item = dynamic_cast<LLViewerInventoryItem*>(static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getInventoryObject()); if(inv_item) { bool can_save = inv_item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED); - LLInventoryType::EType curr_type = current_item->getListener()->getInventoryType(); + LLInventoryType::EType curr_type = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getInventoryType(); return can_save && (curr_type == LLInventoryType::IT_TEXTURE || curr_type == LLInventoryType::IT_SNAPSHOT); } } @@ -1098,28 +1112,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata) const std::string command_name = userdata.asString(); if (command_name == "delete") { - BOOL can_delete = FALSE; - LLFolderView* root = getActivePanel()->getRootFolder(); - if (root) - { - can_delete = TRUE; - std::set<LLUUID> selection_set = root->getSelectionList(); - if (selection_set.empty()) return FALSE; - for (std::set<LLUUID>::iterator iter = selection_set.begin(); - iter != selection_set.end(); - ++iter) - { - const LLUUID &item_id = (*iter); - LLFolderViewItem *item = root->getItemByID(item_id); - const LLFolderViewEventListener *listener = item->getListener(); - llassert(listener); - if (!listener) return FALSE; - can_delete &= listener->isItemRemovable(); - can_delete &= !listener->isItemInTrash(); - } - return can_delete; - } - return FALSE; + return getActivePanel()->isSelectionRemovable(); } if (command_name == "save_texture") { @@ -1129,7 +1122,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata) { LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); if (!current_item) return FALSE; - const LLUUID& item_id = current_item->getListener()->getUUID(); + const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID(); const LLViewerInventoryItem *item = gInventory.getItem(item_id); if (item && item->getIsLinkType() && !item->getIsBrokenLink()) { @@ -1141,11 +1134,11 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata) if (command_name == "find_links") { LLFolderView* root = getActivePanel()->getRootFolder(); - std::set<LLUUID> selection_set = root->getSelectionList(); + std::set<LLFolderViewItem*> selection_set = root->getSelectionList(); if (selection_set.size() != 1) return FALSE; LLFolderViewItem* current_item = root->getCurSelectedItem(); if (!current_item) return FALSE; - const LLUUID& item_id = current_item->getListener()->getUUID(); + const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID(); const LLInventoryObject *obj = gInventory.getObject(item_id); if (obj && !obj->getIsLinkType() && LLAssetType::lookupCanLink(obj->getType())) { @@ -1158,7 +1151,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata) { LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); if (!current_item) return FALSE; - const LLUUID& item_id = current_item->getListener()->getUUID(); + const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID(); const LLViewerInventoryItem *item = gInventory.getItem(item_id); if (item && item->getIsBrokenLink()) { @@ -1169,6 +1162,8 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata) if (command_name == "share") { + LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); + if (!current_item) return FALSE; LLSidepanelInventory* parent = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); return parent ? parent->canShare() : FALSE; } diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp index 7cb4bbf891..dcecce6fe4 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; } @@ -89,14 +94,14 @@ LLInventoryPanel * LLPanelMarketplaceInbox::setupInventoryPanel() mInventoryPanel->setShape(inventory_placeholder_rect); // Set the sort order newest to oldest - mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE); - mInventoryPanel->getFilter()->markDefault(); + mInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_DATE); + mInventoryPanel->getFilter().markDefault(); // Set selection callback for proper update of inventory status buttons mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceInbox::onSelectionChange, this)); // Set up the note to display when the inbox is empty - mInventoryPanel->getFilter()->setEmptyLookupMessage("InventoryInboxNoItems"); + mInventoryPanel->getFilter().setEmptyLookupMessage("InventoryInboxNoItems"); // Hide the placeholder text inbox_inventory_placeholder->setVisible(FALSE); @@ -109,9 +114,9 @@ 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()); } @@ -123,7 +128,6 @@ BOOL LLPanelMarketplaceInbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL dr U32 LLPanelMarketplaceInbox::getFreshItemCount() const { -#if SUPPORTING_FRESH_ITEM_COUNT // // NOTE: When turning this on, be sure to test the no inbox/outbox case because this code probably @@ -134,7 +138,7 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const if (mInventoryPanel) { - const LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder(); + LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder(); if (inbox_folder) { @@ -163,15 +167,12 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const if (inbox_item_view && inbox_item_view->isFresh()) { fresh_item_count++; - } - } + } + } } } return fresh_item_count; -#else - return getTotalItemCount(); -#endif } U32 LLPanelMarketplaceInbox::getTotalItemCount() const @@ -216,7 +217,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 +225,22 @@ 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); -#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/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp index 678e4f2843..adfb2dee86 100644 --- a/indra/newview/llpanelmarketplaceinboxinventory.cpp +++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp @@ -29,7 +29,8 @@ #include "llpanelmarketplaceinboxinventory.h" #include "llfolderview.h" -#include "llfoldervieweventlistener.h" +#include "llfolderviewitem.h" +#include "llfolderviewmodel.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llpanellandmarks.h" @@ -39,6 +40,8 @@ #define DEBUGGING_FRESHNESS 0 +const LLColor4U DEFAULT_WHITE(255, 255, 255); + // // statics // @@ -53,107 +56,42 @@ static LLDefaultChildRegistry::Register<LLInboxFolderViewItem> r3("inbox_folder_ // LLInboxInventoryPanel::LLInboxInventoryPanel(const LLInboxInventoryPanel::Params& p) - : LLInventoryPanel(p) -{ -} +: LLInventoryPanel(p) +{} LLInboxInventoryPanel::~LLInboxInventoryPanel() -{ -} - -// virtual -void LLInboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params) -{ - // Determine the root folder in case specified, and - // build the views starting with that folder. - - LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false); - - // leslie -- temporary HACK to work around sim not creating inbox 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 inbox inventory panel start_folder: " << start_folder_name << llendl; - } - } - // leslie -- end temporary HACK - - if (root_id == LLUUID::null) - { - llwarns << "Inbox inventory panel has no root folder!" << llendl; - root_id = LLUUID::generateNewID(); - } - - LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY, - LLAssetType::AT_CATEGORY, - LLInventoryType::IT_CATEGORY, - this, - NULL, - root_id); - - mFolderRoot = createFolderView(new_listener, params.use_label_suffix()); -} +{} LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge) { + LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + LLInboxFolderViewFolder::Params params; params.name = bridge->getDisplayName(); - params.icon = bridge->getIcon(); - params.icon_open = bridge->getOpenIcon(); - - if (mShowItemLinkOverlays) // if false, then links show up just like normal items - { - params.icon_overlay = LLUI::getUIImage("Inv_Link"); - } - params.root = mFolderRoot; params.listener = bridge; params.tool_tip = params.name; + params.font_color = item_color; + params.font_highlight_color = item_color; return LLUICtrlFactory::create<LLInboxFolderViewFolder>(params); } LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge) { + LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + LLInboxFolderViewItem::Params params; params.name = bridge->getDisplayName(); - params.icon = bridge->getIcon(); - params.icon_open = bridge->getOpenIcon(); - - if (mShowItemLinkOverlays) // if false, then links show up just like normal items - { - params.icon_overlay = LLUI::getUIImage("Inv_Link"); - } - params.creation_date = bridge->getCreationDate(); params.root = mFolderRoot; params.listener = bridge; params.rect = LLRect (0, 0, 0, 0); params.tool_tip = params.name; + params.font_color = item_color; + params.font_highlight_color = item_color; return LLUICtrlFactory::create<LLInboxFolderViewItem>(params); } @@ -163,26 +101,40 @@ LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * b // LLInboxFolderViewFolder::LLInboxFolderViewFolder(const Params& p) - : LLFolderViewFolder(p) - , LLBadgeOwner(getHandle()) - , mFresh(false) +: LLFolderViewFolder(p), + LLBadgeOwner(getHandle()), + mFresh(false) { -#if SUPPORTING_FRESH_ITEM_COUNT initBadgeParams(p.new_badge()); -#endif +} + +void LLInboxFolderViewFolder::addItem(LLFolderViewItem* item) +{ + LLFolderViewFolder::addItem(item); + + if(item) + { + LLInvFVBridge* itemBridge = static_cast<LLInvFVBridge*>(item->getViewModelItem()); + LLFolderBridge * bridge = static_cast<LLFolderBridge *>(getViewModelItem()); + bridge->updateHierarchyCreationDate(itemBridge->getCreationDate()); + } + + // Compute freshness if our parent is the root folder for the inbox + if (mParentFolder == mRoot) + { + computeFreshness(); + } } // virtual void LLInboxFolderViewFolder::draw() { -#if SUPPORTING_FRESH_ITEM_COUNT if (!badgeHasParent()) { addBadgeToParentPanel(); } setBadgeVisibility(mFresh); -#endif LLFolderViewFolder::draw(); } @@ -207,7 +159,7 @@ void LLInboxFolderViewFolder::computeFreshness() if (last_expansion_utc > 0) { - mFresh = (mCreationDate > last_expansion_utc); + mFresh = (static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getCreationDate() > last_expansion_utc); #if DEBUGGING_FRESHNESS if (mFresh) @@ -229,16 +181,6 @@ void LLInboxFolderViewFolder::deFreshify() gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected()); } -void LLInboxFolderViewFolder::setCreationDate(time_t creation_date_utc) -{ - mCreationDate = creation_date_utc; - - if (mParentFolder == mRoot) - { - computeFreshness(); - } -} - // // LLInboxFolderViewItem Implementation // @@ -248,24 +190,18 @@ LLInboxFolderViewItem::LLInboxFolderViewItem(const Params& p) , LLBadgeOwner(getHandle()) , mFresh(false) { -#if SUPPORTING_FRESH_ITEM_COUNT initBadgeParams(p.new_badge()); -#endif } -BOOL LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) +void LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder) { - BOOL retval = LLFolderViewItem::addToFolder(folder, root); + LLFolderViewItem::addToFolder(folder); -#if SUPPORTING_FRESH_ITEM_COUNT // Compute freshness if our parent is the root folder for the inbox if (mParentFolder == mRoot) { computeFreshness(); } -#endif - - return retval; } BOOL LLInboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask) @@ -278,14 +214,12 @@ BOOL LLInboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask) // virtual void LLInboxFolderViewItem::draw() { -#if SUPPORTING_FRESH_ITEM_COUNT if (!badgeHasParent()) { addBadgeToParentPanel(); } setBadgeVisibility(mFresh); -#endif LLFolderViewItem::draw(); } @@ -303,7 +237,7 @@ void LLInboxFolderViewItem::computeFreshness() if (last_expansion_utc > 0) { - mFresh = (mCreationDate > last_expansion_utc); + mFresh = (static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getCreationDate() > last_expansion_utc); #if DEBUGGING_FRESHNESS if (mFresh) diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h index d6b827ee3e..c05e18c300 100644 --- a/indra/newview/llpanelmarketplaceinboxinventory.h +++ b/indra/newview/llpanelmarketplaceinboxinventory.h @@ -33,7 +33,6 @@ #include "llfolderviewitem.h" -#define SUPPORTING_FRESH_ITEM_COUNT 1 @@ -47,9 +46,6 @@ public: ~LLInboxInventoryPanel(); // virtual - void buildFolderView(const LLInventoryPanel::Params& params); - - // virtual LLFolderViewFolder * createFolderViewFolder(LLInvFVBridge * bridge); LLFolderViewItem * createFolderViewItem(LLInvFVBridge * bridge); }; @@ -63,13 +59,13 @@ public: Optional<LLBadge::Params> new_badge; Params() - : new_badge("new_badge") - { - } + : new_badge("new_badge") + {} }; LLInboxFolderViewFolder(const Params& p); + void addItem(LLFolderViewItem* item); void draw(); void selectItem(); @@ -81,8 +77,6 @@ public: bool isFresh() const { return mFresh; } protected: - void setCreationDate(time_t creation_date_utc); - bool mFresh; }; @@ -95,14 +89,13 @@ public: Optional<LLBadge::Params> new_badge; Params() - : new_badge("new_badge") - { - } + : new_badge("new_badge") + {} }; LLInboxFolderViewItem(const Params& p); - BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); + void addToFolder(LLFolderViewFolder* folder); BOOL handleDoubleClick(S32 x, S32 y, MASK mask); void draw(); 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 deleted file mode 100644 index ed1206aec8..0000000000 --- a/indra/newview/llpanelmarketplaceoutboxinventory.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/** - * @file llpanelmarketplaceoutboxinventory.cpp - * @brief LLOutboxInventoryPanel class definition - * - * $LicenseInfo:firstyear=2009&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 "llpanelmarketplaceoutboxinventory.h" - -#include "llfolderview.h" -#include "llfoldervieweventlistener.h" -#include "llinventorybridge.h" -#include "llinventoryfunctions.h" -#include "llpanellandmarks.h" -#include "llplacesinventorybridge.h" -#include "lltrans.h" -#include "llviewerfoldertype.h" - - -// -// statics -// - -static LLDefaultChildRegistry::Register<LLOutboxInventoryPanel> r1("outbox_inventory_panel"); -static LLDefaultChildRegistry::Register<LLOutboxFolderViewFolder> r2("outbox_folder_view_folder"); - - -// -// 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 -// - -LLOutboxInventoryPanel::LLOutboxInventoryPanel(const LLOutboxInventoryPanel::Params& p) - : LLInventoryPanel(p) -{ -} - -LLOutboxInventoryPanel::~LLOutboxInventoryPanel() -{ -} - -// virtual -void LLOutboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params) -{ - // Determine the root folder in case specified, and - // build the views starting with that folder. - - 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; - root_id = LLUUID::generateNewID(); - } - - LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY, - LLAssetType::AT_CATEGORY, - LLInventoryType::IT_CATEGORY, - this, - NULL, - root_id); - - mFolderRoot = createFolderView(new_listener, params.use_label_suffix()); -} - -LLFolderViewFolder * LLOutboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge) -{ - LLOutboxFolderViewFolder::Params params; - - params.name = bridge->getDisplayName(); - params.icon = bridge->getIcon(); - params.icon_open = bridge->getOpenIcon(); - - if (mShowItemLinkOverlays) // if false, then links show up just like normal items - { - params.icon_overlay = LLUI::getUIImage("Inv_Link"); - } - - params.root = mFolderRoot; - params.listener = bridge; - params.tool_tip = params.name; - - return LLUICtrlFactory::create<LLOutboxFolderViewFolder>(params); -} - -LLFolderViewItem * LLOutboxInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge) -{ - LLFolderViewItem::Params params; - - params.name = bridge->getDisplayName(); - params.icon = bridge->getIcon(); - params.icon_open = bridge->getOpenIcon(); - - if (mShowItemLinkOverlays) // if false, then links show up just like normal items - { - params.icon_overlay = LLUI::getUIImage("Inv_Link"); - } - - params.creation_date = bridge->getCreationDate(); - params.root = mFolderRoot; - params.listener = bridge; - params.rect = LLRect (0, 0, 0, 0); - params.tool_tip = params.name; - - return LLUICtrlFactory::create<LLOutboxFolderViewItem>(params); -} - -// -// LLOutboxFolderViewFolder Implementation -// - -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(); -} - -void LLOutboxFolderViewFolder::setErrorString(const std::string& errorString) -{ - 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) -{ - mError = errorCode; - - if (hasError()) - { - setToolTip(LLTrans::getString(MARKETPLACE_ERROR_NAMES[mError])); - } - else - { - setToolTip(LLStringExplicit("")); - } -} - -// -// LLOutboxFolderViewItem Implementation -// - -BOOL LLOutboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask) -{ - return TRUE; -} - -// eof diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.h b/indra/newview/llpanelmarketplaceoutboxinventory.h deleted file mode 100644 index 346680a79d..0000000000 --- a/indra/newview/llpanelmarketplaceoutboxinventory.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file llpanelmarketplaceoutboxinventory.h - * @brief LLOutboxInventoryPanel class declaration - * - * $LicenseInfo:firstyear=2009&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_OUTBOXINVENTORYPANEL_H -#define LL_OUTBOXINVENTORYPANEL_H - - -#include "llbadgeowner.h" -#include "llinventorypanel.h" -#include "llfolderviewitem.h" - - -class LLOutboxInventoryPanel : public LLInventoryPanel -{ -public: - struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params> - { - Params() {} - }; - - LLOutboxInventoryPanel(const Params& p); - ~LLOutboxInventoryPanel(); - - // virtual - void buildFolderView(const LLInventoryPanel::Params& params); - - // virtual - LLFolderViewFolder * createFolderViewFolder(LLInvFVBridge * bridge); - LLFolderViewItem * createFolderViewItem(LLInvFVBridge * bridge); -}; - - -class LLOutboxFolderViewFolder : public LLFolderViewFolder, public LLBadgeOwner -{ -public: - struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params> - { - Optional<LLBadge::Params> error_badge; - - Params() - : error_badge("error_badge") - { - } - }; - - 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) - { - } - - // virtual - BOOL handleDoubleClick(S32 x, S32 y, MASK mask); -}; - - -#endif //LL_OUTBOXINVENTORYPANEL_H diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp index 7e47a96f44..a9af56f750 100644 --- a/indra/newview/llpanelme.cpp +++ b/indra/newview/llpanelme.cpp @@ -48,16 +48,10 @@ #include "lltabcontainer.h" #include "lltexturectrl.h" -#define PICKER_SECOND_LIFE "2nd_life_pic" -#define PICKER_FIRST_LIFE "real_world_pic" -#define PANEL_PROFILE "panel_profile" - -static LLRegisterPanelClassWrapper<LLPanelMyProfileEdit> t_panel_me_profile_edit("edit_profile_panel"); static LLRegisterPanelClassWrapper<LLPanelMe> t_panel_me_profile("panel_me"); LLPanelMe::LLPanelMe(void) : LLPanelProfile() - , mEditPanel(NULL) { setAvatarId(gAgent.getID()); } @@ -73,282 +67,3 @@ void LLPanelMe::onOpen(const LLSD& key) { LLPanelProfile::onOpen(key); } - -void LLPanelMe::buildEditPanel() -{ - if (NULL == mEditPanel) - { - mEditPanel = new LLPanelMyProfileEdit(); - - // Note: Remove support for editing profile through this method. - // All profile editing should go through the web. - //mEditPanel->childSetAction("save_btn", boost::bind(&LLPanelMe::onSaveChangesClicked, this), this); - - //mEditPanel->childSetAction("cancel_btn", boost::bind(&LLPanelMe::onCancelClicked, this), this); - } -} - - -void LLPanelMe::onEditProfileClicked() -{ - buildEditPanel(); -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -LLPanelMyProfileEdit::LLPanelMyProfileEdit() - : LLPanelMyProfile() -{ - buildFromFile( "panel_edit_profile.xml"); - - setAvatarId(gAgent.getID()); - - LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLPanelMyProfileEdit::onAvatarNameChanged, this)); -} - -void LLPanelMyProfileEdit::onOpen(const LLSD& key) -{ - resetData(); - - // Disable editing until data is loaded, or edited fields will be overwritten when data - // is loaded. - enableEditing(false); - - // force new avatar name fetch so we have latest update time - LLAvatarNameCache::fetch(gAgent.getID()); - LLPanelMyProfile::onOpen(getAvatarId()); - - LLAvatarName av_name; - if (LLAvatarNameCache::useDisplayNames()) - { - if (LLAvatarNameCache::get(gAgent.getID(), &av_name) && av_name.mIsDisplayNameDefault) - { - LLFirstUse::setDisplayName(); - } - else - { - LLFirstUse::setDisplayName(false); - } - } - - if (LLAvatarNameCache::useDisplayNames()) - { - getChild<LLUICtrl>("user_label")->setVisible( true ); - getChild<LLUICtrl>("user_slid")->setVisible( true ); - getChild<LLUICtrl>("display_name_label")->setVisible( true ); - getChild<LLUICtrl>("set_name")->setVisible( true ); - getChild<LLUICtrl>("set_name")->setEnabled( true ); - getChild<LLUICtrl>("solo_user_name")->setVisible( false ); - getChild<LLUICtrl>("solo_username_label")->setVisible( false ); - } - else - { - getChild<LLUICtrl>("user_label")->setVisible( false ); - getChild<LLUICtrl>("user_slid")->setVisible( false ); - getChild<LLUICtrl>("display_name_label")->setVisible( false ); - getChild<LLUICtrl>("set_name")->setVisible( false ); - getChild<LLUICtrl>("set_name")->setEnabled( false ); - getChild<LLUICtrl>("solo_user_name")->setVisible( true ); - getChild<LLUICtrl>("solo_username_label")->setVisible( true ); - } -} - -void LLPanelMyProfileEdit::onClose(const LLSD& key) -{ - if (LLAvatarNameCache::useDisplayNames()) - { - LLFirstUse::setDisplayName(false); - } -} - -void LLPanelMyProfileEdit::processProperties(void* data, EAvatarProcessorType type) -{ - if(APT_PROPERTIES == type) - { - const LLAvatarData* avatar_data = static_cast<const LLAvatarData*>(data); - if(avatar_data && getAvatarId() == avatar_data->avatar_id) - { - // *TODO dzaporozhan - // Workaround for ticket EXT-1099, waiting for fix for ticket EXT-1128 - enableEditing(true); - processProfileProperties(avatar_data); - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); - } - } -} - -void LLPanelMyProfileEdit::processProfileProperties(const LLAvatarData* avatar_data) -{ - fillCommonData(avatar_data); - - // 'Home page' was hidden in LLPanelAvatarProfile::fillCommonData() to fix EXT-4734 - // Show 'Home page' in Edit My Profile (EXT-4873) - getChildView("homepage_edit")->setVisible( true); - - fillPartnerData(avatar_data); - - fillAccountStatus(avatar_data); - - getChild<LLUICtrl>("show_in_search_checkbox")->setValue((BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH)); - - LLAvatarNameCache::get(avatar_data->avatar_id, - boost::bind(&LLPanelMyProfileEdit::onNameCache, this, _1, _2)); -} - -void LLPanelMyProfileEdit::onNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) -{ - getChild<LLUICtrl>("user_name")->setValue( av_name.mDisplayName ); - getChild<LLUICtrl>("user_slid")->setValue( av_name.mUsername ); - getChild<LLUICtrl>("user_name_small")->setValue( av_name.mDisplayName ); - getChild<LLUICtrl>("solo_user_name")->setValue( av_name.mDisplayName ); - - - if (LLAvatarNameCache::useDisplayNames()) - { - getChild<LLUICtrl>("user_label")->setVisible( true ); - getChild<LLUICtrl>("user_slid")->setVisible( true ); - getChild<LLUICtrl>("display_name_label")->setVisible( true ); - getChild<LLUICtrl>("set_name")->setVisible( true ); - getChild<LLUICtrl>("set_name")->setEnabled( true ); - - getChild<LLUICtrl>("solo_user_name")->setVisible( false ); - getChild<LLUICtrl>("solo_username_label")->setVisible( false ); - - // show smaller display name if too long to display in regular size - if (getChild<LLTextBox>("user_name")->getTextPixelWidth() > getChild<LLTextBox>("user_name")->getRect().getWidth()) - { - getChild<LLUICtrl>("user_name_small")->setVisible( true ); - getChild<LLUICtrl>("user_name")->setVisible( false ); - } - else - { - getChild<LLUICtrl>("user_name_small")->setVisible( false ); - getChild<LLUICtrl>("user_name")->setVisible( true ); - } - } - else - { - getChild<LLUICtrl>("user_label")->setVisible( false ); - getChild<LLUICtrl>("user_slid")->setVisible( false ); - getChild<LLUICtrl>("display_name_label")->setVisible( false ); - getChild<LLUICtrl>("set_name")->setVisible( false ); - getChild<LLUICtrl>("set_name")->setEnabled( false ); - - getChild<LLUICtrl>("solo_user_name")->setVisible( true ); - getChild<LLUICtrl>("user_name_small")->setVisible( false ); - getChild<LLUICtrl>("user_name")->setVisible( false ); - getChild<LLUICtrl>("solo_username_label")->setVisible( true ); - } -} - - -void LLPanelMyProfileEdit::onAvatarNameChanged() -{ - LLAvatarNameCache::get(getAvatarId(), - boost::bind(&LLPanelMyProfileEdit::onNameCache, this, _1, _2)); -} - -BOOL LLPanelMyProfileEdit::postBuild() -{ - initTexturePickerMouseEvents(); - - getChild<LLUICtrl>("partner_edit_link")->setTextArg("[URL]", getString("partner_edit_link_url")); - getChild<LLUICtrl>("my_account_link")->setTextArg("[URL]", getString("my_account_link_url")); - - getChild<LLUICtrl>("set_name")->setCommitCallback( - boost::bind(&LLPanelMyProfileEdit::onClickSetName, this)); - - LLHints::registerHintTarget("set_display_name", getChild<LLUICtrl>("set_name")->getHandle()); - LLViewerDisplayName::addNameChangedCallback(boost::bind(&LLPanelMyProfileEdit::onAvatarNameChanged, this)); - return LLPanelAvatarProfile::postBuild(); -} -/** - * Inits map with texture picker and appropriate edit icon. - * Sets callbacks of Mouse Enter and Mouse Leave signals of Texture Pickers - */ -void LLPanelMyProfileEdit::initTexturePickerMouseEvents() -{ - LLTextureCtrl* text_pic = getChild<LLTextureCtrl>(PICKER_SECOND_LIFE); - LLIconCtrl* text_icon = getChild<LLIconCtrl>("2nd_life_edit_icon"); - mTextureEditIconMap[text_pic->getName()] = text_icon; - text_pic->setMouseEnterCallback(boost::bind(&LLPanelMyProfileEdit::onTexturePickerMouseEnter, this, _1)); - text_pic->setMouseLeaveCallback(boost::bind(&LLPanelMyProfileEdit::onTexturePickerMouseLeave, this, _1)); - text_icon->setVisible(FALSE); - - text_pic = getChild<LLTextureCtrl>(PICKER_FIRST_LIFE); - text_icon = getChild<LLIconCtrl>("real_world_edit_icon"); - mTextureEditIconMap[text_pic->getName()] = text_icon; - text_pic->setMouseEnterCallback(boost::bind(&LLPanelMyProfileEdit::onTexturePickerMouseEnter, this, _1)); - text_pic->setMouseLeaveCallback(boost::bind(&LLPanelMyProfileEdit::onTexturePickerMouseLeave, this, _1)); - text_icon->setVisible(FALSE); -} - -void LLPanelMyProfileEdit::resetData() -{ - LLPanelMyProfile::resetData(); - - //childSetTextArg("name_text", "[FIRST]", LLStringUtil::null); - //childSetTextArg("name_text", "[LAST]", LLStringUtil::null); - getChild<LLUICtrl>("user_name")->setValue( LLSD() ); - getChild<LLUICtrl>("user_slid")->setValue( LLSD() ); - getChild<LLUICtrl>("solo_user_name")->setValue( LLSD() ); - getChild<LLUICtrl>("user_name_small")->setValue( LLSD() ); -} - -void LLPanelMyProfileEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl) -{ - mTextureEditIconMap[ctrl->getName()]->setVisible(TRUE); -} -void LLPanelMyProfileEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl) -{ - mTextureEditIconMap[ctrl->getName()]->setVisible(FALSE); -} - -void LLPanelMyProfileEdit::onClickSetName() -{ - LLAvatarNameCache::get(getAvatarId(), - boost::bind(&LLPanelMyProfileEdit::onAvatarNameCache, - this, _1, _2)); - - LLFirstUse::setDisplayName(false); -} - -void LLPanelMyProfileEdit::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) -{ - if (av_name.mDisplayName.empty()) - { - // something is wrong, tell user to try again later - LLNotificationsUtil::add("SetDisplayNameFailedGeneric"); - return; - } - - llinfos << "name-change now " << LLDate::now() << " next_update " - << LLDate(av_name.mNextUpdate) << llendl; - F64 now_secs = LLDate::now().secondsSinceEpoch(); - - if (now_secs < av_name.mNextUpdate) - { - // if the update time is more than a year in the future, it means updates have been blocked - // show a more general message - const int YEAR = 60*60*24*365; - if (now_secs + YEAR < av_name.mNextUpdate) - { - LLNotificationsUtil::add("SetDisplayNameBlocked"); - return; - } - } - - LLFloaterReg::showInstance("display_name"); -} - -void LLPanelMyProfileEdit::enableEditing(bool enable) -{ - getChildView("2nd_life_pic")->setEnabled(enable); - getChildView("real_world_pic")->setEnabled(enable); - getChildView("sl_description_edit")->setEnabled(enable); - getChildView("fl_description_edit")->setEnabled(enable); - getChildView("homepage_edit")->setEnabled(enable); - getChildView("show_in_search_checkbox")->setEnabled(enable); -} diff --git a/indra/newview/llpanelme.h b/indra/newview/llpanelme.h index b0f5d184cc..60e9d4317d 100644 --- a/indra/newview/llpanelme.h +++ b/indra/newview/llpanelme.h @@ -30,15 +30,9 @@ #include "llpanel.h" #include "llpanelprofile.h" -class LLAvatarName; -class LLPanelMyProfileEdit; -class LLPanelProfile; -class LLIconCtrl; - /** -* Panel for displaying Agent's profile, it consists of two sub panels - Profile -* and Picks. -* LLPanelMe allows user to edit his profile and picks. +* Panel for displaying Agent's Picks and Classifieds panel. +* LLPanelMe allows user to edit his picks and classifieds. */ class LLPanelMe : public LLPanelProfile { @@ -51,60 +45,6 @@ public: /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ BOOL postBuild(); - -private: - - void buildEditPanel(); - - void onEditProfileClicked(); - - LLPanelMyProfileEdit * mEditPanel; - -}; - -class LLPanelMyProfileEdit : public LLPanelMyProfile -{ - LOG_CLASS(LLPanelMyProfileEdit); - -public: - - LLPanelMyProfileEdit(); - - /*virtual*/void processProperties(void* data, EAvatarProcessorType type); - - /*virtual*/BOOL postBuild(); - - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(const LLSD& key); - - void onAvatarNameChanged(); - -protected: - - /*virtual*/void resetData(); - - void processProfileProperties(const LLAvatarData* avatar_data); - void onNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); - -private: - void initTexturePickerMouseEvents(); - void onTexturePickerMouseEnter(LLUICtrl* ctrl); - void onTexturePickerMouseLeave(LLUICtrl* ctrl); - void onClickSetName(); - void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); - - /** - * Enabled/disables controls to prevent overwriting edited data upon receiving - * current data from server. - */ - void enableEditing(bool enable); - - - -private: - // map TexturePicker name => Edit Icon pointer should be visible while hovering Texture Picker - typedef std::map<std::string, LLIconCtrl*> texture_edit_icon_map_t; - texture_edit_icon_map_t mTextureEditIconMap; }; #endif // LL_LLPANELMEPROFILE_H diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index 2bbd15ae11..a50d9074f7 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -52,6 +52,7 @@ #include "llvovolume.h" #include "llstatusbar.h" #include "llsdutil.h" +#include "llvieweraudio.h" #include "llfloaterreg.h" #include "llfloaterpreference.h" // for the gear icon @@ -175,7 +176,7 @@ void LLPanelNearByMedia::handleMediaAutoPlayChanged(const LLSD& newvalue) { // update mParcelAudioAutoStart if AUTO_PLAY_MEDIA_SETTING changes mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) && - gSavedSettings.getBOOL("MediaTentativeAutoPlay"); + gSavedSettings.getBOOL("MediaTentativeAutoPlay"); } /*virtual*/ @@ -807,14 +808,26 @@ bool LLPanelNearByMedia::setDisabled(const LLUUID &row_id, bool disabled) { if (row_id == PARCEL_AUDIO_LIST_ITEM_UUID) { - if (disabled) onClickParcelAudioStop(); - else onClickParcelAudioStart(); + if (disabled) + { + onClickParcelAudioStop(); + } + else + { + onClickParcelAudioPlay(); + } return true; } else if (row_id == PARCEL_MEDIA_LIST_ITEM_UUID) { - if (disabled) onClickDisableParcelMedia(); - else onClickEnableParcelMedia(); + if (disabled) + { + onClickDisableParcelMedia(); + } + else + { + onClickEnableParcelMedia(); + } return true; } else { @@ -857,24 +870,11 @@ void LLPanelNearByMedia::onClickParcelMediaPause() LLViewerParcelMedia::pause(); } -void LLPanelNearByMedia::onClickParcelAudioStart() -{ - // User *explicitly* started the internet stream, so keep the stream - // playing and updated as they cross to other parcels etc. - mParcelAudioAutoStart = true; - - if (!gAudiop) - return; - - gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); -} - void LLPanelNearByMedia::onClickParcelAudioPlay() { // User *explicitly* started the internet stream, so keep the stream // playing and updated as they cross to other parcels etc. mParcelAudioAutoStart = true; - if (!gAudiop) return; @@ -883,8 +883,9 @@ void LLPanelNearByMedia::onClickParcelAudioPlay() // 'false' means unpause gAudiop->pauseInternetStream(false); } - else { - gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); + else + { + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL()); } } @@ -894,11 +895,10 @@ void LLPanelNearByMedia::onClickParcelAudioStop() // re-start audio when i.e. they move to another parcel, until // they explicitly start it again. mParcelAudioAutoStart = false; - if (!gAudiop) return; - gAudiop->stopInternetStream(); + LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); } void LLPanelNearByMedia::onClickParcelAudioPause() diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h index be4d313743..c3634de9b4 100644 --- a/indra/newview/llpanelnearbymedia.h +++ b/indra/newview/llpanelnearbymedia.h @@ -115,7 +115,6 @@ private: void onClickParcelMediaPause(); void onClickParcelAudioPlay(); void onClickParcelAudioStop(); - void onClickParcelAudioStart(); void onClickParcelAudioPause(); void onCheckAutoPlay(); void onAdvancedButtonClick(); diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 1f77e7a602..d87b565b32 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -119,7 +119,6 @@ BOOL LLPanelObject::postBuild() mCheckPhantom = getChild<LLCheckBoxCtrl>("Phantom Checkbox Ctrl"); childSetCommitCallback("Phantom Checkbox Ctrl",onCommitPhantom,this); - // Position mLabelPosition = getChild<LLTextBox>("label position"); mCtrlPosX = getChild<LLSpinCtrl>("Pos X"); @@ -245,6 +244,7 @@ BOOL LLPanelObject::postBuild() mCtrlSculptTexture->setDropCallback( boost::bind(&LLPanelObject::onDropSculpt, this, _2 )); // Don't allow (no copy) or (no transfer) textures to be selected during immediate mode mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + mCtrlSculptTexture->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); // Allow any texture to be used during non-immediate mode. mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE); LLAggregatePermissions texture_perms; @@ -271,7 +271,7 @@ BOOL LLPanelObject::postBuild() childSetCommitCallback("sculpt mirror control", onCommitSculptType, this); mCtrlSculptInvert = getChild<LLCheckBoxCtrl>("sculpt invert control"); childSetCommitCallback("sculpt invert control", onCommitSculptType, this); - + // Start with everyone disabled clearCtrls(); @@ -283,7 +283,6 @@ LLPanelObject::LLPanelObject() mIsPhysical(FALSE), mIsTemporary(FALSE), mIsPhantom(FALSE), - mCastShadows(TRUE), mSelectedType(MI_BOX), mSculptTextureRevert(LLUUID::null), mSculptTypeRevert(0) @@ -342,9 +341,9 @@ void LLPanelObject::getState( ) } // can move or rotate only linked group with move permissions, or sub-object with move and modify perms - BOOL enable_move = objectp->permMove() && !objectp->isAttachment() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); - BOOL enable_scale = objectp->permMove() && objectp->permModify(); - BOOL enable_rotate = objectp->permMove() && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts")); + BOOL enable_move = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && !objectp->isAttachment() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); + BOOL enable_scale = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && objectp->permModify(); + BOOL enable_rotate = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts")); S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME )) @@ -462,9 +461,16 @@ void LLPanelObject::getState( ) getChildView("select_single")->setVisible( TRUE); getChildView("select_single")->setEnabled(TRUE); } + + BOOL is_flexible = volobjp && volobjp->isFlexible(); + BOOL is_permanent = root_objectp->flagObjectPermanent(); + BOOL is_permanent_enforced = root_objectp->isPermanentEnforced(); + BOOL is_character = root_objectp->flagCharacter(); + llassert(!is_permanent || !is_character); // should never have a permanent object that is also a character + // Lock checkbox - only modifiable if you own the object. BOOL self_owned = (gAgent.getID() == owner_id); - mCheckLock->setEnabled( roots_selected > 0 && self_owned ); + mCheckLock->setEnabled( roots_selected > 0 && self_owned && !is_permanent_enforced); // More lock and debit checkbox - get the values BOOL valid; @@ -494,30 +500,27 @@ void LLPanelObject::getState( ) } } - BOOL is_flexible = volobjp && volobjp->isFlexible(); - // Physics checkbox - mIsPhysical = root_objectp->usePhysics(); + mIsPhysical = root_objectp->flagUsePhysics(); + llassert(!is_permanent || !mIsPhysical); // should never have a permanent object that is also physical + mCheckPhysics->set( mIsPhysical ); mCheckPhysics->setEnabled( roots_selected>0 && (editable || gAgent.isGodlike()) - && !is_flexible); + && !is_flexible && !is_permanent); mIsTemporary = root_objectp->flagTemporaryOnRez(); + llassert(!is_permanent || !mIsTemporary); // should never has a permanent object that is also temporary + mCheckTemporary->set( mIsTemporary ); - mCheckTemporary->setEnabled( roots_selected>0 && editable ); + mCheckTemporary->setEnabled( roots_selected>0 && editable && !is_permanent); mIsPhantom = root_objectp->flagPhantom(); + BOOL is_volume_detect = root_objectp->flagVolumeDetect(); + llassert(!is_character || !mIsPhantom); // should never have a character that is also a phantom mCheckPhantom->set( mIsPhantom ); - mCheckPhantom->setEnabled( roots_selected>0 && editable && !is_flexible ); + mCheckPhantom->setEnabled( roots_selected>0 && editable && !is_flexible && !is_permanent_enforced && !is_character && !is_volume_detect); - -#if 0 // 1.9.2 - mCastShadows = root_objectp->flagCastShadows(); - mCheckCastShadows->set( mCastShadows ); - mCheckCastShadows->setEnabled( roots_selected==1 && editable ); -#endif - //---------------------------------------------------------------------------- S32 selected_item = MI_BOX; @@ -555,7 +558,7 @@ void LLPanelObject::getState( ) { // Only allowed to change these parameters for objects // that you have permissions on AND are not attachments. - enabled = root_objectp->permModify(); + enabled = root_objectp->permModify() && !root_objectp->isPermanentEnforced(); // Volume type const LLVolumeParams &volume_params = objectp->getVolume()->getParams(); @@ -1214,22 +1217,6 @@ void LLPanelObject::sendIsPhantom() } } -void LLPanelObject::sendCastShadows() -{ - BOOL value = mCheckCastShadows->get(); - if( mCastShadows != value ) - { - LLSelectMgr::getInstance()->selectionUpdateCastShadows(value); - mCastShadows = value; - - llinfos << "update cast shadows sent" << llendl; - } - else - { - llinfos << "update cast shadows not changed" << llendl; - } -} - // static void LLPanelObject::onCommitParametric( LLUICtrl* ctrl, void* userdata ) { @@ -1886,10 +1873,6 @@ void LLPanelObject::clearCtrls() mCheckPhantom ->set(FALSE); mCheckPhantom ->setEnabled( FALSE ); -#if 0 // 1.9.2 - mCheckCastShadows->set(FALSE); - mCheckCastShadows->setEnabled( FALSE ); -#endif // Disable text labels mLabelPosition ->setEnabled( FALSE ); mLabelSize ->setEnabled( FALSE ); @@ -1977,14 +1960,6 @@ void LLPanelObject::onCommitPhantom( LLUICtrl* ctrl, void* userdata ) self->sendIsPhantom(); } -// static -void LLPanelObject::onCommitCastShadows( LLUICtrl* ctrl, void* userdata ) -{ - LLPanelObject* self = (LLPanelObject*) userdata; - self->sendCastShadows(); -} - - void LLPanelObject::onSelectSculpt(const LLSD& data) { LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control"); diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h index 475dfdaedb..c4cf27ab1a 100644 --- a/indra/newview/llpanelobject.h +++ b/indra/newview/llpanelobject.h @@ -64,7 +64,6 @@ public: static void onCommitRotation( LLUICtrl* ctrl, void* userdata); static void onCommitTemporary( LLUICtrl* ctrl, void* userdata); static void onCommitPhantom( LLUICtrl* ctrl, void* userdata); - static void onCommitCastShadows( LLUICtrl* ctrl, void* userdata); static void onCommitPhysics( LLUICtrl* ctrl, void* userdata); static void onCommitParametric(LLUICtrl* ctrl, void* userdata); @@ -75,8 +74,7 @@ public: void onSelectSculpt(const LLSD& data); BOOL onDropSculpt(LLInventoryItem* item); static void onCommitSculptType( LLUICtrl *ctrl, void* userdata); - - + protected: void getState(); @@ -87,7 +85,6 @@ protected: void sendIsTemporary(); void sendIsPhantom(); - void sendCastShadows(); void sendSculpt(); void getVolumeParams(LLVolumeParams& volume_params); @@ -153,7 +150,6 @@ protected: LLCheckBoxCtrl *mCheckPhysics; LLCheckBoxCtrl *mCheckTemporary; LLCheckBoxCtrl *mCheckPhantom; - LLCheckBoxCtrl *mCheckCastShadows; LLTextureCtrl *mCtrlSculptTexture; LLTextBox *mLabelSculptType; @@ -165,7 +161,6 @@ protected: BOOL mIsPhysical; // to avoid sending "physical" when not changed BOOL mIsTemporary; // to avoid sending "temporary" when not changed BOOL mIsPhantom; // to avoid sending "phantom" when not changed - BOOL mCastShadows; // to avoid sending "cast shadows" when not changed S32 mSelectedType; // So we know what selected type we last were LLUUID mSculptTextureRevert; // so we can revert the sculpt texture on cancel diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 98ea680504..7555ac7b2c 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -66,17 +66,19 @@ #include "llviewerobjectlist.h" #include "llviewermessage.h" +const LLColor4U DEFAULT_WHITE(255, 255, 255); ///---------------------------------------------------------------------------- /// Class LLTaskInvFVBridge ///---------------------------------------------------------------------------- -class LLTaskInvFVBridge : public LLFolderViewEventListener +class LLTaskInvFVBridge : public LLFolderViewModelItemInventory { protected: LLUUID mUUID; std::string mName; mutable std::string mDisplayName; + mutable std::string mSearchableName; LLPanelObjectInventory* mPanel; U32 mFlags; LLAssetType::EType mAssetType; @@ -102,40 +104,47 @@ public: S32 getPrice(); static bool commitBuyItem(const LLSD& notification, const LLSD& response); - // LLFolderViewEventListener functionality + // LLFolderViewModelItemInventory functionality virtual const std::string& getName() const; virtual const std::string& getDisplayName() const; + virtual const std::string& getSearchableName() const; + virtual PermissionMask getPermissionMask() const { return PERM_NONE; } /*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; } virtual const LLUUID& getUUID() const { return mUUID; } virtual time_t getCreationDate() const; + virtual void setCreationDate(time_t creation_date_utc); + virtual LLUIImagePtr getIcon() const; virtual void openItem(); virtual BOOL canOpenItem() const { return FALSE; } virtual void closeItem() {} - virtual void previewItem(); virtual void selectItem() {} virtual BOOL isItemRenameable() const; virtual BOOL renameItem(const std::string& new_name); virtual BOOL isItemMovable() const; virtual BOOL isItemRemovable() const; virtual BOOL removeItem(); - virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch); - virtual void move(LLFolderViewEventListener* parent_listener); + virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch); + virtual void move(LLFolderViewModelItem* parent_listener); virtual BOOL isItemCopyable() const; virtual BOOL copyToClipboard() const; - virtual void cutToClipboard(); + virtual BOOL cutToClipboard() const; virtual BOOL isClipboardPasteable() const; virtual void pasteFromClipboard(); virtual void pasteLinkFromClipboard(); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); virtual void performAction(LLInventoryModel* model, std::string action); virtual BOOL isUpToDate() const { return TRUE; } - virtual BOOL hasChildren() const { return FALSE; } + virtual bool hasChildren() const { return FALSE; } virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; } virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; } + virtual EInventorySortGroup getSortGroup() const { return SG_ITEM; } + virtual LLInventoryObject* getInventoryObject() const { return findInvObject(); } + // LLDragAndDropBridge functionality + virtual LLToolDragAndDrop::ESource getDragSource() const { return LLToolDragAndDrop::SOURCE_WORLD; } virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const; virtual BOOL dragOrDrop(MASK mask, BOOL drop, EDragAndDropType cargo_type, @@ -147,7 +156,8 @@ LLTaskInvFVBridge::LLTaskInvFVBridge( LLPanelObjectInventory* panel, const LLUUID& uuid, const std::string& name, - U32 flags): + U32 flags) +: LLFolderViewModelItemInventory(panel->getRootViewModel()), mUUID(uuid), mName(name), mPanel(panel), @@ -330,15 +340,27 @@ const std::string& LLTaskInvFVBridge::getDisplayName() const } } + mSearchableName.assign(mDisplayName + getLabelSuffix()); + return mDisplayName; } +const std::string& LLTaskInvFVBridge::getSearchableName() const +{ + return mSearchableName; +} + + // BUG: No creation dates for task inventory time_t LLTaskInvFVBridge::getCreationDate() const { return 0; } +void LLTaskInvFVBridge::setCreationDate(time_t creation_date_utc) +{} + + LLUIImagePtr LLTaskInvFVBridge::getIcon() const { const BOOL item_is_multi = (mFlags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS); @@ -352,11 +374,6 @@ void LLTaskInvFVBridge::openItem() lldebugs << "LLTaskInvFVBridge::openItem()" << llendl; } -void LLTaskInvFVBridge::previewItem() -{ - openItem(); -} - BOOL LLTaskInvFVBridge::isItemRenameable() const { if(gAgent.isGodlike()) return TRUE; @@ -467,7 +484,7 @@ BOOL LLTaskInvFVBridge::removeItem() return FALSE; } -void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) +void LLTaskInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch) { if (!mPanel) { @@ -507,7 +524,7 @@ void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& } } -void LLTaskInvFVBridge::move(LLFolderViewEventListener* parent_listener) +void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener) { } @@ -524,8 +541,9 @@ BOOL LLTaskInvFVBridge::copyToClipboard() const return FALSE; } -void LLTaskInvFVBridge::cutToClipboard() +BOOL LLTaskInvFVBridge::cutToClipboard() const { + return FALSE; } BOOL LLTaskInvFVBridge::isClipboardPasteable() const @@ -708,7 +726,7 @@ public: virtual BOOL renameItem(const std::string& new_name); virtual BOOL isItemRemovable() const; virtual void buildContextMenu(LLMenuGL& menu, U32 flags); - virtual BOOL hasChildren() const; + virtual bool hasChildren() const; virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const; virtual BOOL dragOrDrop(MASK mask, BOOL drop, EDragAndDropType cargo_type, @@ -716,6 +734,7 @@ public: std::string& tooltip_msg); virtual BOOL canOpenItem() const { return TRUE; } virtual void openItem(); + virtual EInventorySortGroup getSortGroup() const { return SG_NORMAL_FOLDER; } }; LLTaskCategoryBridge::LLTaskCategoryBridge( @@ -738,15 +757,7 @@ const std::string& LLTaskCategoryBridge::getDisplayName() const if (cat) { - // Localize "Contents" folder. - if (cat->getParentUUID().isNull() && cat->getName() == "Contents") - { - mDisplayName.assign(LLTrans::getString("ViewerObjectContents")); - } - else - { - mDisplayName.assign(cat->getName()); - } + mDisplayName.assign(cat->getName()); } return mDisplayName; @@ -774,7 +785,7 @@ void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags) hide_context_entries(menu, items, disabled_items); } -BOOL LLTaskCategoryBridge::hasChildren() const +bool LLTaskCategoryBridge::hasChildren() const { // return TRUE if we have or do know know if we have children. // *FIX: For now, return FALSE - we will know for sure soon enough. @@ -1488,7 +1499,7 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&do_nothing)); mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&do_nothing)); mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&do_nothing)); - mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars)); + mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this)); } // Destroys the object @@ -1513,7 +1524,7 @@ BOOL LLPanelObjectInventory::postBuild() void LLPanelObjectInventory::doToSelected(const LLSD& userdata) { - mFolders->doToSelected(&gInventory, userdata); + LLInventoryAction::doToSelected(&gInventory, mFolders, userdata.asString()); } void LLPanelObjectInventory::clearContents() @@ -1525,6 +1536,8 @@ void LLPanelObjectInventory::clearContents() LLToolDragAndDrop::getInstance()->endDrag(); } + clearItemIDs(); + if( mScroller ) { // removes mFolders @@ -1540,21 +1553,26 @@ void LLPanelObjectInventory::reset() { clearContents(); - //setBorderVisible(FALSE); - mCommitCallbackRegistrar.pushScope(); // push local callbacks + // Reset the inventory model to show all folders by default + mInventoryViewModel.getFilter().setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); + + // Create a new folder view root LLRect dummy_rect(0, 1, 1, 0); LLFolderView::Params p; p.name = "task inventory"; p.title = "task inventory"; - p.task_id = getTaskUUID(); p.parent_panel = this; p.tool_tip= LLTrans::getString("PanelContentsTooltip"); p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL); + p.folder_indentation = -14; // subtract space normally reserved for folder expanders + p.view_model = &mInventoryViewModel; + p.root = NULL; + p.options_menu = "menu_inventory.xml"; + mFolders = LLUICtrlFactory::create<LLFolderView>(p); - // this ensures that we never say "searching..." or "no items found" - mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); + mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar); if (hasFocus()) @@ -1568,7 +1586,7 @@ void LLPanelObjectInventory::reset() scroll_p.rect(scroller_rect); scroll_p.tab_stop(true); scroll_p.follows.flags(FOLLOWS_ALL); - mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_p); + mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroll_p); addChild(mScroller); mScroller->addChild(mFolders); @@ -1599,7 +1617,7 @@ void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object, iter != inventory->end(); ) { LLInventoryObject* item = *iter++; - LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properites", item->getUUID()); + LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properties", item->getUUID()); if(floater) { floater->refresh(); @@ -1614,15 +1632,20 @@ void LLPanelObjectInventory::updateInventory() // << " panel UUID: " << panel->mTaskUUID << "\n" // << " task UUID: " << object->mID << llendl; // We're still interested in this task's inventory. - std::set<LLUUID> selected_items; + std::vector<LLUUID> selected_item_ids; + std::set<LLFolderViewItem*> selected_items; BOOL inventory_has_focus = FALSE; - if (mHaveInventory) + if (mHaveInventory && mFolders) { selected_items = mFolders->getSelectionList(); inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders); } - - reset(); + for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(), end_it = selected_items.end(); + it != end_it; + ++it) + { + selected_item_ids.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID()); + } LLViewerObject* objectp = gObjectList.findObject(mTaskUUID); if (objectp) @@ -1630,19 +1653,21 @@ void LLPanelObjectInventory::updateInventory() LLInventoryObject* inventory_root = objectp->getInventoryRoot(); LLInventoryObject::object_list_t contents; objectp->getInventoryContents(contents); + if (inventory_root) { - createFolderViews(inventory_root, contents); - mHaveInventory = TRUE; + reset(); mIsInventoryEmpty = FALSE; + createFolderViews(inventory_root, contents); mFolders->setEnabled(TRUE); } else { // TODO: create an empty inventory mIsInventoryEmpty = TRUE; - mHaveInventory = TRUE; } + + mHaveInventory = TRUE; } else { @@ -1652,11 +1677,12 @@ void LLPanelObjectInventory::updateInventory() } // restore previous selection - std::set<LLUUID>::iterator selection_it; - BOOL first_item = TRUE; - for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it) + std::vector<LLUUID>::iterator selection_it; + bool first_item = true; + for (selection_it = selected_item_ids.begin(); selection_it != selected_item_ids.end(); ++selection_it) { - LLFolderViewItem* selected_item = mFolders->getItemByID(*selection_it); + LLFolderViewItem* selected_item = getItemByID(*selection_it); + if (selected_item) { //HACK: "set" first item then "change" each other one to get keyboard focus right @@ -1672,7 +1698,10 @@ void LLPanelObjectInventory::updateInventory() } } - mFolders->requestArrange(); + if (mFolders) + { + mFolders->requestArrange(); + } mInventoryNeedsUpdate = FALSE; // Edit menu handler is set in onFocusReceived } @@ -1693,19 +1722,24 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root); if(bridge) { - LLFolderViewFolder* new_folder = NULL; + LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + LLFolderViewFolder::Params p; p.name = inventory_root->getName(); - p.icon = LLUI::getUIImage("Inv_FolderClosed"); - p.icon_open = LLUI::getUIImage("Inv_FolderOpen"); + p.tool_tip = p.name; p.root = mFolders; p.listener = bridge; - p.tool_tip = p.name; - new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p); - new_folder->addToFolder(mFolders, mFolders); + p.font_color = item_color; + p.font_highlight_color = item_color; + + LLFolderViewFolder* new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p); + new_folder->addToFolder(mFolders); new_folder->toggleOpen(); - createViewsForCategory(&contents, inventory_root, new_folder); + if (!contents.empty()) + { + createViewsForCategory(&contents, inventory_root, new_folder); + } } } @@ -1715,6 +1749,8 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li LLInventoryObject* parent, LLFolderViewFolder* folder) { + LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + // Find all in the first pass LLDynamicArray<obj_folder_pair*> child_categories; LLTaskInvFVBridge* bridge; @@ -1737,11 +1773,11 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li { LLFolderViewFolder::Params p; p.name = obj->getName(); - p.icon = LLUI::getUIImage("Inv_FolderClosed"); - p.icon_open = LLUI::getUIImage("Inv_FolderOpen"); p.root = mFolders; p.listener = bridge; p.tool_tip = p.name; + p.font_color = item_color; + p.font_highlight_color = item_color; view = LLUICtrlFactory::create<LLFolderViewFolder>(p); child_categories.put(new obj_folder_pair(obj, (LLFolderViewFolder*)view)); @@ -1750,15 +1786,17 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li { LLFolderViewItem::Params params; params.name(obj->getName()); - params.icon(bridge->getIcon()); params.creation_date(bridge->getCreationDate()); params.root(mFolders); params.listener(bridge); params.rect(LLRect()); params.tool_tip = params.name; + params.font_color = item_color; + params.font_highlight_color = item_color; view = LLUICtrlFactory::create<LLFolderViewItem> (params); } - view->addToFolder(folder, mFolders); + view->addToFolder(folder); + addItemID(obj->getUUID(), view); } } @@ -1826,6 +1864,7 @@ void LLPanelObjectInventory::refresh() removeVOInventoryListener(); clearContents(); } + mInventoryViewModel.setTaskID(mTaskUUID); //llinfos << "LLPanelObjectInventory::refresh() " << mTaskUUID << llendl; } @@ -1913,7 +1952,10 @@ void LLPanelObjectInventory::idle(void* user_data) { LLPanelObjectInventory* self = (LLPanelObjectInventory*)user_data; - + if (self->mFolders) + { + self->mFolders->update(); + } if (self->mInventoryNeedsUpdate) { self->updateInventory(); @@ -1938,3 +1980,32 @@ void LLPanelObjectInventory::onFocusReceived() LLPanel::onFocusReceived(); } + + +LLFolderViewItem* LLPanelObjectInventory::getItemByID( const LLUUID& id ) +{ + std::map<LLUUID, LLFolderViewItem*>::iterator map_it; + map_it = mItemMap.find(id); + if (map_it != mItemMap.end()) + { + return map_it->second; + } + + return NULL; +} + +void LLPanelObjectInventory::removeItemID( const LLUUID& id ) +{ + mItemMap.erase(id); +} + +void LLPanelObjectInventory::addItemID( const LLUUID& id, LLFolderViewItem* itemp ) +{ + mItemMap[id] = itemp; +} + +void LLPanelObjectInventory::clearItemIDs() +{ + mItemMap.clear(); +} + diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h index 607b705f7f..f497c695b3 100644 --- a/indra/newview/llpanelobjectinventory.h +++ b/indra/newview/llpanelobjectinventory.h @@ -29,6 +29,7 @@ #include "llvoinventorylistener.h" #include "llpanel.h" +#include "llinventorypanel.h" // for LLFolderViewModelInventory #include "llinventory.h" @@ -55,6 +56,8 @@ public: virtual BOOL postBuild(); + LLFolderViewModelInventory& getRootViewModel() { return mInventoryViewModel; } + void doToSelected(const LLSD& userdata); void refresh(); @@ -85,8 +88,15 @@ protected: LLInventoryObject* parent, LLFolderViewFolder* folder); void clearContents(); + LLFolderViewItem* getItemByID(const LLUUID& id); + + void addItemID( const LLUUID& id, LLFolderViewItem* itemp ); + void removeItemID(const LLUUID& id); + void clearItemIDs(); private: + std::map<LLUUID, LLFolderViewItem*> mItemMap; + LLScrollContainer* mScroller; LLFolderView* mFolders; @@ -94,6 +104,7 @@ private: BOOL mHaveInventory; BOOL mIsInventoryEmpty; BOOL mInventoryNeedsUpdate; + LLFolderViewModelInventory mInventoryViewModel; }; #endif // LL_LLPANELOBJECTINVENTORY_H diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 35e2e96bab..c09d4393c8 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -169,7 +169,7 @@ public: return menu; } - + private: static void onCreate(const LLSD& param) { @@ -187,7 +187,7 @@ private: static void populateCreateWearableSubmenus(LLMenuGL* menu) { LLView* menu_clothes = gMenuHolder->getChildView("COF.Gear.New_Clothes", FALSE); - LLView* menu_bp = gMenuHolder->getChildView("COF.Geear.New_Body_Parts", FALSE); + LLView* menu_bp = gMenuHolder->getChildView("COF.Gear.New_Body_Parts", FALSE); for (U8 i = LLWearableType::WT_SHAPE; i != (U8) LLWearableType::WT_COUNT; ++i) { @@ -200,8 +200,7 @@ private: p.on_click.function_name = "Wearable.Create"; p.on_click.parameter = LLSD(type_name); - LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ? - menu_clothes : menu_bp; + LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ? menu_clothes : menu_bp; LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent); } } @@ -270,7 +269,7 @@ private: if (inventory_panel->getVisible()) { - inventory_panel->setSortOrder(sort_order); + inventory_panel->getFolderViewModel()->setSorter(sort_order); } else { @@ -738,7 +737,7 @@ void LLPanelOutfitEdit::onSearchEdit(const std::string& string) } // save current folder open state if no filter currently applied - if (mInventoryItemsPanel->getRootFolder()->getFilterSubString().empty()) + if (mInventoryItemsPanel->getFilterSubString().empty()) { mSavedFolderState->setApply(FALSE); mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); @@ -885,13 +884,13 @@ LLPanelOutfitEdit::selection_info_t LLPanelOutfitEdit::getAddMorePanelSelectionT { if (mInventoryItemsPanel != NULL && mInventoryItemsPanel->getVisible()) { - std::set<LLUUID> selected_uuids = mInventoryItemsPanel->getRootFolder()->getSelectionList(); + std::set<LLFolderViewItem*> selected_items = mInventoryItemsPanel->getRootFolder()->getSelectionList(); - result.second = selected_uuids.size(); + result.second = selected_items.size(); if (result.second == 1) { - result.first = getWearableTypeByItemUUID(*(selected_uuids.begin())); + result.first = getWearableTypeByItemUUID(static_cast<LLFolderViewModelItemInventory*>((*selected_items.begin())->getViewModelItem())->getUUID()); } } else if (mWearableItemsList != NULL && mWearableItemsList->getVisible()) @@ -1310,7 +1309,7 @@ void LLPanelOutfitEdit::getCurrentItemUUID(LLUUID& selected_id) LLFolderViewItem* curr_item = mInventoryItemsPanel->getRootFolder()->getCurSelectedItem(); if (!curr_item) return; - LLFolderViewEventListener* listenerp = curr_item->getListener(); + LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(curr_item->getViewModelItem()); if (!listenerp) return; selected_id = listenerp->getUUID(); @@ -1327,9 +1326,13 @@ void LLPanelOutfitEdit::getSelectedItemsUUID(uuid_vec_t& uuid_list) void (uuid_vec_t::* tmp)(LLUUID const &) = &uuid_vec_t::push_back; if (mInventoryItemsPanel->getVisible()) { - std::set<LLUUID> item_set = mInventoryItemsPanel->getRootFolder()->getSelectionList(); - - std::for_each(item_set.begin(), item_set.end(), boost::bind( tmp, &uuid_list, _1)); + std::set<LLFolderViewItem*> item_set = mInventoryItemsPanel->getRootFolder()->getSelectionList(); + for (std::set<LLFolderViewItem*>::iterator it = item_set.begin(), end_it = item_set.end(); + it != end_it; + ++it) + { + uuid_list.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID()); + } } else if (mWearablesListViewPanel->getVisible()) { @@ -1374,13 +1377,13 @@ void LLPanelOutfitEdit::saveListSelection() { if(mWearablesListViewPanel->getVisible()) { - std::set<LLUUID> selected_ids = mInventoryItemsPanel->getRootFolder()->getSelectionList(); + std::set<LLFolderViewItem*> selected_ids = mInventoryItemsPanel->getRootFolder()->getSelectionList(); if(!selected_ids.size()) return; - for (std::set<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id) + for (std::set<LLFolderViewItem*>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id) { - mWearableItemsList->selectItemByUUID(*item_id, true); + mWearableItemsList->selectItemByUUID(static_cast<LLFolderViewModelItemInventory*>((*item_id)->getViewModelItem())->getUUID(), true); } mWearableItemsList->scrollToShowFirstSelectedItem(); } @@ -1398,7 +1401,7 @@ void LLPanelOutfitEdit::saveListSelection() for(std::vector<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id) { - LLFolderViewItem* item = root->getItemByID(*item_id); + LLFolderViewItem* item = mInventoryItemsPanel->getItemByID(*item_id); if (!item) continue; LLFolderViewFolder* parent = item->getParentFolder(); diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index d5e289e6e6..3a5e6756b3 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -72,9 +72,12 @@ static const std::string NEARBY_TAB_NAME = "nearby_panel"; static const std::string FRIENDS_TAB_NAME = "friends_panel"; static const std::string GROUP_TAB_NAME = "groups_panel"; static const std::string RECENT_TAB_NAME = "recent_panel"; +static const std::string BLOCKED_TAB_NAME = "blocked_panel"; // blocked avatars static const std::string COLLAPSED_BY_USER = "collapsed_by_user"; +extern S32 gMaxAgentGroups; + /** Comparator for comparing avatar items by last interaction date */ class LLAvatarItemRecentComparator : public LLAvatarItemComparator { @@ -492,26 +495,37 @@ public: LLPanelPeople::LLPanelPeople() : LLPanel(), - mFilterSubString(LLStringUtil::null), - mFilterSubStringOrig(LLStringUtil::null), - mFilterEditor(NULL), mTabContainer(NULL), mOnlineFriendList(NULL), mAllFriendList(NULL), mNearbyList(NULL), mRecentList(NULL), mGroupList(NULL), - mNearbyGearButton(NULL), - mFriendsGearButton(NULL), - mGroupsGearButton(NULL), - mRecentGearButton(NULL), mMiniMap(NULL) { mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList, this)); mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList, this)); mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList, this)); mButtonsUpdater = new LLButtonsUpdater(boost::bind(&LLPanelPeople::updateButtons, this)); - mCommitCallbackRegistrar.add("People.addFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this)); + + mCommitCallbackRegistrar.add("People.AddFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this)); + mCommitCallbackRegistrar.add("People.AddFriendWizard", boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked, this)); + mCommitCallbackRegistrar.add("People.DelFriend", boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked, this)); + mCommitCallbackRegistrar.add("People.Group.Minus", boost::bind(&LLPanelPeople::onGroupMinusButtonClicked, this)); + mCommitCallbackRegistrar.add("People.Chat", boost::bind(&LLPanelPeople::onChatButtonClicked, this)); + mCommitCallbackRegistrar.add("People.Gear", boost::bind(&LLPanelPeople::onGearButtonClicked, this, _1)); + + mCommitCallbackRegistrar.add("People.Group.Plus.Action", boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked, this, _2)); + mCommitCallbackRegistrar.add("People.Friends.ViewSort.Action", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked, this, _2)); + mCommitCallbackRegistrar.add("People.Nearby.ViewSort.Action", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked, this, _2)); + mCommitCallbackRegistrar.add("People.Groups.ViewSort.Action", boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked, this, _2)); + mCommitCallbackRegistrar.add("People.Recent.ViewSort.Action", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked, this, _2)); + + mEnableCallbackRegistrar.add("People.Friends.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck, this, _2)); + mEnableCallbackRegistrar.add("People.Recent.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck, this, _2)); + mEnableCallbackRegistrar.add("People.Nearby.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck, this, _2)); + + mEnableCallbackRegistrar.add("People.Group.Plus.Validate", boost::bind(&LLPanelPeople::onGroupPlusButtonValidate, this)); } LLPanelPeople::~LLPanelPeople() @@ -525,13 +539,6 @@ LLPanelPeople::~LLPanelPeople() { LLVoiceClient::getInstance()->removeObserver(this); } - - delete mGroupPlusMenuHandle.get(); - delete mNearbyViewSortMenuHandle.get(); - delete mFriendsViewSortMenuHandle.get(); - delete mGroupsViewSortMenuHandle.get(); - delete mRecentViewSortMenuHandle.get(); - } void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list) @@ -551,17 +558,31 @@ void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LL } } + +void LLPanelPeople::removePicker() +{ + if(mPicker.get()) + { + mPicker.get()->closeFloater(); + } +} + BOOL LLPanelPeople::postBuild() { - mFilterEditor = getChild<LLFilterEditor>("filter_input"); - mFilterEditor->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); + getChild<LLFilterEditor>("nearby_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); + getChild<LLFilterEditor>("friends_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); + getChild<LLFilterEditor>("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); + getChild<LLFilterEditor>("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); mTabContainer = getChild<LLTabContainer>("tabs"); mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2)); + mSavedFilters.resize(mTabContainer->getTabCount()); + mSavedOriginalFilters.resize(mTabContainer->getTabCount()); LLPanel* friends_tab = getChild<LLPanel>(FRIENDS_TAB_NAME); // updater is active only if panel is visible to user. friends_tab->setVisibleCallback(boost::bind(&Updater::setActive, mFriendListUpdater, _2)); + friends_tab->setVisibleCallback(boost::bind(&LLPanelPeople::removePicker, this)); mOnlineFriendList = friends_tab->getChild<LLAvatarList>("avatars_online"); mAllFriendList = friends_tab->getChild<LLAvatarList>("avatars_all"); mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online")); @@ -601,14 +622,6 @@ BOOL LLPanelPeople::postBuild() setSortOrder(mAllFriendList, (ESortOrder)gSavedSettings.getU32("FriendsSortOrder"), false); setSortOrder(mNearbyList, (ESortOrder)gSavedSettings.getU32("NearbyPeopleSortOrder"), false); - LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME); - groups_panel->childSetAction("activate_btn", boost::bind(&LLPanelPeople::onActivateButtonClicked, this)); - groups_panel->childSetAction("plus_btn", boost::bind(&LLPanelPeople::onGroupPlusButtonClicked, this)); - - LLPanel* friends_panel = getChild<LLPanel>(FRIENDS_TAB_NAME); - friends_panel->childSetAction("add_btn", boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked, this)); - friends_panel->childSetAction("del_btn", boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked, this)); - mOnlineFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1)); mAllFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1)); mNearbyList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1)); @@ -629,6 +642,19 @@ BOOL LLPanelPeople::postBuild() mGroupList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this)); mGroupList->setReturnCallback(boost::bind(&LLPanelPeople::onChatButtonClicked, this)); + LLMenuButton* groups_gear_btn = getChild<LLMenuButton>("groups_gear_btn"); + + // Use the context menu of the Groups list for the Groups tab gear menu. + LLToggleableMenu* groups_gear_menu = mGroupList->getContextMenu(); + if (groups_gear_menu) + { + groups_gear_btn->setMenu(groups_gear_menu, LLMenuButton::MP_BOTTOM_LEFT); + } + else + { + llwarns << "People->Groups list menu not found" << llendl; + } + LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>("tab_all"); accordion_tab->setDropDownStateChangedCallback( boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mAllFriendList)); @@ -637,70 +663,9 @@ BOOL LLPanelPeople::postBuild() accordion_tab->setDropDownStateChangedCallback( boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mOnlineFriendList)); - buttonSetAction("view_profile_btn", boost::bind(&LLPanelPeople::onViewProfileButtonClicked, this)); - buttonSetAction("group_info_btn", boost::bind(&LLPanelPeople::onGroupInfoButtonClicked, this)); - buttonSetAction("chat_btn", boost::bind(&LLPanelPeople::onChatButtonClicked, this)); - buttonSetAction("im_btn", boost::bind(&LLPanelPeople::onImButtonClicked, this)); - buttonSetAction("call_btn", boost::bind(&LLPanelPeople::onCallButtonClicked, this)); - buttonSetAction("group_call_btn", boost::bind(&LLPanelPeople::onGroupCallButtonClicked, this)); - buttonSetAction("teleport_btn", boost::bind(&LLPanelPeople::onTeleportButtonClicked, this)); - buttonSetAction("share_btn", boost::bind(&LLPanelPeople::onShareButtonClicked, this)); - // Must go after setting commit callback and initializing all pointers to children. mTabContainer->selectTabByName(NEARBY_TAB_NAME); - // Create menus. - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - - registrar.add("People.Group.Plus.Action", boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked, this, _2)); - registrar.add("People.Group.Minus.Action", boost::bind(&LLPanelPeople::onGroupMinusButtonClicked, this)); - registrar.add("People.Friends.ViewSort.Action", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked, this, _2)); - registrar.add("People.Nearby.ViewSort.Action", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked, this, _2)); - registrar.add("People.Groups.ViewSort.Action", boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked, this, _2)); - registrar.add("People.Recent.ViewSort.Action", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked, this, _2)); - - enable_registrar.add("People.Group.Minus.Enable", boost::bind(&LLPanelPeople::isRealGroup, this)); - enable_registrar.add("People.Friends.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck, this, _2)); - enable_registrar.add("People.Recent.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck, this, _2)); - enable_registrar.add("People.Nearby.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck, this, _2)); - - mNearbyGearButton = getChild<LLMenuButton>("nearby_view_sort_btn"); - mFriendsGearButton = getChild<LLMenuButton>("friends_viewsort_btn"); - mGroupsGearButton = getChild<LLMenuButton>("groups_viewsort_btn"); - mRecentGearButton = getChild<LLMenuButton>("recent_viewsort_btn"); - - LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - mGroupPlusMenuHandle = plus_menu->getHandle(); - - LLToggleableMenu* nearby_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_nearby_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if(nearby_view_sort) - { - mNearbyViewSortMenuHandle = nearby_view_sort->getHandle(); - mNearbyGearButton->setMenu(nearby_view_sort); - } - - LLToggleableMenu* friend_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_friends_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if(friend_view_sort) - { - mFriendsViewSortMenuHandle = friend_view_sort->getHandle(); - mFriendsGearButton->setMenu(friend_view_sort); - } - - LLToggleableMenu* group_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_groups_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if(group_view_sort) - { - mGroupsViewSortMenuHandle = group_view_sort->getHandle(); - mGroupsGearButton->setMenu(group_view_sort); - } - - LLToggleableMenu* recent_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_recent_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if(recent_view_sort) - { - mRecentViewSortMenuHandle = recent_view_sort->getHandle(); - mRecentGearButton->setMenu(recent_view_sort); - } - LLVoiceClient::getInstance()->addObserver(this); // call this method in case some list is empty and buttons can be in inconsistent state @@ -735,9 +700,11 @@ void LLPanelPeople::updateFriendListHelpText() if (no_friends_text->getVisible()) { //update help text for empty lists - std::string message_name = mFilterSubString.empty() ? "no_friends_msg" : "no_filtered_friends_msg"; + const std::string& filter = mSavedOriginalFilters[mTabContainer->getCurrentPanelIndex()]; + + std::string message_name = filter.empty() ? "no_friends_msg" : "no_filtered_friends_msg"; LLStringUtil::format_map_t args; - args["[SEARCH_TERM]"] = LLURI::escape(mFilterSubStringOrig); + args["[SEARCH_TERM]"] = LLURI::escape(filter); no_friends_text->setText(getString(message_name, args)); } } @@ -821,31 +788,9 @@ void LLPanelPeople::updateRecentList() mRecentList->setDirty(); } -void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible) -{ - // To make sure we're referencing the right widget (a child of the button bar). - LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name); - button->setVisible(visible); -} - -void LLPanelPeople::buttonSetEnabled(const std::string& btn_name, bool enabled) -{ - // To make sure we're referencing the right widget (a child of the button bar). - LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name); - button->setEnabled(enabled); -} - -void LLPanelPeople::buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb) -{ - // To make sure we're referencing the right widget (a child of the button bar). - LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name); - button->setClickedCallback(cb); -} - void LLPanelPeople::updateButtons() { std::string cur_tab = getActiveTabName(); - bool nearby_tab_active = (cur_tab == NEARBY_TAB_NAME); bool friends_tab_active = (cur_tab == FRIENDS_TAB_NAME); bool group_tab_active = (cur_tab == GROUP_TAB_NAME); //bool recent_tab_active = (cur_tab == RECENT_TAB_NAME); @@ -856,63 +801,47 @@ void LLPanelPeople::updateButtons() bool item_selected = (selected_uuids.size() == 1); bool multiple_selected = (selected_uuids.size() >= 1); - buttonSetVisible("group_info_btn", group_tab_active); - buttonSetVisible("chat_btn", group_tab_active); - buttonSetVisible("view_profile_btn", !group_tab_active); - buttonSetVisible("im_btn", !group_tab_active); - buttonSetVisible("call_btn", !group_tab_active); - buttonSetVisible("group_call_btn", group_tab_active); - buttonSetVisible("teleport_btn", friends_tab_active); - buttonSetVisible("share_btn", nearby_tab_active || friends_tab_active); - if (group_tab_active) { - bool cur_group_active = true; - if (item_selected) { selected_id = mGroupList->getSelectedUUID(); - cur_group_active = (gAgent.getGroupID() == selected_id); } LLPanel* groups_panel = mTabContainer->getCurrentPanel(); - groups_panel->getChildView("activate_btn")->setEnabled(item_selected && !cur_group_active); // "none" or a non-active group selected - groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); + groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected + groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.count())); + groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[REMAINING]", llformat("%d",(gMaxAgentGroups-gAgent.mGroups.count()))); } else { bool is_friend = true; - + bool is_self = false; // Check whether selected avatar is our friend. if (item_selected) { selected_id = selected_uuids.front(); is_friend = LLAvatarTracker::instance().getBuddyInfo(selected_id) != NULL; + is_self = gAgent.getID() == selected_id; } LLPanel* cur_panel = mTabContainer->getCurrentPanel(); if (cur_panel) { - cur_panel->getChildView("add_friend_btn")->setEnabled(!is_friend); + if (cur_panel->hasChild("add_friend_btn", TRUE)) + cur_panel->getChildView("add_friend_btn")->setEnabled(item_selected && !is_friend && !is_self); + if (friends_tab_active) { - cur_panel->getChildView("del_btn")->setEnabled(multiple_selected); + cur_panel->getChildView("friends_del_btn")->setEnabled(multiple_selected); + } + + if (!group_tab_active) + { + cur_panel->getChildView("gear_btn")->setEnabled(multiple_selected); } } } - - bool enable_calls = LLVoiceClient::getInstance()->isVoiceWorking() && LLVoiceClient::getInstance()->voiceEnabled(); - - buttonSetEnabled("view_profile_btn",item_selected); - buttonSetEnabled("share_btn", item_selected); - buttonSetEnabled("im_btn", multiple_selected); // allow starting the friends conference for multiple selection - buttonSetEnabled("call_btn", multiple_selected && enable_calls); - buttonSetEnabled("teleport_btn", multiple_selected && LLAvatarActions::canOfferTeleport(selected_uuids)); - - bool none_group_selected = item_selected && selected_id.isNull(); - buttonSetEnabled("group_info_btn", !none_group_selected); - buttonSetEnabled("group_call_btn", !none_group_selected && enable_calls); - buttonSetEnabled("chat_btn", !none_group_selected); } std::string LLPanelPeople::getActiveTabName() const @@ -943,6 +872,9 @@ LLUUID LLPanelPeople::getCurrentItemID() const if (cur_tab == GROUP_TAB_NAME) return mGroupList->getSelectedUUID(); + if (cur_tab == BLOCKED_TAB_NAME) + return LLUUID::null; // FIXME? + llassert(0 && "unknown tab selected"); return LLUUID::null; } @@ -963,6 +895,8 @@ void LLPanelPeople::getCurrentItemIDs(uuid_vec_t& selected_uuids) const mRecentList->getSelectedUUIDs(selected_uuids); else if (cur_tab == GROUP_TAB_NAME) mGroupList->getSelectedUUIDs(selected_uuids); + else if (cur_tab == BLOCKED_TAB_NAME) + selected_uuids.clear(); // FIXME? else llassert(0 && "unknown tab selected"); @@ -1031,49 +965,60 @@ void LLPanelPeople::setSortOrder(LLAvatarList* list, ESortOrder order, bool save } } -bool LLPanelPeople::isRealGroup() -{ - return getCurrentItemID() != LLUUID::null; -} - void LLPanelPeople::onFilterEdit(const std::string& search_string) { - mFilterSubStringOrig = search_string; - LLStringUtil::trimHead(mFilterSubStringOrig); + const S32 cur_tab_idx = mTabContainer->getCurrentPanelIndex(); + std::string& filter = mSavedOriginalFilters[cur_tab_idx]; + std::string& saved_filter = mSavedFilters[cur_tab_idx]; + + filter = search_string; + LLStringUtil::trimHead(filter); + // Searches are case-insensitive - std::string search_upper = mFilterSubStringOrig; + std::string search_upper = filter; LLStringUtil::toUpper(search_upper); - if (mFilterSubString == search_upper) + if (saved_filter == search_upper) return; - mFilterSubString = search_upper; + saved_filter = search_upper; - //store accordion tabs state before any manipulation with accordion tabs - if(!mFilterSubString.empty()) + // Apply new filter to the current tab. + const std::string cur_tab = getActiveTabName(); + if (cur_tab == NEARBY_TAB_NAME) + { + mNearbyList->setNameFilter(filter); + } + else if (cur_tab == FRIENDS_TAB_NAME) + { + // store accordion tabs opened/closed state before any manipulation with accordion tabs + if (!saved_filter.empty()) { notifyChildren(LLSD().with("action","store_state")); } - - // Apply new filter. - mNearbyList->setNameFilter(mFilterSubStringOrig); - mOnlineFriendList->setNameFilter(mFilterSubStringOrig); - mAllFriendList->setNameFilter(mFilterSubStringOrig); - mRecentList->setNameFilter(mFilterSubStringOrig); - mGroupList->setNameFilter(mFilterSubStringOrig); + mOnlineFriendList->setNameFilter(filter); + mAllFriendList->setNameFilter(filter); setAccordionCollapsedByUser("tab_online", false); setAccordionCollapsedByUser("tab_all", false); - showFriendsAccordionsIfNeeded(); - //restore accordion tabs state _after_ all manipulations... - if(mFilterSubString.empty()) + // restore accordion tabs state _after_ all manipulations + if(saved_filter.empty()) { notifyChildren(LLSD().with("action","restore_state")); } } + else if (cur_tab == GROUP_TAB_NAME) + { + mGroupList->setNameFilter(filter); + } + else if (cur_tab == RECENT_TAB_NAME) + { + mRecentList->setNameFilter(filter); + } +} void LLPanelPeople::onTabSelected(const LLSD& param) { @@ -1081,11 +1026,6 @@ void LLPanelPeople::onTabSelected(const LLSD& param) updateButtons(); showFriendsAccordionsIfNeeded(); - - if (GROUP_TAB_NAME == tab_name) - mFilterEditor->setLabel(getString("groups_filter_label")); - else - mFilterEditor->setLabel(getString("people_filter_label")); } void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl) @@ -1097,6 +1037,10 @@ void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl) } LLUUID clicked_id = item->getAvatarId(); + if(gAgent.getID() == clicked_id) + { + return; + } #if 0 // SJB: Useful for testing, but not currently functional or to spec LLAvatarActions::showProfile(clicked_id); @@ -1127,12 +1071,6 @@ void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list) updateButtons(); } -void LLPanelPeople::onViewProfileButtonClicked() -{ - LLUUID id = getCurrentItemID(); - LLAvatarActions::showProfile(id); -} - void LLPanelPeople::onAddFriendButtonClicked() { LLUUID id = getCurrentItemID(); @@ -1160,15 +1098,26 @@ bool LLPanelPeople::isItemsFreeOfFriends(const uuid_vec_t& uuids) void LLPanelPeople::onAddFriendWizButtonClicked() { + LLPanel* cur_panel = mTabContainer->getCurrentPanel(); + LLView * button = cur_panel->findChild<LLButton>("friends_add_btn", TRUE); + // Show add friend wizard. - LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelPeople::onAvatarPicked, _1, _2), FALSE, TRUE); + LLFloater* root_floater = gFloaterView->getParentFloater(this); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelPeople::onAvatarPicked, _1, _2), FALSE, TRUE, FALSE, root_floater->getName(), button); + if (!picker) + { + return; + } + // Need to disable 'ok' button when friend occurs in selection - if (picker) picker->setOkBtnEnableCb(boost::bind(&LLPanelPeople::isItemsFreeOfFriends, this, _1)); - LLFloater* root_floater = gFloaterView->getParentFloater(this); + picker->setOkBtnEnableCb(boost::bind(&LLPanelPeople::isItemsFreeOfFriends, this, _1)); + if (root_floater) { root_floater->addDependentFloater(picker); } + + mPicker = picker->getHandle(); } void LLPanelPeople::onDeleteFriendButtonClicked() @@ -1186,11 +1135,6 @@ void LLPanelPeople::onDeleteFriendButtonClicked() } } -void LLPanelPeople::onGroupInfoButtonClicked() -{ - LLGroupActions::show(getCurrentItemID()); -} - void LLPanelPeople::onChatButtonClicked() { LLUUID group_id = getCurrentItemID(); @@ -1198,6 +1142,14 @@ void LLPanelPeople::onChatButtonClicked() LLGroupActions::startIM(group_id); } +void LLPanelPeople::onGearButtonClicked(LLUICtrl* btn) +{ + uuid_vec_t selected_uuids; + getCurrentItemIDs(selected_uuids); + // Spawn at bottom left corner of the button. + LLPanelPeopleMenus::gNearbyMenu.show(btn, selected_uuids, 0, 0); +} + void LLPanelPeople::onImButtonClicked() { uuid_vec_t selected_uuids; @@ -1214,11 +1166,6 @@ void LLPanelPeople::onImButtonClicked() } } -void LLPanelPeople::onActivateButtonClicked() -{ - LLGroupActions::activate(mGroupList->getSelectedUUID()); -} - // static void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names) { @@ -1226,19 +1173,15 @@ void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAv LLAvatarActions::requestFriendshipDialog(ids[0], names[0].getCompleteName()); } -void LLPanelPeople::onGroupPlusButtonClicked() +bool LLPanelPeople::onGroupPlusButtonValidate() { if (!gAgent.canJoinGroups()) { LLNotificationsUtil::add("JoinedTooManyGroups"); - return; + return false; } - LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get(); - if (!plus_menu) - return; - - showGroupMenu(plus_menu); + return true; } void LLPanelPeople::onGroupMinusButtonClicked() @@ -1283,10 +1226,6 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata) mAllFriendList->showPermissions(show_permissions); mOnlineFriendList->showPermissions(show_permissions); } - else if (chosen_item == "panel_block_list_sidetray") - { - LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD()); - } } void LLPanelPeople::onGroupsViewSortMenuItemClicked(const LLSD& userdata) @@ -1319,10 +1258,6 @@ void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata) { setSortOrder(mNearbyList, E_SORT_BY_DISTANCE); } - else if (chosen_item == "panel_block_list_sidetray") - { - LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD()); - } } bool LLPanelPeople::onNearbyViewSortMenuItemCheck(const LLSD& userdata) @@ -1356,10 +1291,6 @@ void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata) { mRecentList->toggleIcons(); } - else if (chosen_item == "panel_block_list_sidetray") - { - LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD()); - } } bool LLPanelPeople::onFriendsViewSortMenuItemCheck(const LLSD& userdata) @@ -1388,40 +1319,6 @@ bool LLPanelPeople::onRecentViewSortMenuItemCheck(const LLSD& userdata) return false; } -void LLPanelPeople::onCallButtonClicked() -{ - uuid_vec_t selected_uuids; - getCurrentItemIDs(selected_uuids); - - if (selected_uuids.size() == 1) - { - // initiate a P2P voice chat with the selected user - LLAvatarActions::startCall(getCurrentItemID()); - } - else if (selected_uuids.size() > 1) - { - // initiate an ad-hoc voice chat with multiple users - LLAvatarActions::startAdhocCall(selected_uuids); - } -} - -void LLPanelPeople::onGroupCallButtonClicked() -{ - LLGroupActions::startCall(getCurrentItemID()); -} - -void LLPanelPeople::onTeleportButtonClicked() -{ - uuid_vec_t selected_uuids; - getCurrentItemIDs(selected_uuids); - LLAvatarActions::offerTeleport(selected_uuids); -} - -void LLPanelPeople::onShareButtonClicked() -{ - LLAvatarActions::share(getCurrentItemID()); -} - void LLPanelPeople::onMoreButtonClicked() { // *TODO: not implemented yet diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 46c58cd139..4740964dee 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -68,6 +68,8 @@ private: E_SORT_BY_RECENT_SPEAKERS = 4, } ESortOrder; + void removePicker(); + // methods indirectly called by the updaters void updateFriendListHelpText(); void updateFriendList(); @@ -80,31 +82,22 @@ private: std::string getActiveTabName() const; LLUUID getCurrentItemID() const; void getCurrentItemIDs(uuid_vec_t& selected_uuids) const; - void buttonSetVisible(std::string btn_name, BOOL visible); - void buttonSetEnabled(const std::string& btn_name, bool enabled); - void buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb); void showGroupMenu(LLMenuGL* menu); void setSortOrder(LLAvatarList* list, ESortOrder order, bool save = true); // UI callbacks void onFilterEdit(const std::string& search_string); void onTabSelected(const LLSD& param); - void onViewProfileButtonClicked(); void onAddFriendButtonClicked(); void onAddFriendWizButtonClicked(); void onDeleteFriendButtonClicked(); - void onGroupInfoButtonClicked(); void onChatButtonClicked(); + void onGearButtonClicked(LLUICtrl* btn); void onImButtonClicked(); - void onCallButtonClicked(); - void onGroupCallButtonClicked(); - void onTeleportButtonClicked(); - void onShareButtonClicked(); void onMoreButtonClicked(); - void onActivateButtonClicked(); void onAvatarListDoubleClicked(LLUICtrl* ctrl); void onAvatarListCommitted(LLAvatarList* list); - void onGroupPlusButtonClicked(); + bool onGroupPlusButtonValidate(); void onGroupMinusButtonClicked(); void onGroupPlusMenuItemClicked(const LLSD& userdata); @@ -113,8 +106,6 @@ private: void onGroupsViewSortMenuItemClicked(const LLSD& userdata); void onRecentViewSortMenuItemClicked(const LLSD& userdata); - //returns false only if group is "none" - bool isRealGroup(); bool onFriendsViewSortMenuItemCheck(const LLSD& userdata); bool onRecentViewSortMenuItemCheck(const LLSD& userdata); bool onNearbyViewSortMenuItemCheck(const LLSD& userdata); @@ -135,7 +126,6 @@ private: bool isAccordionCollapsedByUser(LLUICtrl* acc_tab); bool isAccordionCollapsedByUser(const std::string& name); - LLFilterEditor* mFilterEditor; LLTabContainer* mTabContainer; LLAvatarList* mOnlineFriendList; LLAvatarList* mAllFriendList; @@ -144,24 +134,14 @@ private: LLGroupList* mGroupList; LLNetMap* mMiniMap; - LLHandle<LLView> mGroupPlusMenuHandle; - LLHandle<LLView> mNearbyViewSortMenuHandle; - LLHandle<LLView> mFriendsViewSortMenuHandle; - LLHandle<LLView> mGroupsViewSortMenuHandle; - LLHandle<LLView> mRecentViewSortMenuHandle; + std::vector<std::string> mSavedOriginalFilters; + std::vector<std::string> mSavedFilters; Updater* mFriendListUpdater; Updater* mNearbyListUpdater; Updater* mRecentListUpdater; Updater* mButtonsUpdater; - - LLMenuButton* mNearbyGearButton; - LLMenuButton* mFriendsGearButton; - LLMenuButton* mGroupsGearButton; - LLMenuButton* mRecentGearButton; - - std::string mFilterSubString; - std::string mFilterSubStringOrig; + LLHandle< LLFloater > mPicker; }; #endif //LL_LLPANELPEOPLE_H diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp index f12c4de2f7..47d6b49a50 100644 --- a/indra/newview/llpanelpeoplemenus.cpp +++ b/indra/newview/llpanelpeoplemenus.cpp @@ -37,6 +37,7 @@ #include "llagentdata.h" // for gAgentID #include "llavataractions.h" #include "llcallingcard.h" // for LLAvatarTracker +#include "lllogchat.h" #include "llviewermenu.h" // for gMenuHolder namespace LLPanelPeopleMenus @@ -51,6 +52,7 @@ LLContextMenu* NearbyMenu::createMenu() // set up the callbacks for all of the avatar menu items LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + LLContextMenu* menu; if ( mUUIDs.size() == 1 ) { @@ -67,20 +69,22 @@ LLContextMenu* NearbyMenu::createMenu() registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::share, id)); registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, id)); registrar.add("Avatar.BlockUnblock", boost::bind(&LLAvatarActions::toggleBlock, id)); + registrar.add("Avatar.InviteToGroup", boost::bind(&LLAvatarActions::inviteToGroup, id)); + registrar.add("Avatar.Calllog", boost::bind(&LLAvatarActions::viewChatHistory, id)); enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem, this, _2)); enable_registrar.add("Avatar.CheckItem", boost::bind(&NearbyMenu::checkContextMenuItem, this, _2)); // create the context menu from the XUI - return createFromFile("menu_people_nearby.xml"); + menu = createFromFile("menu_people_nearby.xml"); } else { // Set up for multi-selected People // registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mUUIDs)); // *TODO: unimplemented - registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startConference, mUUIDs)); - registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startAdhocCall, mUUIDs)); + registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startConference, mUUIDs, LLUUID::null)); + registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startAdhocCall, mUUIDs, LLUUID::null)); registrar.add("Avatar.OfferTeleport", boost::bind(&NearbyMenu::offerTeleport, this)); registrar.add("Avatar.RemoveFriend",boost::bind(&LLAvatarActions::removeFriendsDialog, mUUIDs)); // registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::startIM, mUUIDs)); // *TODO: unimplemented @@ -88,12 +92,18 @@ LLContextMenu* NearbyMenu::createMenu() enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem, this, _2)); // create the context menu from the XUI - return createFromFile("menu_people_nearby_multiselect.xml"); + menu = createFromFile("menu_people_nearby_multiselect.xml"); } + + return menu; } bool NearbyMenu::enableContextMenuItem(const LLSD& userdata) { + if(gAgent.getID() == mUUIDs.front()) + { + return false; + } std::string item = userdata.asString(); // Note: can_block and can_delete is used only for one person selected menu @@ -171,6 +181,15 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata) { return LLAvatarActions::canOfferTeleport(mUUIDs); } + else if (item == std::string("can_callog")) + { + return LLLogChat::isTranscriptExist(mUUIDs.front()); + } + else if (item == std::string("can_im") || item == std::string("can_invite") || + item == std::string("can_share") || item == std::string("can_pay")) + { + return true; + } return false; } diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 59130236f2..e641370d2e 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -62,6 +62,7 @@ #include "llspinctrl.h" #include "roles_constants.h" #include "llgroupactions.h" +#include "lltrans.h" U8 string_value_to_click_action(std::string p_value); @@ -180,6 +181,9 @@ void LLPanelPermissions::disableAll() getChildView("perm_modify")->setEnabled(FALSE); getChild<LLUICtrl>("perm_modify")->setValue(LLStringUtil::null); + getChildView("pathfinding_attributes_value")->setEnabled(FALSE); + getChild<LLUICtrl>("pathfinding_attributes_value")->setValue(LLStringUtil::null); + getChildView("Creator:")->setEnabled(FALSE); getChild<LLUICtrl>("Creator Name")->setValue(LLStringUtil::null); getChildView("Creator Name")->setEnabled(FALSE); @@ -299,6 +303,9 @@ void LLPanelPermissions::refresh() BOOL is_perm_modify = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode() && LLSelectMgr::getInstance()->selectGetRootsModify()) || LLSelectMgr::getInstance()->selectGetModify(); + BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode() + && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced()) + || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced(); const LLFocusableElement* keyboard_focus_view = gFocusMgr.getKeyboardFocus(); S32 string_index = 0; @@ -307,12 +314,18 @@ void LLPanelPermissions::refresh() getString("text modify info 1"), getString("text modify info 2"), getString("text modify info 3"), - getString("text modify info 4") + getString("text modify info 4"), + getString("text modify info 5"), + getString("text modify info 6") }; if (!is_perm_modify) { string_index += 2; } + else if (!is_nonpermanent_enforced) + { + string_index += 4; + } if (!is_one_object) { ++string_index; @@ -320,6 +333,34 @@ void LLPanelPermissions::refresh() getChildView("perm_modify")->setEnabled(TRUE); getChild<LLUICtrl>("perm_modify")->setValue(MODIFY_INFO_STRINGS[string_index]); + std::string pfAttrName; + + if ((LLSelectMgr::getInstance()->getSelection()->getFirstRootNode() + && LLSelectMgr::getInstance()->selectGetRootsNonPathfinding()) + || LLSelectMgr::getInstance()->selectGetNonPathfinding()) + { + pfAttrName = "Pathfinding_Object_Attr_None"; + } + else if ((LLSelectMgr::getInstance()->getSelection()->getFirstRootNode() + && LLSelectMgr::getInstance()->selectGetRootsPermanent()) + || LLSelectMgr::getInstance()->selectGetPermanent()) + { + pfAttrName = "Pathfinding_Object_Attr_Permanent"; + } + else if ((LLSelectMgr::getInstance()->getSelection()->getFirstRootNode() + && LLSelectMgr::getInstance()->selectGetRootsCharacter()) + || LLSelectMgr::getInstance()->selectGetCharacter()) + { + pfAttrName = "Pathfinding_Object_Attr_Character"; + } + else + { + pfAttrName = "Pathfinding_Object_Attr_MultiSelect"; + } + + getChildView("pathfinding_attributes_value")->setEnabled(TRUE); + getChild<LLUICtrl>("pathfinding_attributes_value")->setValue(LLTrans::getString(pfAttrName)); + getChildView("Permissions:")->setEnabled(TRUE); // Update creator text field @@ -384,7 +425,7 @@ void LLPanelPermissions::refresh() } } - getChildView("button set group")->setEnabled(owners_identical && (mOwnerID == gAgent.getID())); + getChildView("button set group")->setEnabled(root_selected && owners_identical && (mOwnerID == gAgent.getID()) && is_nonpermanent_enforced); getChildView("Name:")->setEnabled(TRUE); LLLineEditor* LineEditorObjectName = getChild<LLLineEditor>("Object Name"); @@ -414,7 +455,7 @@ void LLPanelPermissions::refresh() // figure out the contents of the name, description, & category BOOL edit_name_desc = FALSE; - if (is_one_object && objectp->permModify()) + if (is_one_object && objectp->permModify() && !objectp->isPermanentEnforced()) { edit_name_desc = TRUE; } @@ -594,12 +635,12 @@ void LLPanelPermissions::refresh() BOOL has_change_perm_ability = FALSE; BOOL has_change_sale_ability = FALSE; - if (valid_base_perms && + if (valid_base_perms && is_nonpermanent_enforced && (self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_MANIPULATE)))) { has_change_perm_ability = TRUE; } - if (valid_base_perms && + if (valid_base_perms && is_nonpermanent_enforced && (self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_SET_SALE)))) { has_change_sale_ability = TRUE; @@ -812,8 +853,8 @@ void LLPanelPermissions::refresh() combo_click_action->setValue(LLSD(combo_value)); } } - getChildView("label click action")->setEnabled(is_perm_modify && all_volume); - getChildView("clickaction")->setEnabled(is_perm_modify && all_volume); + getChildView("label click action")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume); + getChildView("clickaction")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume); } diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index 50dc66ed7c..cfbc8f1a94 100755 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -1048,13 +1048,10 @@ void LLPanelPicks::createPickInfoPanel() void LLPanelPicks::createClassifiedInfoPanel() { - if(!mPanelClassifiedInfo) - { - mPanelClassifiedInfo = LLPanelClassifiedInfo::create(); - mPanelClassifiedInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedInfo)); - mPanelClassifiedInfo->setEditClassifiedCallback(boost::bind(&LLPanelPicks::onPanelClassifiedEdit, this)); - mPanelClassifiedInfo->setVisible(FALSE); - } + mPanelClassifiedInfo = LLPanelClassifiedInfo::create(); + mPanelClassifiedInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedInfo)); + mPanelClassifiedInfo->setEditClassifiedCallback(boost::bind(&LLPanelPicks::onPanelClassifiedEdit, this)); + mPanelClassifiedInfo->setVisible(FALSE); } void LLPanelPicks::createClassifiedEditPanel(LLPanelClassifiedEdit** panel) @@ -1072,14 +1069,11 @@ void LLPanelPicks::createClassifiedEditPanel(LLPanelClassifiedEdit** panel) void LLPanelPicks::createPickEditPanel() { - if(!mPanelPickEdit) - { - mPanelPickEdit = LLPanelPickEdit::create(); - mPanelPickEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit)); - mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickSave, this, mPanelPickEdit)); - mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit)); - mPanelPickEdit->setVisible(FALSE); - } + mPanelPickEdit = LLPanelPickEdit::create(); + mPanelPickEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickSave, this, mPanelPickEdit)); + mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setVisible(FALSE); } // void LLPanelPicks::openPickEditPanel(LLPickItem* pick) diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index ce8057eead..83b70d9f29 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -499,9 +499,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, std::string parcel_owner = LLSLURL("agent", parcel->getOwnerID(), "inspect").getSLURLString(); mParcelOwner->setText(parcel_owner); - LLAvatarNameCache::get(region->getOwner(), - boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, - _1, _2, mRegionOwnerText)); + LLAvatarNameCache::get(region->getOwner(), boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, _1, _2, mRegionOwnerText)); } if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus()) @@ -523,9 +521,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID(); if(auth_buyer_id.notNull()) { - LLAvatarNameCache::get(auth_buyer_id, - boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, - _1, _2, mSaleToText)); + LLAvatarNameCache::get(auth_buyer_id, boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, _1, _2, mSaleToText)); // Show sales info to a specific person or a group he belongs to. if (auth_buyer_id != gAgent.getID() && !gAgent.isInGroup(auth_buyer_id)) diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h index a33fc12ce4..f4c6145881 100644 --- a/indra/newview/llpanelplaceprofile.h +++ b/indra/newview/llpanelplaceprofile.h @@ -38,7 +38,7 @@ class LLPanelPlaceProfile : public LLPanelPlaceInfo public: LLPanelPlaceProfile(); /*virtual*/ ~LLPanelPlaceProfile(); - + /*virtual*/ BOOL postBuild(); /*virtual*/ void resetLocation(); diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 6d321d4716..6c2a01fc82 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -366,6 +366,7 @@ void LLPanelPlaces::onOpen(const LLSD& key) if (key.size() != 0) { + isLandmarkEditModeOn = false; std::string key_type = key["type"].asString(); if (key_type == LANDMARK_TAB_INFO_TYPE) { @@ -392,7 +393,6 @@ void LLPanelPlaces::onOpen(const LLSD& key) mPlaceInfoType = key_type; mPosGlobal.setZero(); mItem = NULL; - isLandmarkEditModeOn = false; togglePlaceInfoPanel(TRUE); if (mPlaceInfoType == AGENT_INFO_TYPE) diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 933b40ec79..76d38f067d 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -818,7 +818,7 @@ bool LLPanelPrimMediaControls::isMouseOver() LLCoordGL cursor_pos_gl; S32 x, y; getWindow()->getCursorPosition(&cursor_pos_window); - getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl); + cursor_pos_gl = cursor_pos_window.convert(); if(mMediaControlsStack->getVisible()) { @@ -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/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h index 66956181f2..eeb433e306 100644 --- a/indra/newview/llpanelprimmediacontrols.h +++ b/indra/newview/llpanelprimmediacontrols.h @@ -30,9 +30,9 @@ #include "llpanel.h" #include "llviewermedia.h" #include "llnotificationptr.h" +#include "llcoord.h" class LLButton; -class LLCoordWindow; class LLIconCtrl; class LLLayoutStack; class LLProgressBar; diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 5ce59d8959..e2e7006773 100755 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -38,7 +38,6 @@ #include "llviewernetwork.h" static const std::string PANEL_PICKS = "panel_picks"; -static const std::string PANEL_PROFILE = "panel_profile"; std::string getProfileURL(const std::string& agent_name) { @@ -168,6 +167,23 @@ LLPanelProfile::ChildStack::ChildStack() { } +LLPanelProfile::ChildStack::~ChildStack() +{ + while (mStack.size() != 0) + { + view_list_t& top = mStack.back(); + for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it) + { + LLView* viewp = *it; + if (viewp) + { + viewp->die(); + } + } + mStack.pop_back(); + } +} + void LLPanelProfile::ChildStack::setParent(LLPanel* parent) { llassert_always(parent != NULL); @@ -272,7 +288,6 @@ BOOL LLPanelProfile::postBuild() panel_picks->setProfilePanel(this); getTabContainer()[PANEL_PICKS] = panel_picks; - getTabContainer()[PANEL_PROFILE] = findChild<LLPanelAvatarProfile>(PANEL_PROFILE); return TRUE; } diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index bd4457c240..d97f60ed22 100755 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -74,6 +74,7 @@ private: LOG_CLASS(LLPanelProfile::ChildStack); public: ChildStack(); + ~ChildStack(); void setParent(LLPanel* parent); bool push(); diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp deleted file mode 100644 index 7635aedf58..0000000000 --- a/indra/newview/llpanelprofileview.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/** -* @file llpanelprofileview.cpp -* @brief Side tray "Profile View" panel -* -* $LicenseInfo:firstyear=2009&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 "llpanelprofileview.h" - -#include "llavatarconstants.h" -#include "llavatarnamecache.h" // IDEVO -#include "llclipboard.h" -#include "lluserrelations.h" - -#include "llavatarpropertiesprocessor.h" -#include "llcallingcard.h" -#include "llpanelavatar.h" -#include "llpanelpicks.h" -#include "llpanelprofile.h" -#include "llsidetraypanelcontainer.h" - -static LLRegisterPanelClassWrapper<LLPanelProfileView> t_panel_target_profile("panel_profile_view"); - -static std::string PANEL_NOTES = "panel_notes"; -static const std::string PANEL_PROFILE = "panel_profile"; -static const std::string PANEL_PICKS = "panel_picks"; - - -class AvatarStatusObserver : public LLAvatarPropertiesObserver -{ -public: - AvatarStatusObserver(LLPanelProfileView* profile_view) - { - mProfileView = profile_view; - } - - void processProperties(void* data, EAvatarProcessorType type) - { - if(APT_PROPERTIES != type) return; - const LLAvatarData* avatar_data = static_cast<const LLAvatarData*>(data); - if(avatar_data && mProfileView->getAvatarId() == avatar_data->avatar_id) - { - mProfileView->processOnlineStatus(avatar_data->flags & AVATAR_ONLINE); - LLAvatarPropertiesProcessor::instance().removeObserver(mProfileView->getAvatarId(), this); - } - } - - void subscribe() - { - LLAvatarPropertiesProcessor::instance().addObserver(mProfileView->getAvatarId(), this); - } - -private: - LLPanelProfileView* mProfileView; -}; - -LLPanelProfileView::LLPanelProfileView() -: LLPanelProfile() -, mStatusText(NULL) -, mAvatarStatusObserver(NULL) -{ - mAvatarStatusObserver = new AvatarStatusObserver(this); -} - -LLPanelProfileView::~LLPanelProfileView(void) -{ - delete mAvatarStatusObserver; -} - -/*virtual*/ -void LLPanelProfileView::onOpen(const LLSD& key) -{ - LLUUID id; - if(key.has("id")) - { - id = key["id"]; - } - - if(id.notNull() && getAvatarId() != id) - { - setAvatarId(id); - - // clear name fields, which might have old data - getChild<LLUICtrl>("user_name")->setValue( LLSD() ); - getChild<LLUICtrl>("user_slid")->setValue( LLSD() ); - } - - // Update the avatar name. - LLAvatarNameCache::get(getAvatarId(), - boost::bind(&LLPanelProfileView::onAvatarNameCache, this, _1, _2)); - - updateOnlineStatus(); - - - LLPanelProfile::onOpen(key); -} - -BOOL LLPanelProfileView::postBuild() -{ - LLPanelProfile::postBuild(); - - getTabContainer()[PANEL_NOTES] = findChild<LLPanelAvatarNotes>(PANEL_NOTES); - - //*TODO remove this, according to style guide we don't use status combobox - getTabContainer()[PANEL_PROFILE]->getChildView("online_me_status_text")->setVisible( FALSE); - getTabContainer()[PANEL_PROFILE]->getChildView("status_combo")->setVisible( FALSE); - - mStatusText = getChild<LLTextBox>("status"); - mStatusText->setVisible(false); - - childSetCommitCallback("back",boost::bind(&LLPanelProfileView::onBackBtnClick,this),NULL); - childSetCommitCallback("copy_to_clipboard",boost::bind(&LLPanelProfileView::onCopyToClipboard,this),NULL); - - return TRUE; -} - - -//private - -void LLPanelProfileView::onBackBtnClick() -{ - // Set dummy value to make picks panel dirty, - // This will make Picks reload on next open. - getTabContainer()[PANEL_PICKS]->setValue(LLSD()); - - LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent()); - if(parent) - { - parent->openPreviousPanel(); - } -} - -void LLPanelProfileView::onCopyToClipboard() -{ - std::string name = getChild<LLUICtrl>("user_name")->getValue().asString() + " (" + getChild<LLUICtrl>("user_slid")->getValue().asString() + ")"; - gClipboard.copyFromString(utf8str_to_wstring(name)); -} - -bool LLPanelProfileView::isGrantedToSeeOnlineStatus() -{ - const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - if (NULL == relationship) - return false; - - // *NOTE: GRANT_ONLINE_STATUS is always set to false while changing any other status. - // When avatar disallow me to see her online status processOfflineNotification Message is received by the viewer - // see comments for ChangeUserRights template message. EXT-453. - // If GRANT_ONLINE_STATUS flag is changed it will be applied when viewer restarts. EXT-3880 - return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS); -} - -// method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880 -void LLPanelProfileView::updateOnlineStatus() -{ - // set text box visible to show online status for non-friends who has not set in Preferences - // "Only Friends & Groups can see when I am online" - mStatusText->setVisible(TRUE); - - const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - if (NULL == relationship) - { - // this is non-friend avatar. Status will be updated from LLAvatarPropertiesProcessor. - // in LLPanelProfileView::processOnlineStatus() - - // subscribe observer to get online status. Request will be sent by LLPanelAvatarProfile itself. - // do not subscribe for friend avatar because online status can be wrong overridden - // via LLAvatarData::flags if Preferences: "Only Friends & Groups can see when I am online" is set. - mAvatarStatusObserver->subscribe(); - return; - } - // For friend let check if he allowed me to see his status - - // status should only show if viewer has permission to view online/offline. EXT-453, EXT-3880 - mStatusText->setVisible(isGrantedToSeeOnlineStatus()); - - bool online = relationship->isOnline(); - processOnlineStatus(online); -} - -void LLPanelProfileView::processOnlineStatus(bool online) -{ - std::string status = getString(online ? "status_online" : "status_offline"); - - mStatusText->setValue(status); -} - -void LLPanelProfileView::onAvatarNameCache(const LLUUID& agent_id, - const LLAvatarName& av_name) -{ - getChild<LLUICtrl>("user_name")->setValue( av_name.mDisplayName ); - getChild<LLUICtrl>("user_name_small")->setValue( av_name.mDisplayName ); - getChild<LLUICtrl>("user_slid")->setValue( av_name.mUsername ); - - // show smaller display name if too long to display in regular size - if (getChild<LLTextBox>("user_name")->getTextPixelWidth() > getChild<LLTextBox>("user_name")->getRect().getWidth()) - { - getChild<LLUICtrl>("user_name_small")->setVisible( true ); - getChild<LLUICtrl>("user_name")->setVisible( false ); - } - else - { - getChild<LLUICtrl>("user_name_small")->setVisible( false ); - getChild<LLUICtrl>("user_name")->setVisible( true ); - } - - if (LLAvatarNameCache::useDisplayNames()) - { - getChild<LLUICtrl>("user_label")->setVisible( true ); - getChild<LLUICtrl>("user_slid")->setVisible( true ); - getChild<LLUICtrl>("display_name_label")->setVisible( true ); - getChild<LLUICtrl>("copy_to_clipboard")->setVisible( true ); - getChild<LLUICtrl>("copy_to_clipboard")->setEnabled( true ); - getChild<LLUICtrl>("solo_username_label")->setVisible( false ); - } - else - { - getChild<LLUICtrl>("user_label")->setVisible( false ); - getChild<LLUICtrl>("user_slid")->setVisible( false ); - getChild<LLUICtrl>("display_name_label")->setVisible( false ); - getChild<LLUICtrl>("copy_to_clipboard")->setVisible( false ); - getChild<LLUICtrl>("copy_to_clipboard")->setEnabled( false ); - getChild<LLUICtrl>("solo_username_label")->setVisible( true ); - } -} - -// EOF diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h deleted file mode 100644 index c6d921fdc4..0000000000 --- a/indra/newview/llpanelprofileview.h +++ /dev/null @@ -1,108 +0,0 @@ -/** -* @file llpanelprofileview.h -* @brief Side tray "Profile View" panel -* -* $LicenseInfo:firstyear=2009&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_LLPANELPROFILEVIEW_H -#define LL_LLPANELPROFILEVIEW_H - -#include "llpanel.h" -#include "llpanelprofile.h" -#include "llavatarpropertiesprocessor.h" -#include "llagent.h" -#include "lltooldraganddrop.h" - -class LLAvatarName; -class LLPanelProfile; -class LLPanelProfileTab; -class LLTextBox; -class AvatarStatusObserver; - -/** -* Panel for displaying Avatar's profile. It consists of three sub panels - Profile, -* Picks and Notes. -*/ -class LLPanelProfileView : public LLPanelProfile -{ - LOG_CLASS(LLPanelProfileView); - friend class LLUICtrlFactory; - friend class AvatarStatusObserver; - -public: - - LLPanelProfileView(); - - /*virtual*/ ~LLPanelProfileView(); - - /*virtual*/ void onOpen(const LLSD& key); - - /*virtual*/ BOOL postBuild(); - - BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, - BOOL drop, EDragAndDropType cargo_type, - void *cargo_data, EAcceptance *accept, - std::string& tooltip_msg) - { - LLToolDragAndDrop::handleGiveDragAndDrop(getAvatarId(), gAgent.getSessionID(), drop, - cargo_type, cargo_data, accept); - - return TRUE; - } - - -protected: - - void onBackBtnClick(); - void onCopyToClipboard(); - bool isGrantedToSeeOnlineStatus(); - - /** - * Displays avatar's online status if possible. - * - * Requirements from EXT-3880: - * For friends: - * - Online when online and privacy settings allow to show - * - Offline when offline and privacy settings allow to show - * - Else: nothing - * For other avatars: - * - Online when online and was not set in Preferences/"Only Friends & Groups can see when I am online" - * - Else: Offline - */ - void updateOnlineStatus(); - void processOnlineStatus(bool online); - -private: - // LLCacheName will call this function when avatar name is loaded from server. - // This is required to display names that have not been cached yet. -// void onNameCache( -// const LLUUID& id, -// const std::string& full_name, -// bool is_group); - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); - - LLTextBox* mStatusText; - AvatarStatusObserver* mAvatarStatusObserver; -}; - -#endif //LL_LLPANELPROFILEVIEW_H diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index d3543daff0..0756faf5c0 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -358,7 +358,7 @@ void LLTeleportHistoryPanel::ContextMenu::onInfo() //static void LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback(const std::string& slurl) { - gClipboard.copyFromString(utf8str_to_wstring(slurl)); + LLClipboard::instance().copyToClipboard(utf8str_to_wstring(slurl),0,slurl.size()); } void LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard() @@ -388,7 +388,7 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel() LLTeleportHistoryPanel::~LLTeleportHistoryPanel() { LLTeleportHistoryFlatItemStorage::instance().purge(); - delete mGearMenuHandle.get(); + if (mGearMenuHandle.get()) mGearMenuHandle.get()->die(); mTeleportHistoryChangedConnection.disconnect(); } @@ -972,6 +972,11 @@ void LLTeleportHistoryPanel::onCollapseAllFolders() mItemContainers.get(n)->setDisplayChildren(false); } mHistoryAccordion->arrange(); + + if (mLastSelectedFlatlList) + { + mLastSelectedFlatlList->resetSelection(); + } } void LLTeleportHistoryPanel::onClearTeleportHistory() diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp index 5ed23d2f42..343c140bbb 100644 --- a/indra/newview/llpaneltopinfobar.cpp +++ b/indra/newview/llpaneltopinfobar.cpp @@ -64,9 +64,6 @@ private: LLPanelTopInfoBar::LLPanelTopInfoBar(): mParcelChangedObserver(0) { - LLUICtrl::CommitCallbackRegistry::currentRegistrar() - .add("TopInfoBar.Action", boost::bind(&LLPanelTopInfoBar::onContextMenuItemClicked, this, _2)); - buildFromFile( "panel_topinfo_bar.xml"); } @@ -132,6 +129,11 @@ void LLPanelTopInfoBar::handleLoginComplete() BOOL LLPanelTopInfoBar::handleRightMouseDown(S32 x, S32 y, MASK mask) { + if(!LLUICtrl::CommitCallbackRegistry::getValue("TopInfoBar.Action")) + { + LLUICtrl::CommitCallbackRegistry::currentRegistrar() + .add("TopInfoBar.Action", boost::bind(&LLPanelTopInfoBar::onContextMenuItemClicked, this, _2)); + } show_topinfobar_context_menu(this, x, y); return TRUE; } @@ -203,6 +205,11 @@ void LLPanelTopInfoBar::onVisibilityChange(const LLSD& show) gFloaterView->setMinimizePositionVerticalOffset(minimize_pos_offset); } +boost::signals2::connection LLPanelTopInfoBar::setResizeCallback( const resize_signal_t::slot_type& cb ) +{ + return mResizeSignal.connect(cb); +} + void LLPanelTopInfoBar::draw() { updateParcelInfoText(); @@ -224,7 +231,8 @@ void LLPanelTopInfoBar::buildLocationString(std::string& loc_str, bool show_coor void LLPanelTopInfoBar::setParcelInfoText(const std::string& new_text) { - const LLFontGL* font = mParcelInfoText->getDefaultFont(); + LLRect old_rect = getRect(); + const LLFontGL* font = mParcelInfoText->getFont(); S32 new_text_width = font->getWidth(new_text); mParcelInfoText->setText(new_text); @@ -235,6 +243,11 @@ void LLPanelTopInfoBar::setParcelInfoText(const std::string& new_text) mParcelInfoText->reshape(rect.getWidth(), rect.getHeight(), TRUE); mParcelInfoText->setRect(rect); layoutParcelIcons(); + + if (old_rect != getRect()) + { + mResizeSignal(); + } } void LLPanelTopInfoBar::update() @@ -342,6 +355,8 @@ void LLPanelTopInfoBar::updateHealth() void LLPanelTopInfoBar::layoutParcelIcons() { + LLRect old_rect = getRect(); + // TODO: remove hard-coded values and read them as xml parameters static const int FIRST_ICON_HPAD = 32; static const int LAST_ICON_HPAD = 11; @@ -358,6 +373,11 @@ void LLPanelTopInfoBar::layoutParcelIcons() LLRect rect = getRect(); rect.set(rect.mLeft, rect.mTop, left + LAST_ICON_HPAD, rect.mBottom); setRect(rect); + + if (old_rect != getRect()) + { + mResizeSignal(); + } } S32 LLPanelTopInfoBar::layoutWidget(LLUICtrl* ctrl, S32 left) @@ -449,7 +469,7 @@ void LLPanelTopInfoBar::onContextMenuItemClicked(const LLSD::String& item) LLAgentUI::buildSLURL(slurl, false); LLUIString location_str(slurl.getSLURLString()); - gClipboard.copyFromString(location_str); + LLClipboard::instance().copyToClipboard(location_str,0,location_str.length()); } } diff --git a/indra/newview/llpaneltopinfobar.h b/indra/newview/llpaneltopinfobar.h index e934b522be..d58d95be90 100644 --- a/indra/newview/llpaneltopinfobar.h +++ b/indra/newview/llpaneltopinfobar.h @@ -41,6 +41,8 @@ class LLPanelTopInfoBar : public LLPanel, public LLSingleton<LLPanelTopInfoBar>, friend class LLDestroyClass<LLPanelTopInfoBar>; public: + typedef boost::signals2::signal<void ()> resize_signal_t; + LLPanelTopInfoBar(); ~LLPanelTopInfoBar(); @@ -57,6 +59,8 @@ public: */ void onVisibilityChange(const LLSD& show); + boost::signals2::connection setResizeCallback( const resize_signal_t::slot_type& cb ); + private: class LLParcelChangeObserver; @@ -167,6 +171,8 @@ private: boost::signals2::connection mParcelPropsCtrlConnection; boost::signals2::connection mShowCoordsCtrlConnection; boost::signals2::connection mParcelMgrConnection; + + resize_signal_t mResizeSignal; }; #endif /* LLPANELTOPINFOBAR_H_ */ diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp index 4bbfec8ab7..5fec6d967d 100644 --- a/indra/newview/llpanelvoiceeffect.cpp +++ b/indra/newview/llpanelvoiceeffect.cpp @@ -123,7 +123,6 @@ void LLPanelVoiceEffect::update(bool list_updated) if (mVoiceEffectCombo) { LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); - llassert(effect_interface); if (!effect_interface) return; if (list_updated) { diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 12eea7844d..13b746dbab 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -68,6 +68,7 @@ #include "llworld.h" #include "pipeline.h" #include "llviewershadermgr.h" +#include "llnotificationsutil.h" #include "lldrawpool.h" #include "lluictrlfactory.h" @@ -77,13 +78,15 @@ #include "llviewercontrol.h" #include "llmeshrepository.h" +#include <boost/bind.hpp> + // "Features" Tab BOOL LLPanelVolume::postBuild() { // Flexible Objects Parameters { - childSetCommitCallback("Flexible1D Checkbox Ctrl",onCommitIsFlexible,this); + childSetCommitCallback("Flexible1D Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitIsFlexible, this, _1, _2), NULL); childSetCommitCallback("FlexNumSections",onCommitFlexible,this); getChild<LLUICtrl>("FlexNumSections")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexGravity",onCommitFlexible,this); @@ -255,7 +258,7 @@ void LLPanelVolume::getState( ) owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); // BUG? Check for all objects being editable? - BOOL editable = root_objectp->permModify(); + BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced(); BOOL single_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) && LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1; @@ -351,7 +354,7 @@ void LLPanelVolume::getState( ) getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(is_flexible); if (is_flexible || (volobjp && volobjp->canBeFlexible())) { - getChildView("Flexible1D Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp && !volobjp->isMesh()); + getChildView("Flexible1D Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp && !volobjp->isMesh() && !objectp->isPermanentEnforced()); } else { @@ -495,7 +498,7 @@ void LLPanelVolume::getState( ) mComboPhysicsShapeType->add(getString("Convex Hull"), LLSD(2)); mComboPhysicsShapeType->setValue(LLSD(objectp->getPhysicsShapeType())); - mComboPhysicsShapeType->setEnabled(editable); + mComboPhysicsShapeType->setEnabled(editable && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced())); mObject = objectp; mRootObject = root_objectp; @@ -873,10 +876,26 @@ void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata ) self->refresh(); } -// static -void LLPanelVolume::onCommitIsFlexible( LLUICtrl* ctrl, void* userdata ) +void LLPanelVolume::onCommitIsFlexible(LLUICtrl *, void*) { - LLPanelVolume* self = (LLPanelVolume*) userdata; - self->sendIsFlexible(); + if (mObject->flagObjectPermanent()) + { + LLNotificationsUtil::add("PathfindingLinksets_ChangeToFlexiblePath", LLSD(), LLSD(), boost::bind(&LLPanelVolume::handleResponseChangeToFlexible, this, _1, _2)); + } + else + { + sendIsFlexible(); + } } +void LLPanelVolume::handleResponseChangeToFlexible(const LLSD &pNotification, const LLSD &pResponse) +{ + if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0) + { + sendIsFlexible(); + } + else + { + getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(FALSE); + } +} diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h index 0ef47db0d9..deb6b6f2a6 100644 --- a/indra/newview/llpanelvolume.h +++ b/indra/newview/llpanelvolume.h @@ -61,7 +61,7 @@ public: static void onCommitIsLight( LLUICtrl* ctrl, void* userdata); static void onCommitLight( LLUICtrl* ctrl, void* userdata); - static void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata); + void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata); static void onCommitFlexible( LLUICtrl* ctrl, void* userdata); static void onCommitPhysicsParam( LLUICtrl* ctrl, void* userdata); static void onCommitMaterial( LLUICtrl* ctrl, void* userdata); @@ -84,6 +84,8 @@ protected: void sendPhysicsRestitution(LLUICtrl* ctrl, void* userdata); void sendPhysicsDensity(LLUICtrl* ctrl, void* userdata); + void handleResponseChangeToFlexible(const LLSD &pNotification, const LLSD &pResponse); + /* LLTextBox* mLabelSelectSingleMessage; // Light diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index e2801c09bd..3b9934d4be 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -302,6 +302,6 @@ void LLPanelWearing::copyToClipboard() } } - gClipboard.copyFromString(utf8str_to_wstring(text)); + LLClipboard::instance().copyToClipboard(utf8str_to_wstring(text),0,text.size()); } // EOF diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index fb1153980a..c53760bca1 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -1,6 +1,6 @@ /** * @file llparticipantlist.cpp - * @brief LLParticipantList intended to update view(LLAvatarList) according to incoming messages + * @brief LLParticipantList : model of a conversation session with added speaker events handling * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code @@ -26,38 +26,17 @@ #include "llviewerprecompiledheaders.h" -// common includes -#include "lltrans.h" -#include "llavataractions.h" -#include "llagent.h" - +#include "llavatarnamecache.h" #include "llimview.h" -#include "llnotificationsutil.h" +#include "llfloaterimcontainer.h" #include "llparticipantlist.h" #include "llspeakers.h" -#include "llviewercontrol.h" -#include "llviewermenu.h" -#include "llvoiceclient.h" //LLParticipantList retrieves add, clear and remove events and updates view accordingly #if LL_MSVC #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally #endif -static const LLAvatarItemAgentOnTopComparator AGENT_ON_TOP_NAME_COMPARATOR; - -// helper function to update AvatarList Item's indicator in the voice participant list -static void update_speaker_indicator(const LLAvatarList* const avatar_list, const LLUUID& avatar_uuid, bool is_muted) -{ - LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(avatar_list->getItemByValue(avatar_uuid)); - if (item) - { - LLOutputMonitorCtrl* indicator = item->getChild<LLOutputMonitorCtrl>("speaking_indicator"); - indicator->setIsMuted(is_muted); - } -} - - // See EXT-4301. /** * class LLAvalineUpdater - observe the list of voice participants in session and check @@ -197,15 +176,9 @@ private: uuid_set_t mAvalineCallers; }; -LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, - LLAvatarList* avatar_list, - bool use_context_menu/* = true*/, - bool exclude_agent /*= true*/, - bool can_toggle_icons /*= true*/) : +LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model) : + LLConversationItemSession(data_source->getSessionID(), root_view_model), mSpeakerMgr(data_source), - mAvatarList(avatar_list), - mParticipantListMenu(NULL), - mExcludeAgent(exclude_agent), mValidateSpeakerCallback(NULL) { @@ -216,36 +189,16 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, mSpeakerRemoveListener = new SpeakerRemoveListener(*this); mSpeakerClearListener = new SpeakerClearListener(*this); mSpeakerModeratorListener = new SpeakerModeratorUpdateListener(*this); + mSpeakerUpdateListener = new SpeakerUpdateListener(*this); mSpeakerMuteListener = new SpeakerMuteListener(*this); mSpeakerMgr->addListener(mSpeakerAddListener, "add"); mSpeakerMgr->addListener(mSpeakerRemoveListener, "remove"); mSpeakerMgr->addListener(mSpeakerClearListener, "clear"); mSpeakerMgr->addListener(mSpeakerModeratorListener, "update_moderator"); + mSpeakerMgr->addListener(mSpeakerUpdateListener, "update_speaker"); - mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData")); - LL_DEBUGS("SpeakingIndicator") << "Set session for speaking indicators: " << mSpeakerMgr->getSessionID() << LL_ENDL; - mAvatarList->setSessionID(mSpeakerMgr->getSessionID()); - mAvatarListDoubleClickConnection = mAvatarList->setItemDoubleClickCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, _1)); - mAvatarListRefreshConnection = mAvatarList->setRefreshCompleteCallback(boost::bind(&LLParticipantList::onAvatarListRefreshed, this, _1, _2)); - // Set onAvatarListDoubleClicked as default on_return action. - mAvatarListReturnConnection = mAvatarList->setReturnCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList)); - - if (use_context_menu) - { - mParticipantListMenu = new LLParticipantListMenu(*this); - mAvatarList->setContextMenu(mParticipantListMenu); - } - else - { - mAvatarList->setContextMenu(NULL); - } - - if (use_context_menu && can_toggle_icons) - { - mAvatarList->setShowIcons("ParticipantListShowIcons"); - mAvatarListToggleIconsConnection = gSavedSettings.getControl("ParticipantListShowIcons")->getSignal()->connect(boost::bind(&LLAvatarList::toggleIcons, mAvatarList)); - } + setSessionID(mSpeakerMgr->getSessionID()); //Lets fill avatarList with existing speakers LLSpeakerMgr::speaker_list_t speaker_list; @@ -264,135 +217,32 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, mModeratorToRemoveList.insert(speakerp->mID); } } - // we need to exclude agent id for non group chat - sort(); -} - -LLParticipantList::~LLParticipantList() -{ - mAvatarListDoubleClickConnection.disconnect(); - mAvatarListRefreshConnection.disconnect(); - mAvatarListReturnConnection.disconnect(); - mAvatarListToggleIconsConnection.disconnect(); - - // It is possible Participant List will be re-created from LLCallFloater::onCurrentChannelChanged() - // See ticket EXT-3427 - // hide menu before deleting it to stop enable and check handlers from triggering. - if(mParticipantListMenu && !LLApp::isExiting()) - { - mParticipantListMenu->hide(); - } - - if (mParticipantListMenu) - { - delete mParticipantListMenu; - mParticipantListMenu = NULL; - } - - mAvatarList->setContextMenu(NULL); - mAvatarList->setComparator(NULL); - - delete mAvalineUpdater; -} - -void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible) -{ - mAvatarList->setSpeakingIndicatorsVisible(visible); -}; - -void LLParticipantList::onAvatarListDoubleClicked(LLUICtrl* ctrl) -{ - LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(ctrl); - if(!item) - { - return; - } - - LLUUID clicked_id = item->getAvatarId(); - - if (clicked_id.isNull() || clicked_id == gAgent.getID()) - return; - LLAvatarActions::startIM(clicked_id); -} - -void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param) -{ - LLAvatarList* list = dynamic_cast<LLAvatarList*>(ctrl); - if (list) + // Identify and store what kind of session we are + LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(data_source->getSessionID()); + if (im_session) { - const std::string moderator_indicator(LLTrans::getString("IM_moderator_label")); - const std::size_t moderator_indicator_len = moderator_indicator.length(); - - // Firstly remove moderators indicator - std::set<LLUUID>::const_iterator - moderator_list_it = mModeratorToRemoveList.begin(), - moderator_list_end = mModeratorToRemoveList.end(); - for (;moderator_list_it != moderator_list_end; ++moderator_list_it) + // By default, sessions that can't be identified as group or ad-hoc will be considered P2P (i.e. 1 on 1) + mConvType = CONV_SESSION_1_ON_1; + if (im_session->isAdHocSessionType()) { - LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*> (list->getItemByValue(*moderator_list_it)); - if ( item ) - { - std::string name = item->getAvatarName(); - std::string tooltip = item->getAvatarToolTip(); - size_t found = name.find(moderator_indicator); - if (found != std::string::npos) - { - name.erase(found, moderator_indicator_len); - item->setAvatarName(name); - } - found = tooltip.find(moderator_indicator); - if (found != tooltip.npos) - { - tooltip.erase(found, moderator_indicator_len); - item->setAvatarToolTip(tooltip); - } - } + mConvType = CONV_SESSION_AD_HOC; } - - mModeratorToRemoveList.clear(); - - // Add moderators indicator - moderator_list_it = mModeratorList.begin(); - moderator_list_end = mModeratorList.end(); - for (;moderator_list_it != moderator_list_end; ++moderator_list_it) + else if (im_session->isGroupSessionType()) { - LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*> (list->getItemByValue(*moderator_list_it)); - if ( item ) - { - std::string name = item->getAvatarName(); - std::string tooltip = item->getAvatarToolTip(); - size_t found = name.find(moderator_indicator); - if (found == std::string::npos) - { - name += " "; - name += moderator_indicator; - item->setAvatarName(name); - } - found = tooltip.find(moderator_indicator); - if (found == std::string::npos) - { - tooltip += " "; - tooltip += moderator_indicator; - item->setAvatarToolTip(tooltip); - } - } - } - - // update voice mute state of all items. See EXT-7235 - LLSpeakerMgr::speaker_list_t speaker_list; - - // Use also participants which are not in voice session now (the second arg is TRUE). - // They can already have mModeratorMutedVoice set from the previous voice session - // and LLSpeakerVoiceModerationEvent will not be sent when speaker manager is updated next time. - mSpeakerMgr->getSpeakerList(&speaker_list, TRUE); - for(LLSpeakerMgr::speaker_list_t::iterator it = speaker_list.begin(); it != speaker_list.end(); it++) - { - const LLPointer<LLSpeaker>& speakerp = *it; - - update_speaker_indicator(list, speakerp->mID, speakerp->mModeratorMutedVoice); + mConvType = CONV_SESSION_GROUP; } } + else + { + // That's the only session that doesn't get listed in the LLIMModel as a session... + mConvType = CONV_SESSION_NEARBY; + } +} + +LLParticipantList::~LLParticipantList() +{ + delete mAvalineUpdater; } /* @@ -408,31 +258,11 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param) */ void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id) { - LLPanel* item = mAvatarList->getItemByValue(participant_id); - - if (NULL == item) - { - LL_WARNS("Avaline") << "Something wrong. Unable to find item for: " << participant_id << LL_ENDL; - return; - } - - if (typeid(*item) == typeid(LLAvalineListItem)) + LLConversationItemParticipant* participant = findParticipant(participant_id); + if (participant) { - LL_DEBUGS("Avaline") << "Avaline caller has already correct class type for: " << participant_id << LL_ENDL; - // item representing an Avaline caller has a correct type already. - return; + removeParticipant(participant); } - - LL_DEBUGS("Avaline") << "remove item from the list and re-add it: " << participant_id << LL_ENDL; - - // remove UUID from LLAvatarList::mIDs to be able add it again. - uuid_vec_t& ids = mAvatarList->getIDs(); - uuid_vec_t::iterator pos = std::find(ids.begin(), ids.end(), participant_id); - ids.erase(pos); - - // remove item directly - mAvatarList->removeItem(item); - // re-add avaline caller with a correct class instance. addAvatarIDExceptAgent(participant_id); } @@ -444,37 +274,14 @@ void LLParticipantList::onAvalineCallerRemoved(const LLUUID& participant_id) mSpeakerMgr->removeAvalineSpeaker(participant_id); } -void LLParticipantList::setSortOrder(EParticipantSortOrder order) -{ - const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder"); - - if ( speaker_sort_order != order ) - { - gSavedSettings.setU32("SpeakerParticipantDefaultOrder", (U32)order); - sort(); - } -} - -const LLParticipantList::EParticipantSortOrder LLParticipantList::getSortOrder() const -{ - const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder"); - return EParticipantSortOrder(speaker_sort_order); -} - void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t cb) { mValidateSpeakerCallback = cb; } -void LLParticipantList::updateRecentSpeakersOrder() +void LLParticipantList::update() { - if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder()) - { - // Need to update speakers to sort list correctly - mSpeakerMgr->update(true); - // Resort avatar list - sort(); - } + mSpeakerMgr->update(true); } bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) @@ -487,27 +294,34 @@ bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, co } addAvatarIDExceptAgent(uu_id); - sort(); return true; } bool LLParticipantList::onRemoveItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) { - uuid_vec_t& group_members = mAvatarList->getIDs(); - uuid_vec_t::iterator pos = std::find(group_members.begin(), group_members.end(), event->getValue().asUUID()); - if(pos != group_members.end()) - { - group_members.erase(pos); - mAvatarList->setDirty(); - } + LLUUID avatar_id = event->getValue().asUUID(); + removeParticipant(avatar_id); return true; } bool LLParticipantList::onClearListEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) { - uuid_vec_t& group_members = mAvatarList->getIDs(); - group_members.clear(); - mAvatarList->setDirty(); + clearParticipants(); + return true; +} + +bool LLParticipantList::onSpeakerUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) +{ + const LLSD& evt_data = event->getValue(); + if ( evt_data.has("id") ) + { + LLUUID participant_id = evt_data["id"]; + LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance(); + if (im_box) + { + im_box->setTimeNow(mUUID,participant_id); + } + } return true; } @@ -531,9 +345,7 @@ bool LLParticipantList::onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> e mModeratorList.erase(id); } } - - // apply changes immediately - onAvatarListRefreshed(mAvatarList, LLSD()); + // *TODO : do we have to fire an event so that LLFloaterIMSessionTab::refreshConversation() gets called } } return true; @@ -547,60 +359,45 @@ bool LLParticipantList::onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event // update UI on confirmation of moderator mutes if (event->getValue().asString() == "voice") { - update_speaker_indicator(mAvatarList, speakerp->mID, speakerp->mModeratorMutedVoice); + setParticipantIsMuted(speakerp->mID, speakerp->mModeratorMutedVoice); } return true; } -void LLParticipantList::sort() +void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id) { - if ( !mAvatarList ) - return; - - switch ( getSortOrder() ) + // Do not add if already in there, is the session id (hence not an avatar) or excluded for some reason + if (findParticipant(avatar_id) || (avatar_id == mUUID)) { - case E_SORT_BY_NAME : - // if mExcludeAgent == true , then no need to keep agent on top of the list - if(mExcludeAgent) - { - mAvatarList->sortByName(); - } - else - { - mAvatarList->setComparator(&AGENT_ON_TOP_NAME_COMPARATOR); - mAvatarList->sort(); - } - break; - case E_SORT_BY_RECENT_SPEAKERS: - if (mSortByRecentSpeakers.isNull()) - mSortByRecentSpeakers = new LLAvatarItemRecentSpeakerComparator(*this); - mAvatarList->setComparator(mSortByRecentSpeakers.get()); - mAvatarList->sort(); - break; - default : - llwarns << "Unrecognized sort order for " << mAvatarList->getName() << llendl; - return; + return; } -} - -void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id) -{ - if (mExcludeAgent && gAgent.getID() == avatar_id) return; - if (mAvatarList->contains(avatar_id)) return; bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(avatar_id); + LLConversationItemParticipant* participant = NULL; + if (is_avatar) { - mAvatarList->getIDs().push_back(avatar_id); - mAvatarList->setDirty(); + // Create a participant view model instance + LLAvatarName avatar_name; + bool has_name = LLAvatarNameCache::get(avatar_id, &avatar_name); + participant = new LLConversationItemParticipant(!has_name ? LLTrans::getString("AvatarNameWaiting") : avatar_name.getDisplayName() , avatar_id, mRootViewModel); + participant->fetchAvatarName(); } else { std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id); - mAvatarList->addAvalineItem(avatar_id, mSpeakerMgr->getSessionID(), display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name); + // Create a participant view model instance + participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel); mAvalineUpdater->watchAvalineCaller(avatar_id); } + + // *TODO : Need to update the online/offline status of the participant + // Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id)) + + // Add the participant model to the session's children list + addParticipant(participant); + adjustParticipant(avatar_id); } @@ -619,12 +416,12 @@ void LLParticipantList::adjustParticipant(const LLUUID& speaker_id) bool LLParticipantList::SpeakerAddListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) { /** - * We need to filter speaking objects. These objects shouldn't appear in the list + * We need to filter speaking objects. These objects shouldn't appear in the list. * @see LLFloaterChat::addChat() in llviewermessage.cpp to get detailed call hierarchy */ const LLUUID& speaker_id = event->getValue().asUUID(); LLPointer<LLSpeaker> speaker = mParent.mSpeakerMgr->findSpeaker(speaker_id); - if(speaker.isNull() || speaker->mType == LLSpeaker::SPEAKER_OBJECT) + if (speaker.isNull() || (speaker->mType == LLSpeaker::SPEAKER_OBJECT)) { return false; } @@ -648,6 +445,14 @@ bool LLParticipantList::SpeakerClearListener::handleEvent(LLPointer<LLOldEvents: } // +// LLParticipantList::SpeakerUpdateListener +// +bool LLParticipantList::SpeakerUpdateListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) +{ + return mParent.onSpeakerUpdateEvent(event, userdata); +} + +// // LLParticipantList::SpeakerModeratorListener // bool LLParticipantList::SpeakerModeratorUpdateListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) @@ -660,376 +465,4 @@ bool LLParticipantList::SpeakerMuteListener::handleEvent(LLPointer<LLOldEvents:: return mParent.onSpeakerMuteEvent(event, userdata); } -LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu() -{ - // set up the callbacks for all of the avatar menu items - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - - registrar.add("ParticipantList.Sort", boost::bind(&LLParticipantList::LLParticipantListMenu::sortParticipantList, this, _2)); - registrar.add("ParticipantList.ToggleAllowTextChat", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleAllowTextChat, this, _2)); - registrar.add("ParticipantList.ToggleMuteText", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleMuteText, this, _2)); - - registrar.add("Avatar.Profile", boost::bind(&LLAvatarActions::showProfile, mUUIDs.front())); - registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startIM, mUUIDs.front())); - registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mUUIDs.front())); - registrar.add("Avatar.BlockUnblock", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleMuteVoice, this, _2)); - registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::share, mUUIDs.front())); - registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, mUUIDs.front())); - registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startCall, mUUIDs.front())); - - registrar.add("ParticipantList.ModerateVoice", boost::bind(&LLParticipantList::LLParticipantListMenu::moderateVoice, this, _2)); - - enable_registrar.add("ParticipantList.EnableItem", boost::bind(&LLParticipantList::LLParticipantListMenu::enableContextMenuItem, this, _2)); - enable_registrar.add("ParticipantList.EnableItem.Moderate", boost::bind(&LLParticipantList::LLParticipantListMenu::enableModerateContextMenuItem, this, _2)); - enable_registrar.add("ParticipantList.CheckItem", boost::bind(&LLParticipantList::LLParticipantListMenu::checkContextMenuItem, this, _2)); - - // create the context menu from the XUI - LLContextMenu* main_menu = createFromFile("menu_participant_list.xml"); - - // Don't show sort options for P2P chat - bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1); - main_menu->setItemVisible("SortByName", is_sort_visible); - main_menu->setItemVisible("SortByRecentSpeakers", is_sort_visible); - main_menu->setItemVisible("Moderator Options Separator", isGroupModerator()); - main_menu->setItemVisible("Moderator Options", isGroupModerator()); - main_menu->setItemVisible("View Icons Separator", mParent.mAvatarListToggleIconsConnection.connected()); - main_menu->setItemVisible("View Icons", mParent.mAvatarListToggleIconsConnection.connected()); - main_menu->arrangeAndClear(); - - return main_menu; -} - -void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y) -{ - if (uuids.size() == 0) return; - - LLListContextMenu::show(spawning_view, uuids, x, y); - - const LLUUID& speaker_id = mUUIDs.front(); - BOOL is_muted = isMuted(speaker_id); - - if (is_muted) - { - LLMenuGL::sMenuContainer->getChildView("ModerateVoiceMuteSelected")->setVisible( false); - } - else - { - LLMenuGL::sMenuContainer->getChildView("ModerateVoiceUnMuteSelected")->setVisible( false); - } -} - -void LLParticipantList::LLParticipantListMenu::sortParticipantList(const LLSD& userdata) -{ - std::string param = userdata.asString(); - if ("sort_by_name" == param) - { - mParent.setSortOrder(E_SORT_BY_NAME); - } - else if ("sort_by_recent_speakers" == param) - { - mParent.setSortOrder(E_SORT_BY_RECENT_SPEAKERS); - } -} - -void LLParticipantList::LLParticipantListMenu::toggleAllowTextChat(const LLSD& userdata) -{ - - LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr); - if (mgr) - { - const LLUUID speaker_id = mUUIDs.front(); - mgr->toggleAllowTextChat(speaker_id); - } -} - -void LLParticipantList::LLParticipantListMenu::toggleMute(const LLSD& userdata, U32 flags) -{ - const LLUUID speaker_id = mUUIDs.front(); - BOOL is_muted = LLMuteList::getInstance()->isMuted(speaker_id, flags); - std::string name; - - //fill in name using voice client's copy of name cache - LLPointer<LLSpeaker> speakerp = mParent.mSpeakerMgr->findSpeaker(speaker_id); - if (speakerp.isNull()) - { - return; - } - LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(mParent.mAvatarList->getItemByValue(speaker_id)); - if (NULL == item) return; - - name = item->getAvatarName(); - - LLMute::EType mute_type; - switch (speakerp->mType) - { - case LLSpeaker::SPEAKER_AGENT: - mute_type = LLMute::AGENT; - break; - case LLSpeaker::SPEAKER_OBJECT: - mute_type = LLMute::OBJECT; - break; - case LLSpeaker::SPEAKER_EXTERNAL: - default: - mute_type = LLMute::EXTERNAL; - break; - } - LLMute mute(speaker_id, name, mute_type); - - if (!is_muted) - { - LLMuteList::getInstance()->add(mute, flags); - } - else - { - LLMuteList::getInstance()->remove(mute, flags); - } -} - -void LLParticipantList::LLParticipantListMenu::toggleMuteText(const LLSD& userdata) -{ - toggleMute(userdata, LLMute::flagTextChat); -} - -void LLParticipantList::LLParticipantListMenu::toggleMuteVoice(const LLSD& userdata) -{ - toggleMute(userdata, LLMute::flagVoiceChat); -} - -bool LLParticipantList::LLParticipantListMenu::isGroupModerator() -{ - if (!mParent.mSpeakerMgr) - { - llwarns << "Speaker manager is missing" << llendl; - return false; - } - - // Is session a group call/chat? - if(gAgent.isInGroup(mParent.mSpeakerMgr->getSessionID())) - { - LLSpeaker* speaker = mParent.mSpeakerMgr->findSpeaker(gAgentID).get(); - - // Is agent a moderator? - return speaker && speaker->mIsModerator; - } - return false; -} - -bool LLParticipantList::LLParticipantListMenu::isMuted(const LLUUID& avatar_id) -{ - LLPointer<LLSpeaker> selected_speakerp = mParent.mSpeakerMgr->findSpeaker(avatar_id); - if (!selected_speakerp) return true; - - return selected_speakerp->mStatus == LLSpeaker::STATUS_MUTED; -} - -void LLParticipantList::LLParticipantListMenu::moderateVoice(const LLSD& userdata) -{ - if (!gAgent.getRegion()) return; - - bool moderate_selected = userdata.asString() == "selected"; - - if (moderate_selected) - { - const LLUUID& selected_avatar_id = mUUIDs.front(); - bool is_muted = isMuted(selected_avatar_id); - moderateVoiceParticipant(selected_avatar_id, is_muted); - } - else - { - bool unmute_all = userdata.asString() == "unmute_all"; - moderateVoiceAllParticipants(unmute_all); - } -} - -void LLParticipantList::LLParticipantListMenu::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute) -{ - LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr); - if (mgr) - { - mgr->moderateVoiceParticipant(avatar_id, unmute); - } -} - -void LLParticipantList::LLParticipantListMenu::moderateVoiceAllParticipants(bool unmute) -{ - LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr); - if (mgr) - { - if (!unmute) - { - LLSD payload; - payload["session_id"] = mgr->getSessionID(); - LLNotificationsUtil::add("ConfirmMuteAll", LLSD(), payload, confirmMuteAllCallback); - return; - } - - mgr->moderateVoiceAllParticipants(unmute); - } -} - -// static -void LLParticipantList::LLParticipantListMenu::confirmMuteAllCallback(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - // if Cancel pressed - if (option == 1) - { - return; - } - - const LLSD& payload = notification["payload"]; - const LLUUID& session_id = payload["session_id"]; - - LLIMSpeakerMgr * speaker_manager = dynamic_cast<LLIMSpeakerMgr*> ( - LLIMModel::getInstance()->getSpeakerManager(session_id)); - if (speaker_manager) - { - speaker_manager->moderateVoiceAllParticipants(false); - } - - return; -} - - -bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& userdata) -{ - std::string item = userdata.asString(); - const LLUUID& participant_id = mUUIDs.front(); - - // For now non of "can_view_profile" action and menu actions listed below except "can_block" - // can be performed for Avaline callers. - bool is_participant_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(participant_id); - if (!is_participant_avatar && "can_block" != item) return false; - - if (item == "can_mute_text" || "can_block" == item || "can_share" == item || "can_im" == item - || "can_pay" == item) - { - return mUUIDs.front() != gAgentID; - } - else if (item == std::string("can_add")) - { - // We can add friends if: - // - there are selected people - // - and there are no friends among selection yet. - - bool result = (mUUIDs.size() > 0); - - uuid_vec_t::const_iterator - id = mUUIDs.begin(), - uuids_end = mUUIDs.end(); - - for (;id != uuids_end; ++id) - { - if ( *id == gAgentID || LLAvatarActions::isFriend(*id) ) - { - result = false; - break; - } - } - return result; - } - else if (item == "can_call") - { - bool not_agent = mUUIDs.front() != gAgentID; - bool can_call = not_agent && LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking(); - return can_call; - } - - return true; -} - -/* - Processed menu items with such parameters: - can_allow_text_chat - can_moderate_voice -*/ -bool LLParticipantList::LLParticipantListMenu::enableModerateContextMenuItem(const LLSD& userdata) -{ - // only group moderators can perform actions related to this "enable callback" - if (!isGroupModerator()) return false; - - const LLUUID& participant_id = mUUIDs.front(); - LLPointer<LLSpeaker> speakerp = mParent.mSpeakerMgr->findSpeaker(participant_id); - - // not in voice participants can not be moderated - bool speaker_in_voice = speakerp.notNull() && speakerp->isInVoiceChannel(); - - const std::string& item = userdata.asString(); - - if ("can_moderate_voice" == item) - { - return speaker_in_voice; - } - - // For now non of menu actions except "can_moderate_voice" can be performed for Avaline callers. - bool is_participant_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(participant_id); - if (!is_participant_avatar) return false; - - return true; -} - -bool LLParticipantList::LLParticipantListMenu::checkContextMenuItem(const LLSD& userdata) -{ - std::string item = userdata.asString(); - const LLUUID& id = mUUIDs.front(); - - if (item == "is_muted") - { - return LLMuteList::getInstance()->isMuted(id, LLMute::flagTextChat); - } - else if (item == "is_allowed_text_chat") - { - LLPointer<LLSpeaker> selected_speakerp = mParent.mSpeakerMgr->findSpeaker(id); - - if (selected_speakerp.notNull()) - { - return !selected_speakerp->mModeratorMutedText; - } - } - else if(item == "is_blocked") - { - return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat); - } - else if(item == "is_sorted_by_name") - { - return E_SORT_BY_NAME == mParent.getSortOrder(); - } - else if(item == "is_sorted_by_recent_speakers") - { - return E_SORT_BY_RECENT_SPEAKERS == mParent.getSortOrder(); - } - - return false; -} - -bool LLParticipantList::LLAvatarItemRecentSpeakerComparator::doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const -{ - if (mParent.mSpeakerMgr) - { - LLPointer<LLSpeaker> lhs = mParent.mSpeakerMgr->findSpeaker(avatar_item1->getAvatarId()); - LLPointer<LLSpeaker> rhs = mParent.mSpeakerMgr->findSpeaker(avatar_item2->getAvatarId()); - if ( lhs.notNull() && rhs.notNull() ) - { - // Compare by last speaking time - if( lhs->mLastSpokeTime != rhs->mLastSpokeTime ) - return ( lhs->mLastSpokeTime > rhs->mLastSpokeTime ); - else if ( lhs->mSortIndex != rhs->mSortIndex ) - return ( lhs->mSortIndex < rhs->mSortIndex ); - } - else if ( lhs.notNull() ) - { - // True if only avatar_item1 speaker info available - return true; - } - else if ( rhs.notNull() ) - { - // False if only avatar_item2 speaker info available - return false; - } - } - // By default compare by name. - return LLAvatarItemNameComparator::doCompare(avatar_item1, avatar_item2); -} - //EOF diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index e0b3d42c25..3a3ae76604 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -1,6 +1,6 @@ /** * @file llparticipantlist.h - * @brief LLParticipantList intended to update view(LLAvatarList) according to incoming messages + * @brief LLParticipantList : model of a conversation session with added speaker events handling * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code @@ -28,35 +28,21 @@ #define LL_PARTICIPANTLIST_H #include "llviewerprecompiledheaders.h" -#include "llevent.h" -#include "llavatarlist.h" // for LLAvatarItemRecentSpeakerComparator -#include "lllistcontextmenu.h" +#include "llconversationmodel.h" class LLSpeakerMgr; -class LLAvatarList; class LLUICtrl; class LLAvalineUpdater; -class LLParticipantList +class LLParticipantList : public LLConversationItemSession { LOG_CLASS(LLParticipantList); public: typedef boost::function<bool (const LLUUID& speaker_id)> validate_speaker_callback_t; - LLParticipantList(LLSpeakerMgr* data_source, - LLAvatarList* avatar_list, - bool use_context_menu = true, - bool exclude_agent = true, - bool can_toggle_icons = true); + LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model); ~LLParticipantList(); - void setSpeakingIndicatorsVisible(BOOL visible); - - enum EParticipantSortOrder - { - E_SORT_BY_NAME = 0, - E_SORT_BY_RECENT_SPEAKERS = 1, - }; /** * Adds specified avatar ID to the existing list if it is not Agent's ID @@ -66,15 +52,9 @@ public: void addAvatarIDExceptAgent(const LLUUID& avatar_id); /** - * Set and sort Avatarlist by given order - */ - void setSortOrder(EParticipantSortOrder order = E_SORT_BY_NAME); - const EParticipantSortOrder getSortOrder() const; - - /** - * Refreshes the participant list if it's in sort by recent speaker order. + * Refreshes the participant list. */ - void updateRecentSpeakersOrder(); + void update(); /** * Set a callback to be called before adding a speaker. Invalid speakers will not be added. @@ -93,14 +73,10 @@ protected: bool onRemoveItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); bool onClearListEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); bool onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); + bool onSpeakerUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); bool onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); /** - * Sorts the Avatarlist by stored order - */ - void sort(); - - /** * List of listeners implementing LLOldEvents::LLSimpleListener. * There is no way to handle all the events in one listener as LLSpeakerMgr registers * listeners in such a way that one listener can handle only one type of event @@ -134,6 +110,13 @@ protected: /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); }; + class SpeakerUpdateListener : public BaseSpeakerListener + { + public: + SpeakerUpdateListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {} + /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); + }; + class SpeakerModeratorUpdateListener : public BaseSpeakerListener { public: @@ -149,98 +132,7 @@ protected: /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); }; - /** - * Menu used in the participant list. - */ - class LLParticipantListMenu : public LLListContextMenu - { - public: - LLParticipantListMenu(LLParticipantList& parent):mParent(parent){}; - /*virtual*/ LLContextMenu* createMenu(); - /*virtual*/ void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y); - protected: - LLParticipantList& mParent; - private: - bool enableContextMenuItem(const LLSD& userdata); - bool enableModerateContextMenuItem(const LLSD& userdata); - bool checkContextMenuItem(const LLSD& userdata); - - void sortParticipantList(const LLSD& userdata); - void toggleAllowTextChat(const LLSD& userdata); - void toggleMute(const LLSD& userdata, U32 flags); - void toggleMuteText(const LLSD& userdata); - void toggleMuteVoice(const LLSD& userdata); - - /** - * Return true if Agent is group moderator(and moderator of group call). - */ - bool isGroupModerator(); - - // Voice moderation support - /** - * Check whether specified by argument avatar is muted for group chat or not. - */ - bool isMuted(const LLUUID& avatar_id); - - /** - * Processes Voice moderation menu items. - * - * It calls either moderateVoiceParticipant() or moderateVoiceParticipant() depend on - * passed parameter. - * - * @param userdata can be "selected" or "others". - * - * @see moderateVoiceParticipant() - * @see moderateVoiceAllParticipants() - */ - void moderateVoice(const LLSD& userdata); - - /** - * Mutes/Unmutes avatar for current group voice chat. - * - * It only marks avatar as muted for session and does not use local Agent's Block list. - * It does not mute Agent itself. - * - * @param[in] avatar_id UUID of avatar to be processed - * @param[in] unmute if true - specified avatar will be muted, otherwise - unmuted. - * - * @see moderateVoiceAllParticipants() - */ - void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute); - - /** - * Mutes/Unmutes all avatars for current group voice chat. - * - * It only marks avatars as muted for session and does not use local Agent's Block list. - * - * @param[in] unmute if true - avatars will be muted, otherwise - unmuted. - * - * @see moderateVoiceParticipant() - */ - void moderateVoiceAllParticipants(bool unmute); - - static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response); - }; - - /** - * Comparator for comparing avatar items by last spoken time - */ - class LLAvatarItemRecentSpeakerComparator : public LLAvatarItemNameComparator, public LLRefCount - { - LOG_CLASS(LLAvatarItemRecentSpeakerComparator); - public: - LLAvatarItemRecentSpeakerComparator(LLParticipantList& parent):mParent(parent){}; - virtual ~LLAvatarItemRecentSpeakerComparator() {}; - protected: - virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const; - private: - LLParticipantList& mParent; - }; - private: - void onAvatarListDoubleClicked(LLUICtrl* ctrl); - void onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param); - void onAvalineCallerFound(const LLUUID& participant_id); void onAvalineCallerRemoved(const LLUUID& participant_id); @@ -252,7 +144,6 @@ private: void adjustParticipant(const LLUUID& speaker_id); LLSpeakerMgr* mSpeakerMgr; - LLAvatarList* mAvatarList; std::set<LLUUID> mModeratorList; std::set<LLUUID> mModeratorToRemoveList; @@ -260,25 +151,10 @@ private: LLPointer<SpeakerAddListener> mSpeakerAddListener; LLPointer<SpeakerRemoveListener> mSpeakerRemoveListener; LLPointer<SpeakerClearListener> mSpeakerClearListener; + LLPointer<SpeakerUpdateListener> mSpeakerUpdateListener; LLPointer<SpeakerModeratorUpdateListener> mSpeakerModeratorListener; LLPointer<SpeakerMuteListener> mSpeakerMuteListener; - LLParticipantListMenu* mParticipantListMenu; - - /** - * This field manages an adding a new avatar_id in the mAvatarList - * If true, then agent_id wont be added into mAvatarList - * Also by default this field is controlling a sort procedure, @c sort() - */ - bool mExcludeAgent; - - // boost::connections - boost::signals2::connection mAvatarListDoubleClickConnection; - boost::signals2::connection mAvatarListRefreshConnection; - boost::signals2::connection mAvatarListReturnConnection; - boost::signals2::connection mAvatarListToggleIconsConnection; - - LLPointer<LLAvatarItemRecentSpeakerComparator> mSortByRecentSpeakers; validate_speaker_callback_t mValidateSpeakerCallback; LLAvalineUpdater* mAvalineUpdater; }; diff --git a/indra/newview/llpathfindingcharacter.cpp b/indra/newview/llpathfindingcharacter.cpp new file mode 100644 index 0000000000..00f2ebc4bb --- /dev/null +++ b/indra/newview/llpathfindingcharacter.cpp @@ -0,0 +1,99 @@ +/** +* @file llpathfindingcharacter.cpp +* @brief Definition of a pathfinding character that contains various properties required for havok pathfinding. +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llpathfindingcharacter.h" + +#include <string> + +#include "llpathfindingobject.h" +#include "llsd.h" + +#define CHARACTER_CPU_TIME_FIELD "cpu_time" +#define CHARACTER_HORIZONTAL_FIELD "horizontal" +#define CHARACTER_LENGTH_FIELD "length" +#define CHARACTER_RADIUS_FIELD "radius" + +//--------------------------------------------------------------------------- +// LLPathfindingCharacter +//--------------------------------------------------------------------------- + +LLPathfindingCharacter::LLPathfindingCharacter(const std::string &pUUID, const LLSD& pCharacterData) + : LLPathfindingObject(pUUID, pCharacterData), + mCPUTime(0U), + mIsHorizontal(FALSE), + mLength(0.0f), + mRadius(0.0f) +{ + parseCharacterData(pCharacterData); +} + +LLPathfindingCharacter::LLPathfindingCharacter(const LLPathfindingCharacter& pOther) + : LLPathfindingObject(pOther), + mCPUTime(pOther.mCPUTime), + mIsHorizontal(pOther.mIsHorizontal), + mLength(pOther.mLength), + mRadius(pOther.mRadius) +{ +} + +LLPathfindingCharacter::~LLPathfindingCharacter() +{ +} + +LLPathfindingCharacter& LLPathfindingCharacter::operator =(const LLPathfindingCharacter& pOther) +{ + dynamic_cast<LLPathfindingObject &>(*this) = pOther; + + mCPUTime = pOther.mCPUTime; + mIsHorizontal = pOther.mIsHorizontal; + mLength = pOther.mLength; + mRadius = pOther.mRadius; + + return *this; +} + +void LLPathfindingCharacter::parseCharacterData(const LLSD &pCharacterData) +{ + llassert(pCharacterData.has(CHARACTER_CPU_TIME_FIELD)); + llassert(pCharacterData.get(CHARACTER_CPU_TIME_FIELD).isReal()); + mCPUTime = pCharacterData.get(CHARACTER_CPU_TIME_FIELD).asReal(); + + llassert(pCharacterData.has(CHARACTER_HORIZONTAL_FIELD)); + llassert(pCharacterData.get(CHARACTER_HORIZONTAL_FIELD).isBoolean()); + mIsHorizontal = pCharacterData.get(CHARACTER_HORIZONTAL_FIELD).asBoolean(); + + llassert(pCharacterData.has(CHARACTER_LENGTH_FIELD)); + llassert(pCharacterData.get(CHARACTER_LENGTH_FIELD).isReal()); + mLength = pCharacterData.get(CHARACTER_LENGTH_FIELD).asReal(); + + llassert(pCharacterData.has(CHARACTER_RADIUS_FIELD)); + llassert(pCharacterData.get(CHARACTER_RADIUS_FIELD).isReal()); + mRadius = pCharacterData.get(CHARACTER_RADIUS_FIELD).asReal(); +} diff --git a/indra/newview/llpathfindingcharacter.h b/indra/newview/llpathfindingcharacter.h new file mode 100644 index 0000000000..7cf9f401b0 --- /dev/null +++ b/indra/newview/llpathfindingcharacter.h @@ -0,0 +1,63 @@ +/** +* @file llpathfindingcharacter.h +* @brief Definition of a pathfinding character that contains various properties required for havok pathfinding. +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLPATHFINDINGCHARACTER_H +#define LL_LLPATHFINDINGCHARACTER_H + +#include <string> + +#include "llpathfindingobject.h" + +class LLSD; + +class LLPathfindingCharacter : public LLPathfindingObject +{ +public: + LLPathfindingCharacter(const std::string &pUUID, const LLSD &pCharacterData); + LLPathfindingCharacter(const LLPathfindingCharacter& pOther); + virtual ~LLPathfindingCharacter(); + + LLPathfindingCharacter& operator =(const LLPathfindingCharacter& pOther); + + inline F32 getCPUTime() const {return mCPUTime;}; + + inline BOOL isHorizontal() const {return mIsHorizontal;}; + inline F32 getLength() const {return mLength;}; + inline F32 getRadius() const {return mRadius;}; + +protected: + +private: + void parseCharacterData(const LLSD &pCharacterData); + + F32 mCPUTime; + + BOOL mIsHorizontal; + F32 mLength; + F32 mRadius; +}; + +#endif // LL_LLPATHFINDINGCHARACTER_H diff --git a/indra/newview/llpathfindingcharacterlist.cpp b/indra/newview/llpathfindingcharacterlist.cpp new file mode 100644 index 0000000000..12340cebfa --- /dev/null +++ b/indra/newview/llpathfindingcharacterlist.cpp @@ -0,0 +1,69 @@ +/** +* @file llpathfindingcharacterlist.cpp +* @brief Implementation of llpathfindingcharacterlist +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llpathfindingcharacterlist.h" + +#include "llpathfindingcharacter.h" +#include "llpathfindingobject.h" +#include "llpathfindingobjectlist.h" +#include "llsd.h" + +//--------------------------------------------------------------------------- +// LLPathfindingCharacterList +//--------------------------------------------------------------------------- + +LLPathfindingCharacterList::LLPathfindingCharacterList() + : LLPathfindingObjectList() +{ +} + +LLPathfindingCharacterList::LLPathfindingCharacterList(const LLSD& pCharacterListData) + : LLPathfindingObjectList() +{ + parseCharacterListData(pCharacterListData); +} + +LLPathfindingCharacterList::~LLPathfindingCharacterList() +{ +} + +void LLPathfindingCharacterList::parseCharacterListData(const LLSD& pCharacterListData) +{ + LLPathfindingObjectMap &objectMap = getObjectMap(); + + for (LLSD::map_const_iterator characterDataIter = pCharacterListData.beginMap(); + characterDataIter != pCharacterListData.endMap(); ++characterDataIter) + { + const std::string& uuid(characterDataIter->first); + const LLSD& characterData = characterDataIter->second; + LLPathfindingObjectPtr character(new LLPathfindingCharacter(uuid, characterData)); + objectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(uuid, character)); + } +} diff --git a/indra/newview/llpathfindingcharacterlist.h b/indra/newview/llpathfindingcharacterlist.h new file mode 100644 index 0000000000..4ecf70001d --- /dev/null +++ b/indra/newview/llpathfindingcharacterlist.h @@ -0,0 +1,47 @@ +/** +* @file llpathfindingcharacterlist.h +* @brief Header file for llpathfindingcharacterlist +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLPATHFINDINGCHARACTERLIST_H +#define LL_LLPATHFINDINGCHARACTERLIST_H + +#include "llpathfindingobjectlist.h" + +class LLSD; + +class LLPathfindingCharacterList : public LLPathfindingObjectList +{ +public: + LLPathfindingCharacterList(); + LLPathfindingCharacterList(const LLSD& pCharacterListData); + virtual ~LLPathfindingCharacterList(); + +protected: + +private: + void parseCharacterListData(const LLSD& pCharacterListData); +}; + +#endif // LL_LLPATHFINDINGCHARACTERLIST_H diff --git a/indra/newview/llpathfindinglinkset.cpp b/indra/newview/llpathfindinglinkset.cpp new file mode 100644 index 0000000000..50b76378f5 --- /dev/null +++ b/indra/newview/llpathfindinglinkset.cpp @@ -0,0 +1,408 @@ +/** +* @file llpathfindinglinkset.cpp +* @brief Definition of a pathfinding linkset that contains various properties required for havok pathfinding. +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llpathfindinglinkset.h" + +#include <string> + +#include "llpathfindingobject.h" +#include "llsd.h" + +#define LINKSET_LAND_IMPACT_FIELD "landimpact" +#define LINKSET_MODIFIABLE_FIELD "modifiable" +#define LINKSET_CATEGORY_FIELD "navmesh_category" +#define LINKSET_CAN_BE_VOLUME "can_be_volume" +#define LINKSET_IS_SCRIPTED_FIELD "is_scripted" +#define LINKSET_PHANTOM_FIELD "phantom" +#define LINKSET_WALKABILITY_A_FIELD "A" +#define LINKSET_WALKABILITY_B_FIELD "B" +#define LINKSET_WALKABILITY_C_FIELD "C" +#define LINKSET_WALKABILITY_D_FIELD "D" + +#define LINKSET_CATEGORY_VALUE_INCLUDE 0 +#define LINKSET_CATEGORY_VALUE_EXCLUDE 1 +#define LINKSET_CATEGORY_VALUE_IGNORE 2 + +//--------------------------------------------------------------------------- +// LLPathfindingLinkset +//--------------------------------------------------------------------------- + +const S32 LLPathfindingLinkset::MIN_WALKABILITY_VALUE(0); +const S32 LLPathfindingLinkset::MAX_WALKABILITY_VALUE(100); + +LLPathfindingLinkset::LLPathfindingLinkset(const LLSD& pTerrainData) + : LLPathfindingObject(), + mIsTerrain(true), + mLandImpact(0U), + mIsModifiable(FALSE), + mCanBeVolume(FALSE), + mIsScripted(FALSE), + mHasIsScripted(TRUE), + mLinksetUse(kUnknown), + mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE), + mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE), + mWalkabilityCoefficientC(MIN_WALKABILITY_VALUE), + mWalkabilityCoefficientD(MIN_WALKABILITY_VALUE) +{ + parsePathfindingData(pTerrainData); +} + +LLPathfindingLinkset::LLPathfindingLinkset(const std::string &pUUID, const LLSD& pLinksetData) + : LLPathfindingObject(pUUID, pLinksetData), + mIsTerrain(false), + mLandImpact(0U), + mIsModifiable(TRUE), + mCanBeVolume(TRUE), + mIsScripted(FALSE), + mHasIsScripted(FALSE), + mLinksetUse(kUnknown), + mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE), + mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE), + mWalkabilityCoefficientC(MIN_WALKABILITY_VALUE), + mWalkabilityCoefficientD(MIN_WALKABILITY_VALUE) +{ + parseLinksetData(pLinksetData); + parsePathfindingData(pLinksetData); +} + +LLPathfindingLinkset::LLPathfindingLinkset(const LLPathfindingLinkset& pOther) + : LLPathfindingObject(pOther), + mIsTerrain(pOther.mIsTerrain), + mLandImpact(pOther.mLandImpact), + mIsModifiable(pOther.mIsModifiable), + mCanBeVolume(pOther.mCanBeVolume), + mIsScripted(pOther.mIsScripted), + mHasIsScripted(pOther.mHasIsScripted), + mLinksetUse(pOther.mLinksetUse), + mWalkabilityCoefficientA(pOther.mWalkabilityCoefficientA), + mWalkabilityCoefficientB(pOther.mWalkabilityCoefficientB), + mWalkabilityCoefficientC(pOther.mWalkabilityCoefficientC), + mWalkabilityCoefficientD(pOther.mWalkabilityCoefficientD) +{ +} + +LLPathfindingLinkset::~LLPathfindingLinkset() +{ +} + +LLPathfindingLinkset& LLPathfindingLinkset::operator =(const LLPathfindingLinkset& pOther) +{ + dynamic_cast<LLPathfindingObject &>(*this) = pOther; + + mIsTerrain = pOther.mIsTerrain; + mLandImpact = pOther.mLandImpact; + mIsModifiable = pOther.mIsModifiable; + mCanBeVolume = pOther.mCanBeVolume; + mIsScripted = pOther.mIsScripted; + mHasIsScripted = pOther.mHasIsScripted; + mLinksetUse = pOther.mLinksetUse; + mWalkabilityCoefficientA = pOther.mWalkabilityCoefficientA; + mWalkabilityCoefficientB = pOther.mWalkabilityCoefficientB; + mWalkabilityCoefficientC = pOther.mWalkabilityCoefficientC; + mWalkabilityCoefficientD = pOther.mWalkabilityCoefficientD; + + return *this; +} + +BOOL LLPathfindingLinkset::isPhantom() const +{ + return isPhantom(getLinksetUse()); +} + +LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUseWithToggledPhantom(ELinksetUse pLinksetUse) +{ + BOOL isPhantom = LLPathfindingLinkset::isPhantom(pLinksetUse); + ENavMeshGenerationCategory navMeshGenerationCategory = getNavMeshGenerationCategory(pLinksetUse); + + return getLinksetUse(!isPhantom, navMeshGenerationCategory); +} + +bool LLPathfindingLinkset::isShowUnmodifiablePhantomWarning(ELinksetUse pLinksetUse) const +{ + return (!isModifiable() && (isPhantom() != isPhantom(pLinksetUse))); +} + +bool LLPathfindingLinkset::isShowPhantomToggleWarning(ELinksetUse pLinksetUse) const +{ + return (isModifiable() && (isPhantom() != isPhantom(pLinksetUse))); +} + +bool LLPathfindingLinkset::isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const +{ + return (!canBeVolume() && ((pLinksetUse == kMaterialVolume) || (pLinksetUse == kExclusionVolume))); +} + +LLSD LLPathfindingLinkset::encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const +{ + LLSD itemData; + + if (!isTerrain() && (pLinksetUse != kUnknown) && (getLinksetUse() != pLinksetUse) && + (canBeVolume() || ((pLinksetUse != kMaterialVolume) && (pLinksetUse != kExclusionVolume)))) + { + if (isModifiable()) + { + itemData[LINKSET_PHANTOM_FIELD] = static_cast<bool>(isPhantom(pLinksetUse)); + } + + itemData[LINKSET_CATEGORY_FIELD] = convertCategoryToLLSD(getNavMeshGenerationCategory(pLinksetUse)); + } + + if (mWalkabilityCoefficientA != pA) + { + itemData[LINKSET_WALKABILITY_A_FIELD] = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE); + } + + if (mWalkabilityCoefficientB != pB) + { + itemData[LINKSET_WALKABILITY_B_FIELD] = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE); + } + + if (mWalkabilityCoefficientC != pC) + { + itemData[LINKSET_WALKABILITY_C_FIELD] = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE); + } + + if (mWalkabilityCoefficientD != pD) + { + itemData[LINKSET_WALKABILITY_D_FIELD] = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE); + } + + return itemData; +} + +void LLPathfindingLinkset::parseLinksetData(const LLSD &pLinksetData) +{ + llassert(pLinksetData.has(LINKSET_LAND_IMPACT_FIELD)); + llassert(pLinksetData.get(LINKSET_LAND_IMPACT_FIELD).isInteger()); + llassert(pLinksetData.get(LINKSET_LAND_IMPACT_FIELD).asInteger() >= 0); + mLandImpact = pLinksetData.get(LINKSET_LAND_IMPACT_FIELD).asInteger(); + + llassert(pLinksetData.has(LINKSET_MODIFIABLE_FIELD)); + llassert(pLinksetData.get(LINKSET_MODIFIABLE_FIELD).isBoolean()); + mIsModifiable = pLinksetData.get(LINKSET_MODIFIABLE_FIELD).asBoolean(); + + mHasIsScripted = pLinksetData.has(LINKSET_IS_SCRIPTED_FIELD); + if (mHasIsScripted) + { + llassert(pLinksetData.get(LINKSET_IS_SCRIPTED_FIELD).isBoolean()); + mIsScripted = pLinksetData.get(LINKSET_IS_SCRIPTED_FIELD).asBoolean(); + } +} + +void LLPathfindingLinkset::parsePathfindingData(const LLSD &pLinksetData) +{ + bool isPhantom = false; + if (pLinksetData.has(LINKSET_PHANTOM_FIELD)) + { + llassert(pLinksetData.get(LINKSET_PHANTOM_FIELD).isBoolean()); + isPhantom = pLinksetData.get(LINKSET_PHANTOM_FIELD).asBoolean(); + } + + llassert(pLinksetData.has(LINKSET_CATEGORY_FIELD)); + mLinksetUse = getLinksetUse(isPhantom, convertCategoryFromLLSD(pLinksetData.get(LINKSET_CATEGORY_FIELD))); + + if (pLinksetData.has(LINKSET_CAN_BE_VOLUME)) + { + llassert(pLinksetData.get(LINKSET_CAN_BE_VOLUME).isBoolean()); + mCanBeVolume = pLinksetData.get(LINKSET_CAN_BE_VOLUME).asBoolean(); + } + + llassert(pLinksetData.has(LINKSET_WALKABILITY_A_FIELD)); + llassert(pLinksetData.get(LINKSET_WALKABILITY_A_FIELD).isInteger()); + mWalkabilityCoefficientA = pLinksetData.get(LINKSET_WALKABILITY_A_FIELD).asInteger(); + llassert(mWalkabilityCoefficientA >= MIN_WALKABILITY_VALUE); + llassert(mWalkabilityCoefficientA <= MAX_WALKABILITY_VALUE); + + llassert(pLinksetData.has(LINKSET_WALKABILITY_B_FIELD)); + llassert(pLinksetData.get(LINKSET_WALKABILITY_B_FIELD).isInteger()); + mWalkabilityCoefficientB = pLinksetData.get(LINKSET_WALKABILITY_B_FIELD).asInteger(); + llassert(mWalkabilityCoefficientB >= MIN_WALKABILITY_VALUE); + llassert(mWalkabilityCoefficientB <= MAX_WALKABILITY_VALUE); + + llassert(pLinksetData.has(LINKSET_WALKABILITY_C_FIELD)); + llassert(pLinksetData.get(LINKSET_WALKABILITY_C_FIELD).isInteger()); + mWalkabilityCoefficientC = pLinksetData.get(LINKSET_WALKABILITY_C_FIELD).asInteger(); + llassert(mWalkabilityCoefficientC >= MIN_WALKABILITY_VALUE); + llassert(mWalkabilityCoefficientC <= MAX_WALKABILITY_VALUE); + + llassert(pLinksetData.has(LINKSET_WALKABILITY_D_FIELD)); + llassert(pLinksetData.get(LINKSET_WALKABILITY_D_FIELD).isInteger()); + mWalkabilityCoefficientD = pLinksetData.get(LINKSET_WALKABILITY_D_FIELD).asInteger(); + llassert(mWalkabilityCoefficientD >= MIN_WALKABILITY_VALUE); + llassert(mWalkabilityCoefficientD <= MAX_WALKABILITY_VALUE); +} + +BOOL LLPathfindingLinkset::isPhantom(ELinksetUse pLinksetUse) +{ + BOOL retVal; + + switch (pLinksetUse) + { + case kWalkable : + case kStaticObstacle : + case kDynamicObstacle : + retVal = false; + break; + case kMaterialVolume : + case kExclusionVolume : + case kDynamicPhantom : + retVal = true; + break; + case kUnknown : + default : + retVal = false; + llassert(0); + break; + } + + return retVal; +} + +LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUse(bool pIsPhantom, ENavMeshGenerationCategory pNavMeshGenerationCategory) +{ + ELinksetUse linksetUse = kUnknown; + + if (pIsPhantom) + { + switch (pNavMeshGenerationCategory) + { + case kNavMeshGenerationIgnore : + linksetUse = kDynamicPhantom; + break; + case kNavMeshGenerationInclude : + linksetUse = kMaterialVolume; + break; + case kNavMeshGenerationExclude : + linksetUse = kExclusionVolume; + break; + default : + linksetUse = kUnknown; + llassert(0); + break; + } + } + else + { + switch (pNavMeshGenerationCategory) + { + case kNavMeshGenerationIgnore : + linksetUse = kDynamicObstacle; + break; + case kNavMeshGenerationInclude : + linksetUse = kWalkable; + break; + case kNavMeshGenerationExclude : + linksetUse = kStaticObstacle; + break; + default : + linksetUse = kUnknown; + llassert(0); + break; + } + } + + return linksetUse; +} + +LLPathfindingLinkset::ENavMeshGenerationCategory LLPathfindingLinkset::getNavMeshGenerationCategory(ELinksetUse pLinksetUse) +{ + ENavMeshGenerationCategory navMeshGenerationCategory; + switch (pLinksetUse) + { + case kWalkable : + case kMaterialVolume : + navMeshGenerationCategory = kNavMeshGenerationInclude; + break; + case kStaticObstacle : + case kExclusionVolume : + navMeshGenerationCategory = kNavMeshGenerationExclude; + break; + case kDynamicObstacle : + case kDynamicPhantom : + navMeshGenerationCategory = kNavMeshGenerationIgnore; + break; + case kUnknown : + default : + navMeshGenerationCategory = kNavMeshGenerationIgnore; + llassert(0); + break; + } + + return navMeshGenerationCategory; +} + +LLSD LLPathfindingLinkset::convertCategoryToLLSD(ENavMeshGenerationCategory pNavMeshGenerationCategory) +{ + LLSD llsd; + + switch (pNavMeshGenerationCategory) + { + case kNavMeshGenerationIgnore : + llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_IGNORE); + break; + case kNavMeshGenerationInclude : + llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_INCLUDE); + break; + case kNavMeshGenerationExclude : + llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_EXCLUDE); + break; + default : + llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_IGNORE); + llassert(0); + break; + } + + return llsd; +} + +LLPathfindingLinkset::ENavMeshGenerationCategory LLPathfindingLinkset::convertCategoryFromLLSD(const LLSD &llsd) +{ + ENavMeshGenerationCategory navMeshGenerationCategory; + + llassert(llsd.isInteger()); + switch (llsd.asInteger()) + { + case LINKSET_CATEGORY_VALUE_IGNORE : + navMeshGenerationCategory = kNavMeshGenerationIgnore; + break; + case LINKSET_CATEGORY_VALUE_INCLUDE : + navMeshGenerationCategory = kNavMeshGenerationInclude; + break; + case LINKSET_CATEGORY_VALUE_EXCLUDE : + navMeshGenerationCategory = kNavMeshGenerationExclude; + break; + default : + navMeshGenerationCategory = kNavMeshGenerationIgnore; + llassert(0); + break; + } + + return navMeshGenerationCategory; +} diff --git a/indra/newview/llpathfindinglinkset.h b/indra/newview/llpathfindinglinkset.h new file mode 100644 index 0000000000..308a3a1e0f --- /dev/null +++ b/indra/newview/llpathfindinglinkset.h @@ -0,0 +1,114 @@ +/** +* @file llpathfindinglinkset.h +* @brief Definition of a pathfinding linkset that contains various properties required for havok pathfinding. +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLPATHFINDINGLINKSET_H +#define LL_LLPATHFINDINGLINKSET_H + +#include <string> + +#include "llpathfindingobject.h" + +class LLSD; + +class LLPathfindingLinkset : public LLPathfindingObject +{ +public: + typedef enum + { + kUnknown, + kWalkable, + kStaticObstacle, + kDynamicObstacle, + kMaterialVolume, + kExclusionVolume, + kDynamicPhantom + } ELinksetUse; + + LLPathfindingLinkset(const LLSD &pTerrainData); + LLPathfindingLinkset(const std::string &pUUID, const LLSD &pLinksetData); + LLPathfindingLinkset(const LLPathfindingLinkset& pOther); + virtual ~LLPathfindingLinkset(); + + LLPathfindingLinkset& operator = (const LLPathfindingLinkset& pOther); + + inline bool isTerrain() const {return mIsTerrain;}; + inline U32 getLandImpact() const {return mLandImpact;}; + BOOL isModifiable() const {return mIsModifiable;}; + BOOL isPhantom() const; + BOOL canBeVolume() const {return mCanBeVolume;}; + static ELinksetUse getLinksetUseWithToggledPhantom(ELinksetUse pLinksetUse); + + inline ELinksetUse getLinksetUse() const {return mLinksetUse;}; + + inline BOOL isScripted() const {return mIsScripted;}; + inline BOOL hasIsScripted() const {return mHasIsScripted;}; + + inline S32 getWalkabilityCoefficientA() const {return mWalkabilityCoefficientA;}; + inline S32 getWalkabilityCoefficientB() const {return mWalkabilityCoefficientB;}; + inline S32 getWalkabilityCoefficientC() const {return mWalkabilityCoefficientC;}; + inline S32 getWalkabilityCoefficientD() const {return mWalkabilityCoefficientD;}; + + bool isShowUnmodifiablePhantomWarning(ELinksetUse pLinksetUse) const; + bool isShowPhantomToggleWarning(ELinksetUse pLinksetUse) const; + bool isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const; + LLSD encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const; + + static const S32 MIN_WALKABILITY_VALUE; + static const S32 MAX_WALKABILITY_VALUE; + +protected: + +private: + typedef enum + { + kNavMeshGenerationIgnore, + kNavMeshGenerationInclude, + kNavMeshGenerationExclude + } ENavMeshGenerationCategory; + + void parseLinksetData(const LLSD &pLinksetData); + void parsePathfindingData(const LLSD &pLinksetData); + + static BOOL isPhantom(ELinksetUse pLinksetUse); + static ELinksetUse getLinksetUse(bool pIsPhantom, ENavMeshGenerationCategory pNavMeshGenerationCategory); + static ENavMeshGenerationCategory getNavMeshGenerationCategory(ELinksetUse pLinksetUse); + static LLSD convertCategoryToLLSD(ENavMeshGenerationCategory pNavMeshGenerationCategory); + static ENavMeshGenerationCategory convertCategoryFromLLSD(const LLSD &llsd); + + bool mIsTerrain; + U32 mLandImpact; + BOOL mIsModifiable; + BOOL mCanBeVolume; + BOOL mIsScripted; + BOOL mHasIsScripted; + ELinksetUse mLinksetUse; + S32 mWalkabilityCoefficientA; + S32 mWalkabilityCoefficientB; + S32 mWalkabilityCoefficientC; + S32 mWalkabilityCoefficientD; +}; + +#endif // LL_LLPATHFINDINGLINKSET_H diff --git a/indra/newview/llpathfindinglinksetlist.cpp b/indra/newview/llpathfindinglinksetlist.cpp new file mode 100644 index 0000000000..b886e46765 --- /dev/null +++ b/indra/newview/llpathfindinglinksetlist.cpp @@ -0,0 +1,210 @@ +/** +* @file llpathfindinglinksetlist.cpp +* @brief Implementation of llpathfindinglinksetlist +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llpathfindinglinksetlist.h" + +#include <string> +#include <map> + +#include "llpathfindinglinkset.h" +#include "llpathfindingobject.h" +#include "llpathfindingobjectlist.h" +#include "llsd.h" + +//--------------------------------------------------------------------------- +// LLPathfindingLinksetList +//--------------------------------------------------------------------------- + +LLPathfindingLinksetList::LLPathfindingLinksetList() + : LLPathfindingObjectList() +{ +} + +LLPathfindingLinksetList::LLPathfindingLinksetList(const LLSD& pLinksetListData) + : LLPathfindingObjectList() +{ + parseLinksetListData(pLinksetListData); +} + +LLPathfindingLinksetList::~LLPathfindingLinksetList() +{ +} + +LLSD LLPathfindingLinksetList::encodeObjectFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const +{ + LLSD listData; + + for (const_iterator linksetIter = begin(); linksetIter != end(); ++linksetIter) + { + const LLPathfindingObjectPtr objectPtr = linksetIter->second; + const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get()); + + if (!linkset->isTerrain()) + { + LLSD linksetData = linkset->encodeAlteredFields(pLinksetUse, pA, pB, pC, pD); + if (!linksetData.isUndefined()) + { + const std::string& uuid(linksetIter->first); + listData[uuid] = linksetData; + } + } + } + + return listData; +} + +LLSD LLPathfindingLinksetList::encodeTerrainFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const +{ + LLSD terrainData; + + for (const_iterator linksetIter = begin(); linksetIter != end(); ++linksetIter) + { + const LLPathfindingObjectPtr objectPtr = linksetIter->second; + const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get()); + + if (linkset->isTerrain()) + { + terrainData = linkset->encodeAlteredFields(pLinksetUse, pA, pB, pC, pD); + break; + } + } + + return terrainData; +} + +bool LLPathfindingLinksetList::isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const +{ + bool isShowWarning = false; + + for (const_iterator objectIter = begin(); !isShowWarning && (objectIter != end()); ++objectIter) + { + const LLPathfindingObjectPtr objectPtr = objectIter->second; + const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get()); + isShowWarning = linkset->isShowUnmodifiablePhantomWarning(pLinksetUse); + } + + return isShowWarning; +} + +bool LLPathfindingLinksetList::isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const +{ + bool isShowWarning = false; + + for (const_iterator objectIter = begin(); !isShowWarning && (objectIter != end()); ++objectIter) + { + const LLPathfindingObjectPtr objectPtr = objectIter->second; + const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get()); + isShowWarning = linkset->isShowPhantomToggleWarning(pLinksetUse); + } + + return isShowWarning; +} + +bool LLPathfindingLinksetList::isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const +{ + bool isShowWarning = false; + + for (const_iterator objectIter = begin(); !isShowWarning && (objectIter != end()); ++objectIter) + { + const LLPathfindingObjectPtr objectPtr = objectIter->second; + const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get()); + isShowWarning = linkset->isShowCannotBeVolumeWarning(pLinksetUse); + } + + return isShowWarning; +} + +void LLPathfindingLinksetList::determinePossibleStates(BOOL &pCanBeWalkable, BOOL &pCanBeStaticObstacle, BOOL &pCanBeDynamicObstacle, + BOOL &pCanBeMaterialVolume, BOOL &pCanBeExclusionVolume, BOOL &pCanBeDynamicPhantom) const +{ + pCanBeWalkable = FALSE; + pCanBeStaticObstacle = FALSE; + pCanBeDynamicObstacle = FALSE; + pCanBeMaterialVolume = FALSE; + pCanBeExclusionVolume = FALSE; + pCanBeDynamicPhantom = FALSE; + + for (const_iterator objectIter = begin(); + !(pCanBeWalkable && pCanBeStaticObstacle && pCanBeDynamicObstacle && pCanBeMaterialVolume && pCanBeExclusionVolume && pCanBeDynamicPhantom) && (objectIter != end()); + ++objectIter) + { + const LLPathfindingObjectPtr objectPtr = objectIter->second; + const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get()); + + if (linkset->isTerrain()) + { + pCanBeWalkable = TRUE; + } + else + { + if (linkset->isModifiable()) + { + pCanBeWalkable = TRUE; + pCanBeStaticObstacle = TRUE; + pCanBeDynamicObstacle = TRUE; + pCanBeDynamicPhantom = TRUE; + if (linkset->canBeVolume()) + { + pCanBeMaterialVolume = TRUE; + pCanBeExclusionVolume = TRUE; + } + } + else if (linkset->isPhantom()) + { + pCanBeDynamicPhantom = TRUE; + if (linkset->canBeVolume()) + { + pCanBeMaterialVolume = TRUE; + pCanBeExclusionVolume = TRUE; + } + } + else + { + pCanBeWalkable = TRUE; + pCanBeStaticObstacle = TRUE; + pCanBeDynamicObstacle = TRUE; + } + } + } +} + +void LLPathfindingLinksetList::parseLinksetListData(const LLSD& pLinksetListData) +{ + LLPathfindingObjectMap &objectMap = getObjectMap(); + + for (LLSD::map_const_iterator linksetDataIter = pLinksetListData.beginMap(); + linksetDataIter != pLinksetListData.endMap(); ++linksetDataIter) + { + const std::string& uuid(linksetDataIter->first); + const LLSD& linksetData = linksetDataIter->second; + LLPathfindingObjectPtr linksetPtr(new LLPathfindingLinkset(uuid, linksetData)); + objectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(uuid, linksetPtr)); + } +} diff --git a/indra/newview/llpathfindinglinksetlist.h b/indra/newview/llpathfindinglinksetlist.h new file mode 100644 index 0000000000..1d38e4c11a --- /dev/null +++ b/indra/newview/llpathfindinglinksetlist.h @@ -0,0 +1,58 @@ +/** +* @file llpathfindinglinksetlist.h +* @brief Header file for llpathfindinglinksetlist +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLPATHFINDINGLINKSETLIST_H +#define LL_LLPATHFINDINGLINKSETLIST_H + +#include "llpathfindinglinkset.h" +#include "llpathfindingobjectlist.h" + +class LLSD; + +class LLPathfindingLinksetList : public LLPathfindingObjectList +{ +public: + LLPathfindingLinksetList(); + LLPathfindingLinksetList(const LLSD& pLinksetListData); + virtual ~LLPathfindingLinksetList(); + + LLSD encodeObjectFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const; + LLSD encodeTerrainFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const; + + bool isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; + bool isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; + bool isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; + + void determinePossibleStates(BOOL &pCanBeWalkable, BOOL &pCanBeStaticObstacle, BOOL &pCanBeDynamicObstacle, + BOOL &pCanBeMaterialVolume, BOOL &pCanBeExclusionVolume, BOOL &pCanBeDynamicPhantom) const; + +protected: + +private: + void parseLinksetListData(const LLSD& pLinksetListData); +}; + +#endif // LL_LLPATHFINDINGLINKSETLIST_H diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp new file mode 100644 index 0000000000..2dd01e931e --- /dev/null +++ b/indra/newview/llpathfindingmanager.cpp @@ -0,0 +1,1049 @@ +/** +* @file llpathfindingmanager.cpp +* @brief Implementation of llpathfindingmanager +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llpathfindingmanager.h" + +#include <string> +#include <map> + +#include <boost/bind.hpp> +#include <boost/function.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/signals2.hpp> + +#include "llagent.h" +#include "llhttpclient.h" +#include "llhttpnode.h" +#include "llnotificationsutil.h" +#include "llpathfindingcharacterlist.h" +#include "llpathfindinglinkset.h" +#include "llpathfindinglinksetlist.h" +#include "llpathfindingnavmesh.h" +#include "llpathfindingnavmeshstatus.h" +#include "llpathfindingobject.h" +#include "llpathinglib.h" +#include "llsingleton.h" +#include "llsd.h" +#include "lltrans.h" +#include "lluuid.h" +#include "llviewerregion.h" +#include "llweb.h" + +#define CAP_SERVICE_RETRIEVE_NAVMESH "RetrieveNavMeshSrc" + +#define CAP_SERVICE_NAVMESH_STATUS "NavMeshGenerationStatus" + +#define CAP_SERVICE_OBJECT_LINKSETS "ObjectNavMeshProperties" +#define CAP_SERVICE_TERRAIN_LINKSETS "TerrainNavMeshProperties" + +#define CAP_SERVICE_CHARACTERS "CharacterProperties" + +#define SIM_MESSAGE_NAVMESH_STATUS_UPDATE "/message/NavMeshStatusUpdate" +#define SIM_MESSAGE_AGENT_STATE_UPDATE "/message/AgentStateUpdate" +#define SIM_MESSAGE_BODY_FIELD "body" + +#define CAP_SERVICE_AGENT_STATE "AgentState" + +#define AGENT_STATE_CAN_REBAKE_REGION_FIELD "can_modify_navmesh" + +//--------------------------------------------------------------------------- +// LLNavMeshSimStateChangeNode +//--------------------------------------------------------------------------- + +class LLNavMeshSimStateChangeNode : public LLHTTPNode +{ +public: + virtual void post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const; +}; + +LLHTTPRegistration<LLNavMeshSimStateChangeNode> gHTTPRegistrationNavMeshSimStateChangeNode(SIM_MESSAGE_NAVMESH_STATUS_UPDATE); + + +//--------------------------------------------------------------------------- +// LLAgentStateChangeNode +//--------------------------------------------------------------------------- +class LLAgentStateChangeNode : public LLHTTPNode +{ +public: + virtual void post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const; +}; + +LLHTTPRegistration<LLAgentStateChangeNode> gHTTPRegistrationAgentStateChangeNode(SIM_MESSAGE_AGENT_STATE_UPDATE); + +//--------------------------------------------------------------------------- +// NavMeshStatusResponder +//--------------------------------------------------------------------------- + +class NavMeshStatusResponder : public LLHTTPClient::Responder +{ +public: + NavMeshStatusResponder(const std::string &pCapabilityURL, LLViewerRegion *pRegion, bool pIsGetStatusOnly); + virtual ~NavMeshStatusResponder(); + + virtual void result(const LLSD &pContent); + virtual void error(U32 pStatus, const std::string& pReason); + +protected: + +private: + std::string mCapabilityURL; + LLViewerRegion *mRegion; + LLUUID mRegionUUID; + bool mIsGetStatusOnly; +}; + +//--------------------------------------------------------------------------- +// NavMeshResponder +//--------------------------------------------------------------------------- + +class NavMeshResponder : public LLHTTPClient::Responder +{ +public: + NavMeshResponder(const std::string &pCapabilityURL, U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr); + virtual ~NavMeshResponder(); + + virtual void result(const LLSD &pContent); + virtual void error(U32 pStatus, const std::string& pReason); + +protected: + +private: + std::string mCapabilityURL; + U32 mNavMeshVersion; + LLPathfindingNavMeshPtr mNavMeshPtr; +}; + +//--------------------------------------------------------------------------- +// AgentStateResponder +//--------------------------------------------------------------------------- + +class AgentStateResponder : public LLHTTPClient::Responder +{ +public: + AgentStateResponder(const std::string &pCapabilityURL); + virtual ~AgentStateResponder(); + + virtual void result(const LLSD &pContent); + virtual void error(U32 pStatus, const std::string& pReason); + +protected: + +private: + std::string mCapabilityURL; +}; + + +//--------------------------------------------------------------------------- +// NavMeshRebakeResponder +//--------------------------------------------------------------------------- +class NavMeshRebakeResponder : public LLHTTPClient::Responder +{ +public: + NavMeshRebakeResponder(const std::string &pCapabilityURL, LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback); + virtual ~NavMeshRebakeResponder(); + + virtual void result(const LLSD &pContent); + virtual void error(U32 pStatus, const std::string& pReason); + +protected: + +private: + std::string mCapabilityURL; + LLPathfindingManager::rebake_navmesh_callback_t mRebakeNavMeshCallback; +}; + +//--------------------------------------------------------------------------- +// LinksetsResponder +//--------------------------------------------------------------------------- + +class LinksetsResponder +{ +public: + LinksetsResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pLinksetsCallback, bool pIsObjectRequested, bool pIsTerrainRequested); + virtual ~LinksetsResponder(); + + void handleObjectLinksetsResult(const LLSD &pContent); + void handleObjectLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL); + void handleTerrainLinksetsResult(const LLSD &pContent); + void handleTerrainLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL); + +protected: + +private: + void sendCallback(); + + typedef enum + { + kNotRequested, + kWaiting, + kReceivedGood, + kReceivedError + } EMessagingState; + + LLPathfindingManager::request_id_t mRequestId; + LLPathfindingManager::object_request_callback_t mLinksetsCallback; + + EMessagingState mObjectMessagingState; + EMessagingState mTerrainMessagingState; + + LLPathfindingObjectListPtr mObjectLinksetListPtr; + LLPathfindingObjectPtr mTerrainLinksetPtr; +}; + +typedef boost::shared_ptr<LinksetsResponder> LinksetsResponderPtr; + +//--------------------------------------------------------------------------- +// ObjectLinksetsResponder +//--------------------------------------------------------------------------- + +class ObjectLinksetsResponder : public LLHTTPClient::Responder +{ +public: + ObjectLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr); + virtual ~ObjectLinksetsResponder(); + + virtual void result(const LLSD &pContent); + virtual void error(U32 pStatus, const std::string &pReason); + +protected: + +private: + std::string mCapabilityURL; + LinksetsResponderPtr mLinksetsResponsderPtr; +}; + +//--------------------------------------------------------------------------- +// TerrainLinksetsResponder +//--------------------------------------------------------------------------- + +class TerrainLinksetsResponder : public LLHTTPClient::Responder +{ +public: + TerrainLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr); + virtual ~TerrainLinksetsResponder(); + + virtual void result(const LLSD &pContent); + virtual void error(U32 pStatus, const std::string &pReason); + +protected: + +private: + std::string mCapabilityURL; + LinksetsResponderPtr mLinksetsResponsderPtr; +}; + +//--------------------------------------------------------------------------- +// CharactersResponder +//--------------------------------------------------------------------------- + +class CharactersResponder : public LLHTTPClient::Responder +{ +public: + CharactersResponder(const std::string &pCapabilityURL, LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback); + virtual ~CharactersResponder(); + + virtual void result(const LLSD &pContent); + virtual void error(U32 pStatus, const std::string &pReason); + +protected: + +private: + std::string mCapabilityURL; + LLPathfindingManager::request_id_t mRequestId; + LLPathfindingManager::object_request_callback_t mCharactersCallback; +}; + +//--------------------------------------------------------------------------- +// LLPathfindingManager +//--------------------------------------------------------------------------- + +LLPathfindingManager::LLPathfindingManager() + : LLSingleton<LLPathfindingManager>(), + mNavMeshMap(), + mAgentStateSignal() +{ +} + +LLPathfindingManager::~LLPathfindingManager() +{ + quitSystem(); +} + +void LLPathfindingManager::initSystem() +{ + if (LLPathingLib::getInstance() == NULL) + { + LLPathingLib::initSystem(); + } +} + +void LLPathfindingManager::quitSystem() +{ + if (LLPathingLib::getInstance() != NULL) + { + LLPathingLib::quitSystem(); + } +} + +bool LLPathfindingManager::isPathfindingViewEnabled() const +{ + return (LLPathingLib::getInstance() != NULL); +} + +bool LLPathfindingManager::isPathfindingEnabledForCurrentRegion() const +{ + return isPathfindingEnabledForRegion(getCurrentRegion()); +} + +bool LLPathfindingManager::isPathfindingEnabledForRegion(LLViewerRegion *pRegion) const +{ + std::string retrieveNavMeshURL = getRetrieveNavMeshURLForRegion(pRegion); + return !retrieveNavMeshURL.empty(); +} + +bool LLPathfindingManager::isAllowViewTerrainProperties() const +{ + LLViewerRegion* region = getCurrentRegion(); + return (gAgent.isGodlike() || ((region != NULL) && region->canManageEstate())); +} + +LLPathfindingNavMesh::navmesh_slot_t LLPathfindingManager::registerNavMeshListenerForRegion(LLViewerRegion *pRegion, LLPathfindingNavMesh::navmesh_callback_t pNavMeshCallback) +{ + LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pRegion); + return navMeshPtr->registerNavMeshListener(pNavMeshCallback); +} + +void LLPathfindingManager::requestGetNavMeshForRegion(LLViewerRegion *pRegion, bool pIsGetStatusOnly) +{ + LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pRegion); + + if (pRegion == NULL) + { + navMeshPtr->handleNavMeshNotEnabled(); + } + else if (!pRegion->capabilitiesReceived()) + { + navMeshPtr->handleNavMeshWaitForRegionLoad(); + pRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetNavMeshForRegion, this, _1, pIsGetStatusOnly)); + } + else if (!isPathfindingEnabledForRegion(pRegion)) + { + navMeshPtr->handleNavMeshNotEnabled(); + } + else + { + std::string navMeshStatusURL = getNavMeshStatusURLForRegion(pRegion); + llassert(!navMeshStatusURL.empty()); + navMeshPtr->handleNavMeshCheckVersion(); + LLHTTPClient::ResponderPtr navMeshStatusResponder = new NavMeshStatusResponder(navMeshStatusURL, pRegion, pIsGetStatusOnly); + LLHTTPClient::get(navMeshStatusURL, navMeshStatusResponder); + } +} + +void LLPathfindingManager::requestGetLinksets(request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const +{ + LLPathfindingObjectListPtr emptyLinksetListPtr; + LLViewerRegion *currentRegion = getCurrentRegion(); + + if (currentRegion == NULL) + { + pLinksetsCallback(pRequestId, kRequestNotEnabled, emptyLinksetListPtr); + } + else if (!currentRegion->capabilitiesReceived()) + { + pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr); + currentRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetLinksetsForRegion, this, _1, pRequestId, pLinksetsCallback)); + } + else + { + std::string objectLinksetsURL = getObjectLinksetsURLForCurrentRegion(); + std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion(); + if (objectLinksetsURL.empty() || terrainLinksetsURL.empty()) + { + pLinksetsCallback(pRequestId, kRequestNotEnabled, emptyLinksetListPtr); + } + else + { + pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr); + + bool doRequestTerrain = isAllowViewTerrainProperties(); + LinksetsResponderPtr linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, true, doRequestTerrain)); + + LLHTTPClient::ResponderPtr objectLinksetsResponder = new ObjectLinksetsResponder(objectLinksetsURL, linksetsResponderPtr); + LLHTTPClient::get(objectLinksetsURL, objectLinksetsResponder); + + if (doRequestTerrain) + { + LLHTTPClient::ResponderPtr terrainLinksetsResponder = new TerrainLinksetsResponder(terrainLinksetsURL, linksetsResponderPtr); + LLHTTPClient::get(terrainLinksetsURL, terrainLinksetsResponder); + } + } + } +} + +void LLPathfindingManager::requestSetLinksets(request_id_t pRequestId, const LLPathfindingObjectListPtr &pLinksetListPtr, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD, object_request_callback_t pLinksetsCallback) const +{ + LLPathfindingObjectListPtr emptyLinksetListPtr; + + std::string objectLinksetsURL = getObjectLinksetsURLForCurrentRegion(); + std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion(); + if (objectLinksetsURL.empty() || terrainLinksetsURL.empty()) + { + pLinksetsCallback(pRequestId, kRequestNotEnabled, emptyLinksetListPtr); + } + else if ((pLinksetListPtr == NULL) || pLinksetListPtr->isEmpty()) + { + pLinksetsCallback(pRequestId, kRequestCompleted, emptyLinksetListPtr); + } + else + { + const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(pLinksetListPtr.get()); + + LLSD objectPostData = linksetList->encodeObjectFields(pLinksetUse, pA, pB, pC, pD); + LLSD terrainPostData; + if (isAllowViewTerrainProperties()) + { + terrainPostData = linksetList->encodeTerrainFields(pLinksetUse, pA, pB, pC, pD); + } + + if (objectPostData.isUndefined() && terrainPostData.isUndefined()) + { + pLinksetsCallback(pRequestId, kRequestCompleted, emptyLinksetListPtr); + } + else + { + pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr); + + LinksetsResponderPtr linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, !objectPostData.isUndefined(), !terrainPostData.isUndefined())); + + if (!objectPostData.isUndefined()) + { + LLHTTPClient::ResponderPtr objectLinksetsResponder = new ObjectLinksetsResponder(objectLinksetsURL, linksetsResponderPtr); + LLHTTPClient::put(objectLinksetsURL, objectPostData, objectLinksetsResponder); + } + + if (!terrainPostData.isUndefined()) + { + LLHTTPClient::ResponderPtr terrainLinksetsResponder = new TerrainLinksetsResponder(terrainLinksetsURL, linksetsResponderPtr); + LLHTTPClient::put(terrainLinksetsURL, terrainPostData, terrainLinksetsResponder); + } + } + } +} + +void LLPathfindingManager::requestGetCharacters(request_id_t pRequestId, object_request_callback_t pCharactersCallback) const +{ + LLPathfindingObjectListPtr emptyCharacterListPtr; + + LLViewerRegion *currentRegion = getCurrentRegion(); + + if (currentRegion == NULL) + { + pCharactersCallback(pRequestId, kRequestNotEnabled, emptyCharacterListPtr); + } + else if (!currentRegion->capabilitiesReceived()) + { + pCharactersCallback(pRequestId, kRequestStarted, emptyCharacterListPtr); + currentRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetCharactersForRegion, this, _1, pRequestId, pCharactersCallback)); + } + else + { + std::string charactersURL = getCharactersURLForCurrentRegion(); + if (charactersURL.empty()) + { + pCharactersCallback(pRequestId, kRequestNotEnabled, emptyCharacterListPtr); + } + else + { + pCharactersCallback(pRequestId, kRequestStarted, emptyCharacterListPtr); + + LLHTTPClient::ResponderPtr charactersResponder = new CharactersResponder(charactersURL, pRequestId, pCharactersCallback); + LLHTTPClient::get(charactersURL, charactersResponder); + } + } +} + +LLPathfindingManager::agent_state_slot_t LLPathfindingManager::registerAgentStateListener(agent_state_callback_t pAgentStateCallback) +{ + return mAgentStateSignal.connect(pAgentStateCallback); +} + +void LLPathfindingManager::requestGetAgentState() +{ + LLViewerRegion *currentRegion = getCurrentRegion(); + + if (currentRegion == NULL) + { + mAgentStateSignal(FALSE); + } + else + { + if (!currentRegion->capabilitiesReceived()) + { + currentRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetAgentStateForRegion, this, _1)); + } + else if (!isPathfindingEnabledForRegion(currentRegion)) + { + mAgentStateSignal(FALSE); + } + else + { + std::string agentStateURL = getAgentStateURLForRegion(currentRegion); + llassert(!agentStateURL.empty()); + LLHTTPClient::ResponderPtr responder = new AgentStateResponder(agentStateURL); + LLHTTPClient::get(agentStateURL, responder); + } + } +} + +void LLPathfindingManager::requestRebakeNavMesh(rebake_navmesh_callback_t pRebakeNavMeshCallback) +{ + LLViewerRegion *currentRegion = getCurrentRegion(); + + if (currentRegion == NULL) + { + pRebakeNavMeshCallback(false); + } + else if (!isPathfindingEnabledForRegion(currentRegion)) + { + pRebakeNavMeshCallback(false); + } + else + { + std::string navMeshStatusURL = getNavMeshStatusURLForCurrentRegion(); + llassert(!navMeshStatusURL.empty()); + LLSD postData; + postData["command"] = "rebuild"; + LLHTTPClient::ResponderPtr responder = new NavMeshRebakeResponder(navMeshStatusURL, pRebakeNavMeshCallback); + LLHTTPClient::post(navMeshStatusURL, postData, responder); + } +} + +void LLPathfindingManager::sendRequestGetNavMeshForRegion(LLPathfindingNavMeshPtr navMeshPtr, LLViewerRegion *pRegion, const LLPathfindingNavMeshStatus &pNavMeshStatus) +{ + if ((pRegion == NULL) || !pRegion->isAlive()) + { + navMeshPtr->handleNavMeshNotEnabled(); + } + else + { + std::string navMeshURL = getRetrieveNavMeshURLForRegion(pRegion); + + if (navMeshURL.empty()) + { + navMeshPtr->handleNavMeshNotEnabled(); + } + else + { + navMeshPtr->handleNavMeshStart(pNavMeshStatus); + LLHTTPClient::ResponderPtr responder = new NavMeshResponder(navMeshURL, pNavMeshStatus.getVersion(), navMeshPtr); + + LLSD postData; + LLHTTPClient::post(navMeshURL, postData, responder); + } + } +} + +void LLPathfindingManager::handleDeferredGetAgentStateForRegion(const LLUUID &pRegionUUID) +{ + LLViewerRegion *currentRegion = getCurrentRegion(); + + if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID)) + { + requestGetAgentState(); + } +} + +void LLPathfindingManager::handleDeferredGetNavMeshForRegion(const LLUUID &pRegionUUID, bool pIsGetStatusOnly) +{ + LLViewerRegion *currentRegion = getCurrentRegion(); + + if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID)) + { + requestGetNavMeshForRegion(currentRegion, pIsGetStatusOnly); + } +} + +void LLPathfindingManager::handleDeferredGetLinksetsForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const +{ + LLViewerRegion *currentRegion = getCurrentRegion(); + + if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID)) + { + requestGetLinksets(pRequestId, pLinksetsCallback); + } +} + +void LLPathfindingManager::handleDeferredGetCharactersForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pCharactersCallback) const +{ + LLViewerRegion *currentRegion = getCurrentRegion(); + + if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID)) + { + requestGetCharacters(pRequestId, pCharactersCallback); + } +} + +void LLPathfindingManager::handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion, bool pIsGetStatusOnly) +{ + LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pNavMeshStatus.getRegionUUID()); + + if (!pNavMeshStatus.isValid()) + { + navMeshPtr->handleNavMeshError(); + } + else + { + if (navMeshPtr->hasNavMeshVersion(pNavMeshStatus)) + { + navMeshPtr->handleRefresh(pNavMeshStatus); + } + else if (pIsGetStatusOnly) + { + navMeshPtr->handleNavMeshNewVersion(pNavMeshStatus); + } + else + { + sendRequestGetNavMeshForRegion(navMeshPtr, pRegion, pNavMeshStatus); + } + } +} + +void LLPathfindingManager::handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus) +{ + LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pNavMeshStatus.getRegionUUID()); + + if (!pNavMeshStatus.isValid()) + { + navMeshPtr->handleNavMeshError(); + } + else + { + navMeshPtr->handleNavMeshNewVersion(pNavMeshStatus); + } +} + +void LLPathfindingManager::handleAgentState(BOOL pCanRebakeRegion) +{ + mAgentStateSignal(pCanRebakeRegion); +} + +LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForRegion(const LLUUID &pRegionUUID) +{ + LLPathfindingNavMeshPtr navMeshPtr; + NavMeshMap::iterator navMeshIter = mNavMeshMap.find(pRegionUUID); + if (navMeshIter == mNavMeshMap.end()) + { + navMeshPtr = LLPathfindingNavMeshPtr(new LLPathfindingNavMesh(pRegionUUID)); + mNavMeshMap.insert(std::pair<LLUUID, LLPathfindingNavMeshPtr>(pRegionUUID, navMeshPtr)); + } + else + { + navMeshPtr = navMeshIter->second; + } + + return navMeshPtr; +} + +LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForRegion(LLViewerRegion *pRegion) +{ + LLUUID regionUUID; + if (pRegion != NULL) + { + regionUUID = pRegion->getRegionID(); + } + + return getNavMeshForRegion(regionUUID); +} + +std::string LLPathfindingManager::getNavMeshStatusURLForCurrentRegion() const +{ + return getNavMeshStatusURLForRegion(getCurrentRegion()); +} + +std::string LLPathfindingManager::getNavMeshStatusURLForRegion(LLViewerRegion *pRegion) const +{ + return getCapabilityURLForRegion(pRegion, CAP_SERVICE_NAVMESH_STATUS); +} + +std::string LLPathfindingManager::getRetrieveNavMeshURLForRegion(LLViewerRegion *pRegion) const +{ + return getCapabilityURLForRegion(pRegion, CAP_SERVICE_RETRIEVE_NAVMESH); +} + +std::string LLPathfindingManager::getObjectLinksetsURLForCurrentRegion() const +{ + return getCapabilityURLForCurrentRegion(CAP_SERVICE_OBJECT_LINKSETS); +} + +std::string LLPathfindingManager::getTerrainLinksetsURLForCurrentRegion() const +{ + return getCapabilityURLForCurrentRegion(CAP_SERVICE_TERRAIN_LINKSETS); +} + +std::string LLPathfindingManager::getCharactersURLForCurrentRegion() const +{ + return getCapabilityURLForCurrentRegion(CAP_SERVICE_CHARACTERS); +} + +std::string LLPathfindingManager::getAgentStateURLForRegion(LLViewerRegion *pRegion) const +{ + return getCapabilityURLForRegion(pRegion, CAP_SERVICE_AGENT_STATE); +} + +std::string LLPathfindingManager::getCapabilityURLForCurrentRegion(const std::string &pCapabilityName) const +{ + return getCapabilityURLForRegion(getCurrentRegion(), pCapabilityName); +} + +std::string LLPathfindingManager::getCapabilityURLForRegion(LLViewerRegion *pRegion, const std::string &pCapabilityName) const +{ + std::string capabilityURL(""); + + if (pRegion != NULL) + { + capabilityURL = pRegion->getCapability(pCapabilityName); + } + + if (capabilityURL.empty()) + { + llwarns << "cannot find capability '" << pCapabilityName << "' for current region '" + << ((pRegion != NULL) ? pRegion->getName() : "<null>") << "'" << llendl; + } + + return capabilityURL; +} + +LLViewerRegion *LLPathfindingManager::getCurrentRegion() const +{ + return gAgent.getRegion(); +} + +//--------------------------------------------------------------------------- +// LLNavMeshSimStateChangeNode +//--------------------------------------------------------------------------- + +void LLNavMeshSimStateChangeNode::post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const +{ + llassert(pInput.has(SIM_MESSAGE_BODY_FIELD)); + llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).isMap()); + LLPathfindingNavMeshStatus navMeshStatus(pInput.get(SIM_MESSAGE_BODY_FIELD)); + LLPathfindingManager::getInstance()->handleNavMeshStatusUpdate(navMeshStatus); +} + +//--------------------------------------------------------------------------- +// LLAgentStateChangeNode +//--------------------------------------------------------------------------- + +void LLAgentStateChangeNode::post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const +{ + llassert(pInput.has(SIM_MESSAGE_BODY_FIELD)); + llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).isMap()); + llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).has(AGENT_STATE_CAN_REBAKE_REGION_FIELD)); + llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean()); + BOOL canRebakeRegion = pInput.get(SIM_MESSAGE_BODY_FIELD).get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean(); + + LLPathfindingManager::getInstance()->handleAgentState(canRebakeRegion); +} + +//--------------------------------------------------------------------------- +// NavMeshStatusResponder +//--------------------------------------------------------------------------- + +NavMeshStatusResponder::NavMeshStatusResponder(const std::string &pCapabilityURL, LLViewerRegion *pRegion, bool pIsGetStatusOnly) + : LLHTTPClient::Responder(), + mCapabilityURL(pCapabilityURL), + mRegion(pRegion), + mRegionUUID(), + mIsGetStatusOnly(pIsGetStatusOnly) +{ + if (mRegion != NULL) + { + mRegionUUID = mRegion->getRegionID(); + } +} + +NavMeshStatusResponder::~NavMeshStatusResponder() +{ +} + +void NavMeshStatusResponder::result(const LLSD &pContent) +{ + LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID, pContent); + LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly); +} + +void NavMeshStatusResponder::error(U32 pStatus, const std::string& pReason) +{ + llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; + LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID); + LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly); +} + +//--------------------------------------------------------------------------- +// NavMeshResponder +//--------------------------------------------------------------------------- + +NavMeshResponder::NavMeshResponder(const std::string &pCapabilityURL, U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr) + : LLHTTPClient::Responder(), + mCapabilityURL(pCapabilityURL), + mNavMeshVersion(pNavMeshVersion), + mNavMeshPtr(pNavMeshPtr) +{ +} + +NavMeshResponder::~NavMeshResponder() +{ +} + +void NavMeshResponder::result(const LLSD &pContent) +{ + mNavMeshPtr->handleNavMeshResult(pContent, mNavMeshVersion); +} + +void NavMeshResponder::error(U32 pStatus, const std::string& pReason) +{ + mNavMeshPtr->handleNavMeshError(pStatus, pReason, mCapabilityURL, mNavMeshVersion); +} + +//--------------------------------------------------------------------------- +// AgentStateResponder +//--------------------------------------------------------------------------- + +AgentStateResponder::AgentStateResponder(const std::string &pCapabilityURL) +: LLHTTPClient::Responder() +, mCapabilityURL(pCapabilityURL) +{ +} + +AgentStateResponder::~AgentStateResponder() +{ +} + +void AgentStateResponder::result(const LLSD &pContent) +{ + llassert(pContent.has(AGENT_STATE_CAN_REBAKE_REGION_FIELD)); + llassert(pContent.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean()); + BOOL canRebakeRegion = pContent.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean(); + LLPathfindingManager::getInstance()->handleAgentState(canRebakeRegion); +} + +void AgentStateResponder::error(U32 pStatus, const std::string &pReason) +{ + llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; + LLPathfindingManager::getInstance()->handleAgentState(FALSE); +} + + +//--------------------------------------------------------------------------- +// navmesh rebake responder +//--------------------------------------------------------------------------- +NavMeshRebakeResponder::NavMeshRebakeResponder(const std::string &pCapabilityURL, LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback) + : LLHTTPClient::Responder(), + mCapabilityURL(pCapabilityURL), + mRebakeNavMeshCallback(pRebakeNavMeshCallback) +{ +} + +NavMeshRebakeResponder::~NavMeshRebakeResponder() +{ +} + +void NavMeshRebakeResponder::result(const LLSD &pContent) +{ + mRebakeNavMeshCallback(true); +} + +void NavMeshRebakeResponder::error(U32 pStatus, const std::string &pReason) +{ + llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; + mRebakeNavMeshCallback(false); +} + +//--------------------------------------------------------------------------- +// LinksetsResponder +//--------------------------------------------------------------------------- + +LinksetsResponder::LinksetsResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pLinksetsCallback, bool pIsObjectRequested, bool pIsTerrainRequested) + : mRequestId(pRequestId), + mLinksetsCallback(pLinksetsCallback), + mObjectMessagingState(pIsObjectRequested ? kWaiting : kNotRequested), + mTerrainMessagingState(pIsTerrainRequested ? kWaiting : kNotRequested), + mObjectLinksetListPtr(), + mTerrainLinksetPtr() +{ +} + +LinksetsResponder::~LinksetsResponder() +{ +} + +void LinksetsResponder::handleObjectLinksetsResult(const LLSD &pContent) +{ + mObjectLinksetListPtr = LLPathfindingObjectListPtr(new LLPathfindingLinksetList(pContent)); + + mObjectMessagingState = kReceivedGood; + if (mTerrainMessagingState != kWaiting) + { + sendCallback(); + } +} + +void LinksetsResponder::handleObjectLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL) +{ + llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; + mObjectMessagingState = kReceivedError; + if (mTerrainMessagingState != kWaiting) + { + sendCallback(); + } +} + +void LinksetsResponder::handleTerrainLinksetsResult(const LLSD &pContent) +{ + mTerrainLinksetPtr = LLPathfindingObjectPtr(new LLPathfindingLinkset(pContent)); + + mTerrainMessagingState = kReceivedGood; + if (mObjectMessagingState != kWaiting) + { + sendCallback(); + } +} + +void LinksetsResponder::handleTerrainLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL) +{ + mTerrainMessagingState = kReceivedError; + if (mObjectMessagingState != kWaiting) + { + sendCallback(); + } +} + +void LinksetsResponder::sendCallback() +{ + llassert(mObjectMessagingState != kWaiting); + llassert(mTerrainMessagingState != kWaiting); + LLPathfindingManager::ERequestStatus requestStatus = + ((((mObjectMessagingState == kReceivedGood) || (mObjectMessagingState == kNotRequested)) && + ((mTerrainMessagingState == kReceivedGood) || (mTerrainMessagingState == kNotRequested))) ? + LLPathfindingManager::kRequestCompleted : LLPathfindingManager::kRequestError); + + if (mObjectMessagingState != kReceivedGood) + { + mObjectLinksetListPtr = LLPathfindingObjectListPtr(new LLPathfindingLinksetList()); + } + + if (mTerrainMessagingState == kReceivedGood) + { + mObjectLinksetListPtr->update(mTerrainLinksetPtr); + } + + mLinksetsCallback(mRequestId, requestStatus, mObjectLinksetListPtr); +} + +//--------------------------------------------------------------------------- +// ObjectLinksetsResponder +//--------------------------------------------------------------------------- + +ObjectLinksetsResponder::ObjectLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr) + : LLHTTPClient::Responder(), + mCapabilityURL(pCapabilityURL), + mLinksetsResponsderPtr(pLinksetsResponsderPtr) +{ +} + +ObjectLinksetsResponder::~ObjectLinksetsResponder() +{ +} + +void ObjectLinksetsResponder::result(const LLSD &pContent) +{ + mLinksetsResponsderPtr->handleObjectLinksetsResult(pContent); +} + +void ObjectLinksetsResponder::error(U32 pStatus, const std::string &pReason) +{ + mLinksetsResponsderPtr->handleObjectLinksetsError(pStatus, pReason, mCapabilityURL); +} + +//--------------------------------------------------------------------------- +// TerrainLinksetsResponder +//--------------------------------------------------------------------------- + +TerrainLinksetsResponder::TerrainLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr) + : LLHTTPClient::Responder(), + mCapabilityURL(pCapabilityURL), + mLinksetsResponsderPtr(pLinksetsResponsderPtr) +{ +} + +TerrainLinksetsResponder::~TerrainLinksetsResponder() +{ +} + +void TerrainLinksetsResponder::result(const LLSD &pContent) +{ + mLinksetsResponsderPtr->handleTerrainLinksetsResult(pContent); +} + +void TerrainLinksetsResponder::error(U32 pStatus, const std::string &pReason) +{ + mLinksetsResponsderPtr->handleTerrainLinksetsError(pStatus, pReason, mCapabilityURL); +} + +//--------------------------------------------------------------------------- +// CharactersResponder +//--------------------------------------------------------------------------- + +CharactersResponder::CharactersResponder(const std::string &pCapabilityURL, LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback) + : LLHTTPClient::Responder(), + mCapabilityURL(pCapabilityURL), + mRequestId(pRequestId), + mCharactersCallback(pCharactersCallback) +{ +} + +CharactersResponder::~CharactersResponder() +{ +} + +void CharactersResponder::result(const LLSD &pContent) +{ + LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList(pContent)); + mCharactersCallback(mRequestId, LLPathfindingManager::kRequestCompleted, characterListPtr); +} + +void CharactersResponder::error(U32 pStatus, const std::string &pReason) +{ + llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; + + LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList()); + mCharactersCallback(mRequestId, LLPathfindingManager::kRequestError, characterListPtr); +} diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h new file mode 100644 index 0000000000..c61ff244fc --- /dev/null +++ b/indra/newview/llpathfindingmanager.h @@ -0,0 +1,127 @@ +/** +* @file llpathfindingmanager.h +* @brief Header file for llpathfindingmanager +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLPATHFINDINGMANAGER_H +#define LL_LLPATHFINDINGMANAGER_H + +#include <string> +#include <map> + +#include <boost/function.hpp> +#include <boost/signals2.hpp> + +#include "llpathfindinglinkset.h" +#include "llpathfindingobjectlist.h" +#include "llpathfindingnavmesh.h" +#include "llsingleton.h" + +class LLPathfindingNavMeshStatus; +class LLUUID; +class LLViewerRegion; + +class LLPathfindingManager : public LLSingleton<LLPathfindingManager> +{ + friend class LLNavMeshSimStateChangeNode; + friend class NavMeshStatusResponder; + friend class LLAgentStateChangeNode; + friend class AgentStateResponder; +public: + typedef enum { + kRequestStarted, + kRequestCompleted, + kRequestNotEnabled, + kRequestError + } ERequestStatus; + + LLPathfindingManager(); + virtual ~LLPathfindingManager(); + + void initSystem(); + void quitSystem(); + + bool isPathfindingViewEnabled() const; + bool isPathfindingEnabledForCurrentRegion() const; + bool isPathfindingEnabledForRegion(LLViewerRegion *pRegion) const; + + bool isAllowViewTerrainProperties() const; + + LLPathfindingNavMesh::navmesh_slot_t registerNavMeshListenerForRegion(LLViewerRegion *pRegion, LLPathfindingNavMesh::navmesh_callback_t pNavMeshCallback); + void requestGetNavMeshForRegion(LLViewerRegion *pRegion, bool pIsGetStatusOnly); + + typedef U32 request_id_t; + typedef boost::function<void (request_id_t, ERequestStatus, LLPathfindingObjectListPtr)> object_request_callback_t; + + void requestGetLinksets(request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const; + void requestSetLinksets(request_id_t pRequestId, const LLPathfindingObjectListPtr &pLinksetListPtr, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD, object_request_callback_t pLinksetsCallback) const; + + void requestGetCharacters(request_id_t pRequestId, object_request_callback_t pCharactersCallback) const; + + typedef boost::function<void (BOOL)> agent_state_callback_t; + typedef boost::signals2::signal<void (BOOL)> agent_state_signal_t; + typedef boost::signals2::connection agent_state_slot_t; + + agent_state_slot_t registerAgentStateListener(agent_state_callback_t pAgentStateCallback); + void requestGetAgentState(); + + typedef boost::function<void (bool)> rebake_navmesh_callback_t; + void requestRebakeNavMesh(rebake_navmesh_callback_t pRebakeNavMeshCallback); + +protected: + +private: + typedef std::map<LLUUID, LLPathfindingNavMeshPtr> NavMeshMap; + + void sendRequestGetNavMeshForRegion(LLPathfindingNavMeshPtr navMeshPtr, LLViewerRegion *pRegion, const LLPathfindingNavMeshStatus &pNavMeshStatus); + + void handleDeferredGetAgentStateForRegion(const LLUUID &pRegionUUID); + void handleDeferredGetNavMeshForRegion(const LLUUID &pRegionUUID, bool pIsGetStatusOnly); + void handleDeferredGetLinksetsForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const; + void handleDeferredGetCharactersForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pCharactersCallback) const; + + void handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion, bool pIsGetStatusOnly); + void handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus); + + void handleAgentState(BOOL pCanRebakeRegion); + + LLPathfindingNavMeshPtr getNavMeshForRegion(const LLUUID &pRegionUUID); + LLPathfindingNavMeshPtr getNavMeshForRegion(LLViewerRegion *pRegion); + + std::string getNavMeshStatusURLForCurrentRegion() const; + std::string getNavMeshStatusURLForRegion(LLViewerRegion *pRegion) const; + std::string getRetrieveNavMeshURLForRegion(LLViewerRegion *pRegion) const; + std::string getObjectLinksetsURLForCurrentRegion() const; + std::string getTerrainLinksetsURLForCurrentRegion() const; + std::string getCharactersURLForCurrentRegion() const; + std::string getAgentStateURLForRegion(LLViewerRegion *pRegion) const; + std::string getCapabilityURLForCurrentRegion(const std::string &pCapabilityName) const; + std::string getCapabilityURLForRegion(LLViewerRegion *pRegion, const std::string &pCapabilityName) const; + LLViewerRegion *getCurrentRegion() const; + + NavMeshMap mNavMeshMap; + agent_state_signal_t mAgentStateSignal; +}; + +#endif // LL_LLPATHFINDINGMANAGER_H diff --git a/indra/newview/llpathfindingnavmesh.cpp b/indra/newview/llpathfindingnavmesh.cpp new file mode 100644 index 0000000000..e01dd3a152 --- /dev/null +++ b/indra/newview/llpathfindingnavmesh.cpp @@ -0,0 +1,205 @@ +/** +* @file llpathfindingnavmesh.cpp +* @brief Implementation of llpathfindingnavmesh +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llpathfindingnavmesh.h" + +#include <string> + +#include "llpathfindingnavmeshstatus.h" +#include "llsd.h" +#include "llsdserialize.h" +#include "lluuid.h" + +#define NAVMESH_VERSION_FIELD "navmesh_version" +#define NAVMESH_DATA_FIELD "navmesh_data" + +//--------------------------------------------------------------------------- +// LLPathfindingNavMesh +//--------------------------------------------------------------------------- + +LLPathfindingNavMesh::LLPathfindingNavMesh(const LLUUID &pRegionUUID) + : mNavMeshStatus(pRegionUUID), + mNavMeshRequestStatus(kNavMeshRequestUnknown), + mNavMeshSignal(), + mNavMeshData() + +{ +} + +LLPathfindingNavMesh::~LLPathfindingNavMesh() +{ +} + +LLPathfindingNavMesh::navmesh_slot_t LLPathfindingNavMesh::registerNavMeshListener(navmesh_callback_t pNavMeshCallback) +{ + return mNavMeshSignal.connect(pNavMeshCallback); +} + +bool LLPathfindingNavMesh::hasNavMeshVersion(const LLPathfindingNavMeshStatus &pNavMeshStatus) const +{ + return ((mNavMeshStatus.getVersion() == pNavMeshStatus.getVersion()) && + ((mNavMeshRequestStatus == kNavMeshRequestStarted) || (mNavMeshRequestStatus == kNavMeshRequestCompleted) || + ((mNavMeshRequestStatus == kNavMeshRequestChecking) && !mNavMeshData.empty()))); +} + +void LLPathfindingNavMesh::handleNavMeshWaitForRegionLoad() +{ + setRequestStatus(kNavMeshRequestWaiting); +} + +void LLPathfindingNavMesh::handleNavMeshCheckVersion() +{ + setRequestStatus(kNavMeshRequestChecking); +} + +void LLPathfindingNavMesh::handleRefresh(const LLPathfindingNavMeshStatus &pNavMeshStatus) +{ + llassert(mNavMeshStatus.getRegionUUID() == pNavMeshStatus.getRegionUUID()); + llassert(mNavMeshStatus.getVersion() == pNavMeshStatus.getVersion()); + mNavMeshStatus = pNavMeshStatus; + if (mNavMeshRequestStatus == kNavMeshRequestChecking) + { + llassert(!mNavMeshData.empty()); + setRequestStatus(kNavMeshRequestCompleted); + } + else + { + sendStatus(); + } +} + +void LLPathfindingNavMesh::handleNavMeshNewVersion(const LLPathfindingNavMeshStatus &pNavMeshStatus) +{ + llassert(mNavMeshStatus.getRegionUUID() == pNavMeshStatus.getRegionUUID()); + if (mNavMeshStatus.getVersion() == pNavMeshStatus.getVersion()) + { + mNavMeshStatus = pNavMeshStatus; + sendStatus(); + } + else + { + mNavMeshData.clear(); + mNavMeshStatus = pNavMeshStatus; + setRequestStatus(kNavMeshRequestNeedsUpdate); + } +} + +void LLPathfindingNavMesh::handleNavMeshStart(const LLPathfindingNavMeshStatus &pNavMeshStatus) +{ + llassert(mNavMeshStatus.getRegionUUID() == pNavMeshStatus.getRegionUUID()); + mNavMeshStatus = pNavMeshStatus; + setRequestStatus(kNavMeshRequestStarted); +} + +void LLPathfindingNavMesh::handleNavMeshResult(const LLSD &pContent, U32 pNavMeshVersion) +{ + llassert(pContent.has(NAVMESH_VERSION_FIELD)); + if (pContent.has(NAVMESH_VERSION_FIELD)) + { + llassert(pContent.get(NAVMESH_VERSION_FIELD).isInteger()); + llassert(pContent.get(NAVMESH_VERSION_FIELD).asInteger() >= 0); + U32 embeddedNavMeshVersion = static_cast<U32>(pContent.get(NAVMESH_VERSION_FIELD).asInteger()); + llassert(embeddedNavMeshVersion == pNavMeshVersion); // stinson 03/13/2012 : does this ever occur? + if (embeddedNavMeshVersion != pNavMeshVersion) + { + llwarns << "Mismatch between expected and embedded navmesh versions occurred" << llendl; + pNavMeshVersion = embeddedNavMeshVersion; + } + } + + if (mNavMeshStatus.getVersion() == pNavMeshVersion) + { + ENavMeshRequestStatus status; + if ( pContent.has(NAVMESH_DATA_FIELD) ) + { + const LLSD::Binary &value = pContent.get(NAVMESH_DATA_FIELD).asBinary(); + unsigned int binSize = value.size(); + std::string newStr(reinterpret_cast<const char *>(&value[0]), binSize); + std::istringstream streamdecomp( newStr ); + unsigned int decompBinSize = 0; + bool valid = false; + U8* pUncompressedNavMeshContainer = unzip_llsdNavMesh( valid, decompBinSize, streamdecomp, binSize ) ; + if ( !valid ) + { + llwarns << "Unable to decompress the navmesh llsd." << llendl; + status = kNavMeshRequestError; + } + else + { + llassert(pUncompressedNavMeshContainer); + mNavMeshData.resize( decompBinSize ); + memcpy( &mNavMeshData[0], &pUncompressedNavMeshContainer[0], decompBinSize ); + status = kNavMeshRequestCompleted; + } + if ( pUncompressedNavMeshContainer ) + { + free( pUncompressedNavMeshContainer ); + } + } + else + { + llwarns << "No mesh data received" << llendl; + status = kNavMeshRequestError; + } + setRequestStatus(status); + } +} + +void LLPathfindingNavMesh::handleNavMeshNotEnabled() +{ + mNavMeshData.clear(); + setRequestStatus(kNavMeshRequestNotEnabled); +} + +void LLPathfindingNavMesh::handleNavMeshError() +{ + mNavMeshData.clear(); + setRequestStatus(kNavMeshRequestError); +} + +void LLPathfindingNavMesh::handleNavMeshError(U32 pStatus, const std::string &pReason, const std::string &pURL, U32 pNavMeshVersion) +{ + llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; + if (mNavMeshStatus.getVersion() == pNavMeshVersion) + { + handleNavMeshError(); + } +} + +void LLPathfindingNavMesh::setRequestStatus(ENavMeshRequestStatus pNavMeshRequestStatus) +{ + mNavMeshRequestStatus = pNavMeshRequestStatus; + sendStatus(); +} + +void LLPathfindingNavMesh::sendStatus() +{ + mNavMeshSignal(mNavMeshRequestStatus, mNavMeshStatus, mNavMeshData); +} diff --git a/indra/newview/llpathfindingnavmesh.h b/indra/newview/llpathfindingnavmesh.h new file mode 100644 index 0000000000..7a844f54ce --- /dev/null +++ b/indra/newview/llpathfindingnavmesh.h @@ -0,0 +1,91 @@ +/** +* @file llpathfindingnavmesh.h +* @brief Header file for llpathfindingnavmesh +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLPATHFINDINGNAVMESH_H +#define LL_LLPATHFINDINGNAVMESH_H + +#include <string> + +#include <boost/shared_ptr.hpp> +#include <boost/function.hpp> +#include <boost/signals2.hpp> + +#include "llpathfindingnavmeshstatus.h" +#include "llsd.h" + +class LLPathfindingNavMesh; +class LLUUID; + +typedef boost::shared_ptr<LLPathfindingNavMesh> LLPathfindingNavMeshPtr; + +class LLPathfindingNavMesh +{ +public: + typedef enum { + kNavMeshRequestUnknown, + kNavMeshRequestWaiting, + kNavMeshRequestChecking, + kNavMeshRequestNeedsUpdate, + kNavMeshRequestStarted, + kNavMeshRequestCompleted, + kNavMeshRequestNotEnabled, + kNavMeshRequestError + } ENavMeshRequestStatus; + + typedef boost::function<void (ENavMeshRequestStatus, const LLPathfindingNavMeshStatus &, const LLSD::Binary &)> navmesh_callback_t; + typedef boost::signals2::signal<void (ENavMeshRequestStatus, const LLPathfindingNavMeshStatus &, const LLSD::Binary &)> navmesh_signal_t; + typedef boost::signals2::connection navmesh_slot_t; + + LLPathfindingNavMesh(const LLUUID &pRegionUUID); + virtual ~LLPathfindingNavMesh(); + + navmesh_slot_t registerNavMeshListener(navmesh_callback_t pNavMeshCallback); + + bool hasNavMeshVersion(const LLPathfindingNavMeshStatus &pNavMeshStatus) const; + + void handleNavMeshWaitForRegionLoad(); + void handleNavMeshCheckVersion(); + void handleRefresh(const LLPathfindingNavMeshStatus &pNavMeshStatus); + void handleNavMeshNewVersion(const LLPathfindingNavMeshStatus &pNavMeshStatus); + void handleNavMeshStart(const LLPathfindingNavMeshStatus &pNavMeshStatus); + void handleNavMeshResult(const LLSD &pContent, U32 pNavMeshVersion); + void handleNavMeshNotEnabled(); + void handleNavMeshError(); + void handleNavMeshError(U32 pStatus, const std::string &pReason, const std::string &pURL, U32 pNavMeshVersion); + +protected: + +private: + void setRequestStatus(ENavMeshRequestStatus pNavMeshRequestStatus); + void sendStatus(); + + LLPathfindingNavMeshStatus mNavMeshStatus; + ENavMeshRequestStatus mNavMeshRequestStatus; + navmesh_signal_t mNavMeshSignal; + LLSD::Binary mNavMeshData; +}; + +#endif // LL_LLPATHFINDINGNAVMESH_H diff --git a/indra/newview/llpathfindingnavmeshstatus.cpp b/indra/newview/llpathfindingnavmeshstatus.cpp new file mode 100644 index 0000000000..2eaa6075ca --- /dev/null +++ b/indra/newview/llpathfindingnavmeshstatus.cpp @@ -0,0 +1,145 @@ +/** +* @file llpathfindingnavmeshstatus.cpp +* @brief Implementation of llpathfindingnavmeshstatus +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llpathfindingnavmeshstatus.h" + +#include <string> + +#include "llsd.h" +#include "llstring.h" +#include "lluuid.h" + +#define REGION_FIELD "region_id" +#define STATUS_FIELD "status" +#define VERSION_FIELD "version" + +const std::string LLPathfindingNavMeshStatus::sStatusPending("pending"); +const std::string LLPathfindingNavMeshStatus::sStatusBuilding("building"); +const std::string LLPathfindingNavMeshStatus::sStatusComplete("complete"); +const std::string LLPathfindingNavMeshStatus::sStatusRepending("repending"); + + +//--------------------------------------------------------------------------- +// LLPathfindingNavMeshStatus +//--------------------------------------------------------------------------- + +LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus() + : mIsValid(false), + mRegionUUID(), + mVersion(0U), + mStatus(kComplete) +{ +} + +LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID) + : mIsValid(false), + mRegionUUID(pRegionUUID), + mVersion(0U), + mStatus(kComplete) +{ +} + +LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID, const LLSD &pContent) + : mIsValid(true), + mRegionUUID(pRegionUUID), + mVersion(0U), + mStatus(kComplete) +{ + parseStatus(pContent); +} + +LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLSD &pContent) + : mIsValid(true), + mRegionUUID(), + mVersion(0U), + mStatus(kComplete) +{ + llassert(pContent.has(REGION_FIELD)); + llassert(pContent.get(REGION_FIELD).isUUID()); + mRegionUUID = pContent.get(REGION_FIELD).asUUID(); + + parseStatus(pContent); +} + +LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLPathfindingNavMeshStatus &pOther) + : mIsValid(pOther.mIsValid), + mRegionUUID(pOther.mRegionUUID), + mVersion(pOther.mVersion), + mStatus(pOther.mStatus) +{ +} + +LLPathfindingNavMeshStatus::~LLPathfindingNavMeshStatus() +{ +} + +LLPathfindingNavMeshStatus &LLPathfindingNavMeshStatus::operator =(const LLPathfindingNavMeshStatus &pOther) +{ + mIsValid = pOther.mIsValid; + mRegionUUID = pOther.mRegionUUID; + mVersion = pOther.mVersion; + mStatus = pOther.mStatus; + + return *this; +} + +void LLPathfindingNavMeshStatus::parseStatus(const LLSD &pContent) +{ + llassert(pContent.has(VERSION_FIELD)); + llassert(pContent.get(VERSION_FIELD).isInteger()); + llassert(pContent.get(VERSION_FIELD).asInteger() >= 0); + mVersion = static_cast<U32>(pContent.get(VERSION_FIELD).asInteger()); + + llassert(pContent.has(STATUS_FIELD)); + llassert(pContent.get(STATUS_FIELD).isString()); + std::string status = pContent.get(STATUS_FIELD).asString(); + + if (LLStringUtil::compareStrings(status, sStatusPending) == 0) + { + mStatus = kPending; + } + else if (LLStringUtil::compareStrings(status, sStatusBuilding) == 0) + { + mStatus = kBuilding; + } + else if (LLStringUtil::compareStrings(status, sStatusComplete) == 0) + { + mStatus = kComplete; + } + else if (LLStringUtil::compareStrings(status, sStatusRepending) == 0) + { + mStatus = kRepending; + } + else + { + mStatus = kComplete; + llassert(0); + } +} diff --git a/indra/newview/llpathfindingnavmeshstatus.h b/indra/newview/llpathfindingnavmeshstatus.h new file mode 100644 index 0000000000..74533fa484 --- /dev/null +++ b/indra/newview/llpathfindingnavmeshstatus.h @@ -0,0 +1,77 @@ +/** +* @file llpathfindingnavmeshstatus.h +* @brief Header file for llpathfindingnavmeshstatus +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLPATHFINDINGNAVMESHSTATUS_H +#define LL_LLPATHFINDINGNAVMESHSTATUS_H + +#include <string> + +#include "lluuid.h" + +class LLSD; + +class LLPathfindingNavMeshStatus +{ +public: + typedef enum + { + kPending, + kBuilding, + kComplete, + kRepending + } ENavMeshStatus; + + LLPathfindingNavMeshStatus(); + LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID); + LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID, const LLSD &pContent); + LLPathfindingNavMeshStatus(const LLSD &pContent); + LLPathfindingNavMeshStatus(const LLPathfindingNavMeshStatus &pOther); + virtual ~LLPathfindingNavMeshStatus(); + + LLPathfindingNavMeshStatus &operator =(const LLPathfindingNavMeshStatus &pOther); + + bool isValid() const {return mIsValid;}; + const LLUUID &getRegionUUID() const {return mRegionUUID;}; + U32 getVersion() const {return mVersion;}; + ENavMeshStatus getStatus() const {return mStatus;}; + +protected: + +private: + void parseStatus(const LLSD &pContent); + + bool mIsValid; + LLUUID mRegionUUID; + U32 mVersion; + ENavMeshStatus mStatus; + + static const std::string sStatusPending; + static const std::string sStatusBuilding; + static const std::string sStatusComplete; + static const std::string sStatusRepending; +}; + +#endif // LL_LLPATHFINDINGNAVMESHSTATUS_H diff --git a/indra/newview/llpathfindingnavmeshzone.cpp b/indra/newview/llpathfindingnavmeshzone.cpp new file mode 100644 index 0000000000..e190dbba65 --- /dev/null +++ b/indra/newview/llpathfindingnavmeshzone.cpp @@ -0,0 +1,423 @@ +/** +* @file llpathfindingnavmeshzone.cpp +* @brief Implementation of llpathfindingnavmeshzone +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llpathfindingnavmeshzone.h" + +#include <vector> + +#include <boost/bind.hpp> +#include <boost/function.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/signals2.hpp> + +#include "llagent.h" +#include "llpathfindingmanager.h" +#include "llpathfindingnavmesh.h" +#include "llpathfindingnavmeshstatus.h" +#include "llpathinglib.h" +#include "llsd.h" +#include "lluuid.h" +#include "llviewercontrol.h" +#include "llviewerregion.h" + +#define CENTER_REGION 99 + +//--------------------------------------------------------------------------- +// LLPathfindingNavMeshZone +//--------------------------------------------------------------------------- + +LLPathfindingNavMeshZone::LLPathfindingNavMeshZone() + : mNavMeshLocationPtrs(), + mNavMeshZoneRequestStatus(kNavMeshZoneRequestUnknown), + mNavMeshZoneSignal() +{ +} + +LLPathfindingNavMeshZone::~LLPathfindingNavMeshZone() +{ +} + +LLPathfindingNavMeshZone::navmesh_zone_slot_t LLPathfindingNavMeshZone::registerNavMeshZoneListener(navmesh_zone_callback_t pNavMeshZoneCallback) +{ + return mNavMeshZoneSignal.connect(pNavMeshZoneCallback); +} + +void LLPathfindingNavMeshZone::initialize() +{ + mNavMeshLocationPtrs.clear(); + + NavMeshLocationPtr centerNavMeshPtr(new NavMeshLocation(CENTER_REGION, boost::bind(&LLPathfindingNavMeshZone::handleNavMeshLocation, this))); + mNavMeshLocationPtrs.push_back(centerNavMeshPtr); + + U32 neighborRegionDir = gSavedSettings.getU32("PathfindingRetrieveNeighboringRegion"); + if (neighborRegionDir != CENTER_REGION) + { + NavMeshLocationPtr neighborNavMeshPtr(new NavMeshLocation(neighborRegionDir, boost::bind(&LLPathfindingNavMeshZone::handleNavMeshLocation, this))); + mNavMeshLocationPtrs.push_back(neighborNavMeshPtr); + } +} + +void LLPathfindingNavMeshZone::enable() +{ + for (NavMeshLocationPtrs::iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin(); + navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter) + { + NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter; + navMeshLocationPtr->enable(); + } +} + +void LLPathfindingNavMeshZone::disable() +{ + for (NavMeshLocationPtrs::iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin(); + navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter) + { + NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter; + navMeshLocationPtr->disable(); + } +} + +void LLPathfindingNavMeshZone::refresh() +{ + if (LLPathingLib::getInstance() != NULL) + { + LLPathingLib::getInstance()->cleanupResidual(); + } + + for (NavMeshLocationPtrs::iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin(); + navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter) + { + NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter; + navMeshLocationPtr->refresh(); + } +} + +LLPathfindingNavMeshZone::ENavMeshZoneStatus LLPathfindingNavMeshZone::getNavMeshZoneStatus() const +{ + bool hasPending = false; + bool hasBuilding = false; + bool hasComplete = false; + bool hasRepending = false; + + for (NavMeshLocationPtrs::const_iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin(); + navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter) + { + const NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter; + + switch (navMeshLocationPtr->getNavMeshStatus()) + { + case LLPathfindingNavMeshStatus::kPending : + hasPending = true; + break; + case LLPathfindingNavMeshStatus::kBuilding : + hasBuilding = true; + break; + case LLPathfindingNavMeshStatus::kComplete : + hasComplete = true; + break; + case LLPathfindingNavMeshStatus::kRepending : + hasRepending = true; + break; + default : + hasPending = true; + llassert(0); + break; + } + } + + ENavMeshZoneStatus zoneStatus = kNavMeshZoneComplete; + if (hasRepending || (hasPending && hasBuilding)) + { + zoneStatus = kNavMeshZonePendingAndBuilding; + } + else if (hasComplete) + { + if (hasPending) + { + zoneStatus = kNavMeshZoneSomePending; + } + else if (hasBuilding) + { + zoneStatus = kNavMeshZoneSomeBuilding; + } + else + { + zoneStatus = kNavMeshZoneComplete; + } + } + else if (hasPending) + { + zoneStatus = kNavMeshZonePending; + } + else if (hasBuilding) + { + zoneStatus = kNavMeshZoneBuilding; + } + + return zoneStatus; +} + +void LLPathfindingNavMeshZone::handleNavMeshLocation() +{ + updateStatus(); +} + +void LLPathfindingNavMeshZone::updateStatus() +{ + bool hasRequestUnknown = false; + bool hasRequestWaiting = false; + bool hasRequestChecking = false; + bool hasRequestNeedsUpdate = false; + bool hasRequestStarted = false; + bool hasRequestCompleted = false; + bool hasRequestNotEnabled = false; + bool hasRequestError = false; + + for (NavMeshLocationPtrs::const_iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin(); + navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter) + { + const NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter; + switch (navMeshLocationPtr->getRequestStatus()) + { + case LLPathfindingNavMesh::kNavMeshRequestUnknown : + hasRequestUnknown = true; + break; + case LLPathfindingNavMesh::kNavMeshRequestWaiting : + hasRequestWaiting = true; + break; + case LLPathfindingNavMesh::kNavMeshRequestChecking : + hasRequestChecking = true; + break; + case LLPathfindingNavMesh::kNavMeshRequestNeedsUpdate : + hasRequestNeedsUpdate = true; + break; + case LLPathfindingNavMesh::kNavMeshRequestStarted : + hasRequestStarted = true; + break; + case LLPathfindingNavMesh::kNavMeshRequestCompleted : + hasRequestCompleted = true; + break; + case LLPathfindingNavMesh::kNavMeshRequestNotEnabled : + hasRequestNotEnabled = true; + break; + case LLPathfindingNavMesh::kNavMeshRequestError : + hasRequestError = true; + break; + default : + hasRequestError = true; + llassert(0); + break; + } + } + + ENavMeshZoneRequestStatus zoneRequestStatus = kNavMeshZoneRequestUnknown; + if (hasRequestWaiting) + { + zoneRequestStatus = kNavMeshZoneRequestWaiting; + } + else if (hasRequestNeedsUpdate) + { + zoneRequestStatus = kNavMeshZoneRequestNeedsUpdate; + } + else if (hasRequestChecking) + { + zoneRequestStatus = kNavMeshZoneRequestChecking; + } + else if (hasRequestStarted) + { + zoneRequestStatus = kNavMeshZoneRequestStarted; + } + else if (hasRequestError) + { + zoneRequestStatus = kNavMeshZoneRequestError; + } + else if (hasRequestUnknown) + { + zoneRequestStatus = kNavMeshZoneRequestUnknown; + } + else if (hasRequestCompleted) + { + zoneRequestStatus = kNavMeshZoneRequestCompleted; + } + else if (hasRequestNotEnabled) + { + zoneRequestStatus = kNavMeshZoneRequestNotEnabled; + } + else + { + zoneRequestStatus = kNavMeshZoneRequestError; + llassert(0); + } + + if ((mNavMeshZoneRequestStatus != kNavMeshZoneRequestCompleted) && + (zoneRequestStatus == kNavMeshZoneRequestCompleted)) + { + llassert(LLPathingLib::getInstance() != NULL); + if (LLPathingLib::getInstance() != NULL) + { + LLPathingLib::getInstance()->processNavMeshData(); + } + } + + mNavMeshZoneRequestStatus = zoneRequestStatus; + mNavMeshZoneSignal(mNavMeshZoneRequestStatus); +} + +//--------------------------------------------------------------------------- +// LLPathfindingNavMeshZone::NavMeshLocation +//--------------------------------------------------------------------------- + +LLPathfindingNavMeshZone::NavMeshLocation::NavMeshLocation(S32 pDirection, navmesh_location_callback_t pLocationCallback) + : mDirection(pDirection), + mRegionUUID(), + mHasNavMesh(false), + mNavMeshVersion(0U), + mNavMeshStatus(LLPathfindingNavMeshStatus::kComplete), + mLocationCallback(pLocationCallback), + mRequestStatus(LLPathfindingNavMesh::kNavMeshRequestUnknown), + mNavMeshSlot() +{ +} + +LLPathfindingNavMeshZone::NavMeshLocation::~NavMeshLocation() +{ +} + +void LLPathfindingNavMeshZone::NavMeshLocation::enable() +{ + clear(); + + LLViewerRegion *region = getRegion(); + if (region == NULL) + { + mRegionUUID.setNull(); + } + else + { + mRegionUUID = region->getRegionID(); + mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(region, boost::bind(&LLPathfindingNavMeshZone::NavMeshLocation::handleNavMesh, this, _1, _2, _3)); + } +} + +void LLPathfindingNavMeshZone::NavMeshLocation::refresh() +{ + LLViewerRegion *region = getRegion(); + + if (region == NULL) + { + llassert(mRegionUUID.isNull()); + LLPathfindingNavMeshStatus newNavMeshStatus(mRegionUUID); + LLSD::Binary nullData; + handleNavMesh(LLPathfindingNavMesh::kNavMeshRequestNotEnabled, newNavMeshStatus, nullData); + } + else + { + llassert(mRegionUUID == region->getRegionID()); + LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(region, false); + } +} + +void LLPathfindingNavMeshZone::NavMeshLocation::disable() +{ + clear(); +} + +LLPathfindingNavMesh::ENavMeshRequestStatus LLPathfindingNavMeshZone::NavMeshLocation::getRequestStatus() const +{ + return mRequestStatus; +} + +LLPathfindingNavMeshStatus::ENavMeshStatus LLPathfindingNavMeshZone::NavMeshLocation::getNavMeshStatus() const +{ + return mNavMeshStatus; +} + +void LLPathfindingNavMeshZone::NavMeshLocation::handleNavMesh(LLPathfindingNavMesh::ENavMeshRequestStatus pNavMeshRequestStatus, const LLPathfindingNavMeshStatus &pNavMeshStatus, const LLSD::Binary &pNavMeshData) +{ + llassert(mRegionUUID == pNavMeshStatus.getRegionUUID()); + + if ((pNavMeshRequestStatus == LLPathfindingNavMesh::kNavMeshRequestCompleted) && + (!mHasNavMesh || (mNavMeshVersion != pNavMeshStatus.getVersion()))) + { + llassert(!pNavMeshData.empty()); + mHasNavMesh = true; + mNavMeshVersion = pNavMeshStatus.getVersion(); + llassert(LLPathingLib::getInstance() != NULL); + if (LLPathingLib::getInstance() != NULL) + { + LLPathingLib::getInstance()->extractNavMeshSrcFromLLSD(pNavMeshData, mDirection); + } + } + + mRequestStatus = pNavMeshRequestStatus; + mNavMeshStatus = pNavMeshStatus.getStatus(); + mLocationCallback(); +} + +void LLPathfindingNavMeshZone::NavMeshLocation::clear() +{ + mHasNavMesh = false; + mRequestStatus = LLPathfindingNavMesh::kNavMeshRequestUnknown; + mNavMeshStatus = LLPathfindingNavMeshStatus::kComplete; + if (mNavMeshSlot.connected()) + { + mNavMeshSlot.disconnect(); + } +} + +LLViewerRegion *LLPathfindingNavMeshZone::NavMeshLocation::getRegion() const +{ + LLViewerRegion *region = NULL; + + LLViewerRegion *currentRegion = gAgent.getRegion(); + if (currentRegion != NULL) + { + if (mDirection == CENTER_REGION) + { + region = currentRegion; + } + else + { + //User wants to pull in a neighboring region + std::vector<S32> availableRegions; + currentRegion->getNeighboringRegionsStatus( availableRegions ); + //Is the desired region in the available list + std::vector<S32>::iterator foundElem = std::find(availableRegions.begin(),availableRegions.end(),mDirection); + if ( foundElem != availableRegions.end() ) + { + std::vector<LLViewerRegion*> neighborRegionsPtrs; + currentRegion->getNeighboringRegions( neighborRegionsPtrs ); + region = neighborRegionsPtrs[foundElem - availableRegions.begin()]; + } + } + } + + return region; +} diff --git a/indra/newview/llpathfindingnavmeshzone.h b/indra/newview/llpathfindingnavmeshzone.h new file mode 100644 index 0000000000..baa1cc5979 --- /dev/null +++ b/indra/newview/llpathfindingnavmeshzone.h @@ -0,0 +1,128 @@ +/** +* @file llpathfindingnavmeshzone.h +* @brief Header file for llpathfindingnavmeshzone +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLPATHFINDINGNAVMESHZONE_H +#define LL_LLPATHFINDINGNAVMESHZONE_H + +#include <vector> + +#include <boost/shared_ptr.hpp> +#include <boost/function.hpp> +#include <boost/signals2.hpp> + +#include "llpathfindingnavmesh.h" +#include "llpathfindingnavmeshstatus.h" +#include "llsd.h" +#include "lluuid.h" + +class LLViewerRegion; + +class LLPathfindingNavMeshZone +{ +public: + typedef enum { + kNavMeshZoneRequestUnknown, + kNavMeshZoneRequestWaiting, + kNavMeshZoneRequestChecking, + kNavMeshZoneRequestNeedsUpdate, + kNavMeshZoneRequestStarted, + kNavMeshZoneRequestCompleted, + kNavMeshZoneRequestNotEnabled, + kNavMeshZoneRequestError + } ENavMeshZoneRequestStatus; + + typedef enum { + kNavMeshZonePending, + kNavMeshZoneBuilding, + kNavMeshZoneSomePending, + kNavMeshZoneSomeBuilding, + kNavMeshZonePendingAndBuilding, + kNavMeshZoneComplete + } ENavMeshZoneStatus; + + typedef boost::function<void (ENavMeshZoneRequestStatus)> navmesh_zone_callback_t; + typedef boost::signals2::signal<void (ENavMeshZoneRequestStatus)> navmesh_zone_signal_t; + typedef boost::signals2::connection navmesh_zone_slot_t; + + LLPathfindingNavMeshZone(); + virtual ~LLPathfindingNavMeshZone(); + + navmesh_zone_slot_t registerNavMeshZoneListener(navmesh_zone_callback_t pNavMeshZoneCallback); + void initialize(); + + void enable(); + void disable(); + void refresh(); + + ENavMeshZoneStatus getNavMeshZoneStatus() const; + +protected: + +private: + typedef boost::function<void (void)> navmesh_location_callback_t; + class NavMeshLocation + { + public: + NavMeshLocation(S32 pDirection, navmesh_location_callback_t pLocationCallback); + virtual ~NavMeshLocation(); + + void enable(); + void refresh(); + void disable(); + + LLPathfindingNavMesh::ENavMeshRequestStatus getRequestStatus() const; + LLPathfindingNavMeshStatus::ENavMeshStatus getNavMeshStatus() const; + + protected: + + private: + void handleNavMesh(LLPathfindingNavMesh::ENavMeshRequestStatus pNavMeshRequestStatus, const LLPathfindingNavMeshStatus &pNavMeshStatus, const LLSD::Binary &pNavMeshData); + + void clear(); + LLViewerRegion *getRegion() const; + + S32 mDirection; + LLUUID mRegionUUID; + bool mHasNavMesh; + U32 mNavMeshVersion; + LLPathfindingNavMeshStatus::ENavMeshStatus mNavMeshStatus; + navmesh_location_callback_t mLocationCallback; + LLPathfindingNavMesh::ENavMeshRequestStatus mRequestStatus; + LLPathfindingNavMesh::navmesh_slot_t mNavMeshSlot; + }; + + typedef boost::shared_ptr<NavMeshLocation> NavMeshLocationPtr; + typedef std::vector<NavMeshLocationPtr> NavMeshLocationPtrs; + + void handleNavMeshLocation(); + void updateStatus(); + + NavMeshLocationPtrs mNavMeshLocationPtrs; + ENavMeshZoneRequestStatus mNavMeshZoneRequestStatus; + navmesh_zone_signal_t mNavMeshZoneSignal; +}; + +#endif // LL_LLPATHFINDINGNAVMESHZONE_H diff --git a/indra/newview/llpathfindingobject.cpp b/indra/newview/llpathfindingobject.cpp new file mode 100644 index 0000000000..900763eae4 --- /dev/null +++ b/indra/newview/llpathfindingobject.cpp @@ -0,0 +1,200 @@ +/** +* @file llpathfindingobject.cpp +* @brief Implementation of llpathfindingobject +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llpathfindingobject.h" + +#include <string> + +#include "llavatarname.h" +#include "llavatarnamecache.h" +#include "llsd.h" +#include "lluuid.h" +#include "v3math.h" + +#define PATHFINDING_OBJECT_NAME_FIELD "name" +#define PATHFINDING_OBJECT_DESCRIPTION_FIELD "description" +#define PATHFINDING_OBJECT_OWNER_FIELD "owner" +#define PATHFINDING_OBJECT_POSITION_FIELD "position" +#define PATHFINDING_OBJECT_IS_GROUP_OWNED_FIELD "owner_is_group" + +//--------------------------------------------------------------------------- +// LLPathfindingObject +//--------------------------------------------------------------------------- + +LLPathfindingObject::LLPathfindingObject() + : mUUID(), + mName(), + mDescription(), + mOwnerUUID(), + mHasOwnerName(false), + mOwnerName(), + mAvatarNameCacheConnection(), + mIsGroupOwned(false), + mLocation(), + mOwnerNameSignal() +{ +} + +LLPathfindingObject::LLPathfindingObject(const std::string &pUUID, const LLSD &pObjectData) + : mUUID(pUUID), + mName(), + mDescription(), + mOwnerUUID(), + mHasOwnerName(false), + mOwnerName(), + mAvatarNameCacheConnection(), + mIsGroupOwned(false), + mLocation(), + mOwnerNameSignal() +{ + parseObjectData(pObjectData); +} + +LLPathfindingObject::LLPathfindingObject(const LLPathfindingObject& pOther) + : mUUID(pOther.mUUID), + mName(pOther.mName), + mDescription(pOther.mDescription), + mOwnerUUID(pOther.mOwnerUUID), + mHasOwnerName(false), + mOwnerName(), + mAvatarNameCacheConnection(), + mIsGroupOwned(pOther.mIsGroupOwned), + mLocation(pOther.mLocation), + mOwnerNameSignal() +{ + fetchOwnerName(); +} + +LLPathfindingObject::~LLPathfindingObject() +{ + disconnectAvatarNameCacheConnection(); +} + +LLPathfindingObject &LLPathfindingObject::operator =(const LLPathfindingObject& pOther) +{ + mUUID = pOther.mUUID; + mName = pOther.mName; + mDescription = pOther.mDescription; + mOwnerUUID = pOther.mOwnerUUID; + fetchOwnerName(); + mIsGroupOwned = pOther.mIsGroupOwned; + mLocation = pOther.mLocation; + + return *this; +} + +std::string LLPathfindingObject::getOwnerName() const +{ + std::string ownerName; + + if (hasOwner()) + { + ownerName = mOwnerName.getCompleteName(); + } + + return ownerName; +} + +LLPathfindingObject::name_connection_t LLPathfindingObject::registerOwnerNameListener(name_callback_t pOwnerNameCallback) +{ + llassert(hasOwner()); + + name_connection_t connection; + if (hasOwnerName()) + { + pOwnerNameCallback(this); + } + else + { + connection = mOwnerNameSignal.connect(pOwnerNameCallback); + } + + return connection; +} + +void LLPathfindingObject::parseObjectData(const LLSD &pObjectData) +{ + llassert(pObjectData.has(PATHFINDING_OBJECT_NAME_FIELD)); + llassert(pObjectData.get(PATHFINDING_OBJECT_NAME_FIELD).isString()); + mName = pObjectData.get(PATHFINDING_OBJECT_NAME_FIELD).asString(); + + llassert(pObjectData.has(PATHFINDING_OBJECT_DESCRIPTION_FIELD)); + llassert(pObjectData.get(PATHFINDING_OBJECT_DESCRIPTION_FIELD).isString()); + mDescription = pObjectData.get(PATHFINDING_OBJECT_DESCRIPTION_FIELD).asString(); + + llassert(pObjectData.has(PATHFINDING_OBJECT_OWNER_FIELD)); + llassert(pObjectData.get(PATHFINDING_OBJECT_OWNER_FIELD).isUUID()); + mOwnerUUID = pObjectData.get(PATHFINDING_OBJECT_OWNER_FIELD).asUUID(); + fetchOwnerName(); + + if (pObjectData.has(PATHFINDING_OBJECT_IS_GROUP_OWNED_FIELD)) + { + llassert(pObjectData.get(PATHFINDING_OBJECT_IS_GROUP_OWNED_FIELD).isBoolean()); + mIsGroupOwned = pObjectData.get(PATHFINDING_OBJECT_IS_GROUP_OWNED_FIELD).asBoolean(); + } + + llassert(pObjectData.has(PATHFINDING_OBJECT_POSITION_FIELD)); + llassert(pObjectData.get(PATHFINDING_OBJECT_POSITION_FIELD).isArray()); + mLocation.setValue(pObjectData.get(PATHFINDING_OBJECT_POSITION_FIELD)); +} + +void LLPathfindingObject::fetchOwnerName() +{ + mHasOwnerName = false; + if (hasOwner()) + { + mHasOwnerName = LLAvatarNameCache::get(mOwnerUUID, &mOwnerName); + if (!mHasOwnerName) + { + disconnectAvatarNameCacheConnection(); + mAvatarNameCacheConnection = LLAvatarNameCache::get(mOwnerUUID, boost::bind(&LLPathfindingObject::handleAvatarNameFetch, this, _1, _2)); + } + } +} + +void LLPathfindingObject::handleAvatarNameFetch(const LLUUID &pOwnerUUID, const LLAvatarName &pAvatarName) +{ + llassert(mOwnerUUID == pOwnerUUID); + + mOwnerName = pAvatarName; + mHasOwnerName = true; + + disconnectAvatarNameCacheConnection(); + + mOwnerNameSignal(this); +} + +void LLPathfindingObject::disconnectAvatarNameCacheConnection() +{ + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } +} diff --git a/indra/newview/llpathfindingobject.h b/indra/newview/llpathfindingobject.h new file mode 100644 index 0000000000..b8d3ca2364 --- /dev/null +++ b/indra/newview/llpathfindingobject.h @@ -0,0 +1,92 @@ +/** +* @file llpathfindingobject.h +* @brief Header file for llpathfindingobject +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLPATHFINDINGOBJECT_H +#define LL_LLPATHFINDINGOBJECT_H + +#include <string> + +#include <boost/shared_ptr.hpp> +#include <boost/function.hpp> +#include <boost/signals2.hpp> + +#include "llavatarname.h" +#include "llavatarnamecache.h" +#include "lluuid.h" +#include "v3math.h" + +class LLPathfindingObject; +class LLSD; + +typedef boost::shared_ptr<LLPathfindingObject> LLPathfindingObjectPtr; + +class LLPathfindingObject +{ +public: + LLPathfindingObject(); + LLPathfindingObject(const std::string &pUUID, const LLSD &pObjectData); + LLPathfindingObject(const LLPathfindingObject& pOther); + virtual ~LLPathfindingObject(); + + LLPathfindingObject& operator =(const LLPathfindingObject& pOther); + + inline const LLUUID& getUUID() const {return mUUID;}; + inline const std::string& getName() const {return mName;}; + inline const std::string& getDescription() const {return mDescription;}; + inline BOOL hasOwner() const {return mOwnerUUID.notNull();}; + inline bool hasOwnerName() const {return mHasOwnerName;}; + std::string getOwnerName() const; + inline BOOL isGroupOwned() const {return mIsGroupOwned;}; + inline const LLVector3& getLocation() const {return mLocation;}; + + typedef boost::function<void (const LLPathfindingObject *)> name_callback_t; + typedef boost::signals2::signal<void (const LLPathfindingObject *)> name_signal_t; + typedef boost::signals2::connection name_connection_t; + + name_connection_t registerOwnerNameListener(name_callback_t pOwnerNameCallback); + +protected: + +private: + void parseObjectData(const LLSD &pObjectData); + + void fetchOwnerName(); + void handleAvatarNameFetch(const LLUUID &pOwnerUUID, const LLAvatarName &pAvatarName); + void disconnectAvatarNameCacheConnection(); + + LLUUID mUUID; + std::string mName; + std::string mDescription; + LLUUID mOwnerUUID; + bool mHasOwnerName; + LLAvatarName mOwnerName; + LLAvatarNameCache::callback_connection_t mAvatarNameCacheConnection; + BOOL mIsGroupOwned; + LLVector3 mLocation; + name_signal_t mOwnerNameSignal; +}; + +#endif // LL_LLPATHFINDINGOBJECT_H diff --git a/indra/newview/llpathfindingobjectlist.cpp b/indra/newview/llpathfindingobjectlist.cpp new file mode 100644 index 0000000000..f1ecb45fc0 --- /dev/null +++ b/indra/newview/llpathfindingobjectlist.cpp @@ -0,0 +1,122 @@ +/** +* @file llpathfindingobjectlist.cpp +* @brief Implementation of llpathfindingobjectlist +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llpathfindingobjectlist.h" + +#include <string> +#include <map> + +#include "llpathfindingobject.h" + +//--------------------------------------------------------------------------- +// LLPathfindingObjectList +//--------------------------------------------------------------------------- + +LLPathfindingObjectList::LLPathfindingObjectList() + : mObjectMap() +{ +} + +LLPathfindingObjectList::~LLPathfindingObjectList() +{ + clear(); +} + +bool LLPathfindingObjectList::isEmpty() const +{ + return mObjectMap.empty(); +} + +void LLPathfindingObjectList::clear() +{ + for (LLPathfindingObjectMap::iterator objectIter = mObjectMap.begin(); objectIter != mObjectMap.end(); ++objectIter) + { + objectIter->second.reset(); + } + mObjectMap.clear(); +} + +void LLPathfindingObjectList::update(LLPathfindingObjectPtr pUpdateObjectPtr) +{ + if (pUpdateObjectPtr != NULL) + { + std::string updateObjectId = pUpdateObjectPtr->getUUID().asString(); + + LLPathfindingObjectMap::iterator foundObjectIter = mObjectMap.find(updateObjectId); + if (foundObjectIter == mObjectMap.end()) + { + mObjectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(updateObjectId, pUpdateObjectPtr)); + } + else + { + foundObjectIter->second = pUpdateObjectPtr; + } + } +} + +void LLPathfindingObjectList::update(LLPathfindingObjectListPtr pUpdateObjectListPtr) +{ + if ((pUpdateObjectListPtr != NULL) && !pUpdateObjectListPtr->isEmpty()) + { + for (LLPathfindingObjectMap::const_iterator updateObjectIter = pUpdateObjectListPtr->begin(); + updateObjectIter != pUpdateObjectListPtr->end(); ++updateObjectIter) + { + const LLPathfindingObjectPtr updateObjectPtr = updateObjectIter->second; + update(updateObjectPtr); + } + } +} + +LLPathfindingObjectPtr LLPathfindingObjectList::find(const std::string &pObjectId) const +{ + LLPathfindingObjectPtr objectPtr; + + LLPathfindingObjectMap::const_iterator objectIter = mObjectMap.find(pObjectId); + if (objectIter != mObjectMap.end()) + { + objectPtr = objectIter->second; + } + + return objectPtr; +} + +LLPathfindingObjectList::const_iterator LLPathfindingObjectList::begin() const +{ + return mObjectMap.begin(); +} + +LLPathfindingObjectList::const_iterator LLPathfindingObjectList::end() const +{ + return mObjectMap.end(); +} + +LLPathfindingObjectMap &LLPathfindingObjectList::getObjectMap() +{ + return mObjectMap; +} diff --git a/indra/newview/llpathfindingobjectlist.h b/indra/newview/llpathfindingobjectlist.h new file mode 100644 index 0000000000..61580582d3 --- /dev/null +++ b/indra/newview/llpathfindingobjectlist.h @@ -0,0 +1,68 @@ +/** +* @file llpathfindingobjectlist.h +* @brief Header file for llpathfindingobjectlist +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLPATHFINDINGOBJECTLIST_H +#define LL_LLPATHFINDINGOBJECTLIST_H + +#include <string> +#include <map> + +#include <boost/shared_ptr.hpp> + +#include "llpathfindingobject.h" + +class LLPathfindingObjectList; + +typedef boost::shared_ptr<LLPathfindingObjectList> LLPathfindingObjectListPtr; +typedef std::map<std::string, LLPathfindingObjectPtr> LLPathfindingObjectMap; + +class LLPathfindingObjectList +{ +public: + LLPathfindingObjectList(); + virtual ~LLPathfindingObjectList(); + + bool isEmpty() const; + + void clear(); + + void update(LLPathfindingObjectPtr pUpdateObjectPtr); + void update(LLPathfindingObjectListPtr pUpdateObjectListPtr); + + LLPathfindingObjectPtr find(const std::string &pObjectId) const; + + typedef LLPathfindingObjectMap::const_iterator const_iterator; + const_iterator begin() const; + const_iterator end() const; + +protected: + LLPathfindingObjectMap &getObjectMap(); + +private: + LLPathfindingObjectMap mObjectMap; +}; + +#endif // LL_LLPATHFINDINGOBJECTLIST_H diff --git a/indra/newview/llpathfindingpathtool.cpp b/indra/newview/llpathfindingpathtool.cpp new file mode 100644 index 0000000000..006755e20b --- /dev/null +++ b/indra/newview/llpathfindingpathtool.cpp @@ -0,0 +1,467 @@ +/** +* @file llpathfindingpathtool.cpp +* @brief Implementation of llpathfindingpathtool +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llpathfindingpathtool.h" + +#include <boost/function.hpp> +#include <boost/signals2.hpp> + +#include "llagent.h" +#include "llpathfindingmanager.h" +#include "llpathinglib.h" +#include "llsingleton.h" +#include "lltool.h" +#include "llviewercamera.h" +#include "llviewerregion.h" +#include "llviewerwindow.h" + +#define PATH_TOOL_NAME "PathfindingPathTool" + +LLPathfindingPathTool::LLPathfindingPathTool() + : LLTool(PATH_TOOL_NAME), + LLSingleton<LLPathfindingPathTool>(), + mFinalPathData(), + mTempPathData(), + mPathResult(LLPathingLib::LLPL_NO_PATH), + mCharacterType(kCharacterTypeNone), + mPathEventSignal(), + mIsLeftMouseButtonHeld(false), + mIsMiddleMouseButtonHeld(false), + mIsRightMouseButtonHeld(false) +{ + setCharacterWidth(1.0f); + setCharacterType(mCharacterType); +} + +LLPathfindingPathTool::~LLPathfindingPathTool() +{ +} + +BOOL LLPathfindingPathTool::handleMouseDown(S32 pX, S32 pY, MASK pMask) +{ + BOOL returnVal = FALSE; + + if (!mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld) + { + if (isAnyPathToolModKeys(pMask)) + { + gViewerWindow->setCursor(isPointAModKeys(pMask) + ? UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD + : UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD); + computeFinalPoints(pX, pY, pMask); + mIsLeftMouseButtonHeld = true; + setMouseCapture(TRUE); + returnVal = TRUE; + } + else if (!isCameraModKeys(pMask)) + { + gViewerWindow->setCursor(UI_CURSOR_TOOLNO); + mIsLeftMouseButtonHeld = true; + setMouseCapture(TRUE); + returnVal = TRUE; + } + } + mIsLeftMouseButtonHeld = true; + + return returnVal; +} + +BOOL LLPathfindingPathTool::handleMouseUp(S32 pX, S32 pY, MASK pMask) +{ + BOOL returnVal = FALSE; + + if (mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld) + { + computeFinalPoints(pX, pY, pMask); + setMouseCapture(FALSE); + returnVal = TRUE; + } + mIsLeftMouseButtonHeld = false; + + return returnVal; +} + +BOOL LLPathfindingPathTool::handleMiddleMouseDown(S32 pX, S32 pY, MASK pMask) +{ + setMouseCapture(TRUE); + mIsMiddleMouseButtonHeld = true; + gViewerWindow->setCursor(UI_CURSOR_TOOLNO); + + return TRUE; +} + +BOOL LLPathfindingPathTool::handleMiddleMouseUp(S32 pX, S32 pY, MASK pMask) +{ + if (!mIsLeftMouseButtonHeld && mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld) + { + setMouseCapture(FALSE); + } + mIsMiddleMouseButtonHeld = false; + + return TRUE; +} + +BOOL LLPathfindingPathTool::handleRightMouseDown(S32 pX, S32 pY, MASK pMask) +{ + setMouseCapture(TRUE); + mIsRightMouseButtonHeld = true; + gViewerWindow->setCursor(UI_CURSOR_TOOLNO); + + return TRUE; +} + +BOOL LLPathfindingPathTool::handleRightMouseUp(S32 pX, S32 pY, MASK pMask) +{ + if (!mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && mIsRightMouseButtonHeld) + { + setMouseCapture(FALSE); + } + mIsRightMouseButtonHeld = false; + + return TRUE; +} + +BOOL LLPathfindingPathTool::handleDoubleClick(S32 pX, S32 pY, MASK pMask) +{ + return TRUE; +} + +BOOL LLPathfindingPathTool::handleHover(S32 pX, S32 pY, MASK pMask) +{ + BOOL returnVal = FALSE; + + if (!mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld && !isAnyPathToolModKeys(pMask)) + { + gViewerWindow->setCursor(UI_CURSOR_TOOLPATHFINDING); + } + + if (!mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld && isAnyPathToolModKeys(pMask)) + { + gViewerWindow->setCursor(isPointAModKeys(pMask) + ? (mIsLeftMouseButtonHeld ? UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD : UI_CURSOR_TOOLPATHFINDING_PATH_START) + : (mIsLeftMouseButtonHeld ? UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD : UI_CURSOR_TOOLPATHFINDING_PATH_END)); + computeTempPoints(pX, pY, pMask); + returnVal = TRUE; + } + else + { + clearTemp(); + computeFinalPath(); + } + + return returnVal; +} + +BOOL LLPathfindingPathTool::handleKey(KEY pKey, MASK pMask) +{ + // Eat the escape key or else the camera tool will pick up and reset to default view. This, + // in turn, will cause some other methods to get called. And one of those methods will reset + // the current toolset back to the basic toolset. This means that the pathfinding path toolset + // will no longer be active, but typically with pathfinding path elements on screen. + return (pKey == KEY_ESCAPE); +} + +LLPathfindingPathTool::EPathStatus LLPathfindingPathTool::getPathStatus() const +{ + EPathStatus status = kPathStatusUnknown; + + if (LLPathingLib::getInstance() == NULL) + { + status = kPathStatusNotImplemented; + } + else if ((gAgent.getRegion() != NULL) && !gAgent.getRegion()->capabilitiesReceived()) + { + status = kPathStatusUnknown; + } + else if (!LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion()) + { + status = kPathStatusNotEnabled; + } + else if (!hasFinalA() && !hasFinalB()) + { + status = kPathStatusChooseStartAndEndPoints; + } + else if (!hasFinalA()) + { + status = kPathStatusChooseStartPoint; + } + else if (!hasFinalB()) + { + status = kPathStatusChooseEndPoint; + } + else if (mPathResult == LLPathingLib::LLPL_PATH_GENERATED_OK) + { + status = kPathStatusHasValidPath; + } + else if (mPathResult == LLPathingLib::LLPL_NO_PATH) + { + status = kPathStatusHasInvalidPath; + } + else + { + status = kPathStatusError; + } + + return status; +} + +F32 LLPathfindingPathTool::getCharacterWidth() const +{ + return mFinalPathData.mCharacterWidth; +} + +void LLPathfindingPathTool::setCharacterWidth(F32 pCharacterWidth) +{ + mFinalPathData.mCharacterWidth = pCharacterWidth; + mTempPathData.mCharacterWidth = pCharacterWidth; + computeFinalPath(); +} + +LLPathfindingPathTool::ECharacterType LLPathfindingPathTool::getCharacterType() const +{ + return mCharacterType; +} + +void LLPathfindingPathTool::setCharacterType(ECharacterType pCharacterType) +{ + mCharacterType = pCharacterType; + + LLPathingLib::LLPLCharacterType characterType; + switch (pCharacterType) + { + case kCharacterTypeNone : + characterType = LLPathingLib::LLPL_CHARACTER_TYPE_NONE; + break; + case kCharacterTypeA : + characterType = LLPathingLib::LLPL_CHARACTER_TYPE_A; + break; + case kCharacterTypeB : + characterType = LLPathingLib::LLPL_CHARACTER_TYPE_B; + break; + case kCharacterTypeC : + characterType = LLPathingLib::LLPL_CHARACTER_TYPE_C; + break; + case kCharacterTypeD : + characterType = LLPathingLib::LLPL_CHARACTER_TYPE_D; + break; + default : + characterType = LLPathingLib::LLPL_CHARACTER_TYPE_NONE; + llassert(0); + break; + } + mFinalPathData.mCharacterType = characterType; + mTempPathData.mCharacterType = characterType; + computeFinalPath(); +} + +bool LLPathfindingPathTool::isRenderPath() const +{ + return (hasFinalA() || hasFinalB() || hasTempA() || hasTempB()); +} + +void LLPathfindingPathTool::clearPath() +{ + clearFinal(); + clearTemp(); + computeFinalPath(); +} + +LLPathfindingPathTool::path_event_slot_t LLPathfindingPathTool::registerPathEventListener(path_event_callback_t pPathEventCallback) +{ + return mPathEventSignal.connect(pPathEventCallback); +} + +bool LLPathfindingPathTool::isAnyPathToolModKeys(MASK pMask) const +{ + return ((pMask & (MASK_CONTROL|MASK_SHIFT)) != 0); +} + +bool LLPathfindingPathTool::isPointAModKeys(MASK pMask) const +{ + return ((pMask & MASK_CONTROL) != 0); +} + +bool LLPathfindingPathTool::isPointBModKeys(MASK pMask) const +{ + return ((pMask & MASK_SHIFT) != 0); +} + +bool LLPathfindingPathTool::isCameraModKeys(MASK pMask) const +{ + return ((pMask & MASK_ALT) != 0); +} + +void LLPathfindingPathTool::getRayPoints(S32 pX, S32 pY, LLVector3 &pRayStart, LLVector3 &pRayEnd) const +{ + LLVector3 dv = gViewerWindow->mouseDirectionGlobal(pX, pY); + LLVector3 mousePos = LLViewerCamera::getInstance()->getOrigin(); + pRayStart = mousePos; + pRayEnd = mousePos + dv * 150; +} + +void LLPathfindingPathTool::computeFinalPoints(S32 pX, S32 pY, MASK pMask) +{ + LLVector3 rayStart, rayEnd; + getRayPoints(pX, pY, rayStart, rayEnd); + + if (isPointAModKeys(pMask)) + { + setFinalA(rayStart, rayEnd); + } + else if (isPointBModKeys(pMask)) + { + setFinalB(rayStart, rayEnd); + } + computeFinalPath(); +} + +void LLPathfindingPathTool::computeTempPoints(S32 pX, S32 pY, MASK pMask) +{ + LLVector3 rayStart, rayEnd; + getRayPoints(pX, pY, rayStart, rayEnd); + + if (isPointAModKeys(pMask)) + { + setTempA(rayStart, rayEnd); + if (hasFinalB()) + { + setTempB(getFinalBStart(), getFinalBEnd()); + } + } + else if (isPointBModKeys(pMask)) + { + if (hasFinalA()) + { + setTempA(getFinalAStart(), getFinalAEnd()); + } + setTempB(rayStart, rayEnd); + } + computeTempPath(); +} + +void LLPathfindingPathTool::setFinalA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint) +{ + mFinalPathData.mStartPointA = pStartPoint; + mFinalPathData.mEndPointA = pEndPoint; + mFinalPathData.mHasPointA = true; +} + +bool LLPathfindingPathTool::hasFinalA() const +{ + return mFinalPathData.mHasPointA; +} + +const LLVector3 &LLPathfindingPathTool::getFinalAStart() const +{ + return mFinalPathData.mStartPointA; +} + +const LLVector3 &LLPathfindingPathTool::getFinalAEnd() const +{ + return mFinalPathData.mEndPointA; +} + +void LLPathfindingPathTool::setTempA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint) +{ + mTempPathData.mStartPointA = pStartPoint; + mTempPathData.mEndPointA = pEndPoint; + mTempPathData.mHasPointA = true; +} + +bool LLPathfindingPathTool::hasTempA() const +{ + return mTempPathData.mHasPointA; +} + +void LLPathfindingPathTool::setFinalB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint) +{ + mFinalPathData.mStartPointB = pStartPoint; + mFinalPathData.mEndPointB = pEndPoint; + mFinalPathData.mHasPointB = true; +} + +bool LLPathfindingPathTool::hasFinalB() const +{ + return mFinalPathData.mHasPointB; +} + +const LLVector3 &LLPathfindingPathTool::getFinalBStart() const +{ + return mFinalPathData.mStartPointB; +} + +const LLVector3 &LLPathfindingPathTool::getFinalBEnd() const +{ + return mFinalPathData.mEndPointB; +} + +void LLPathfindingPathTool::setTempB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint) +{ + mTempPathData.mStartPointB = pStartPoint; + mTempPathData.mEndPointB = pEndPoint; + mTempPathData.mHasPointB = true; +} + +bool LLPathfindingPathTool::hasTempB() const +{ + return mTempPathData.mHasPointB; +} + +void LLPathfindingPathTool::clearFinal() +{ + mFinalPathData.mHasPointA = false; + mFinalPathData.mHasPointB = false; +} + +void LLPathfindingPathTool::clearTemp() +{ + mTempPathData.mHasPointA = false; + mTempPathData.mHasPointB = false; +} + +void LLPathfindingPathTool::computeFinalPath() +{ + mPathResult = LLPathingLib::LLPL_NO_PATH; + if (LLPathingLib::getInstance() != NULL) + { + mPathResult = LLPathingLib::getInstance()->generatePath(mFinalPathData); + } + mPathEventSignal(); +} + +void LLPathfindingPathTool::computeTempPath() +{ + mPathResult = LLPathingLib::LLPL_NO_PATH; + if (LLPathingLib::getInstance() != NULL) + { + mPathResult = LLPathingLib::getInstance()->generatePath(mTempPathData); + } + mPathEventSignal(); +} diff --git a/indra/newview/llpathfindingpathtool.h b/indra/newview/llpathfindingpathtool.h new file mode 100644 index 0000000000..97284265f1 --- /dev/null +++ b/indra/newview/llpathfindingpathtool.h @@ -0,0 +1,138 @@ +/** +* @file llpathfindingpathtool.h +* @brief Header file for llpathfindingpathtool +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLPATHFINDINGPATHTOOL_H +#define LL_LLPATHFINDINGPATHTOOL_H + +#include <boost/function.hpp> +#include <boost/signals2.hpp> + +#include "llpathinglib.h" +#include "llsingleton.h" +#include "lltool.h" + +class LLPathfindingPathTool : public LLTool, public LLSingleton<LLPathfindingPathTool> +{ +public: + typedef enum + { + kPathStatusUnknown, + kPathStatusChooseStartAndEndPoints, + kPathStatusChooseStartPoint, + kPathStatusChooseEndPoint, + kPathStatusHasValidPath, + kPathStatusHasInvalidPath, + kPathStatusNotEnabled, + kPathStatusNotImplemented, + kPathStatusError + } EPathStatus; + + typedef enum + { + kCharacterTypeNone, + kCharacterTypeA, + kCharacterTypeB, + kCharacterTypeC, + kCharacterTypeD + } ECharacterType; + + LLPathfindingPathTool(); + virtual ~LLPathfindingPathTool(); + + typedef boost::function<void (void)> path_event_callback_t; + typedef boost::signals2::signal<void (void)> path_event_signal_t; + typedef boost::signals2::connection path_event_slot_t; + + virtual BOOL handleMouseDown(S32 pX, S32 pY, MASK pMask); + virtual BOOL handleMouseUp(S32 pX, S32 pY, MASK pMask); + virtual BOOL handleMiddleMouseDown(S32 pX, S32 pY, MASK pMask); + virtual BOOL handleMiddleMouseUp(S32 pX, S32 pY, MASK pMask); + virtual BOOL handleRightMouseDown(S32 pX, S32 pY, MASK pMask); + virtual BOOL handleRightMouseUp(S32 pX, S32 pY, MASK pMask); + virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + + virtual BOOL handleHover(S32 pX, S32 pY, MASK pMask); + + virtual BOOL handleKey(KEY pKey, MASK pMask); + + EPathStatus getPathStatus() const; + + F32 getCharacterWidth() const; + void setCharacterWidth(F32 pCharacterWidth); + + ECharacterType getCharacterType() const; + void setCharacterType(ECharacterType pCharacterType); + + bool isRenderPath() const; + void clearPath(); + + path_event_slot_t registerPathEventListener(path_event_callback_t pPathEventCallback); + +protected: + +private: + bool isAnyPathToolModKeys(MASK pMask) const; + bool isPointAModKeys(MASK pMask) const; + bool isPointBModKeys(MASK pMask) const; + bool isCameraModKeys(MASK pMask) const; + + void getRayPoints(S32 pX, S32 pY, LLVector3 &pRayStart, LLVector3 &pRayEnd) const; + void computeFinalPoints(S32 pX, S32 pY, MASK pMask); + void computeTempPoints(S32 pX, S32 pY, MASK pMask); + + void setFinalA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint); + bool hasFinalA() const; + const LLVector3 &getFinalAStart() const; + const LLVector3 &getFinalAEnd() const; + + void setTempA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint); + bool hasTempA() const; + + void setFinalB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint); + bool hasFinalB() const; + const LLVector3 &getFinalBStart() const; + const LLVector3 &getFinalBEnd() const; + + void setTempB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint); + bool hasTempB() const; + + void clearFinal(); + void clearTemp(); + + void computeFinalPath(); + void computeTempPath(); + + LLPathingLib::PathingPacket mFinalPathData; + LLPathingLib::PathingPacket mTempPathData; + LLPathingLib::LLPLResult mPathResult; + ECharacterType mCharacterType; + path_event_signal_t mPathEventSignal; + bool mIsLeftMouseButtonHeld; + bool mIsMiddleMouseButtonHeld; + bool mIsRightMouseButtonHeld; +}; + +#endif // LL_LLPATHFINDINGPATHTOOL_H diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp new file mode 100644 index 0000000000..11c12e6c10 --- /dev/null +++ b/indra/newview/llpersistentnotificationstorage.cpp @@ -0,0 +1,145 @@ +/** +* @file llpersistentnotificationstorage.cpp +* @brief Implementation of llpersistentnotificationstorage +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llpersistentnotificationstorage.h" + +#include "llchannelmanager.h" +#include "llnotificationstorage.h" +#include "llscreenchannel.h" +#include "llscriptfloater.h" +#include "llviewermessage.h" + +LLPersistentNotificationStorage::LLPersistentNotificationStorage() + : LLSingleton<LLPersistentNotificationStorage>() + , LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml")) +{ +} + +LLPersistentNotificationStorage::~LLPersistentNotificationStorage() +{ +} + +static LLFastTimer::DeclareTimer FTM_SAVE_NOTIFICATIONS("Save Notifications"); + +void LLPersistentNotificationStorage::saveNotifications() +{ + LLFastTimer _(FTM_SAVE_NOTIFICATIONS); + + boost::intrusive_ptr<LLPersistentNotificationChannel> history_channel = boost::dynamic_pointer_cast<LLPersistentNotificationChannel>(LLNotifications::instance().getChannel("Persistent")); + if (!history_channel) + { + return; + } + + LLSD output = LLSD::emptyMap(); + LLSD& data = output["data"]; + + for ( std::vector<LLNotificationPtr>::iterator it = history_channel->beginHistory(), end_it = history_channel->endHistory(); + it != end_it; + ++it) + { + LLNotificationPtr notification = *it; + + // After a notification was placed in Persist channel, it can become + // responded, expired or canceled - in this case we are should not save it + if(notification->isRespondedTo() || notification->isCancelled() + || notification->isExpired()) + { + continue; + } + + data.append(notification->asLLSD(true)); + } + + writeNotifications(output); +} + +static LLFastTimer::DeclareTimer FTM_LOAD_NOTIFICATIONS("Load Notifications"); + +void LLPersistentNotificationStorage::loadNotifications() +{ + LLFastTimer _(FTM_LOAD_NOTIFICATIONS); + + LLNotifications::instance().getChannel("Persistent")-> + connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1)); + + LLSD input; + if (!readNotifications(input) ||input.isUndefined()) + { + return; + } + + LLSD& data = input["data"]; + if (data.isUndefined()) + { + return; + } + + using namespace LLNotificationsUI; + LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()-> + findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + + LLNotifications& instance = LLNotifications::instance(); + + for (LLSD::array_const_iterator notification_it = data.beginArray(); + notification_it != data.endArray(); + ++notification_it) + { + LLSD notification_params = *notification_it; + LLNotificationPtr notification(new LLNotification(notification_params)); + + LLNotificationResponderPtr responder(createResponder(notification_params["name"], notification_params["responder"])); + notification->setResponseFunctor(responder); + + instance.add(notification); + + // hide script floaters so they don't confuse the user and don't overlap startup toast + LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false); + + if(notification_channel) + { + // hide saved toasts so they don't confuse the user + notification_channel->hideToast(notification->getID()); + } + } +} + +bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload) +{ + // we ignore "load" messages, but rewrite the persistence file on any other + const std::string sigtype = payload["sigtype"].asString(); + if ("load" != sigtype) + { + saveNotifications(); + } + return false; +} + +// EOF diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h new file mode 100644 index 0000000000..98a825d2c1 --- /dev/null +++ b/indra/newview/llpersistentnotificationstorage.h @@ -0,0 +1,63 @@ +/** +* @file llpersistentnotificationstorage.h +* @brief Header file for llpersistentnotificationstorage +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLPERSISTENTNOTIFICATIONSTORAGE_H +#define LL_LLPERSISTENTNOTIFICATIONSTORAGE_H + +#include "llerror.h" +#include "llnotificationstorage.h" +#include "llsingleton.h" + +class LLSD; + +// Class that saves not responded(unread) notifications. +// Unread notifications are saved in open_notifications.xml in SL account folder +// +// Notifications that should be saved(if unread) are marked with persist="true" in notifications.xml +// Notifications using functor responders are saved automatically (see llviewermessage.cpp +// lure_callback_reg for example). +// Notifications using object responders(LLOfferInfo) need additional tuning. Responder object should +// be a) serializable(implement LLNotificationResponderInterface), +// b) registered with LLResponderRegistry (found in llpersistentnotificationstorage.cpp). + +class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>, public LLNotificationStorage +{ + LOG_CLASS(LLPersistentNotificationStorage); +public: + LLPersistentNotificationStorage(); + ~LLPersistentNotificationStorage(); + + void saveNotifications(); + void loadNotifications(); + +protected: + +private: + bool onPersistentChannelChanged(const LLSD& payload); +}; + +#endif // LL_LLPERSISTENTNOTIFICATIONSTORAGE_H + diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index e124916c48..cb6989c9dd 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -67,6 +67,19 @@ inline F64 llsgn(const F64 a) class LLPhysicsMotion { public: + typedef enum + { + SMOOTHING = 0, + MASS, + GRAVITY, + SPRING, + GAIN, + DAMPING, + DRAG, + MAX_EFFECT, + NUM_PARAMS + } eParamName; + /* param_driver_name: The param that controls the params that are being affected by the physics. joint_name: The joint that the body part is attached to. The joint is @@ -98,6 +111,11 @@ public: mPositionLastUpdate_local(0) { mJointState = new LLJointState; + + for (U32 i = 0; i < NUM_PARAMS; ++i) + { + mParamCache[i] = NULL; + } } BOOL initialize(); @@ -111,16 +129,43 @@ public: return mJointState; } protected: - F32 getParamValue(const std::string& controller_key) - { - const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key); + + F32 getParamValue(eParamName param) + { + static std::string controller_key[] = + { + "Smoothing", + "Mass", + "Gravity", + "Spring", + "Gain", + "Damping", + "Drag", + "MaxEffect" + }; + + if (!mParamCache[param]) + { + const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key[param]); if (entry == mParamControllers.end()) { - return sDefaultController[controller_key]; + return sDefaultController[controller_key[param]]; } const std::string& param_name = (*entry).second.c_str(); - return mCharacter->getVisualParamWeight(param_name.c_str()); - } + mParamCache[param] = mCharacter->getVisualParam(param_name.c_str()); + } + + if (mParamCache[param]) + { + return mParamCache[param]->getWeight(); + } + else + { + return sDefaultController[controller_key[param]]; + } + } + + void setParamValue(LLViewerVisualParam *param, const F32 new_value_local, F32 behavior_maxeffect); @@ -150,6 +195,8 @@ private: F32 mLastTime; + LLVisualParam* mParamCache[NUM_PARAMS]; + static default_controller_map_t sDefaultController; }; @@ -427,7 +474,6 @@ BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask) return TRUE; } - // Return TRUE if character has to update visual params. BOOL LLPhysicsMotion::onUpdate(F32 time) { @@ -471,15 +517,16 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) LLJoint *joint = mJointState->getJoint(); - const F32 behavior_mass = getParamValue("Mass"); - const F32 behavior_gravity = getParamValue("Gravity"); - const F32 behavior_spring = getParamValue("Spring"); - const F32 behavior_gain = getParamValue("Gain"); - const F32 behavior_damping = getParamValue("Damping"); - const F32 behavior_drag = getParamValue("Drag"); - const BOOL physics_test = FALSE; // Enable this to simulate bouncing on all parts. + const F32 behavior_mass = getParamValue(MASS); + const F32 behavior_gravity = getParamValue(GRAVITY); + const F32 behavior_spring = getParamValue(SPRING); + const F32 behavior_gain = getParamValue(GAIN); + const F32 behavior_damping = getParamValue(DAMPING); + const F32 behavior_drag = getParamValue(DRAG); + F32 behavior_maxeffect = getParamValue(MAX_EFFECT); + + const BOOL physics_test = FALSE; // Enable this to simulate bouncing on all parts. - F32 behavior_maxeffect = getParamValue("MaxEffect"); if (physics_test) behavior_maxeffect = 1.0f; diff --git a/indra/newview/llplacesfolderview.cpp b/indra/newview/llplacesfolderview.cpp new file mode 100644 index 0000000000..3caa93ae71 --- /dev/null +++ b/indra/newview/llplacesfolderview.cpp @@ -0,0 +1,74 @@ +/** +* @file llplacesfolderview.cpp +* @brief llplacesfolderview used within llplacesinventorypanel +* @author Gilbert@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llplacesfolderview.h" + +#include "llplacesinventorypanel.h" +#include "llpanellandmarks.h" + +LLPlacesFolderView::LLPlacesFolderView(const LLFolderView::Params& p) + : LLFolderView(p) +{ + // we do not need auto select functionality in places landmarks, so override default behavior. + // this disables applying of the LLSelectFirstFilteredItem in LLFolderView::doIdle. + // Fixed issues: EXT-1631, EXT-4994. + mAutoSelectOverride = TRUE; +} + +BOOL LLPlacesFolderView::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + // let children to change selection first + childrenHandleRightMouseDown(x, y, mask); + mParentLandmarksPanel->setCurrentSelectedList((LLPlacesInventoryPanel*)getParentPanel()); + + // then determine its type and set necessary menu handle + if (getCurSelectedItem()) + { + LLInventoryType::EType inventory_type = static_cast<LLFolderViewModelItemInventory*>(getCurSelectedItem()->getViewModelItem())->getInventoryType(); + inventory_type_menu_handle_t::iterator it_handle = mMenuHandlesByInventoryType.find(inventory_type); + + if (it_handle != mMenuHandlesByInventoryType.end()) + { + mPopupMenuHandle = (*it_handle).second; + } + else + { + llwarns << "Requested menu handle for non-setup inventory type: " << inventory_type << llendl; + } + + } + + return LLFolderView::handleRightMouseDown(x, y, mask); +} + +void LLPlacesFolderView::setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle) +{ + mMenuHandlesByInventoryType[asset_type] = menu_handle; +} + diff --git a/indra/newview/llplacesfolderview.h b/indra/newview/llplacesfolderview.h new file mode 100644 index 0000000000..8c5be39b5e --- /dev/null +++ b/indra/newview/llplacesfolderview.h @@ -0,0 +1,72 @@ +/** +* @file llplacesfolderview.h +* @brief llplacesfolderview used within llplacesinventorypanel +* @author Gilbert@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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_LLPLACESFOLDERVIEW_H +#define LL_LLPLACESFOLDERVIEW_H + +#include "llfolderview.h" +#include "llinventorypanel.h" + +class LLLandmarksPanel; + +class LLPlacesFolderView : public LLFolderView +{ +public: + + struct Params : public LLInitParam::Block<Params, LLFolderView::Params> + { + Params() + {} + }; + + LLPlacesFolderView(const LLFolderView::Params& p); + /** + * Handles right mouse down + * + * Contains workaround for EXT-2786: sets current selected list for landmark + * panel using @c mParentLandmarksPanel which is set in @c LLLandmarksPanel::initLandmarksPanel + */ + /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + + void setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle); + + void setParentLandmarksPanel(LLLandmarksPanel* panel) + { + mParentLandmarksPanel = panel; + } + +private: + /** + * holds pointer to landmark panel. This pointer is used in @c LLPlacesFolderView::handleRightMouseDown + */ + LLLandmarksPanel* mParentLandmarksPanel; + typedef std::map<LLInventoryType::EType, LLHandle<LLView> > inventory_type_menu_handle_t; + inventory_type_menu_handle_t mMenuHandlesByInventoryType; + +}; + +#endif // LL_LLPLACESFOLDERVIEW_H + diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp index 225ac6e224..ebd9604c5b 100644 --- a/indra/newview/llplacesinventorybridge.cpp +++ b/indra/newview/llplacesinventorybridge.cpp @@ -85,34 +85,33 @@ void LLPlacesLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) void LLPlacesFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { + std::vector<std::string> items; + std::vector<std::string> disabled_items; + + LLInventoryPanel* inv_panel = mInventoryPanel.get(); + bool is_open = false; + if (inv_panel) { - std::vector<std::string> items; - std::vector<std::string> disabled_items; + LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getItemByID(mUUID)); + is_open = (NULL != folder) && folder->isOpen(); + } - LLInventoryPanel* inv_panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); - bool is_open = false; - if (inv_panel) - { - LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID)); - is_open = (NULL != folder) && folder->isOpen(); - } + // collect all items' names + fill_items_with_menu_items(items, menu); - // collect all items' names - fill_items_with_menu_items(items, menu); + // remove expand or collapse menu item depend on folder state + std::string collapse_expand_item_to_hide(is_open ? "expand" : "collapse"); + std::vector<std::string>::iterator it = std::find(items.begin(), items.end(), collapse_expand_item_to_hide); + if (it != items.end()) items.erase(it); - // remove expand or collapse menu item depend on folder state - std::string collapse_expand_item_to_hide(is_open ? "expand" : "collapse"); - std::vector<std::string>::iterator it = std::find(items.begin(), items.end(), collapse_expand_item_to_hide); - if (it != items.end()) items.erase(it); - // Disabled items are processed via LLLandmarksPanel::isActionEnabled() - // they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601 + // Disabled items are processed via LLLandmarksPanel::isActionEnabled() + // they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601 - // repeat parent functionality - sSelf = getHandle(); // necessary for "New Folder" functionality + // repeat parent functionality + sSelf = getHandle(); // necessary for "New Folder" functionality - hide_context_entries(menu, items, disabled_items); - } + hide_context_entries(menu, items, disabled_items); } //virtual @@ -137,10 +136,10 @@ void LLPlacesFolderBridge::performAction(LLInventoryModel* model, std::string ac LLFolderViewFolder* LLPlacesFolderBridge::getFolder() { LLFolderViewFolder* folder = NULL; - LLInventoryPanel* inv_panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); + LLInventoryPanel* inv_panel = mInventoryPanel.get(); if (inv_panel) { - folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID)); + folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getItemByID(mUUID)); } return folder; @@ -152,6 +151,7 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge( LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, + LLFolderViewModelInventory* view_model, LLFolderView* root, const LLUUID& uuid, U32 flags/* = 0x00*/) const @@ -170,11 +170,12 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge( if (actual_asset_type == LLAssetType::AT_LINK_FOLDER) { // *TODO: Create a link folder handler instead if it is necessary - new_listener = LLInventoryFVBridgeBuilder::createBridge( + new_listener = LLInventoryFolderViewModelBuilder::createBridge( asset_type, actual_asset_type, inv_type, inventory, + view_model, root, uuid, flags); @@ -183,11 +184,12 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge( new_listener = new LLPlacesFolderBridge(inv_type, inventory, root, uuid); break; default: - new_listener = LLInventoryFVBridgeBuilder::createBridge( + new_listener = LLInventoryFolderViewModelBuilder::createBridge( asset_type, actual_asset_type, inv_type, inventory, + view_model, root, uuid, flags); diff --git a/indra/newview/llplacesinventorybridge.h b/indra/newview/llplacesinventorybridge.h index 52beacef9c..07d18d03c5 100644 --- a/indra/newview/llplacesinventorybridge.h +++ b/indra/newview/llplacesinventorybridge.h @@ -82,13 +82,14 @@ protected: * * It builds Bridges for Landmarks and Folders in Places Landmarks Panel */ -class LLPlacesInventoryBridgeBuilder : public LLInventoryFVBridgeBuilder +class LLPlacesInventoryBridgeBuilder : public LLInventoryFolderViewModelBuilder { public: /*virtual*/ LLInvFVBridge* createBridge(LLAssetType::EType asset_type, LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, + LLFolderViewModelInventory* view_model, LLFolderView* root, const LLUUID& uuid, U32 flags = 0x00) const; diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp index f7823f4fe8..4c2213c198 100644 --- a/indra/newview/llplacesinventorypanel.cpp +++ b/indra/newview/llplacesinventorypanel.cpp @@ -30,7 +30,8 @@ #include "llplacesinventorypanel.h" -#include "llfoldervieweventlistener.h" +#include "llfolderviewmodel.h" +#include "llplacesfolderview.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llpanellandmarks.h" @@ -57,44 +58,35 @@ LLPlacesInventoryPanel::~LLPlacesInventoryPanel() delete mSavedFolderState; } -void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params) -{ - // Determine the root folder in case specified, and - // build the views starting with that folder. - const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder); - - LLUUID root_id; - if ("LIBRARY" == params.start_folder()) - { - root_id = gInventory.getLibraryRootFolderID(); - } - else - { - root_id = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null); - } - - LLRect folder_rect(0, - 0, - getRect().getWidth(), - 0); - LLPlacesFolderView::Params p; - p.name = getName(); - p.title = getLabel(); - p.rect = folder_rect; - p.listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY, - LLAssetType::AT_CATEGORY, - LLInventoryType::IT_CATEGORY, - this, - NULL, - root_id); - p.parent_panel = this; - p.allow_multiselect = mAllowMultiSelect; - p.use_ellipses = true; // truncate inventory item text so remove horizontal scroller - mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p); +LLFolderView * LLPlacesInventoryPanel::createFolderRoot(LLUUID root_id ) +{ + LLPlacesFolderView::Params p; + + p.name = getName(); + p.title = getLabel(); + p.rect = LLRect(0, 0, getRect().getWidth(), 0); + p.parent_panel = this; + p.tool_tip = p.name; + p.listener = mInvFVBridgeBuilder->createBridge( LLAssetType::AT_CATEGORY, + LLAssetType::AT_CATEGORY, + LLInventoryType::IT_CATEGORY, + this, + &mInventoryViewModel, + NULL, + root_id); + p.view_model = &mInventoryViewModel; + p.use_label_suffix = mParams.use_label_suffix; + p.allow_multiselect = mAllowMultiSelect; + p.show_empty_message = mShowEmptyMessage; + p.show_item_link_overlays = mShowItemLinkOverlays; + p.root = NULL; + p.use_ellipses = mParams.folder_view.use_ellipses; + p.options_menu = "menu_inventory.xml"; + + return LLUICtrlFactory::create<LLPlacesFolderView>(p); } - // save current folder open state void LLPlacesInventoryPanel::saveFolderState() { @@ -128,59 +120,3 @@ S32 LLPlacesInventoryPanel::notify(const LLSD& info) } return 0; } - -/************************************************************************/ -/* PROTECTED METHODS */ -/************************************************************************/ - - - -/************************************************************************/ -/* LLPlacesFolderView implementation */ -/************************************************************************/ - -////////////////////////////////////////////////////////////////////////// -// PUBLIC METHODS -////////////////////////////////////////////////////////////////////////// - -LLPlacesFolderView::LLPlacesFolderView(const LLFolderView::Params& p) -: LLFolderView(p) -{ - // we do not need auto select functionality in places landmarks, so override default behavior. - // this disables applying of the LLSelectFirstFilteredItem in LLFolderView::doIdle. - // Fixed issues: EXT-1631, EXT-4994. - mAutoSelectOverride = TRUE; -} - -BOOL LLPlacesFolderView::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ - // let children to change selection first - childrenHandleRightMouseDown(x, y, mask); - mParentLandmarksPanel->setCurrentSelectedList((LLPlacesInventoryPanel*)getParentPanel()); - - // then determine its type and set necessary menu handle - if (getCurSelectedItem()) - { - LLInventoryType::EType inventory_type = getCurSelectedItem()->getListener()->getInventoryType(); - inventory_type_menu_handle_t::iterator it_handle = mMenuHandlesByInventoryType.find(inventory_type); - - if (it_handle != mMenuHandlesByInventoryType.end()) - { - mPopupMenuHandle = (*it_handle).second; - } - else - { - llwarns << "Requested menu handle for non-setup inventory type: " << inventory_type << llendl; - } - - } - - return LLFolderView::handleRightMouseDown(x, y, mask); -} - -void LLPlacesFolderView::setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle) -{ - mMenuHandlesByInventoryType[asset_type] = menu_handle; -} - -// EOF diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h index f647e7f970..2805fc4257 100644 --- a/indra/newview/llplacesinventorypanel.h +++ b/indra/newview/llplacesinventorypanel.h @@ -29,9 +29,9 @@ #include "llfloaterinventory.h" #include "llinventorypanel.h" -#include "llfolderview.h" class LLLandmarksPanel; +class LLFolderView; class LLPlacesInventoryPanel : public LLInventoryPanel { @@ -46,8 +46,7 @@ public: LLPlacesInventoryPanel(const Params& p); ~LLPlacesInventoryPanel(); - /*virtual*/ void buildFolderView(const LLInventoryPanel::Params& params); - + LLFolderView * createFolderRoot(LLUUID root_id ); void saveFolderState(); void restoreFolderState(); @@ -57,36 +56,4 @@ private: LLSaveFolderState* mSavedFolderState; }; - -class LLPlacesFolderView : public LLFolderView -{ -public: - LLPlacesFolderView(const LLFolderView::Params& p); - /** - * Handles right mouse down - * - * Contains workaround for EXT-2786: sets current selected list for landmark - * panel using @c mParentLandmarksPanel which is set in @c LLLandmarksPanel::initLandmarksPanel - */ - /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); - - void setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle); - - void setParentLandmarksPanel(LLLandmarksPanel* panel) - { - mParentLandmarksPanel = panel; - } - - S32 getSelectedCount() { return (S32)mSelectedItems.size(); } - -private: - /** - * holds pointer to landmark panel. This pointer is used in @c LLPlacesFolderView::handleRightMouseDown - */ - LLLandmarksPanel* mParentLandmarksPanel; - typedef std::map<LLInventoryType::EType, LLHandle<LLView> > inventory_type_menu_handle_t; - inventory_type_menu_handle_t mMenuHandlesByInventoryType; - -}; - #endif //LL_LLINVENTORYSUBTREEPANEL_H diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp index 450f9b2be7..5f5258bbce 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/newview/llpolymesh.cpp @@ -129,22 +129,22 @@ void LLPolyMeshSharedData::freeMeshData() { mNumVertices = 0; - delete [] mBaseCoords; + ll_aligned_free_16(mBaseCoords); mBaseCoords = NULL; - delete [] mBaseNormals; + ll_aligned_free_16(mBaseNormals); mBaseNormals = NULL; - delete [] mBaseBinormals; + ll_aligned_free_16(mBaseBinormals); mBaseBinormals = NULL; - delete [] mTexCoords; + ll_aligned_free_16(mTexCoords); mTexCoords = NULL; - delete [] mDetailTexCoords; + ll_aligned_free_16(mDetailTexCoords); mDetailTexCoords = NULL; - delete [] mWeights; + ll_aligned_free_16(mWeights); mWeights = NULL; } @@ -229,15 +229,19 @@ U32 LLPolyMeshSharedData::getNumKB() BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices ) { U32 i; - mBaseCoords = new LLVector3[ numVertices ]; - mBaseNormals = new LLVector3[ numVertices ]; - mBaseBinormals = new LLVector3[ numVertices ]; - mTexCoords = new LLVector2[ numVertices ]; - mDetailTexCoords = new LLVector2[ numVertices ]; - mWeights = new F32[ numVertices ]; + mBaseCoords = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); + mBaseNormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); + mBaseBinormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); + mTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2)); + mDetailTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2)); + mWeights = (F32*) ll_aligned_malloc_16(numVertices*sizeof(F32)); for (i = 0; i < numVertices; i++) { - mWeights[i] = 0.f; + mBaseCoords[i].clear(); + mBaseNormals[i].clear(); + mBaseBinormals[i].clear(); + mTexCoords[i].clear(); + mWeights[i] = 0.f; } mNumVertices = numVertices; return TRUE; @@ -408,39 +412,47 @@ BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName ) allocateVertexData( numVertices ); - //---------------------------------------------------------------- - // Coords - //---------------------------------------------------------------- - numRead = fread(mBaseCoords, 3*sizeof(float), numVertices, fp); - llendianswizzle(mBaseCoords, sizeof(float), 3*numVertices); - if (numRead != numVertices) - { - llerrs << "can't read Coordinates from " << fileName << llendl; - return FALSE; - } - - //---------------------------------------------------------------- - // Normals - //---------------------------------------------------------------- - numRead = fread(mBaseNormals, 3*sizeof(float), numVertices, fp); - llendianswizzle(mBaseNormals, sizeof(float), 3*numVertices); - if (numRead != numVertices) - { - llerrs << " can't read Normals from " << fileName << llendl; - return FALSE; - } - - //---------------------------------------------------------------- - // Binormals - //---------------------------------------------------------------- - numRead = fread(mBaseBinormals, 3*sizeof(float), numVertices, fp); - llendianswizzle(mBaseBinormals, sizeof(float), 3*numVertices); - if (numRead != numVertices) - { - llerrs << " can't read Binormals from " << fileName << llendl; - return FALSE; - } - + for (U16 i = 0; i < numVertices; ++i) + { + //---------------------------------------------------------------- + // Coords + //---------------------------------------------------------------- + numRead = fread(&mBaseCoords[i], sizeof(float), 3, fp); + llendianswizzle(&mBaseCoords[i], sizeof(float), 3); + if (numRead != 3) + { + llerrs << "can't read Coordinates from " << fileName << llendl; + return FALSE; + } + } + + for (U16 i = 0; i < numVertices; ++i) + { + //---------------------------------------------------------------- + // Normals + //---------------------------------------------------------------- + numRead = fread(&mBaseNormals[i], sizeof(float), 3, fp); + llendianswizzle(&mBaseNormals[i], sizeof(float), 3); + if (numRead != 3) + { + llerrs << " can't read Normals from " << fileName << llendl; + return FALSE; + } + } + + for (U16 i = 0; i < numVertices; ++i) + { + //---------------------------------------------------------------- + // Binormals + //---------------------------------------------------------------- + numRead = fread(&mBaseBinormals[i], sizeof(float), 3, fp); + llendianswizzle(&mBaseBinormals[i], sizeof(float), 3); + if (numRead != 3) + { + llerrs << " can't read Binormals from " << fileName << llendl; + return FALSE; + } + } //---------------------------------------------------------------- // TexCoords @@ -738,8 +750,6 @@ const LLVector2 &LLPolyMeshSharedData::getUVs(U32 index) //----------------------------------------------------------------------------- LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_mesh) { - LLMemType mt(LLMemType::MTYPE_AVATAR_MESH); - llassert(shared_data); mSharedData = shared_data; @@ -767,21 +777,28 @@ LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_ { // Allocate memory without initializing every vector // NOTE: This makes asusmptions about the size of LLVector[234] - int nverts = mSharedData->mNumVertices; - int nfloats = nverts * (2*4 + 3*3 + 2 + 4); + S32 nverts = mSharedData->mNumVertices; + //make sure it's an even number of verts for alignment + nverts += nverts%2; + S32 nfloats = nverts * ( + 4 + //coords + 4 + //normals + 4 + //weights + 2 + //coords + 4 + //scaled normals + 4 + //binormals + 4); //scaled binormals + //use 16 byte aligned vertex data to make LLPolyMesh SSE friendly mVertexData = (F32*) ll_aligned_malloc_16(nfloats*4); - int offset = 0; - mCoords = (LLVector4*)(mVertexData + offset); offset += 4*nverts; - mNormals = (LLVector4*)(mVertexData + offset); offset += 4*nverts; - mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts; - mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts; - - // these members don't need to be 16-byte aligned, but the first one might be - // read during an aligned memcpy of mTexCoords - mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mScaledBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; + S32 offset = 0; + mCoords = (LLVector4a*)(mVertexData + offset); offset += 4*nverts; + mNormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts; + mClothingWeights = (LLVector4a*)(mVertexData + offset); offset += 4*nverts; + mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts; + mScaledNormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts; + mBinormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts; + mScaledBinormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts; initializeForMorph(); } } @@ -906,7 +923,7 @@ void LLPolyMesh::dumpDiagInfo() //----------------------------------------------------------------------------- // getWritableCoords() //----------------------------------------------------------------------------- -LLVector4 *LLPolyMesh::getWritableCoords() +LLVector4a *LLPolyMesh::getWritableCoords() { return mCoords; } @@ -914,7 +931,7 @@ LLVector4 *LLPolyMesh::getWritableCoords() //----------------------------------------------------------------------------- // getWritableNormals() //----------------------------------------------------------------------------- -LLVector4 *LLPolyMesh::getWritableNormals() +LLVector4a *LLPolyMesh::getWritableNormals() { return mNormals; } @@ -922,7 +939,7 @@ LLVector4 *LLPolyMesh::getWritableNormals() //----------------------------------------------------------------------------- // getWritableBinormals() //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getWritableBinormals() +LLVector4a *LLPolyMesh::getWritableBinormals() { return mBinormals; } @@ -931,7 +948,7 @@ LLVector3 *LLPolyMesh::getWritableBinormals() //----------------------------------------------------------------------------- // getWritableClothingWeights() //----------------------------------------------------------------------------- -LLVector4 *LLPolyMesh::getWritableClothingWeights() +LLVector4a *LLPolyMesh::getWritableClothingWeights() { return mClothingWeights; } @@ -947,7 +964,7 @@ LLVector2 *LLPolyMesh::getWritableTexCoords() //----------------------------------------------------------------------------- // getScaledNormals() //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getScaledNormals() +LLVector4a *LLPolyMesh::getScaledNormals() { return mScaledNormals; } @@ -955,7 +972,7 @@ LLVector3 *LLPolyMesh::getScaledNormals() //----------------------------------------------------------------------------- // getScaledBinormals() //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getScaledBinormals() +LLVector4a *LLPolyMesh::getScaledBinormals() { return mScaledBinormals; } @@ -966,17 +983,17 @@ LLVector3 *LLPolyMesh::getScaledBinormals() //----------------------------------------------------------------------------- void LLPolyMesh::initializeForMorph() { - for (U32 i = 0; i < mSharedData->mNumVertices; ++i) + LLVector4a::memcpyNonAliased16((F32*) mCoords, (F32*) mSharedData->mBaseCoords, sizeof(LLVector4a) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mScaledNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mScaledBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices + mSharedData->mNumVertices%2)); + + for (U32 i = 0; i < mSharedData->mNumVertices; ++i) { - mCoords[i] = LLVector4(mSharedData->mBaseCoords[i]); - mNormals[i] = LLVector4(mSharedData->mBaseNormals[i]); + mClothingWeights[i].clear(); } - - memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memcpy(mTexCoords, mSharedData->mTexCoords, sizeof(LLVector2) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices); } //----------------------------------------------------------------------------- @@ -1098,7 +1115,7 @@ BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node) LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp) { mAvatar = avatarp; - mDefaultVec.setVec(0.001f, 0.001f, 0.001f); + mDefaultVec.splat(0.001f); } //----------------------------------------------------------------------------- @@ -1171,8 +1188,12 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info) //----------------------------------------------------------------------------- // apply() //----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion"); + void LLPolySkeletalDistortion::apply( ESex avatar_sex ) { + LLFastTimer t(FTM_POLYSKELETAL_DISTORTION_APPLY); + F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight(); LLJoint* joint; @@ -1228,11 +1249,14 @@ LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data, { LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); cloned_morph_data->mName = name; + LLVector4a dir; + dir.load3(direction.mV); + for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) { - cloned_morph_data->mCoords[v] = direction; - cloned_morph_data->mNormals[v] = LLVector3(0,0,0); - cloned_morph_data->mBinormals[v] = LLVector3(0,0,0); + cloned_morph_data->mCoords[v] = dir; + cloned_morph_data->mNormals[v].clear(); + cloned_morph_data->mBinormals[v].clear(); } return cloned_morph_data; } @@ -1243,17 +1267,27 @@ LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data, { LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); cloned_morph_data->mName = name; + + LLVector4a sc; + sc.splat(scale); + + LLVector4a nsc; + nsc.set(scale, -scale, scale, scale); + for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) { - cloned_morph_data->mCoords[v] = src_data->mCoords[v]*scale; - cloned_morph_data->mNormals[v] = src_data->mNormals[v]*scale; - cloned_morph_data->mBinormals[v] = src_data->mBinormals[v]*scale; - if (cloned_morph_data->mCoords[v][1] < 0) - { - cloned_morph_data->mCoords[v][1] *= -1; - cloned_morph_data->mNormals[v][1] *= -1; - cloned_morph_data->mBinormals[v][1] *= -1; - } + if (cloned_morph_data->mCoords[v][1] < 0) + { + cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc); + cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc); + cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc); + } + else + { + cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc); + cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc); + cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc); + } } return cloned_morph_data; } diff --git a/indra/newview/llpolymesh.h b/indra/newview/llpolymesh.h index ba2bf85570..28da230541 100644 --- a/indra/newview/llpolymesh.h +++ b/indra/newview/llpolymesh.h @@ -73,9 +73,9 @@ private: // vertex data S32 mNumVertices; - LLVector3 *mBaseCoords; - LLVector3 *mBaseNormals; - LLVector3 *mBaseBinormals; + LLVector4a *mBaseCoords; + LLVector4a *mBaseNormals; + LLVector4a *mBaseBinormals; LLVector2 *mTexCoords; LLVector2 *mDetailTexCoords; F32 *mWeights; @@ -217,41 +217,41 @@ public: } // Get coords - const LLVector4 *getCoords() const{ + const LLVector4a *getCoords() const{ return mCoords; } // non const version - LLVector4 *getWritableCoords(); + LLVector4a *getWritableCoords(); // Get normals - const LLVector4 *getNormals() const{ + const LLVector4a *getNormals() const{ return mNormals; } // Get normals - const LLVector3 *getBinormals() const{ + const LLVector4a *getBinormals() const{ return mBinormals; } // Get base mesh normals - const LLVector3 *getBaseNormals() const{ + const LLVector4a *getBaseNormals() const{ llassert(mSharedData); return mSharedData->mBaseNormals; } // Get base mesh normals - const LLVector3 *getBaseBinormals() const{ + const LLVector4a *getBaseBinormals() const{ llassert(mSharedData); return mSharedData->mBaseBinormals; } // intermediate morphed normals and output normals - LLVector4 *getWritableNormals(); - LLVector3 *getScaledNormals(); + LLVector4a *getWritableNormals(); + LLVector4a *getScaledNormals(); - LLVector3 *getWritableBinormals(); - LLVector3 *getScaledBinormals(); + LLVector4a *getWritableBinormals(); + LLVector4a *getScaledBinormals(); // Get texCoords const LLVector2 *getTexCoords() const { @@ -275,9 +275,9 @@ public: F32 *getWritableWeights() const; - LLVector4 *getWritableClothingWeights(); + LLVector4a *getWritableClothingWeights(); - const LLVector4 *getClothingWeights() + const LLVector4a *getClothingWeights() { return mClothingWeights; } @@ -341,17 +341,17 @@ protected: // Single array of floats for allocation / deletion F32 *mVertexData; // deformed vertices (resulting from application of morph targets) - LLVector4 *mCoords; + LLVector4a *mCoords; // deformed normals (resulting from application of morph targets) - LLVector3 *mScaledNormals; + LLVector4a *mScaledNormals; // output normals (after normalization) - LLVector4 *mNormals; + LLVector4a *mNormals; // deformed binormals (resulting from application of morph targets) - LLVector3 *mScaledBinormals; + LLVector4a *mScaledBinormals; // output binormals (after normalization) - LLVector3 *mBinormals; + LLVector4a *mBinormals; // weight values that mark verts as clothing/skin - LLVector4 *mClothingWeights; + LLVector4a *mClothingWeights; // output texture coordinates LLVector2 *mTexCoords; @@ -400,12 +400,24 @@ protected: // LLPolySkeletalDeformation // A set of joint scale data for deforming the avatar mesh //----------------------------------------------------------------------------- + +LL_ALIGN_PREFIX(16) class LLPolySkeletalDistortion : public LLViewerVisualParam { public: LLPolySkeletalDistortion(LLVOAvatar *avatarp); ~LLPolySkeletalDistortion(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + // Special: These functions are overridden by child classes LLPolySkeletalDistortionInfo* getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; } // This sets mInfo and calls initialization functions @@ -419,20 +431,21 @@ public: // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion() { return 0.1f; } - /*virtual*/ const LLVector3& getAvgDistortion() { return mDefaultVec; } + /*virtual*/ const LLVector4a& getAvgDistortion() { return mDefaultVec; } /*virtual*/ F32 getMaxDistortion() { return 0.1f; } - /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector3(0.001f, 0.001f, 0.001f);} - /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;}; - /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;}; + /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);} + /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;}; + /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;}; protected: + LL_ALIGN_16(LLVector4a mDefaultVec); + typedef std::map<LLJoint*, LLVector3> joint_vec_map_t; joint_vec_map_t mJointScales; joint_vec_map_t mJointOffsets; - LLVector3 mDefaultVec; // Backlink only; don't make this an LLPointer. LLVOAvatar *mAvatar; -}; +} LL_ALIGN_POSTFIX(16); #endif // LL_LLPOLYMESH_H diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp index cefd7df3fe..495fdc348c 100644 --- a/indra/newview/llpolymorph.cpp +++ b/indra/newview/llpolymorph.cpp @@ -48,7 +48,7 @@ LLPolyMorphData::LLPolyMorphData(const std::string& morph_name) mNumIndices = 0; mCurrentIndex = 0; mTotalDistortion = 0.f; - mAvgDistortion.zeroVec(); + mAvgDistortion.clear(); mMaxDistortion = 0.f; mVertexIndices = NULL; mCoords = NULL; @@ -73,9 +73,11 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) : { const S32 numVertices = mNumIndices; - mCoords = new LLVector3[numVertices]; - mNormals = new LLVector3[numVertices]; - mBinormals = new LLVector3[numVertices]; + U32 size = sizeof(LLVector4a)*numVertices; + + mCoords = static_cast<LLVector4a*>( ll_aligned_malloc_16(size) ); + mNormals = static_cast<LLVector4a*>( ll_aligned_malloc_16(size) ); + mBinormals = static_cast<LLVector4a*>( ll_aligned_malloc_16(size) ); mTexCoords = new LLVector2[numVertices]; mVertexIndices = new U32[numVertices]; @@ -89,17 +91,12 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) : } } - //----------------------------------------------------------------------------- // ~LLPolyMorphData() //----------------------------------------------------------------------------- LLPolyMorphData::~LLPolyMorphData() { - delete [] mVertexIndices; - delete [] mCoords; - delete [] mNormals; - delete [] mBinormals; - delete [] mTexCoords; + freeData(); } //----------------------------------------------------------------------------- @@ -119,18 +116,27 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) } //------------------------------------------------------------------------- + // free any existing data + //------------------------------------------------------------------------- + freeData(); + + //------------------------------------------------------------------------- // allocate vertices //------------------------------------------------------------------------- - mCoords = new LLVector3[numVertices]; - mNormals = new LLVector3[numVertices]; - mBinormals = new LLVector3[numVertices]; + + U32 size = sizeof(LLVector4a)*numVertices; + + mCoords = static_cast<LLVector4a*>(ll_aligned_malloc_16(size)); + mNormals = static_cast<LLVector4a*>(ll_aligned_malloc_16(size)); + mBinormals = static_cast<LLVector4a*>(ll_aligned_malloc_16(size)); + mTexCoords = new LLVector2[numVertices]; // Actually, we are allocating more space than we need for the skiplist mVertexIndices = new U32[numVertices]; mNumIndices = 0; mTotalDistortion = 0.f; mMaxDistortion = 0.f; - mAvgDistortion.zeroVec(); + mAvgDistortion.clear(); mMesh = mesh; //------------------------------------------------------------------------- @@ -152,36 +158,36 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) } - numRead = fread(&mCoords[v].mV, sizeof(F32), 3, fp); - llendianswizzle(&mCoords[v].mV, sizeof(F32), 3); + numRead = fread(&mCoords[v], sizeof(F32), 3, fp); + llendianswizzle(&mCoords[v], sizeof(F32), 3); if (numRead != 3) { llwarns << "Can't read morph target vertex coordinates" << llendl; return FALSE; } - F32 magnitude = mCoords[v].magVec(); + F32 magnitude = mCoords[v].getLength3().getF32(); mTotalDistortion += magnitude; - mAvgDistortion.mV[VX] += fabs(mCoords[v].mV[VX]); - mAvgDistortion.mV[VY] += fabs(mCoords[v].mV[VY]); - mAvgDistortion.mV[VZ] += fabs(mCoords[v].mV[VZ]); + LLVector4a t; + t.setAbs(mCoords[v]); + mAvgDistortion.add(t); if (magnitude > mMaxDistortion) { mMaxDistortion = magnitude; } - numRead = fread(&mNormals[v].mV, sizeof(F32), 3, fp); - llendianswizzle(&mNormals[v].mV, sizeof(F32), 3); + numRead = fread(&mNormals[v], sizeof(F32), 3, fp); + llendianswizzle(&mNormals[v], sizeof(F32), 3); if (numRead != 3) { llwarns << "Can't read morph target normal" << llendl; return FALSE; } - numRead = fread(&mBinormals[v].mV, sizeof(F32), 3, fp); - llendianswizzle(&mBinormals[v].mV, sizeof(F32), 3); + numRead = fread(&mBinormals[v], sizeof(F32), 3, fp); + llendianswizzle(&mBinormals[v], sizeof(F32), 3); if (numRead != 3) { llwarns << "Can't read morph target binormal" << llendl; @@ -200,13 +206,49 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) mNumIndices++; } - mAvgDistortion = mAvgDistortion * (1.f/(F32)mNumIndices); - mAvgDistortion.normVec(); + mAvgDistortion.mul(1.f/(F32)mNumIndices); + mAvgDistortion.normalize3fast(); return TRUE; } //----------------------------------------------------------------------------- +// freeData() +//----------------------------------------------------------------------------- +void LLPolyMorphData::freeData() +{ + if (mCoords != NULL) + { + ll_aligned_free_16(mCoords); + mCoords = NULL; + } + + if (mNormals != NULL) + { + ll_aligned_free_16(mNormals); + mNormals = NULL; + } + + if (mBinormals != NULL) + { + ll_aligned_free_16(mBinormals); + mBinormals = NULL; + } + + if (mTexCoords != NULL) + { + delete [] mTexCoords; + mTexCoords = NULL; + } + + if (mVertexIndices != NULL) + { + delete [] mVertexIndices; + mVertexIndices = NULL; + } +} + +//----------------------------------------------------------------------------- // LLPolyMorphTargetInfo() //----------------------------------------------------------------------------- LLPolyMorphTargetInfo::LLPolyMorphTargetInfo() @@ -367,9 +409,9 @@ BOOL LLPolyMorphTarget::parseData(LLXmlTreeNode* node) //----------------------------------------------------------------------------- // getVertexDistortion() //----------------------------------------------------------------------------- -LLVector3 LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh) +LLVector4a LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh) { - if (!mMorphData || mMesh != mesh) return LLVector3::zero; + if (!mMorphData || mMesh != mesh) return LLVector4a::getZero(); for(U32 index = 0; index < mMorphData->mNumIndices; index++) { @@ -379,17 +421,17 @@ LLVector3 LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh } } - return LLVector3::zero; + return LLVector4a::getZero(); } //----------------------------------------------------------------------------- // getFirstDistortion() //----------------------------------------------------------------------------- -const LLVector3 *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) +const LLVector4a *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { - if (!mMorphData) return &LLVector3::zero; + if (!mMorphData) return &LLVector4a::getZero(); - LLVector3* resultVec; + LLVector4a* resultVec; mMorphData->mCurrentIndex = 0; if (mMorphData->mNumIndices) { @@ -411,11 +453,11 @@ const LLVector3 *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh ** //----------------------------------------------------------------------------- // getNextDistortion() //----------------------------------------------------------------------------- -const LLVector3 *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) +const LLVector4a *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { - if (!mMorphData) return &LLVector3::zero; + if (!mMorphData) return &LLVector4a::getZero(); - LLVector3* resultVec; + LLVector4a* resultVec; mMorphData->mCurrentIndex++; if (mMorphData->mCurrentIndex < mMorphData->mNumIndices) { @@ -451,7 +493,7 @@ F32 LLPolyMorphTarget::getTotalDistortion() //----------------------------------------------------------------------------- // getAvgDistortion() //----------------------------------------------------------------------------- -const LLVector3& LLPolyMorphTarget::getAvgDistortion() +const LLVector4a& LLPolyMorphTarget::getAvgDistortion() { if (mMorphData) { @@ -459,7 +501,7 @@ const LLVector3& LLPolyMorphTarget::getAvgDistortion() } else { - return LLVector3::zero; + return LLVector4a::getZero(); } } @@ -481,6 +523,8 @@ F32 LLPolyMorphTarget::getMaxDistortion() //----------------------------------------------------------------------------- // apply() //----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_APPLY_MORPH_TARGET("Apply Morph"); + void LLPolyMorphTarget::apply( ESex avatar_sex ) { if (!mMorphData || mNumMorphMasksPending > 0) @@ -488,6 +532,8 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) return; } + LLFastTimer t(FTM_APPLY_MORPH_TARGET); + mLastSex = avatar_sex; // Check for NaN condition (NaN is detected if a variable doesn't equal itself. @@ -508,15 +554,15 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) if (delta_weight != 0.f) { llassert(!mMesh->isLOD()); - LLVector4 *coords = mMesh->getWritableCoords(); + LLVector4a *coords = mMesh->getWritableCoords(); - LLVector3 *scaled_normals = mMesh->getScaledNormals(); - LLVector4 *normals = mMesh->getWritableNormals(); + LLVector4a *scaled_normals = mMesh->getScaledNormals(); + LLVector4a *normals = mMesh->getWritableNormals(); - LLVector3 *scaled_binormals = mMesh->getScaledBinormals(); - LLVector3 *binormals = mMesh->getWritableBinormals(); + LLVector4a *scaled_binormals = mMesh->getScaledBinormals(); + LLVector4a *binormals = mMesh->getWritableBinormals(); - LLVector4 *clothing_weights = mMesh->getWritableClothingWeights(); + LLVector4a *clothing_weights = mMesh->getWritableClothingWeights(); LLVector2 *tex_coords = mMesh->getWritableTexCoords(); F32 *maskWeightArray = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL; @@ -531,31 +577,38 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) maskWeight = maskWeightArray[vert_index_morph]; } - coords[vert_index_mesh] += LLVector4(mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight); + + LLVector4a pos = mMorphData->mCoords[vert_index_morph]; + pos.mul(delta_weight*maskWeight); + coords[vert_index_mesh].add(pos); if (getInfo()->mIsClothingMorph && clothing_weights) { - LLVector3 clothing_offset = mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight; - LLVector4* clothing_weight = &clothing_weights[vert_index_mesh]; - clothing_weight->mV[VX] += clothing_offset.mV[VX]; - clothing_weight->mV[VY] += clothing_offset.mV[VY]; - clothing_weight->mV[VZ] += clothing_offset.mV[VZ]; - clothing_weight->mV[VW] = maskWeight; + LLVector4a clothing_offset = mMorphData->mCoords[vert_index_morph]; + clothing_offset.mul(delta_weight * maskWeight); + LLVector4a* clothing_weight = &clothing_weights[vert_index_mesh]; + clothing_weight->add(clothing_offset); + clothing_weight->getF32ptr()[VW] = maskWeight; } // calculate new normals based on half angles - scaled_normals[vert_index_mesh] += mMorphData->mNormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; - LLVector3 normalized_normal = scaled_normals[vert_index_mesh]; - normalized_normal.normVec(); - normals[vert_index_mesh] = LLVector4(normalized_normal); + LLVector4a norm = mMorphData->mNormals[vert_index_morph]; + norm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); + scaled_normals[vert_index_mesh].add(norm); + norm = scaled_normals[vert_index_mesh]; + norm.normalize3fast(); + normals[vert_index_mesh] = norm; // calculate new binormals - scaled_binormals[vert_index_mesh] += mMorphData->mBinormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; - LLVector3 tangent = scaled_binormals[vert_index_mesh] % normalized_normal; - LLVector3 normalized_binormal = normalized_normal % tangent; - normalized_binormal.normVec(); - binormals[vert_index_mesh] = normalized_binormal; - + LLVector4a binorm = mMorphData->mBinormals[vert_index_morph]; + binorm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); + scaled_binormals[vert_index_mesh].add(binorm); + LLVector4a tangent; + tangent.setCross3(scaled_binormals[vert_index_mesh], norm); + LLVector4a& normalized_binormal = binormals[vert_index_mesh]; + normalized_binormal.setCross3(norm, tangent); + normalized_binormal.normalize3fast(); + tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight; } @@ -582,7 +635,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) //----------------------------------------------------------------------------- void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert) { - LLVector4 *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL; + LLVector4a *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL; if (!mVertMask) { @@ -596,29 +649,47 @@ void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S3 if (maskWeights) { - LLVector4 *coords = mMesh->getWritableCoords(); - LLVector3 *scaled_normals = mMesh->getScaledNormals(); - LLVector3 *scaled_binormals = mMesh->getScaledBinormals(); + LLVector4a *coords = mMesh->getWritableCoords(); + LLVector4a *scaled_normals = mMesh->getScaledNormals(); + LLVector4a *scaled_binormals = mMesh->getScaledBinormals(); LLVector2 *tex_coords = mMesh->getWritableTexCoords(); + LLVector4Logical clothing_mask; + clothing_mask.clear(); + clothing_mask.setElement<0>(); + clothing_mask.setElement<1>(); + clothing_mask.setElement<2>(); + + for(U32 vert = 0; vert < mMorphData->mNumIndices; vert++) { F32 lastMaskWeight = mLastWeight * maskWeights[vert]; S32 out_vert = mMorphData->mVertexIndices[vert]; // remove effect of existing masked morph - coords[out_vert] -= LLVector4(mMorphData->mCoords[vert]) * lastMaskWeight; - scaled_normals[out_vert] -= mMorphData->mNormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR; - scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR; + LLVector4a t; + t = mMorphData->mCoords[vert]; + t.mul(lastMaskWeight); + coords[out_vert].sub(t); + + t = mMorphData->mNormals[vert]; + t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR); + scaled_normals[out_vert].sub(t); + + t = mMorphData->mBinormals[vert]; + t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR); + scaled_binormals[out_vert].sub(t); + tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * lastMaskWeight; if (clothing_weights) { - LLVector3 clothing_offset = mMorphData->mCoords[vert] * lastMaskWeight; - LLVector4* clothing_weight = &clothing_weights[out_vert]; - clothing_weight->mV[VX] -= clothing_offset.mV[VX]; - clothing_weight->mV[VY] -= clothing_offset.mV[VY]; - clothing_weight->mV[VZ] -= clothing_offset.mV[VZ]; + LLVector4a clothing_offset = mMorphData->mCoords[vert]; + clothing_offset.mul(lastMaskWeight); + LLVector4a* clothing_weight = &clothing_weights[out_vert]; + LLVector4a t; + t.setSub(*clothing_weight, clothing_offset); + clothing_weight->setSelectWithMask(clothing_mask, t, *clothing_weight); } } } @@ -654,7 +725,7 @@ LLPolyVertexMask::~LLPolyVertexMask() //----------------------------------------------------------------------------- // generateMask() //----------------------------------------------------------------------------- -void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4 *clothing_weights) +void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights) { // RN debug output that uses Image Debugger (http://www.cs.unc.edu/~baxter/projects/imdebug/) // BOOL debugImg = FALSE; @@ -698,7 +769,7 @@ void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, if (clothing_weights) { - clothing_weights[vertIndex].mV[VW] = mWeights[index]; + clothing_weights[vertIndex].getF32ptr()[VW] = mWeights[index]; } } mWeightsGenerated = TRUE; diff --git a/indra/newview/llpolymorph.h b/indra/newview/llpolymorph.h index 8a024f2e9e..24940c52e0 100644 --- a/indra/newview/llpolymorph.h +++ b/indra/newview/llpolymorph.h @@ -41,6 +41,7 @@ class LLWearable; //----------------------------------------------------------------------------- // LLPolyMorphData() //----------------------------------------------------------------------------- +LL_ALIGN_PREFIX(16) class LLPolyMorphData { public: @@ -48,6 +49,16 @@ public: ~LLPolyMorphData(); LLPolyMorphData(const LLPolyMorphData &rhs); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + BOOL loadBinary(LLFILE* fp, LLPolyMeshSharedData *mesh); const std::string& getName() { return mName; } @@ -58,16 +69,20 @@ public: U32 mNumIndices; U32* mVertexIndices; U32 mCurrentIndex; - LLVector3* mCoords; - LLVector3* mNormals; - LLVector3* mBinormals; + LLVector4a* mCoords; + LLVector4a* mNormals; + LLVector4a* mBinormals; LLVector2* mTexCoords; F32 mTotalDistortion; // vertex distortion summed over entire morph F32 mMaxDistortion; // maximum single vertex distortion in a given morph - LLVector3 mAvgDistortion; // average vertex distortion, to infer directionality of the morph + LL_ALIGN_16(LLVector4a mAvgDistortion); // average vertex distortion, to infer directionality of the morph LLPolyMeshSharedData* mMesh; -}; + +private: + void freeData(); +} LL_ALIGN_POSTFIX(16); + //----------------------------------------------------------------------------- // LLPolyVertexMask() @@ -78,7 +93,7 @@ public: LLPolyVertexMask(LLPolyMorphData* morph_data); ~LLPolyVertexMask(); - void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4 *clothing_weights); + void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights); F32* getMorphMaskWeights(); @@ -157,11 +172,11 @@ public: // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion(); - /*virtual*/ const LLVector3& getAvgDistortion(); + /*virtual*/ const LLVector4a& getAvgDistortion(); /*virtual*/ F32 getMaxDistortion(); - /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); - /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); - /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); + /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); + /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); + /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); void applyMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert); void addPendingMorphMask() { mNumMorphMasksPending++; } diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp index 9fbb67a63a..08829c1184 100644 --- a/indra/newview/llpopupview.cpp +++ b/indra/newview/llpopupview.cpp @@ -83,7 +83,7 @@ void LLPopupView::draw() LLUI::pushMatrix(); { - LLUI::translate( (F32) screen_x, (F32) screen_y, 0.f); + LLUI::translate( (F32) screen_x, (F32) screen_y); popup->draw(); } LLUI::popMatrix(); diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index 18626e3273..04934b13f1 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -464,7 +464,9 @@ LLMultiPreview::LLMultiPreview() void LLMultiPreview::onOpen(const LLSD& key) { - LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel(); + // Floater could be something else than LLPreview, eg LLFloaterProfile. + LLPreview* frontmost_preview = dynamic_cast<LLPreview*>(mTabContainer->getCurrentPanel()); + if (frontmost_preview && frontmost_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED) { frontmost_preview->loadAsset(); @@ -477,8 +479,13 @@ void LLMultiPreview::handleReshape(const LLRect& new_rect, bool by_user) { if(new_rect.getWidth() != getRect().getWidth() || new_rect.getHeight() != getRect().getHeight()) { - LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel(); - if (frontmost_preview) frontmost_preview->userResized(); + // Floater could be something else than LLPreview, eg LLFloaterProfile. + LLPreview* frontmost_preview = dynamic_cast<LLPreview*>(mTabContainer->getCurrentPanel()); + + if (frontmost_preview) + { + frontmost_preview->userResized(); + } } LLFloater::handleReshape(new_rect, by_user); } @@ -486,7 +493,9 @@ void LLMultiPreview::handleReshape(const LLRect& new_rect, bool by_user) void LLMultiPreview::tabOpen(LLFloater* opened_floater, bool from_click) { - LLPreview* opened_preview = (LLPreview*)opened_floater; + // Floater could be something else than LLPreview, eg LLFloaterProfile. + LLPreview* opened_preview = dynamic_cast<LLPreview*>(opened_floater); + if (opened_preview && opened_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED) { opened_preview->loadAsset(); diff --git a/indra/newview/llpreview.h b/indra/newview/llpreview.h index 896e17c3c3..759430c3a5 100644 --- a/indra/newview/llpreview.h +++ b/indra/newview/llpreview.h @@ -32,6 +32,7 @@ #include "llpointer.h" #include "lluuid.h" #include "llinventoryobserver.h" +#include "llextendedstatus.h" #include <map> class LLInventoryItem; diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp index 8e8b530e13..35ac0537a3 100644 --- a/indra/newview/llpreviewanim.cpp +++ b/indra/newview/llpreviewanim.cpp @@ -43,19 +43,7 @@ extern LLAgent gAgent; LLPreviewAnim::LLPreviewAnim(const LLSD& key) : LLPreview( key ) { -} - -// static -void LLPreviewAnim::endAnimCallback( void *userdata ) -{ - LLHandle<LLFloater>* handlep = ((LLHandle<LLFloater>*)userdata); - LLFloater* self = handlep->get(); - delete handlep; // done with the handle - if (self) - { - self->getChild<LLUICtrl>("Anim play btn")->setValue(FALSE); - self->getChild<LLUICtrl>("Anim audition btn")->setValue(FALSE); - } + mCommitCallbackRegistrar.add("PreviewAnim.Play", boost::bind(&LLPreviewAnim::play, this, _2)); } // virtual @@ -68,106 +56,115 @@ BOOL LLPreviewAnim::postBuild() getChild<LLUICtrl>("desc")->setValue(item->getDescription()); } - childSetAction("Anim play btn",playAnim, this); - childSetAction("Anim audition btn",auditionAnim, this); - childSetCommitCallback("desc", LLPreview::onText, this); getChild<LLLineEditor>("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); - + return LLPreview::postBuild(); } -void LLPreviewAnim::activate(e_activation_type type) +// static +// llinventorybridge also calls into here +void LLPreviewAnim::play(const LLSD& param) { - switch ( type ) + const LLInventoryItem *item = getItem(); + + if(item) { - case PLAY: + LLUUID itemID=item->getAssetUUID(); + + std::string btn_name = param.asString(); + LLButton* btn_inuse; + LLButton* btn_other; + + if ("Inworld" == btn_name) { - playAnim( (void *) this ); - break; + btn_inuse = getChild<LLButton>("Inworld"); + btn_other = getChild<LLButton>("Locally"); } - case AUDITION: + else if ("Locally" == btn_name) { - auditionAnim( (void *) this ); - break; + btn_inuse = getChild<LLButton>("Locally"); + btn_other = getChild<LLButton>("Inworld"); } - default: + else { - //do nothing + return; } - } -} - -// static -void LLPreviewAnim::playAnim( void *userdata ) -{ - LLPreviewAnim* self = (LLPreviewAnim*) userdata; - const LLInventoryItem *item = self->getItem(); - if(item) - { - LLUUID itemID=item->getAssetUUID(); + if (btn_inuse) + { + btn_inuse->toggleState(); + } - LLButton* btn = self->getChild<LLButton>("Anim play btn"); - if (btn) + if (btn_other) { - btn->toggleState(); + btn_other->setEnabled(false); } - if (self->getChild<LLUICtrl>("Anim play btn")->getValue().asBoolean() ) + if (getChild<LLUICtrl>(btn_name)->getValue().asBoolean() ) { - self->mPauseRequest = NULL; - gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_START); + if("Inworld" == btn_name) + { + gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_START); + } + else + { + gAgentAvatarp->startMotion(item->getAssetUUID()); + } + LLMotion* motion = gAgentAvatarp->findMotion(itemID); if (motion) { - motion->setDeactivateCallback(&endAnimCallback, (void *)(new LLHandle<LLFloater>(self->getHandle()))); + mItemID = itemID; + mDidStart = false; } } else { gAgentAvatarp->stopMotion(itemID); gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_STOP); + + if (btn_other) + { + btn_other->setEnabled(true); + } } } } -// static -void LLPreviewAnim::auditionAnim( void *userdata ) +// virtual +void LLPreviewAnim::draw() { - LLPreviewAnim* self = (LLPreviewAnim*) userdata; - const LLInventoryItem *item = self->getItem(); - - if(item) + LLPreview::draw(); + if (!this->mItemID.isNull()) { - LLUUID itemID=item->getAssetUUID(); - - LLButton* btn = self->getChild<LLButton>("Anim audition btn"); - if (btn) - { - btn->toggleState(); - } - - if (self->getChild<LLUICtrl>("Anim audition btn")->getValue().asBoolean() ) + LLMotion* motion = gAgentAvatarp->findMotion(this->mItemID); + if (motion) { - self->mPauseRequest = NULL; - gAgentAvatarp->startMotion(item->getAssetUUID()); - LLMotion* motion = gAgentAvatarp->findMotion(itemID); - - if (motion) + if (motion->isStopped() && this->mDidStart) { - motion->setDeactivateCallback(&endAnimCallback, (void *)(new LLHandle<LLFloater>(self->getHandle()))); + cleanup(); + } + if(gAgentAvatarp->isMotionActive(this->mItemID) && !this->mDidStart) + { + this->mDidStart = true; } - } - else - { - gAgentAvatarp->stopMotion(itemID); - gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_STOP); } } } // virtual +void LLPreviewAnim::cleanup() +{ + this->mItemID = LLUUID::null; + this->mDidStart = false; + getChild<LLUICtrl>("Inworld")->setValue(FALSE); + getChild<LLUICtrl>("Locally")->setValue(FALSE); + getChild<LLUICtrl>("Inworld")->setEnabled(true); + getChild<LLUICtrl>("Locally")->setEnabled(true); +} + +// virtual void LLPreviewAnim::onClose(bool app_quitting) { const LLInventoryItem *item = getItem(); @@ -176,12 +173,5 @@ void LLPreviewAnim::onClose(bool app_quitting) { gAgentAvatarp->stopMotion(item->getAssetUUID()); gAgent.sendAnimationRequest(item->getAssetUUID(), ANIM_REQUEST_STOP); - LLMotion* motion = gAgentAvatarp->findMotion(item->getAssetUUID()); - - if (motion) - { - // *TODO: minor memory leak here, user data is never deleted (Use real callbacks) - motion->setDeactivateCallback(NULL, (void *)NULL); - } } } diff --git a/indra/newview/llpreviewanim.h b/indra/newview/llpreviewanim.h index 32e07ee33a..8eaed6ca1f 100644 --- a/indra/newview/llpreviewanim.h +++ b/indra/newview/llpreviewanim.h @@ -33,24 +33,18 @@ class LLPreviewAnim : public LLPreview { public: - enum e_activation_type { NONE = 0, PLAY = 1, AUDITION = 2 }; - LLPreviewAnim(const LLSD& key); - static void playAnim( void* userdata ); - static void auditionAnim( void* userdata ); - static void endAnimCallback( void *userdata ); + LLPreviewAnim(const LLSD& key); /*virtual*/ BOOL postBuild(); /*virtual*/ void onClose(bool app_quitting); - void activate(e_activation_type type); + void draw(); + void cleanup(); + void play(const LLSD& param); protected: - LLAnimPauseRequest mPauseRequest; - LLUUID mItemID; - std::string mTitle; - LLUUID mObjectID; - LLButton* mPlayBtn; - LLButton* mAuditionBtn; + LLUUID mItemID; + bool mDidStart; }; -#endif // LL_LLPREVIEWSOUND_H +#endif // LL_LLPREVIEWANIM_H diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 4974dde282..3a9360fd23 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -29,7 +29,6 @@ #include "llpreviewnotecard.h" #include "llinventory.h" -#include "llinventoryfunctions.h" // for change_item_parent() #include "llagent.h" #include "llassetuploadresponders.h" @@ -494,7 +493,7 @@ void LLPreviewNotecard::deleteNotecard() if (item != NULL) { const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - change_item_parent(&gInventory, item, trash_id, FALSE); + gInventory.changeItemParent(item, trash_id, FALSE); } closeFloater(); diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index b19bf5d234..968a912ea2 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" @@ -304,7 +305,11 @@ BOOL LLFloaterScriptSearch::handleKeyHere(KEY key, MASK mask) { if (mEditorCore) { - return mEditorCore->handleKeyHere(key, mask); + BOOL handled = mEditorCore->handleKeyHere(key, mask); + if (!handled) + { + LLFloater::handleKeyHere(key, mask); + } } return FALSE; @@ -503,6 +508,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) @@ -806,7 +819,7 @@ void LLScriptEdCore::onBtnDynamicHelp() if (!live_help_floater) { live_help_floater = new LLFloater(LLSD()); - live_help_floater->buildFromFile("floater_lsl_guide.xml", NULL); + live_help_floater->buildFromFile("floater_lsl_guide.xml"); LLFloater* parent = dynamic_cast<LLFloater*>(getParent()); llassert(parent); if (parent) @@ -1096,6 +1109,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/llprogressview.cpp b/indra/newview/llprogressview.cpp index 5d7a5b1c59..989f0b0e60 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -40,6 +40,7 @@ #include "llagent.h" #include "llbutton.h" +#include "llcallbacklist.h" #include "llfocusmgr.h" #include "llnotifications.h" #include "llprogressbar.h" @@ -72,6 +73,8 @@ LLProgressView::LLProgressView() mStartupComplete(false) { mUpdateEvents.listen("self", boost::bind(&LLProgressView::handleUpdate, this, _1)); + mFadeToWorldTimer.stop(); + mFadeFromLoginTimer.stop(); } BOOL LLProgressView::postBuild() @@ -87,15 +90,13 @@ BOOL LLProgressView::postBuild() mCancelBtn = getChild<LLButton>("cancel_btn"); mCancelBtn->setClickedCallback( LLProgressView::onCancelButtonClicked, NULL ); - mFadeToWorldTimer.stop(); - mFadeFromLoginTimer.stop(); getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle())); getChild<LLTextBox>("message_text")->setClickedCallback(onClickMessage, this); // hidden initially, until we need it - LLPanel::setVisible(FALSE); + setVisible(FALSE); LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLProgressView::onAlertModal, this, _1)); @@ -106,6 +107,9 @@ BOOL LLProgressView::postBuild() LLProgressView::~LLProgressView() { + // Just in case something went wrong, make sure we deregister our idle callback. + gIdleCallbacks.deleteFunction(onIdle, this); + gFocusMgr.releaseFocusIfNeeded( this ); sInstance = NULL; @@ -154,6 +158,7 @@ void LLProgressView::revealIntroPanel() } mFadeFromLoginTimer.start(); + gIdleCallbacks.addFunction(onIdle, this); } void LLProgressView::setStartupComplete() @@ -236,13 +241,6 @@ void LLProgressView::draw() } LLPanel::draw(); - - if (mFadeFromLoginTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME ) - { - mFadeFromLoginTimer.stop(); - LLPanelLogin::closePanel(); - } - return; } @@ -267,7 +265,7 @@ void LLProgressView::draw() gFocusMgr.releaseFocusIfNeeded( this ); // turn off panel that hosts intro so we see the world - LLPanel::setVisible(FALSE); + setVisible(FALSE); // stop observing events since we no longer care mMediaCtrl->remObserver( this ); @@ -424,3 +422,21 @@ void LLProgressView::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent even } } } + + +// static +void LLProgressView::onIdle(void* user_data) +{ + LLProgressView* self = (LLProgressView*) user_data; + + // Close login panel on mFadeToWorldTimer expiration. + if (self->mFadeFromLoginTimer.getStarted() && + self->mFadeFromLoginTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME) + { + self->mFadeFromLoginTimer.stop(); + LLPanelLogin::closePanel(); + + // Nothing to do anymore. + gIdleCallbacks.deleteFunction(onIdle, user_data); + } +} diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h index fac00ad04d..813576b21d 100644 --- a/indra/newview/llprogressview.h +++ b/indra/newview/llprogressview.h @@ -41,6 +41,8 @@ class LLProgressView : public LLViewerMediaObserver { + LOG_CLASS(LLProgressView); + public: LLProgressView(); virtual ~LLProgressView(); @@ -74,10 +76,6 @@ public: static void onClickMessage(void*); bool onAlertModal(const LLSD& sd); - // note - this is not just hiding the intro panel - it also hides the parent panel - // and is used when the intro is finished and we want to show the world - void removeIntroPanel(); - protected: LLProgressBar* mProgressBar; LLMediaCtrl* mMediaCtrl; @@ -96,6 +94,7 @@ protected: LLEventStream mUpdateEvents; bool handleUpdate(const LLSD& event_data); + static void onIdle(void* user_data); }; #endif // LL_LLPROGRESSVIEW_H diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 15ba5195d9..154555b261 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -39,7 +39,7 @@ #include "lldockablefloater.h" #include "llsyswellwindow.h" -#include "llimfloater.h" +#include "llfloaterimsession.h" #include "llscriptfloater.h" #include "llrootview.h" @@ -53,13 +53,22 @@ LLFastTimer::DeclareTimer FTM_GET_CHANNEL_RECT("Calculate Notification Channel R LLRect LLScreenChannelBase::getChannelRect() { LLFastTimer _(FTM_GET_CHANNEL_RECT); + + if (mFloaterSnapRegion == NULL) + { + mFloaterSnapRegion = gViewerWindow->getRootView()->getChildView("floater_snap_region"); + } + + if (mChicletRegion == NULL) + { + mChicletRegion = gViewerWindow->getRootView()->getChildView("chiclet_container"); + } + LLRect channel_rect; LLRect chiclet_rect; - LLView* floater_snap_region = gViewerWindow->getRootView()->getChildView("floater_snap_region"); - floater_snap_region->localRectToScreen(floater_snap_region->getLocalRect(), &channel_rect); - LLView* chiclet_region = gViewerWindow->getRootView()->getChildView("chiclet_container"); - chiclet_region->localRectToScreen(chiclet_region->getLocalRect(), &chiclet_rect); + mFloaterSnapRegion->localRectToScreen(mFloaterSnapRegion->getLocalRect(), &channel_rect); + mChicletRegion->localRectToScreen(mChicletRegion->getLocalRect(), &chiclet_rect); channel_rect.mTop = chiclet_rect.mBottom; return channel_rect; @@ -81,14 +90,31 @@ LLScreenChannelBase::LLScreenChannelBase(const Params& p) mShowToasts(true), mID(p.id), mDisplayToastsAlways(p.display_toasts_always), - mChannelAlignment(p.channel_align) -{ + mChannelAlignment(p.channel_align), + mFloaterSnapRegion(NULL), + mChicletRegion(NULL) +{ mID = p.id; setMouseOpaque( false ); setVisible(FALSE); } +BOOL LLScreenChannelBase::postBuild() +{ + if (mFloaterSnapRegion == NULL) + { + mFloaterSnapRegion = gViewerWindow->getRootView()->getChildView("floater_snap_region"); + } + + if (mChicletRegion == NULL) + { + mChicletRegion = gViewerWindow->getRootView()->getChildView("chiclet_container"); + } + + return TRUE; +} + void LLScreenChannelBase::reshape(S32 width, S32 height, BOOL called_from_parent) { redrawToasts(); @@ -169,17 +195,18 @@ LLScreenChannel::~LLScreenChannel() } -std::list<LLToast*> LLScreenChannel::findToasts(const Matcher& matcher) +std::list<const LLToast*> LLScreenChannel::findToasts(const Matcher& matcher) { - std::list<LLToast*> res; + std::list<const LLToast*> res; // collect stored toasts for (std::vector<ToastElem>::iterator it = mStoredToastList.begin(); it != mStoredToastList.end(); it++) { - if (matcher.matches(it->toast->getNotification())) + const LLToast* toast = it->getToast(); + if (toast && matcher.matches(toast->getNotification())) { - res.push_back(it->toast); + res.push_back(toast); } } @@ -187,9 +214,10 @@ std::list<LLToast*> LLScreenChannel::findToasts(const Matcher& matcher) for (std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++) { - if (matcher.matches(it->toast->getNotification())) + const LLToast* toast = it->getToast(); + if (toast && matcher.matches(toast->getNotification())) { - res.push_back(it->toast); + res.push_back(toast); } } @@ -225,24 +253,39 @@ void LLScreenChannel::addToast(const LLToast::Params& p) { bool store_toast = false, show_toast = false; - mDisplayToastsAlways ? show_toast = true : show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show); + if (mDisplayToastsAlways) + { + show_toast = true; + } + else + { + show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show); + } store_toast = !show_toast && p.can_be_stored && mCanStoreToasts; if(!show_toast && !store_toast) { - mRejectToastSignal(p.notif_id); + LLNotificationPtr notification = LLNotifications::instance().find(p.notif_id); + + if (notification && + (!notification->canLogToIM() || !notification->hasFormElements())) + { + // only cancel notification if it isn't being used in IM session + LLNotifications::instance().cancel(notification); + } return; } - ToastElem new_toast_elem(p); + LLToast* toast = new LLToast(p); + ToastElem new_toast_elem(toast->getHandle()); - new_toast_elem.toast->setOnFadeCallback(boost::bind(&LLScreenChannel::onToastFade, this, _1)); - new_toast_elem.toast->setOnToastDestroyedCallback(boost::bind(&LLScreenChannel::onToastDestroyed, this, _1)); + toast->setOnFadeCallback(boost::bind(&LLScreenChannel::onToastFade, this, _1)); + toast->setOnToastDestroyedCallback(boost::bind(&LLScreenChannel::onToastDestroyed, this, _1)); if(mControlHovering) { - new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2)); - new_toast_elem.toast->setMouseEnterCallback(boost::bind(&LLScreenChannel::stopToastTimer, this, new_toast_elem.toast)); - new_toast_elem.toast->setMouseLeaveCallback(boost::bind(&LLScreenChannel::startToastTimer, this, new_toast_elem.toast)); + toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2)); + toast->setMouseEnterCallback(boost::bind(&LLScreenChannel::stopToastTimer, this, toast)); + toast->setMouseLeaveCallback(boost::bind(&LLScreenChannel::startToastTimer, this, toast)); } if(show_toast) @@ -314,13 +357,13 @@ void LLScreenChannel::onToastFade(LLToast* toast) //-------------------------------------------------------------------------- void LLScreenChannel::deleteToast(LLToast* toast) { - if (toast->isDead()) + if (!toast || toast->isDead()) { return; } // send signal to observers about destroying of a toast - toast->mOnDeleteToastSignal(toast); + toast->closeToast(); // update channel's Hovering state // turning hovering off manually because onMouseLeave won't happen if a toast was closed using a keyboard @@ -328,9 +371,6 @@ void LLScreenChannel::deleteToast(LLToast* toast) { mHoveredToast = NULL; } - - // close the toast - toast->closeFloater(); } //-------------------------------------------------------------------------- @@ -338,12 +378,16 @@ void LLScreenChannel::deleteToast(LLToast* toast) void LLScreenChannel::storeToast(ToastElem& toast_elem) { // do not store clones - std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), toast_elem.id); + std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), toast_elem.getID()); if( it != mStoredToastList.end() ) return; + const LLToast* toast = toast_elem.getToast(); + if (toast) + { mStoredToastList.push_back(toast_elem); - mOnStoreToast(toast_elem.toast->getPanel(), toast_elem.id); + mOnStoreToast(toast->getPanel(), toast->getNotificationID()); + } } //-------------------------------------------------------------------------- @@ -356,9 +400,13 @@ void LLScreenChannel::loadStoredToastsToChannel() for(it = mStoredToastList.begin(); it != mStoredToastList.end(); ++it) { - (*it).toast->setIsHidden(false); - (*it).toast->startTimer(); - mToastList.push_back((*it)); + LLToast* toast = it->getToast(); + if (toast) + { + toast->setIsHidden(false); + toast->startTimer(); + mToastList.push_back(*it); + } } mStoredToastList.clear(); @@ -373,8 +421,9 @@ void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id) if( it == mStoredToastList.end() ) return; - LLToast* toast = (*it).toast; - + LLToast* toast = it->getToast(); + if (toast) + { if(toast->getVisible()) { // toast is already in channel @@ -383,70 +432,96 @@ void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id) toast->setIsHidden(false); toast->startTimer(); - mToastList.push_back((*it)); + mToastList.push_back(*it); + } redrawToasts(); } //-------------------------------------------------------------------------- -void LLScreenChannel::removeStoredToastByNotificationID(LLUUID id) -{ - // *TODO: may be remove this function - std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), id); - - if( it == mStoredToastList.end() ) - return; - - LLToast* toast = (*it).toast; - mStoredToastList.erase(it); - mRejectToastSignal(toast->getNotificationID()); -} - -//-------------------------------------------------------------------------- void LLScreenChannel::killToastByNotificationID(LLUUID id) { // searching among toasts on a screen std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id); + LLNotificationPtr notification = LLNotifications::instance().find(id); + if (!notification) return; if( it != mToastList.end()) { - LLToast* toast = (*it).toast; + LLToast* toast = it->getToast(); // if it is a notification toast and notification is UnResponded - then respond on it // else - simply destroy a toast // // NOTE: if a notification is unresponded this function will be called twice for the same toast. // At first, the notification will be discarded, at second (it will be caused by discarding), // the toast will be destroyed. - if(toast->isNotificationValid()) + if(toast && toast->isNotificationValid()) { - mRejectToastSignal(toast->getNotificationID()); + if (!notification->canLogToIM() || !notification->hasFormElements()) + { + // only cancel notification if it isn't being used in IM session + LLNotifications::instance().cancel(notification); + } } else { - mToastList.erase(it); - deleteToast(toast); - redrawToasts(); + removeToastByNotificationID(id); } - return; } + else + { + // searching among stored toasts + it = find(mStoredToastList.begin(), mStoredToastList.end(), id); - // searching among stored toasts - it = find(mStoredToastList.begin(), mStoredToastList.end(), id); + if( it != mStoredToastList.end() ) + { + LLToast* toast = it->getToast(); + if (toast) + { + if (!notification->canLogToIM() || !notification->hasFormElements()) + { + // only cancel notification if it isn't being used in IM session + LLNotifications::instance().cancel(notification); + } + deleteToast(toast); + } + } + + // Call find() once more, because the mStoredToastList could have been changed + // via notification cancellation and the iterator could have become invalid. + it = find(mStoredToastList.begin(), mStoredToastList.end(), id); + if (it != mStoredToastList.end()) + { + mStoredToastList.erase(it); + } + } +} - if( it != mStoredToastList.end() ) +void LLScreenChannel::removeToastByNotificationID(LLUUID id) +{ + std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id); + while( it != mToastList.end()) { - LLToast* toast = (*it).toast; + deleteToast(it->getToast()); + mToastList.erase(it); + redrawToasts(); + // find next toast with matching id + it = find(mToastList.begin(), mToastList.end(), id); + } + + it = find(mStoredToastList.begin(), mStoredToastList.end(), id); + if (it != mStoredToastList.end()) + { + deleteToast(it->getToast()); mStoredToastList.erase(it); - // send signal to a listener to let him perform some action on toast rejecting - mRejectToastSignal(toast->getNotificationID()); - deleteToast(toast); } } + void LLScreenChannel::killMatchedToasts(const Matcher& matcher) { - std::list<LLToast*> to_delete = findToasts(matcher); - for (std::list<LLToast*>::iterator it = to_delete.begin(); it + std::list<const LLToast*> to_delete = findToasts(matcher); + for (std::list<const LLToast*>::iterator it = to_delete.begin(); it != to_delete.end(); it++) { killToastByNotificationID((*it)-> getNotificationID()); @@ -460,12 +535,15 @@ void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel) if( it != mToastList.end() && panel) { - LLToast* toast = (*it).toast; + LLToast* toast = it->getToast(); + if (toast) + { LLPanel* old_panel = toast->getPanel(); toast->removeChild(old_panel); delete old_panel; toast->insertPanel(panel); toast->startTimer(); + } redrawToasts(); } } @@ -473,12 +551,10 @@ void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel) //-------------------------------------------------------------------------- void LLScreenChannel::redrawToasts() { - LLView* floater_snap_region = gViewerWindow->getRootView()->getChildView("floater_snap_region"); - if (!getParent()) { // connect to floater snap region just to get resize events, we don't care about being a proper widget - floater_snap_region->addChild(this); + mFloaterSnapRegion->addChild(this); setFollows(FOLLOWS_ALL); } @@ -512,24 +588,41 @@ void LLScreenChannel::showToastsBottom() LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get()); - for(it = mToastList.rbegin(); it != mToastList.rend(); ++it) + // Use a local variable instead of mToastList. + // mToastList can be modified during recursive calls and then all iteratos will be invalidated. + std::vector<ToastElem> vToastList( mToastList ); + + for(it = vToastList.rbegin(); it != vToastList.rend(); ++it) { - if(it != mToastList.rbegin()) + if(it != vToastList.rbegin()) { - LLToast* toast = (*(it-1)).toast; + LLToast* toast = (it-1)->getToast(); + if (!toast) + { + llwarns << "Attempt to display a deleted toast." << llendl; + return; + } + bottom = toast->getRect().mTop - toast->getTopPad(); toast_margin = gSavedSettings.getS32("ToastGap"); } - toast_rect = (*it).toast->getRect(); + LLToast* toast = it->getToast(); + if(!toast) + { + llwarns << "Attempt to display a deleted toast." << llendl; + return; + } + + toast_rect = toast->getRect(); toast_rect.setOriginAndSize(getRect().mRight - toast_rect.getWidth(), bottom + toast_margin, toast_rect.getWidth(), toast_rect.getHeight()); - (*it).toast->setRect(toast_rect); + toast->setRect(toast_rect); if(floater && floater->overlapsScreenChannel()) { - if(it == mToastList.rbegin()) + if(it == vToastList.rbegin()) { // move first toast above docked floater S32 shift = floater->getRect().getHeight(); @@ -537,7 +630,7 @@ void LLScreenChannel::showToastsBottom() { shift += floater->getDockControl()->getTongueHeight(); } - (*it).toast->translate(0, shift); + toast->translate(0, shift); } LLRect channel_rect = getChannelRect(); @@ -548,19 +641,20 @@ void LLScreenChannel::showToastsBottom() } } - bool stop_showing_toasts = (*it).toast->getRect().mTop > getRect().mTop; + bool stop_showing_toasts = toast->getRect().mTop > getRect().mTop; if(!stop_showing_toasts) { - if( it != mToastList.rend()-1) + if( it != vToastList.rend()-1) { - S32 toast_top = (*it).toast->getRect().mTop + gSavedSettings.getS32("ToastGap"); + S32 toast_top = toast->getRect().mTop + gSavedSettings.getS32("ToastGap"); stop_showing_toasts = toast_top > getRect().mTop; } } // at least one toast should be visible - if(it == mToastList.rbegin()) + + if(it == vToastList.rbegin()) { stop_showing_toasts = false; } @@ -568,27 +662,32 @@ void LLScreenChannel::showToastsBottom() if(stop_showing_toasts) break; - if( !(*it).toast->getVisible() ) + if( !toast->getVisible() ) { // HACK // EXT-2653: it is necessary to prevent overlapping for secondary showed toasts - (*it).toast->setVisible(TRUE); + toast->setVisible(TRUE); } - if(!(*it).toast->hasFocus()) + if(!toast->hasFocus()) { // Fixing Z-order of toasts (EXT-4862) // Next toast will be positioned under this one. - gFloaterView->sendChildToBack((*it).toast); + gFloaterView->sendChildToBack(toast); } } // Dismiss toasts we don't have space for (STORM-391). - if(it != mToastList.rend()) + if(it != vToastList.rend()) { mHiddenToastsNum = 0; - for(; it != mToastList.rend(); it++) + + for(; it != vToastList.rend(); it++) { - (*it).toast->hide(); + LLToast* toast = it->getToast(); + if (toast) + { + toast->hide(); + } } } } @@ -596,17 +695,31 @@ void LLScreenChannel::showToastsBottom() //-------------------------------------------------------------------------- void LLScreenChannel::showToastsCentre() { + LLToast* toast = mToastList[0].getToast(); + if (!toast) + { + llwarns << "Attempt to display a deleted toast." << llendl; + return; + } + LLRect toast_rect; - S32 bottom = (getRect().mTop - getRect().mBottom)/2 + mToastList[0].toast->getRect().getHeight()/2; + S32 bottom = (getRect().mTop - getRect().mBottom)/2 + toast->getRect().getHeight()/2; std::vector<ToastElem>::reverse_iterator it; for(it = mToastList.rbegin(); it != mToastList.rend(); ++it) { - toast_rect = (*it).toast->getRect(); + LLToast* toast = it->getToast(); + if (!toast) + { + llwarns << "Attempt to display a deleted toast." << llendl; + return; + } + + toast_rect = toast->getRect(); toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, bottom + toast_rect.getHeight() / 2 + gSavedSettings.getS32("ToastGap"), toast_rect.getWidth() ,toast_rect.getHeight()); - (*it).toast->setRect(toast_rect); + toast->setRect(toast_rect); - (*it).toast->setVisible(TRUE); + toast->setVisible(TRUE); } } @@ -624,24 +737,41 @@ void LLScreenChannel::showToastsTop() LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get()); - for(it = mToastList.rbegin(); it != mToastList.rend(); ++it) + // Use a local variable instead of mToastList. + // mToastList can be modified during recursive calls and then all iteratos will be invalidated. + std::vector<ToastElem> vToastList( mToastList ); + + for(it = vToastList.rbegin(); it != vToastList.rend(); ++it) { - if(it != mToastList.rbegin()) + if(it != vToastList.rbegin()) { - LLToast* toast = (*(it-1)).toast; + LLToast* toast = (it-1)->getToast(); + if (!toast) + { + llwarns << "Attempt to display a deleted toast." << llendl; + return; + } + top = toast->getRect().mBottom - toast->getTopPad(); toast_margin = gSavedSettings.getS32("ToastGap"); } - toast_rect = (*it).toast->getRect(); + LLToast* toast = it->getToast(); + if (!toast) + { + llwarns << "Attempt to display a deleted toast." << llendl; + return; + } + + toast_rect = toast->getRect(); toast_rect.setLeftTopAndSize(channel_rect.mRight - toast_rect.getWidth(), top, toast_rect.getWidth(), toast_rect.getHeight()); - (*it).toast->setRect(toast_rect); + toast->setRect(toast_rect); if(floater && floater->overlapsScreenChannel()) { - if(it == mToastList.rbegin()) + if(it == vToastList.rbegin()) { // move first toast above docked floater S32 shift = -floater->getRect().getHeight(); @@ -649,7 +779,7 @@ void LLScreenChannel::showToastsTop() { shift -= floater->getDockControl()->getTongueHeight(); } - (*it).toast->translate(0, shift); + toast->translate(0, shift); } LLRect channel_rect = getChannelRect(); @@ -660,19 +790,19 @@ void LLScreenChannel::showToastsTop() } } - bool stop_showing_toasts = (*it).toast->getRect().mBottom < channel_rect.mBottom; + bool stop_showing_toasts = toast->getRect().mBottom < channel_rect.mBottom; if(!stop_showing_toasts) { - if( it != mToastList.rend()-1) + if( it != vToastList.rend()-1) { - S32 toast_bottom = (*it).toast->getRect().mBottom - gSavedSettings.getS32("ToastGap"); + S32 toast_bottom = toast->getRect().mBottom - gSavedSettings.getS32("ToastGap"); stop_showing_toasts = toast_bottom < channel_rect.mBottom; } } // at least one toast should be visible - if(it == mToastList.rbegin()) + if(it == vToastList.rbegin()) { stop_showing_toasts = false; } @@ -680,29 +810,43 @@ void LLScreenChannel::showToastsTop() if(stop_showing_toasts) break; - if( !(*it).toast->getVisible() ) + if (!toast->getVisible()) { // HACK // EXT-2653: it is necessary to prevent overlapping for secondary showed toasts - (*it).toast->setVisible(TRUE); + toast->setVisible(TRUE); } - if(!(*it).toast->hasFocus()) + if (!toast->hasFocus()) { // Fixing Z-order of toasts (EXT-4862) // Next toast will be positioned under this one. - gFloaterView->sendChildToBack((*it).toast); + gFloaterView->sendChildToBack(toast); } } // Dismiss toasts we don't have space for (STORM-391). - if(it != mToastList.rend()) + std::vector<LLToast*> toasts_to_hide; + + if(it != vToastList.rend()) { mHiddenToastsNum = 0; - for(; it != mToastList.rend(); it++) + + for(; it != vToastList.rend(); it++) { - (*it).toast->hide(); + LLToast* toast = it->getToast(); + if (toast) + { + toasts_to_hide.push_back(toast); + } } } + + for (std::vector<LLToast*>::iterator it = toasts_to_hide.begin(), end_it = toasts_to_hide.end(); + it != end_it; + ++it) + { + (*it)->hide(); + } } //-------------------------------------------------------------------------- @@ -803,7 +947,17 @@ void LLNotificationsUI::LLScreenChannel::startToastTimer(LLToast* toast) void LLScreenChannel::hideToastsFromScreen() { for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++) - (*it).toast->setVisible(FALSE); + { + LLToast* toast = it->getToast(); + if (toast) + { + toast->setVisible(FALSE); + } + else + { + llwarns << "Attempt to hide a deleted toast." << llendl; + } + } } //-------------------------------------------------------------------------- @@ -812,8 +966,15 @@ void LLScreenChannel::hideToast(const LLUUID& notification_id) std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), notification_id); if(mToastList.end() != it) { - ToastElem te = *it; - te.toast->hide(); + LLToast* toast = it->getToast(); + if (toast) + { + toast->hide(); + } + else + { + llwarns << "Attempt to hide a deleted toast." << llendl; + } } } @@ -821,24 +982,25 @@ void LLScreenChannel::closeHiddenToasts(const Matcher& matcher) { // since we can't guarantee that close toast operation doesn't change mToastList // we collect matched toasts that should be closed into separate list - std::list<ToastElem> toasts; + std::list<LLToast*> toasts; for (std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++) { - LLToast * toast = it->toast; + LLToast* toast = it->getToast(); // add to list valid toast that match to provided matcher criteria if (toast != NULL && !toast->isDead() && toast->getNotification() != NULL && !toast->getVisible() && matcher.matches(toast->getNotification())) { - toasts.push_back(*it); + toasts.push_back(toast); } } // close collected toasts - for (std::list<ToastElem>::iterator it = toasts.begin(); it + for (std::list<LLToast*>::iterator it = toasts.begin(); it != toasts.end(); it++) { - it->toast->closeFloater(); + LLToast* toast = *it; + toast->closeFloater(); } } @@ -848,7 +1010,7 @@ void LLScreenChannel::removeToastsFromChannel() hideToastsFromScreen(); for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++) { - deleteToast((*it).toast); + deleteToast(it->getToast()); } mToastList.clear(); } @@ -862,9 +1024,10 @@ void LLScreenChannel::removeAndStoreAllStorableToasts() hideToastsFromScreen(); for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end();) { - if((*it).toast->getCanBeStored()) + LLToast* toast = it->getToast(); + if(toast && toast->getCanBeStored()) { - storeToast(*(it)); + storeToast(*it); it = mToastList.erase(it); } else @@ -884,9 +1047,10 @@ void LLScreenChannel::removeToastsBySessionID(LLUUID id) hideToastsFromScreen(); for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end();) { - if((*it).toast->getSessionID() == id) + LLToast* toast = it->getToast(); + if(toast && toast->getSessionID() == id) { - deleteToast((*it).toast); + deleteToast(toast); it = mToastList.erase(it); } else @@ -944,5 +1108,5 @@ LLToast* LLScreenChannel::getToastByNotificationID(LLUUID id) if (it == mStoredToastList.end()) return NULL; - return it->toast; + return it->getToast(); } diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h index 2f23552828..e5f4807ab7 100644 --- a/indra/newview/llscreenchannel.h +++ b/indra/newview/llscreenchannel.h @@ -69,6 +69,8 @@ public: }; LLScreenChannelBase(const Params&); + + BOOL postBuild(); void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); @@ -82,6 +84,7 @@ public: // kill or modify a toast by its ID virtual void killToastByNotificationID(LLUUID id) {}; virtual void modifyToastNotificationByID(LLUUID id, LLSD data) {}; + virtual void removeToastByNotificationID(LLUUID id){}; // hide all toasts from screen, but not remove them from a channel virtual void hideToastsFromScreen() {}; @@ -115,7 +118,7 @@ public: // get ID of a channel LLUUID getChannelID() { return mID; } - LLHandle<LLScreenChannelBase> getHandle() { mRootHandle.bind(this); return mRootHandle; } + LLHandle<LLScreenChannelBase> getHandle() { return getDerivedHandle<LLScreenChannelBase>(); } protected: void updateRect(); @@ -123,12 +126,11 @@ protected: // Channel's flags bool mControlHovering; - LLToast* mHoveredToast; + LLToast* mHoveredToast; bool mCanStoreToasts; bool mDisplayToastsAlways; // controls whether a channel shows toasts or not bool mShowToasts; - LLRootHandle<LLScreenChannelBase> mRootHandle; // EToastAlignment mToastAlignment; EChannelAlignment mChannelAlignment; @@ -137,6 +139,9 @@ protected: // channel's ID LLUUID mID; + + LLView* mFloaterSnapRegion; + LLView* mChicletRegion; }; @@ -158,7 +163,7 @@ public: virtual bool matches(const LLNotificationPtr) const = 0; }; - std::list<LLToast*> findToasts(const Matcher& matcher); + std::list<const LLToast*> findToasts(const Matcher& matcher); // Channel's outfit-functions // update channel's size and position in the World View @@ -171,6 +176,7 @@ public: void addToast(const LLToast::Params& p); // kill or modify a toast by its ID void killToastByNotificationID(LLUUID id); + void removeToastByNotificationID(LLUUID id); void killMatchedToasts(const Matcher& matcher); void modifyToastByNotificationID(LLUUID id, LLPanel* panel); // hide all toasts from screen, but not remove them from a channel @@ -191,8 +197,6 @@ public: void loadStoredToastsToChannel(); // finds a toast among stored by its Notification ID and throws it on a screen to a channel void loadStoredToastByNotificationIDToChannel(LLUUID id); - // removes a toast from stored finding it by its Notification ID - void removeStoredToastByNotificationID(LLUUID id); // removes from channel all toasts that belongs to the certain IM session void removeToastsBySessionID(LLUUID id); // remove all storable toasts from screen and store them @@ -223,41 +227,45 @@ public: // Channel's signals // signal on storing of faded toasts event - typedef boost::function<void (LLPanel* info_panel, const LLUUID id)> store_tost_callback_t; - typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_tost_signal_t; - store_tost_signal_t mOnStoreToast; - boost::signals2::connection setOnStoreToastCallback(store_tost_callback_t cb) { return mOnStoreToast.connect(cb); } - // signal on rejecting of a toast event - typedef boost::function<void (LLUUID id)> reject_tost_callback_t; - typedef boost::signals2::signal<void (LLUUID id)> reject_tost_signal_t; - reject_tost_signal_t mRejectToastSignal; boost::signals2::connection setOnRejectToastCallback(reject_tost_callback_t cb) { return mRejectToastSignal.connect(cb); } + typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_toast_signal_t; + boost::signals2::connection addOnStoreToastCallback(store_toast_signal_t::slot_type cb) { return mOnStoreToast.connect(cb); } private: - struct ToastElem + store_toast_signal_t mOnStoreToast; + + class ToastElem { - LLUUID id; - LLToast* toast; + public: + ToastElem(const LLHandle<LLToast>& toast) : mToast(toast) + { + } - ToastElem(LLToast::Params p) : id(p.notif_id) + ToastElem(const ToastElem& toast_elem) : mToast(toast_elem.mToast) { - toast = new LLToast(p); } - ToastElem(const ToastElem& toast_elem) + LLToast* getToast() const { - id = toast_elem.id; - toast = toast_elem.toast; + return mToast.get(); + } + + LLUUID getID() const + { + return mToast.isDead() ? LLUUID() : mToast.get()->getNotificationID(); } bool operator == (const LLUUID &id_op) const { - return (id == id_op); + return (getID() == id_op); } bool operator == (LLPanel* panel_op) const { - return (toast == panel_op); + return (mToast.get() == panel_op); } + + private: + LLHandle<LLToast> mToast; }; // Channel's handlers diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp index 85a7e75271..0e0da6bdc7 100644 --- a/indra/newview/llscriptfloater.cpp +++ b/indra/newview/llscriptfloater.cpp @@ -41,7 +41,7 @@ #include "lltoastscripttextbox.h" #include "lltrans.h" #include "llviewerwindow.h" -#include "llimfloater.h" +#include "llfloaterimsession.h" ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -95,7 +95,12 @@ bool LLScriptFloater::toggle(const LLUUID& notification_id) show(notification_id); } - LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(notification_id, true); + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) + { + chiclet_panelp->setChicletToggleState(notification_id, true); + } + return true; } @@ -206,10 +211,14 @@ void LLScriptFloater::setVisible(BOOL visible) if(!visible) { - LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(getNotificationId()); - if(chiclet) + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) { - chiclet->setToggleState(false); + LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(getNotificationId()); + if(NULL != chicletp) + { + chicletp->setToggleState(false); + } } } } @@ -218,15 +227,19 @@ void LLScriptFloater::onMouseDown() { if(getNotificationId().notNull()) { - // Remove new message icon - LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(getNotificationId()); - if (chiclet == NULL) + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) { - llerror("Dock chiclet for LLScriptFloater doesn't exist", 0); - } - else - { - chiclet->setShowNewMessagesIcon(false); + LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(getNotificationId()); + // Remove new message icon + if (NULL == chicletp) + { + llerror("Dock chiclet for LLScriptFloater doesn't exist", 0); + } + else + { + chicletp->setShowNewMessagesIcon(false); + } } } } @@ -262,7 +275,11 @@ void LLScriptFloater::onFocusLost() { if(getNotificationId().notNull()) { - LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(getNotificationId(), false); + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) + { + chiclet_panelp->setChicletToggleState(getNotificationId(), false); + } } } @@ -271,7 +288,11 @@ void LLScriptFloater::onFocusReceived() // first focus will be received before setObjectId() call - don't toggle chiclet if(getNotificationId().notNull()) { - LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(getNotificationId(), true); + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) + { + chiclet_panelp->setChicletToggleState(getNotificationId(), true); + } } } @@ -279,28 +300,30 @@ void LLScriptFloater::dockToChiclet(bool dock) { if (getDockControl() == NULL) { - LLChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLChiclet>(getNotificationId()); - if (chiclet == NULL) - { - llwarns << "Dock chiclet for LLScriptFloater doesn't exist" << llendl; - return; - } - else + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) { - LLChicletBar::getInstance()->getChicletPanel()->scrollToChiclet(chiclet); - } + LLChiclet * chicletp = chiclet_panelp->findChiclet<LLChiclet>(getNotificationId()); + if (NULL == chicletp) + { + llwarns << "Dock chiclet for LLScriptFloater doesn't exist" << llendl; + return; + } - // Stop saving position while we dock floater - bool save = getSavePosition(); - setSavePosition(false); + chiclet_panelp->scrollToChiclet(chicletp); - setDockControl(new LLDockControl(chiclet, this, getDockTongue(), - LLDockControl::BOTTOM)); + // Stop saving position while we dock floater + bool save = getSavePosition(); + setSavePosition(false); - setDocked(dock); + setDockControl(new LLDockControl(chicletp, this, getDockTongue(), + LLDockControl::BOTTOM)); - // Restore saving - setSavePosition(save); + setDocked(dock); + + // Restore saving + setSavePosition(save); + } } } @@ -347,11 +370,15 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id) script_notification_map_t::const_iterator it = findUsingObjectId(object_id); if(it != mNotifications.end()) { - LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(it->first); - if(chiclet) + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) { - // Pass the new_message icon state further. - set_new_message = chiclet->getShowNewMessagesIcon(); + LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(it->first); + if(NULL != chicletp) + { + // Pass the new_message icon state further. + set_new_message = chicletp->getShowNewMessagesIcon(); + } } LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", it->first); @@ -367,14 +394,18 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id) mNotifications.insert(std::make_pair(notification_id, object_id)); - // Create inventory offer chiclet for offer type notifications - if( OBJ_GIVE_INVENTORY == obj_type ) + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) { - LLChicletBar::instance().getChicletPanel()->createChiclet<LLInvOfferChiclet>(notification_id); - } - else - { - LLChicletBar::getInstance()->getChicletPanel()->createChiclet<LLScriptChiclet>(notification_id); + // Create inventory offer chiclet for offer type notifications + if( OBJ_GIVE_INVENTORY == obj_type ) + { + chiclet_panelp->createChiclet<LLInvOfferChiclet>(notification_id); + } + else + { + chiclet_panelp->createChiclet<LLScriptChiclet>(notification_id); + } } LLIMWellWindow::getInstance()->addObjectRow(notification_id, set_new_message); @@ -408,9 +439,20 @@ void LLScriptFloaterManager::onRemoveNotification(const LLUUID& notification_id) } // remove related chiclet - LLChicletBar::getInstance()->getChicletPanel()->removeChiclet(notification_id); + if (LLChicletBar::instanceExists()) + { + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) + { + chiclet_panelp->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/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp index 8d64c8c04f..30400a4c6a 100644 --- a/indra/newview/llsechandler_basic.cpp +++ b/indra/newview/llsechandler_basic.cpp @@ -1360,7 +1360,11 @@ void LLSecAPIBasicHandler::_writeProtectedData() // (even though this file isn't really secure. Perhaps in the future // it may be, however. LLFile::remove(tmp_filename); - throw LLProtectedDataException("Error writing Protected Data Store"); + + // EXP-1825 crash in LLSecAPIBasicHandler::_writeProtectedData() + // Decided throwing an exception here was overkill until we figure out why this happens + //throw LLProtectedDataException("Error writing Protected Data Store"); + llinfos << "LLProtectedDataException(Error writing Protected Data Store)" << llendl; } // move the temporary file to the specified file location. @@ -1369,7 +1373,11 @@ void LLSecAPIBasicHandler::_writeProtectedData() (LLFile::rename(tmp_filename, mProtectedDataFilename))) { LLFile::remove(tmp_filename); - throw LLProtectedDataException("Could not overwrite protected data store"); + + // EXP-1825 crash in LLSecAPIBasicHandler::_writeProtectedData() + // Decided throwing an exception here was overkill until we figure out why this happens + //throw LLProtectedDataException("Could not overwrite protected data store"); + llinfos << "LLProtectedDataException(Could not overwrite protected data store)" << llendl; } } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 5d0d1ef9a3..343316d30a 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -211,7 +211,6 @@ LLSelectMgr::LLSelectMgr() mGridMode = GRID_MODE_WORLD; gSavedSettings.setS32("GridMode", (S32)GRID_MODE_WORLD); - mGridValid = FALSE; mSelectedObjects = new LLObjectSelection(); mHoverObjects = new LLObjectSelection(); @@ -276,7 +275,7 @@ void LLSelectMgr::overrideObjectUpdates() virtual bool apply(LLSelectNode* selectNode) { LLViewerObject* object = selectNode->getObject(); - if (object && object->permMove()) + if (object && object->permMove() && !object->isPermanentEnforced()) { if (!selectNode->mLastPositionLocal.isExactlyZero()) { @@ -390,7 +389,7 @@ LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(LLViewerObject* obj, // don't include an avatar. LLViewerObject* root = obj; - while(!root->isAvatar() && root->getParent() && !root->isJointChild()) + while(!root->isAvatar() && root->getParent()) { LLViewerObject* parent = (LLViewerObject*)root->getParent(); if (parent->isAvatar()) @@ -593,6 +592,12 @@ bool LLSelectMgr::linkObjects() return true; } + if (!LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced()) + { + LLNotificationsUtil::add("CannotLinkPermanent"); + return true; + } + LLUUID owner_id; std::string owner_name; if (!LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name)) @@ -638,7 +643,9 @@ bool LLSelectMgr::enableLinkObjects() { virtual bool apply(LLViewerObject* object) { - return object->permModify(); + LLViewerObject *root_object = (object == NULL) ? NULL : object->getRootEdit(); + return object->permModify() && !object->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()); } } func; const bool firstonly = true; @@ -651,10 +658,12 @@ bool LLSelectMgr::enableLinkObjects() bool LLSelectMgr::enableUnlinkObjects() { LLViewerObject* first_editable_object = LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject(); + LLViewerObject *root_object = (first_editable_object == NULL) ? NULL : first_editable_object->getRootEdit(); bool new_value = LLSelectMgr::getInstance()->selectGetAllRootsValid() && first_editable_object && - !first_editable_object->isAttachment(); + !first_editable_object->isAttachment() && !first_editable_object->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()); return new_value; } @@ -674,7 +683,7 @@ void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_s // don't include an avatar. LLViewerObject* root = object; - while(!root->isAvatar() && root->getParent() && !root->isJointChild()) + while(!root->isAvatar() && root->getParent()) { LLViewerObject* parent = (LLViewerObject*)root->getParent(); if (parent->isAvatar()) @@ -955,7 +964,7 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp) } if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner()) - || (gSavedSettings.getBOOL("SelectMovableOnly") && !objectp->permMove())) + || (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced()))) { // only select my own objects return; @@ -1160,7 +1169,6 @@ void LLSelectMgr::setGridMode(EGridMode mode) mGridMode = mode; gSavedSettings.setS32("GridMode", mode); updateSelectionCenter(); - mGridValid = FALSE; } void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale) @@ -1261,7 +1269,6 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & origin = mGridOrigin; rotation = mGridRotation; scale = mGridScale; - mGridValid = TRUE; } //----------------------------------------------------------------------------- @@ -1387,7 +1394,7 @@ void LLSelectMgr::promoteSelectionToRoot() } LLViewerObject* parentp = object; - while(parentp->getParent() && !(parentp->isRootEdit() || parentp->isJointChild())) + while(parentp->getParent() && !(parentp->isRootEdit())) { parentp = (LLViewerObject*)parentp->getParent(); } @@ -1508,6 +1515,49 @@ struct LLSelectMgrSendFunctor : public LLSelectedObjectFunctor } }; +void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item) +{ + if (!item) + { + return; + } + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID()); + + for (iterator iter = begin(); iter != end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = (*iter)->getObject(); + if (!object) + { + continue; + } + + S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces()); + bool texture_copied = false; + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + //(no-copy) textures must be moved to the object's inventory only once + // without making any copies + if (!texture_copied) + { + LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); + texture_copied = true; + } + + // apply texture for the selected faces + LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); + object->setTEImage(te, image); + dialog_refresh_all(); + + // send the update to the simulator + object->sendTEUpdate(); + } + } + } +} + //----------------------------------------------------------------------------- // selectionSetImage() //----------------------------------------------------------------------------- @@ -1559,8 +1609,18 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid) } return true; } - } setfunc(item, imageid); - getSelection()->applyToTEs(&setfunc); + }; + + if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) + { + getSelection()->applyNoCopyTextureToTEs(item); + } + else + { + f setfunc(item, imageid); + getSelection()->applyToTEs(&setfunc); + } + struct g : public LLSelectedObjectFunctor { @@ -2286,50 +2346,6 @@ void LLSelectMgr::packObjectIDAsParam(LLSelectNode* node, void *) } //----------------------------------------------------------------------------- -// Rotation options -//----------------------------------------------------------------------------- -void LLSelectMgr::selectionResetRotation() -{ - struct f : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - LLQuaternion identity(0.f, 0.f, 0.f, 1.f); - object->setRotation(identity); - if (object->mDrawable.notNull()) - { - gPipeline.markMoved(object->mDrawable, TRUE); - } - object->sendRotationUpdate(); - return true; - } - } func; - getSelection()->applyToRootObjects(&func); -} - -void LLSelectMgr::selectionRotateAroundZ(F32 degrees) -{ - LLQuaternion rot( degrees * DEG_TO_RAD, LLVector3(0,0,1) ); - struct f : public LLSelectedObjectFunctor - { - LLQuaternion mRot; - f(const LLQuaternion& rot) : mRot(rot) {} - virtual bool apply(LLViewerObject* object) - { - object->setRotation( object->getRotationEdit() * mRot ); - if (object->mDrawable.notNull()) - { - gPipeline.markMoved(object->mDrawable, TRUE); - } - object->sendRotationUpdate(); - return true; - } - } func(rot); - getSelection()->applyToRootObjects(&func); -} - - -//----------------------------------------------------------------------------- // selectionTexScaleAutofit() //----------------------------------------------------------------------------- void LLSelectMgr::selectionTexScaleAutofit(F32 repeats_per_meter) @@ -2543,10 +2559,33 @@ BOOL LLSelectMgr::selectGetRootsModify() //----------------------------------------------------------------------------- -// selectGetRootsTransfer() - return TRUE if current agent can transfer all -// selected root objects. +// selectGetNonPermanentEnforced() - return TRUE if all objects are not +// permanent enforced //----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectGetRootsTransfer() +BOOL LLSelectMgr::selectGetNonPermanentEnforced() +{ + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if( object->isPermanentEnforced()) + { + return FALSE; + } + } + return TRUE; +} + +//----------------------------------------------------------------------------- +// selectGetRootsNonPermanentEnforced() - return TRUE if all root objects are +// not permanent enforced +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetRootsNonPermanentEnforced() { for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); iter != getSelection()->root_end(); iter++ ) @@ -2557,19 +2596,42 @@ BOOL LLSelectMgr::selectGetRootsTransfer() { return FALSE; } - if(!object->permTransfer()) + if( object->isPermanentEnforced()) { return FALSE; } } + return TRUE; } //----------------------------------------------------------------------------- -// selectGetRootsCopy() - return TRUE if current agent can copy all -// selected root objects. +// selectGetPermanent() - return TRUE if all objects are permanent //----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectGetRootsCopy() +BOOL LLSelectMgr::selectGetPermanent() +{ + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if( !object->flagObjectPermanent()) + { + return FALSE; + } + } + return TRUE; +} + +//----------------------------------------------------------------------------- +// selectGetRootsPermanent() - return TRUE if all root objects are +// permanent +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetRootsPermanent() { for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); iter != getSelection()->root_end(); iter++ ) @@ -2580,256 +2642,537 @@ BOOL LLSelectMgr::selectGetRootsCopy() { return FALSE; } - if(!object->permCopy()) + if( !object->flagObjectPermanent()) { return FALSE; } } + return TRUE; } //----------------------------------------------------------------------------- -// selectGetCreator() -// Creator information only applies to root objects. +// selectGetCharacter() - return TRUE if all objects are character //----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name) +BOOL LLSelectMgr::selectGetCharacter() { - BOOL identical = TRUE; - BOOL first = TRUE; - LLUUID first_id; - for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin(); - iter != getSelection()->root_object_end(); iter++ ) + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) { - LLSelectNode* node = *iter; - if (!node->mValid) + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) { return FALSE; } + if( !object->flagCharacter()) + { + return FALSE; + } + } + return TRUE; +} - if (first) +//----------------------------------------------------------------------------- +// selectGetRootsCharacter() - return TRUE if all root objects are +// character +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetRootsCharacter() +{ + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) { - first_id = node->mPermissions->getCreator(); - first = FALSE; + return FALSE; } - else + if( !object->flagCharacter()) { - if ( !(first_id == node->mPermissions->getCreator() ) ) - { - identical = FALSE; - break; - } + return FALSE; } } - if (first_id.isNull()) - { - name = LLTrans::getString("AvatarNameNobody"); - return FALSE; - } - - result_id = first_id; - - if (identical) + + return TRUE; +} + +//----------------------------------------------------------------------------- +// selectGetNonPathfinding() - return TRUE if all objects are not pathfinding +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetNonPathfinding() +{ + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) { - name = LLSLURL("agent", first_id, "inspect").getSLURLString(); + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if( object->flagObjectPermanent() || object->flagCharacter()) + { + return FALSE; + } } - else + return TRUE; +} + +//----------------------------------------------------------------------------- +// selectGetRootsNonPathfinding() - return TRUE if all root objects are not +// pathfinding +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetRootsNonPathfinding() +{ + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { - name = LLTrans::getString("AvatarNameMultiple"); + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) + { + return FALSE; + } + if( object->flagObjectPermanent() || object->flagCharacter()) + { + return FALSE; + } } - return identical; + return TRUE; } - //----------------------------------------------------------------------------- -// selectGetOwner() -// Owner information only applies to roots. +// selectGetNonPermanent() - return TRUE if all objects are not permanent //----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name) +BOOL LLSelectMgr::selectGetNonPermanent() { - BOOL identical = TRUE; - BOOL first = TRUE; - BOOL first_group_owned = FALSE; - LLUUID first_id; - for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin(); - iter != getSelection()->root_object_end(); iter++ ) + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) { - LLSelectNode* node = *iter; - if (!node->mValid) + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) { return FALSE; } - - if (first) + if( object->flagObjectPermanent()) { - node->mPermissions->getOwnership(first_id, first_group_owned); - first = FALSE; + return FALSE; } - else + } + return TRUE; +} + +//----------------------------------------------------------------------------- +// selectGetRootsNonPermanent() - return TRUE if all root objects are not +// permanent +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetRootsNonPermanent() +{ + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) { - LLUUID owner_id; - BOOL is_group_owned = FALSE; - if (!(node->mPermissions->getOwnership(owner_id, is_group_owned)) - || owner_id != first_id || is_group_owned != first_group_owned) - { - identical = FALSE; - break; - } + return FALSE; + } + if( object->flagObjectPermanent()) + { + return FALSE; } } - if (first_id.isNull()) + + return TRUE; +} + +//----------------------------------------------------------------------------- +// selectGetNonCharacter() - return TRUE if all objects are not character +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetNonCharacter() +{ + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) { - return FALSE; + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if( object->flagCharacter()) + { + return FALSE; + } } + return TRUE; +} - result_id = first_id; - - if (identical) +//----------------------------------------------------------------------------- +// selectGetRootsNonCharacter() - return TRUE if all root objects are not +// character +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetRootsNonCharacter() +{ + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { - BOOL public_owner = (first_id.isNull() && !first_group_owned); - if (first_group_owned) + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) { - name = LLSLURL("group", first_id, "inspect").getSLURLString(); + return FALSE; } - else if(!public_owner) + if( object->flagCharacter()) { - name = LLSLURL("agent", first_id, "inspect").getSLURLString(); + return FALSE; } - else + } + + return TRUE; +} + + +//----------------------------------------------------------------------------- +// selectGetEditableLinksets() - return TRUE if all objects are editable +// pathfinding linksets +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetEditableLinksets() +{ + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if (object->flagUsePhysics() || + object->flagTemporaryOnRez() || + object->flagCharacter() || + object->flagVolumeDetect() || + object->flagAnimSource() || + (object->getRegion() != gAgent.getRegion()) || + (!gAgent.isGodlike() && + !gAgent.canManageEstate() && + !object->permYouOwner() && + !object->permMove())) { - name = LLTrans::getString("AvatarNameNobody"); + return FALSE; } } - else + return TRUE; +} + +//----------------------------------------------------------------------------- +// selectGetViewableCharacters() - return TRUE if all objects are characters +// viewable within the pathfinding characters floater +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetViewableCharacters() +{ + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) { - name = LLTrans::getString("AvatarNameMultiple"); + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if( !object->flagCharacter() || + (object->getRegion() != gAgent.getRegion())) + { + return FALSE; + } } - - return identical; + return TRUE; } +//----------------------------------------------------------------------------- +// selectGetRootsTransfer() - return TRUE if current agent can transfer all +// selected root objects. +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetRootsTransfer() +{ + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) + { + return FALSE; + } + if(!object->permTransfer()) + { + return FALSE; + } + } + return TRUE; +} //----------------------------------------------------------------------------- -// selectGetLastOwner() -// Owner information only applies to roots. +// selectGetRootsCopy() - return TRUE if current agent can copy all +// selected root objects. //----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name) +BOOL LLSelectMgr::selectGetRootsCopy() { - BOOL identical = TRUE; - BOOL first = TRUE; - LLUUID first_id; - for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin(); - iter != getSelection()->root_object_end(); iter++ ) + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { - LLSelectNode* node = *iter; - if (!node->mValid) + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) { return FALSE; } + if(!object->permCopy()) + { + return FALSE; + } + } + return TRUE; +} - if (first) +struct LLSelectGetFirstTest +{ + LLSelectGetFirstTest() : mIdentical(true), mFirst(true) { } + virtual ~LLSelectGetFirstTest() { } + + // returns false to break out of the iteration. + bool checkMatchingNode(LLSelectNode* node) + { + if (!node || !node->mValid) { - first_id = node->mPermissions->getLastOwner(); - first = FALSE; + return false; + } + + if (mFirst) + { + mFirstValue = getValueFromNode(node); + mFirst = false; } else { - if ( !(first_id == node->mPermissions->getLastOwner() ) ) + if ( mFirstValue != getValueFromNode(node) ) + { + mIdentical = false; + // stop testing once we know not all selected are identical. + return false; + } + } + // continue testing. + return true; + } + + bool mIdentical; + LLUUID mFirstValue; + +protected: + virtual const LLUUID& getValueFromNode(LLSelectNode* node) = 0; + +private: + bool mFirst; +}; + +void LLSelectMgr::getFirst(LLSelectGetFirstTest* test) +{ + if (gSavedSettings.getBOOL("EditLinkedParts")) + { + for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin(); + iter != getSelection()->valid_end(); ++iter ) + { + if (!test->checkMatchingNode(*iter)) + { + break; + } + } + } + else + { + for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin(); + iter != getSelection()->root_object_end(); ++iter ) + { + if (!test->checkMatchingNode(*iter)) { - identical = FALSE; break; } } } - if (first_id.isNull()) +} + +//----------------------------------------------------------------------------- +// selectGetCreator() +// Creator information only applies to roots unless editing linked parts. +//----------------------------------------------------------------------------- +struct LLSelectGetFirstCreator : public LLSelectGetFirstTest +{ +protected: + virtual const LLUUID& getValueFromNode(LLSelectNode* node) + { + return node->mPermissions->getCreator(); + } +}; + +BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name) +{ + LLSelectGetFirstCreator test; + getFirst(&test); + + if (test.mFirstValue.isNull()) + { + name = LLTrans::getString("AvatarNameNobody"); + return FALSE; + } + + result_id = test.mFirstValue; + + if (test.mIdentical) + { + name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString(); + } + else + { + name = LLTrans::getString("AvatarNameMultiple"); + } + + return test.mIdentical; +} + +//----------------------------------------------------------------------------- +// selectGetOwner() +// Owner information only applies to roots unless editing linked parts. +//----------------------------------------------------------------------------- +struct LLSelectGetFirstOwner : public LLSelectGetFirstTest +{ +protected: + virtual const LLUUID& getValueFromNode(LLSelectNode* node) + { + // Don't use 'getOwnership' since we return a reference, not a copy. + // Will return LLUUID::null if unowned (which is not allowed and should never happen.) + return node->mPermissions->isGroupOwned() ? node->mPermissions->getGroup() : node->mPermissions->getOwner(); + } +}; + +BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name) +{ + LLSelectGetFirstOwner test; + getFirst(&test); + + if (test.mFirstValue.isNull()) { return FALSE; } - result_id = first_id; + result_id = test.mFirstValue; - if (identical) + if (test.mIdentical) { - BOOL public_owner = (first_id.isNull()); - if(!public_owner) + bool group_owned = selectIsGroupOwned(); + if (group_owned) { - name = LLSLURL("agent", first_id, "inspect").getSLURLString(); + name = LLSLURL("group", test.mFirstValue, "inspect").getSLURLString(); } else { - name.assign("Public or Group"); + name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString(); } } else { - name.assign( "" ); + name = LLTrans::getString("AvatarNameMultiple"); } - return identical; + return test.mIdentical; } +//----------------------------------------------------------------------------- +// selectGetLastOwner() +// Owner information only applies to roots unless editing linked parts. +//----------------------------------------------------------------------------- +struct LLSelectGetFirstLastOwner : public LLSelectGetFirstTest +{ +protected: + virtual const LLUUID& getValueFromNode(LLSelectNode* node) + { + return node->mPermissions->getLastOwner(); + } +}; + +BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name) +{ + LLSelectGetFirstLastOwner test; + getFirst(&test); + + if (test.mFirstValue.isNull()) + { + return FALSE; + } + + result_id = test.mFirstValue; + + if (test.mIdentical) + { + name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString(); + } + else + { + name.assign( "" ); + } + + return test.mIdentical; +} //----------------------------------------------------------------------------- // selectGetGroup() -// Group information only applies to roots. +// Group information only applies to roots unless editing linked parts. //----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectGetGroup(LLUUID& result_id) +struct LLSelectGetFirstGroup : public LLSelectGetFirstTest { - BOOL identical = TRUE; - BOOL first = TRUE; - LLUUID first_id; - for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin(); - iter != getSelection()->root_object_end(); iter++ ) +protected: + virtual const LLUUID& getValueFromNode(LLSelectNode* node) { - LLSelectNode* node = *iter; - if (!node->mValid) - { - return FALSE; - } - - if (first) - { - first_id = node->mPermissions->getGroup(); - first = FALSE; - } - else - { - if ( !(first_id == node->mPermissions->getGroup() ) ) - { - identical = FALSE; - break; - } - } + return node->mPermissions->getGroup(); } +}; - result_id = first_id; +BOOL LLSelectMgr::selectGetGroup(LLUUID& result_id) +{ + LLSelectGetFirstGroup test; + getFirst(&test); - return identical; + result_id = test.mFirstValue; + return test.mIdentical; } //----------------------------------------------------------------------------- // selectIsGroupOwned() -// Only operates on root nodes. -// Returns TRUE if all have valid data and they are all group owned. +// Only operates on root nodes unless editing linked parts. +// Returns TRUE if the first selected is group owned. //----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectIsGroupOwned() +struct LLSelectGetFirstGroupOwner : public LLSelectGetFirstTest { - BOOL found_one = FALSE; - for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin(); - iter != getSelection()->root_object_end(); iter++ ) +protected: + virtual const LLUUID& getValueFromNode(LLSelectNode* node) { - LLSelectNode* node = *iter; - if (!node->mValid) - { - return FALSE; - } - found_one = TRUE; - if (!node->mPermissions->isGroupOwned()) + if (node->mPermissions->isGroupOwned()) { - return FALSE; + return node->mPermissions->getGroup(); } - } - return found_one ? TRUE : FALSE; + return LLUUID::null; + } +}; + +BOOL LLSelectMgr::selectIsGroupOwned() +{ + LLSelectGetFirstGroupOwner test; + getFirst(&test); + + return test.mFirstValue.notNull() ? TRUE : FALSE; } //----------------------------------------------------------------------------- @@ -3051,11 +3394,11 @@ bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response, // TODO: Make sure you have delete permissions on all of them. const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); // attempt to derez into the trash. - LLDeRezInfo* info = new LLDeRezInfo(DRD_TRASH, trash_id); + LLDeRezInfo info(DRD_TRASH, trash_id); LLSelectMgr::getInstance()->sendListToRegions("DeRezObject", packDeRezHeader, packObjectLocalID, - (void*)info, + (void*) &info, SEND_ONLY_ROOTS); // VEFFECT: Delete Object - one effect for all deletes if (LLSelectMgr::getInstance()->mSelectedObjects->mSelectType != SELECT_TYPE_HUD) @@ -3745,13 +4088,15 @@ void LLSelectMgr::deselectAllIfTooFar() void LLSelectMgr::selectionSetObjectName(const std::string& name) { + std::string name_copy(name); + // we only work correctly if 1 object is selected. if(mSelectedObjects->getRootObjectCount() == 1) { sendListToRegions("ObjectName", packAgentAndSessionID, packObjectName, - (void*)(new std::string(name)), + (void*)(&name_copy), SEND_ONLY_ROOTS); } else if(mSelectedObjects->getObjectCount() == 1) @@ -3759,20 +4104,22 @@ void LLSelectMgr::selectionSetObjectName(const std::string& name) sendListToRegions("ObjectName", packAgentAndSessionID, packObjectName, - (void*)(new std::string(name)), + (void*)(&name_copy), SEND_INDIVIDUALS); } } void LLSelectMgr::selectionSetObjectDescription(const std::string& desc) { + std::string desc_copy(desc); + // we only work correctly if 1 object is selected. if(mSelectedObjects->getRootObjectCount() == 1) { sendListToRegions("ObjectDescription", packAgentAndSessionID, packObjectDescription, - (void*)(new std::string(desc)), + (void*)(&desc_copy), SEND_ONLY_ROOTS); } else if(mSelectedObjects->getObjectCount() == 1) @@ -3780,7 +4127,7 @@ void LLSelectMgr::selectionSetObjectDescription(const std::string& desc) sendListToRegions("ObjectDescription", packAgentAndSessionID, packObjectDescription, - (void*)(new std::string(desc)), + (void*)(&desc_copy), SEND_INDIVIDUALS); } } @@ -4117,8 +4464,7 @@ struct LLSelectMgrApplyFlags : public LLSelectedObjectFunctor virtual bool apply(LLViewerObject* object) { if ( object->permModify() && // preemptive permissions check - object->isRoot() && // don't send for child objects - !object->isJointChild()) + object->isRoot()) // don't send for child objects { object->setFlags( mFlags, mState); } @@ -4144,12 +4490,6 @@ void LLSelectMgr::selectionUpdatePhantom(BOOL is_phantom) getSelection()->applyToObjects(&func); } -void LLSelectMgr::selectionUpdateCastShadows(BOOL cast_shadows) -{ - LLSelectMgrApplyFlags func( FLAGS_CAST_SHADOWS, cast_shadows); - getSelection()->applyToObjects(&func); -} - //---------------------------------------------------------------------- // Helpful packing functions for sendObjectMessage() //---------------------------------------------------------------------- @@ -4298,15 +4638,14 @@ void LLSelectMgr::packObjectName(LLSelectNode* node, void* user_data) gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID()); gMessageSystem->addStringFast(_PREHASH_Name, *name); } - delete name; } // static void LLSelectMgr::packObjectDescription(LLSelectNode* node, void* user_data) { const std::string* desc = (const std::string*)user_data; - if(!desc->empty()) - { + if(desc) + { // Empty (non-null, but zero length) descriptions are OK gMessageSystem->nextBlockFast(_PREHASH_ObjectData); gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID()); gMessageSystem->addStringFast(_PREHASH_Description, *desc); @@ -4638,7 +4977,11 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data } func(id); LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func); - if (node) + if (!node) + { + llwarns << "Couldn't find object " << id << " selected." << llendl; + } + else { if (node->mInventorySerial != inv_serial) { @@ -4709,13 +5052,6 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data dialog_refresh_all(); - // silly hack to allow 'save into inventory' - if(gPopupMenuView->getVisible()) - { - gPopupMenuView->setItemEnabled(SAVE_INTO_INVENTORY, - enable_save_into_inventory(NULL)); - } - // hack for left-click buy object LLToolPie::selectionPropertiesReceived(); } @@ -5556,38 +5892,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) + LLVOVolume* vobj = drawable->getVOVolume(); + if (vobj) + { + LLVertexBuffer::unbind(); + gGL.pushMatrix(); + gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); + + LLVolume* volume = NULL; + + if (drawable->isState(LLDrawable::RIGGED)) { - 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(); - } + vobj->updateRiggedVolume(); + volume = vobj->getRiggedVolume(); } - } - else - { - for (S32 i = 0; i < drawable->getNumFaces(); ++i) + 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, NULL, face.mNumIndices, face.mIndices); } } + + gGL.popMatrix(); } + } void LLSelectNode::renderOneWireframe(const LLColor4& color) @@ -5608,7 +5943,7 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color) if (shader) { - gHighlightProgram.bind(); + gDebugProgram.bind(); } gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -5981,8 +6316,6 @@ void LLSelectMgr::updateSelectionCenter() // matches the root prim's (affecting the orientation of the manipulators). bbox.addBBoxAgent( (mSelectedObjects->getFirstRootObject(TRUE))->getBoundingBoxAgent() ); - std::vector < LLViewerObject *> jointed_objects; - for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); iter != mSelectedObjects->end(); iter++) { @@ -6000,11 +6333,6 @@ void LLSelectMgr::updateSelectionCenter() } bbox.addBBoxAgent( object->getBoundingBoxAgent() ); - - if (object->isJointChild()) - { - jointed_objects.push_back(object); - } } LLVector3 bbox_center_agent = bbox.getCenterAgent(); @@ -6243,7 +6571,7 @@ BOOL LLSelectMgr::canSelectObject(LLViewerObject* object) } if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !object->permYouOwner()) || - (gSavedSettings.getBOOL("SelectMovableOnly") && !object->permMove())) + (gSavedSettings.getBOOL("SelectMovableOnly") && (!object->permMove() || object->isPermanentEnforced()))) { // only select my own objects return FALSE; @@ -6294,19 +6622,19 @@ void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom) bool LLObjectSelection::is_root::operator()(LLSelectNode *node) { LLViewerObject* object = node->getObject(); - return (object != NULL) && !node->mIndividualSelection && (object->isRootEdit() || object->isJointChild()); + return (object != NULL) && !node->mIndividualSelection && (object->isRootEdit()); } bool LLObjectSelection::is_valid_root::operator()(LLSelectNode *node) { LLViewerObject* object = node->getObject(); - return (object != NULL) && node->mValid && !node->mIndividualSelection && (object->isRootEdit() || object->isJointChild()); + return (object != NULL) && node->mValid && !node->mIndividualSelection && (object->isRootEdit()); } bool LLObjectSelection::is_root_object::operator()(LLSelectNode *node) { LLViewerObject* object = node->getObject(); - return (object != NULL) && (object->isRootEdit() || object->isJointChild()); + return (object != NULL) && (object->isRootEdit()); } LLObjectSelection::LLObjectSelection() : @@ -6935,7 +7263,7 @@ LLSelectNode* LLObjectSelection::getFirstMoveableNode(BOOL get_root_first) bool apply(LLSelectNode* node) { LLViewerObject* obj = node->getObject(); - return obj && obj->permMove(); + return obj && obj->permMove() && !obj->isPermanentEnforced(); } } func; LLSelectNode* res = get_root_first ? getFirstRootNode(&func, TRUE) : getFirstNode(&func); @@ -6973,9 +7301,10 @@ LLViewerObject* LLObjectSelection::getFirstDeleteableObject() LLViewerObject* obj = node->getObject(); // you can delete an object if you are the owner // or you have permission to modify it. - if( obj && ( (obj->permModify()) || - (obj->permYouOwner()) || - (!obj->permAnyOwner()) )) // public + if( obj && !obj->isPermanentEnforced() && + ( (obj->permModify()) || + (obj->permYouOwner()) || + (!obj->permAnyOwner()) )) // public { if( !obj->isAttachment() ) { @@ -7015,7 +7344,7 @@ LLViewerObject* LLObjectSelection::getFirstMoveableObject(BOOL get_parent) bool apply(LLSelectNode* node) { LLViewerObject* obj = node->getObject(); - return obj && obj->permMove(); + return obj && obj->permMove() && !obj->isPermanentEnforced(); } } func; return getFirstSelectedObject(&func, get_parent); @@ -7084,7 +7413,7 @@ bool LLSelectMgr::selectionMove(const LLVector3& displ, { obj = (*it)->getObject(); bool enable_pos = false, enable_rot = false; - bool perm_move = obj->permMove(); + bool perm_move = obj->permMove() && !obj->isPermanentEnforced(); bool perm_mod = obj->permModify(); LLVector3d sel_center(getSelectionCenterGlobal()); diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 87ada5ac6b..cc78e35869 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -307,6 +307,15 @@ public: bool applyToRootNodes(LLSelectedNodeFunctor* func, bool firstonly = false); bool applyToNodes(LLSelectedNodeFunctor* func, bool firstonly = false); + /* + * Used to apply (no-copy) textures to the selected object or + * selected face/faces of the object. + * This method moves (no-copy) texture to the object's inventory + * and doesn't make copy of the texture for each face. + * Then this only texture is used for all selected faces. + */ + void applyNoCopyTextureToTEs(LLViewerInventoryItem* item); + ESelectType getSelectType() const { return mSelectType; } private: @@ -334,6 +343,9 @@ typedef LLSafeHandle<LLObjectSelection> LLObjectSelectionHandle; extern template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance(); #endif +// For use with getFirstTest() +struct LLSelectGetFirstTest; + class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr> { public: @@ -501,7 +513,6 @@ public: void selectionUpdatePhysics(BOOL use_physics); void selectionUpdateTemporary(BOOL is_temporary); void selectionUpdatePhantom(BOOL is_ghost); - void selectionUpdateCastShadows(BOOL cast_shadows); void selectionDump(); BOOL selectionAllPCode(LLPCode code); // all objects have this PCode @@ -539,8 +550,6 @@ public: void selectionTexScaleAutofit(F32 repeats_per_meter); void adjustTexturesByScale(BOOL send_to_sim, BOOL stretch); - void selectionResetRotation(); // sets rotation quat to identity - void selectionRotateAroundZ(F32 degrees); bool selectionMove(const LLVector3& displ, F32 rx, F32 ry, F32 rz, U32 update_type); void sendSelectionMove(); @@ -563,6 +572,33 @@ public: BOOL selectGetRootsModify(); BOOL selectGetModify(); + // returns TRUE if is all objects are non-permanent-enforced + BOOL selectGetRootsNonPermanentEnforced(); + BOOL selectGetNonPermanentEnforced(); + + // returns TRUE if is all objects are permanent + BOOL selectGetRootsPermanent(); + BOOL selectGetPermanent(); + + // returns TRUE if is all objects are character + BOOL selectGetRootsCharacter(); + BOOL selectGetCharacter(); + + // returns TRUE if is all objects are not permanent + BOOL selectGetRootsNonPathfinding(); + BOOL selectGetNonPathfinding(); + + // returns TRUE if is all objects are not permanent + BOOL selectGetRootsNonPermanent(); + BOOL selectGetNonPermanent(); + + // returns TRUE if is all objects are not character + BOOL selectGetRootsNonCharacter(); + BOOL selectGetNonCharacter(); + + BOOL selectGetEditableLinksets(); + BOOL selectGetViewableCharacters(); + // returns TRUE if selected objects can be transferred. BOOL selectGetRootsTransfer(); @@ -712,6 +748,9 @@ private: static void packGodlikeHead(void* user_data); static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle); + // Get the first ID that matches test and whether or not all ids are identical in selected objects. + void getFirst(LLSelectGetFirstTest* test); + public: // Observer/callback support for when object selection changes or // properties are received/updated @@ -730,8 +769,6 @@ private: LLVector3 mGridOrigin; LLVector3 mGridScale; EGridMode mGridMode; - BOOL mGridValid; - BOOL mTEMode; // render te LLVector3d mSelectionCenterGlobal; diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 853656905c..adb97ac800 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -38,7 +38,7 @@ #include "llfiltereditor.h" #include "llfloaterreg.h" #include "llfloaterworldmap.h" -#include "llfoldervieweventlistener.h" +#include "llfolderviewmodel.h" #include "lloutfitobserver.h" #include "llpaneleditwearable.h" #include "llpaneloutfitsinventory.h" @@ -267,11 +267,11 @@ void LLSidepanelAppearance::onOpenOutfitButtonClicked() if (inventory_panel) { LLFolderView* root = inventory_panel->getRootFolder(); - LLFolderViewItem *outfit_folder = root->getItemByID(outfit_link->getLinkedUUID()); + LLFolderViewItem *outfit_folder = inventory_panel->getItemByID(outfit_link->getLinkedUUID()); if (outfit_folder) { outfit_folder->setOpen(!outfit_folder->isOpen()); - root->setSelectionFromRoot(outfit_folder,TRUE); + root->setSelection(outfit_folder,TRUE); root->scrollToShowSelection(); } } @@ -456,10 +456,10 @@ void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string& name) void LLSidepanelAppearance::editWearable(LLWearable *wearable, LLView *data, BOOL disable_camera_switch) { LLFloaterSidePanelContainer::showPanel("appearance", LLSD()); - LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(data); if (panel) { + panel->showOutfitsInventoryPanel(); panel->showWearableEditPanel(wearable, disable_camera_switch); } } diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 9d069c3996..8915bb2fef 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -36,6 +36,7 @@ #include "llfirstuse.h" #include "llfloatersidepanelcontainer.h" #include "llfoldertype.h" +#include "llfolderview.h" #include "llhttpclient.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" @@ -47,7 +48,6 @@ #include "lloutfitobserver.h" #include "llpanelmaininventory.h" #include "llpanelmarketplaceinbox.h" -#include "llpanelmarketplaceoutbox.h" #include "llselectmgr.h" #include "llsidepaneliteminfo.h" #include "llsidepaneltaskinfo.h" @@ -68,35 +68,21 @@ 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,29 +120,32 @@ 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() } LLSidepanelInventory::~LLSidepanelInventory() { + LLLayoutPanel* inbox_layout_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); + + // Save the InventoryMainPanelHeight in settings per account + gSavedPerAccountSettings.setS32("InventoryInboxHeight", inbox_layout_panel->getTargetDim()); + if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver)) { gInventory.removeObserver(mCategoriesObserver); } 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 +157,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 +218,34 @@ 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); - // 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) + // Get the previous inbox state from "InventoryInboxToggleState" setting. + bool is_inbox_collapsed = !inbox_button->getToggleState(); + + // Restore the collapsed inbox panel state + LLLayoutPanel* inbox_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); + inv_stack->collapsePanel(inbox_panel, is_inbox_collapsed); + if (!is_inbox_collapsed) + { + inbox_panel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight")); + } + + // 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 +253,95 @@ 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); + const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder); - // 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 +353,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,83 +368,30 @@ 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()) + if (inbox_expanded) + { + inboxPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight")); + if (inboxPanel->isInVisibleChain()) { gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected()); } } + else + { + gSavedPerAccountSettings.setS32("InventoryInboxHeight", inboxPanel->getTargetDim()); + } -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) @@ -625,7 +448,7 @@ void LLSidepanelInventory::onInfoButtonClicked() void LLSidepanelInventory::onShareButtonClicked() { - LLAvatarActions::shareWithAvatars(); + LLAvatarActions::shareWithAvatars(this); } void LLSidepanelInventory::onShopButtonClicked() @@ -649,7 +472,7 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action) } } - current_item->getListener()->performAction(mPanelMainInventory->getActivePanel()->getModel(), action); + static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(mPanelMainInventory->getActivePanel()->getModel(), action); } void LLSidepanelInventory::onWearButtonClicked() @@ -740,77 +563,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); @@ -910,7 +662,7 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem() return NULL; } } - const LLUUID &item_id = current_item->getListener()->getUUID(); + const LLUUID &item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID(); LLInventoryItem *item = gInventory.getItem(item_id); return item; } @@ -919,20 +671,13 @@ U32 LLSidepanelInventory::getSelectedCount() { int count = 0; - std::set<LLUUID> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList(); + std::set<LLFolderViewItem*> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList(); count += selection_list.size(); if ((count == 0) && mInboxEnabled && (mInventoryPanelInbox != NULL)) { 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 +702,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,27 +719,17 @@ 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<LLFolderViewItem*> LLSidepanelInventory::getInboxSelectionList() { - std::set<LLUUID> inventory_selected_uuids; + std::set<LLFolderViewItem*> inventory_selected_uuids; if (mInboxEnabled && (mInventoryPanelInbox != NULL)) { 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..e8b2808d4f 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<LLFolderViewItem*> 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/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp index 1ce05da849..92c2863ffd 100644 --- a/indra/newview/llsidepaneliteminfo.cpp +++ b/indra/newview/llsidepaneliteminfo.cpp @@ -352,7 +352,7 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) getChildView("BtnCreator")->setEnabled(FALSE); getChildView("LabelCreatorTitle")->setEnabled(FALSE); getChildView("LabelCreatorName")->setEnabled(FALSE); - getChild<LLUICtrl>("LabelCreatorName")->setValue(getString("unknown")); + getChild<LLUICtrl>("LabelCreatorName")->setValue(getString("unknown_multiple")); } //////////////// diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index 8774482acd..5532bdc71a 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -61,6 +61,9 @@ #include "llspinctrl.h" #include "roles_constants.h" #include "llgroupactions.h" +#include "lltextbase.h" +#include "llstring.h" +#include "lltrans.h" ///---------------------------------------------------------------------------- /// Class llsidepaneltaskinfo @@ -94,10 +97,12 @@ BOOL LLSidepanelTaskInfo::postBuild() mPayBtn = getChild<LLButton>("pay_btn"); mPayBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onPayButtonClicked, this)); mBuyBtn = getChild<LLButton>("buy_btn"); - mBuyBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onBuyButtonClicked, this)); + mBuyBtn->setClickedCallback(boost::bind(&handle_buy)); mDetailsBtn = getChild<LLButton>("details_btn"); mDetailsBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onDetailsButtonClicked, this)); + mDeedBtn = getChild<LLButton>("button deed"); + mLabelGroupName = getChild<LLNameBox>("Group Name Proxy"); childSetCommitCallback("Object Name", LLSidepanelTaskInfo::onCommitName,this); @@ -117,6 +122,43 @@ BOOL LLSidepanelTaskInfo::postBuild() childSetCommitCallback("checkbox next owner can transfer", &LLSidepanelTaskInfo::onCommitNextOwnerTransfer,this); childSetCommitCallback("clickaction", &LLSidepanelTaskInfo::onCommitClickAction,this); childSetCommitCallback("search_check", &LLSidepanelTaskInfo::onCommitIncludeInSearch,this); + + mDAPermModify = getChild<LLUICtrl>("perm_modify"); + mDACreator = getChildView("Creator:"); + mDACreatorName = getChild<LLUICtrl>("Creator Name"); + mDAOwner = getChildView("Owner:"); + mDAOwnerName = getChild<LLUICtrl>("Owner Name"); + mDAGroup = getChildView("Group:"); + mDAGroupName = getChild<LLUICtrl>("Group Name"); + mDAButtonSetGroup = getChildView("button set group"); + mDAObjectName = getChild<LLUICtrl>("Object Name"); + mDAName = getChildView("Name:"); + mDADescription = getChildView("Description:"); + mDAObjectDescription = getChild<LLUICtrl>("Object Description"); + mDAPermissions = getChildView("Permissions:"); + mDACheckboxShareWithGroup = getChild<LLUICtrl>("checkbox share with group"); + mDAButtonDeed = getChildView("button deed"); + mDACheckboxAllowEveryoneMove = getChild<LLUICtrl>("checkbox allow everyone move"); + mDACheckboxAllowEveryoneCopy = getChild<LLUICtrl>("checkbox allow everyone copy"); + mDANextOwnerCan = getChildView("Next owner can:"); + mDACheckboxNextOwnerCanModify = getChild<LLUICtrl>("checkbox next owner can modify"); + mDACheckboxNextOwnerCanCopy = getChild<LLUICtrl>("checkbox next owner can copy"); + mDACheckboxNextOwnerCanTransfer = getChild<LLUICtrl>("checkbox next owner can transfer"); + mDACheckboxForSale = getChild<LLUICtrl>("checkbox for sale"); + mDASearchCheck = getChild<LLUICtrl>("search_check"); + mDAComboSaleType = getChild<LLComboBox>("sale type"); + mDACost = getChild<LLUICtrl>("Cost"); + mDAEditCost = getChild<LLUICtrl>("Edit Cost"); + mDALabelClickAction = getChildView("label click action"); + mDAComboClickAction = getChild<LLComboBox>("clickaction"); + mDAPathfindingAttributes = getChild<LLTextBase>("pathfinding_attributes_value"); + mDAB = getChildView("B:"); + mDAO = getChildView("O:"); + mDAG = getChildView("G:"); + mDAE = getChildView("E:"); + mDAN = getChildView("N:"); + mDAF = getChildView("F:"); + return TRUE; } @@ -138,81 +180,83 @@ BOOL LLSidepanelTaskInfo::postBuild() void LLSidepanelTaskInfo::disableAll() { - getChildView("perm_modify")->setEnabled(FALSE); - getChild<LLUICtrl>("perm_modify")->setValue(LLStringUtil::null); - - getChildView("Creator:")->setEnabled(FALSE); - getChild<LLUICtrl>("Creator Name")->setValue(LLStringUtil::null); - getChildView("Creator Name")->setEnabled(FALSE); - - getChildView("Owner:")->setEnabled(FALSE); - getChild<LLUICtrl>("Owner Name")->setValue(LLStringUtil::null); - getChildView("Owner Name")->setEnabled(FALSE); - - getChildView("Group:")->setEnabled(FALSE); - getChild<LLUICtrl>("Group Name")->setValue(LLStringUtil::null); - getChildView("Group Name")->setEnabled(FALSE); - getChildView("button set group")->setEnabled(FALSE); - - getChild<LLUICtrl>("Object Name")->setValue(LLStringUtil::null); - getChildView("Object Name")->setEnabled(FALSE); - getChildView("Name:")->setEnabled(FALSE); - getChild<LLUICtrl>("Group Name")->setValue(LLStringUtil::null); - getChildView("Group Name")->setEnabled(FALSE); - getChildView("Description:")->setEnabled(FALSE); - getChild<LLUICtrl>("Object Description")->setValue(LLStringUtil::null); - getChildView("Object Description")->setEnabled(FALSE); - - getChildView("Permissions:")->setEnabled(FALSE); + mDAPermModify->setEnabled(FALSE); + mDAPermModify->setValue(LLStringUtil::null); + + mDACreator->setEnabled(FALSE); + mDACreatorName->setValue(LLStringUtil::null); + mDACreatorName->setEnabled(FALSE); + + mDAOwner->setEnabled(FALSE); + mDAOwnerName->setValue(LLStringUtil::null); + mDAOwnerName->setEnabled(FALSE); + + mDAGroup->setEnabled(FALSE); + mDAGroupName->setValue(LLStringUtil::null); + mDAGroupName->setEnabled(FALSE); + mDAButtonSetGroup->setEnabled(FALSE); + + mDAObjectName->setValue(LLStringUtil::null); + mDAObjectName->setEnabled(FALSE); + mDAName->setEnabled(FALSE); + mDAGroupName->setValue(LLStringUtil::null); + mDAGroupName->setEnabled(FALSE); + mDADescription->setEnabled(FALSE); + mDAObjectDescription->setValue(LLStringUtil::null); + mDAObjectDescription->setEnabled(FALSE); + + mDAPermissions->setEnabled(FALSE); - getChild<LLUICtrl>("checkbox share with group")->setValue(FALSE); - getChildView("checkbox share with group")->setEnabled(FALSE); - getChildView("button deed")->setEnabled(FALSE); + mDACheckboxShareWithGroup->setValue(FALSE); + mDACheckboxShareWithGroup->setEnabled(FALSE); + mDAButtonDeed->setEnabled(FALSE); - getChild<LLUICtrl>("checkbox allow everyone move")->setValue(FALSE); - getChildView("checkbox allow everyone move")->setEnabled(FALSE); - getChild<LLUICtrl>("checkbox allow everyone copy")->setValue(FALSE); - getChildView("checkbox allow everyone copy")->setEnabled(FALSE); + mDACheckboxAllowEveryoneMove->setValue(FALSE); + mDACheckboxAllowEveryoneMove->setEnabled(FALSE); + mDACheckboxAllowEveryoneCopy->setValue(FALSE); + mDACheckboxAllowEveryoneCopy->setEnabled(FALSE); //Next owner can: - getChildView("Next owner can:")->setEnabled(FALSE); - getChild<LLUICtrl>("checkbox next owner can modify")->setValue(FALSE); - getChildView("checkbox next owner can modify")->setEnabled(FALSE); - getChild<LLUICtrl>("checkbox next owner can copy")->setValue(FALSE); - getChildView("checkbox next owner can copy")->setEnabled(FALSE); - getChild<LLUICtrl>("checkbox next owner can transfer")->setValue(FALSE); - getChildView("checkbox next owner can transfer")->setEnabled(FALSE); + mDANextOwnerCan->setEnabled(FALSE); + mDACheckboxNextOwnerCanModify->setValue(FALSE); + mDACheckboxNextOwnerCanModify->setEnabled(FALSE); + mDACheckboxNextOwnerCanCopy->setValue(FALSE); + mDACheckboxNextOwnerCanCopy->setEnabled(FALSE); + mDACheckboxNextOwnerCanTransfer->setValue(FALSE); + mDACheckboxNextOwnerCanTransfer->setEnabled(FALSE); //checkbox for sale - getChild<LLUICtrl>("checkbox for sale")->setValue(FALSE); - getChildView("checkbox for sale")->setEnabled(FALSE); + mDACheckboxForSale->setValue(FALSE); + mDACheckboxForSale->setEnabled(FALSE); //checkbox include in search - getChild<LLUICtrl>("search_check")->setValue(FALSE); - getChildView("search_check")->setEnabled(FALSE); + mDASearchCheck->setValue(FALSE); + mDASearchCheck->setEnabled(FALSE); - LLComboBox* combo_sale_type = getChild<LLComboBox>("sale type"); - combo_sale_type->setValue(LLSaleInfo::FS_COPY); - combo_sale_type->setEnabled(FALSE); + mDAComboSaleType->setValue(LLSaleInfo::FS_COPY); + mDAComboSaleType->setEnabled(FALSE); - getChildView("Cost")->setEnabled(FALSE); - getChild<LLUICtrl>("Cost")->setValue(getString("Cost Default")); - getChild<LLUICtrl>("Edit Cost")->setValue(LLStringUtil::null); - getChildView("Edit Cost")->setEnabled(FALSE); + mDACost->setEnabled(FALSE); + mDACost->setValue(getString("Cost Default")); + mDAEditCost->setValue(LLStringUtil::null); + mDAEditCost->setEnabled(FALSE); - getChildView("label click action")->setEnabled(FALSE); - LLComboBox* combo_click_action = getChild<LLComboBox>("clickaction"); - if (combo_click_action) + mDALabelClickAction->setEnabled(FALSE); + if (mDAComboClickAction) { - combo_click_action->setEnabled(FALSE); - combo_click_action->clear(); + mDAComboClickAction->setEnabled(FALSE); + mDAComboClickAction->clear(); } - getChildView("B:")->setVisible( FALSE); - getChildView("O:")->setVisible( FALSE); - getChildView("G:")->setVisible( FALSE); - getChildView("E:")->setVisible( FALSE); - getChildView("N:")->setVisible( FALSE); - getChildView("F:")->setVisible( FALSE); + + mDAPathfindingAttributes->setEnabled(FALSE); + mDAPathfindingAttributes->setValue(LLStringUtil::null); + + mDAB->setVisible(FALSE); + mDAO->setVisible(FALSE); + mDAG->setVisible(FALSE); + mDAE->setVisible(FALSE); + mDAN->setVisible(FALSE); + mDAF->setVisible(FALSE); mOpenBtn->setEnabled(FALSE); mPayBtn->setEnabled(FALSE); @@ -221,7 +265,7 @@ void LLSidepanelTaskInfo::disableAll() void LLSidepanelTaskInfo::refresh() { - LLButton* btn_deed_to_group = getChild<LLButton>("button deed"); + LLButton* btn_deed_to_group = mDeedBtn; if (btn_deed_to_group) { std::string deedText; @@ -266,6 +310,8 @@ void LLSidepanelTaskInfo::refresh() // BUG: fails if a root and non-root are both single-selected. const BOOL is_perm_modify = (mObjectSelection->getFirstRootNode() && LLSelectMgr::getInstance()->selectGetRootsModify()) || LLSelectMgr::getInstance()->selectGetModify(); + const BOOL is_nonpermanent_enforced = (mObjectSelection->getFirstRootNode() && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced()) || + LLSelectMgr::getInstance()->selectGetNonPermanentEnforced(); S32 string_index = 0; std::string MODIFY_INFO_STRINGS[] = @@ -273,12 +319,18 @@ void LLSidepanelTaskInfo::refresh() getString("text modify info 1"), getString("text modify info 2"), getString("text modify info 3"), - getString("text modify info 4") + getString("text modify info 4"), + getString("text modify info 5"), + getString("text modify info 6") }; if (!is_perm_modify) { string_index += 2; } + else if (!is_nonpermanent_enforced) + { + string_index += 4; + } if (!is_one_object) { ++string_index; @@ -286,6 +338,34 @@ void LLSidepanelTaskInfo::refresh() getChildView("perm_modify")->setEnabled(TRUE); getChild<LLUICtrl>("perm_modify")->setValue(MODIFY_INFO_STRINGS[string_index]); + std::string pfAttrName; + + if ((mObjectSelection->getFirstRootNode() + && LLSelectMgr::getInstance()->selectGetRootsNonPathfinding()) + || LLSelectMgr::getInstance()->selectGetNonPathfinding()) + { + pfAttrName = "Pathfinding_Object_Attr_None"; + } + else if ((mObjectSelection->getFirstRootNode() + && LLSelectMgr::getInstance()->selectGetRootsPermanent()) + || LLSelectMgr::getInstance()->selectGetPermanent()) + { + pfAttrName = "Pathfinding_Object_Attr_Permanent"; + } + else if ((mObjectSelection->getFirstRootNode() + && LLSelectMgr::getInstance()->selectGetRootsCharacter()) + || LLSelectMgr::getInstance()->selectGetCharacter()) + { + pfAttrName = "Pathfinding_Object_Attr_Character"; + } + else + { + pfAttrName = "Pathfinding_Object_Attr_MultiSelect"; + } + + mDAPathfindingAttributes->setEnabled(TRUE); + mDAPathfindingAttributes->setValue(LLTrans::getString(pfAttrName)); + getChildView("Permissions:")->setEnabled(TRUE); // Update creator text field @@ -350,7 +430,7 @@ void LLSidepanelTaskInfo::refresh() } } - getChildView("button set group")->setEnabled(owners_identical && (mOwnerID == gAgent.getID())); + getChildView("button set group")->setEnabled(owners_identical && (mOwnerID == gAgent.getID()) && is_nonpermanent_enforced); getChildView("Name:")->setEnabled(TRUE); LLLineEditor* LineEditorObjectName = getChild<LLLineEditor>("Object Name"); @@ -380,7 +460,7 @@ void LLSidepanelTaskInfo::refresh() // figure out the contents of the name, description, & category BOOL edit_name_desc = FALSE; - if (is_one_object && objectp->permModify()) + if (is_one_object && objectp->permModify() && !objectp->isPermanentEnforced()) { edit_name_desc = TRUE; } @@ -560,12 +640,12 @@ void LLSidepanelTaskInfo::refresh() BOOL has_change_perm_ability = FALSE; BOOL has_change_sale_ability = FALSE; - if (valid_base_perms && + if (valid_base_perms && is_nonpermanent_enforced && (self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_MANIPULATE)))) { has_change_perm_ability = TRUE; } - if (valid_base_perms && + if (valid_base_perms && is_nonpermanent_enforced && (self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_SET_SALE)))) { has_change_sale_ability = TRUE; @@ -777,8 +857,8 @@ void LLSidepanelTaskInfo::refresh() ComboClickAction->setCurrentByIndex((S32)click_action); } } - getChildView("label click action")->setEnabled(is_perm_modify && all_volume); - getChildView("clickaction")->setEnabled(is_perm_modify && all_volume); + getChildView("label click action")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume); + getChildView("clickaction")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume); if (!getIsEditing()) { @@ -1079,8 +1159,6 @@ void LLSidepanelTaskInfo::doClickAction(U8 click_action) // Set click action back to its old value U8 click_action = 0; LLSelectMgr::getInstance()->selectionGetClickAction(&click_action); -// box->setCurrentByIndex((S32)click_action); - return; } } diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h index 384bc479d6..05edcda5ed 100644 --- a/indra/newview/llsidepaneltaskinfo.h +++ b/indra/newview/llsidepaneltaskinfo.h @@ -37,9 +37,11 @@ // Panel for permissions of an object. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLNameBox; class LLCheckBoxCtrl; +class LLComboBox; +class LLNameBox; class LLViewerObject; +class LLTextBase; class LLSidepanelTaskInfo : public LLSidepanelInventorySubpanel { @@ -111,6 +113,7 @@ private: LLButton* mPayBtn; LLButton* mBuyBtn; LLButton* mDetailsBtn; + LLButton* mDeedBtn; protected: LLViewerObject* getObject(); @@ -118,6 +121,44 @@ private: LLPointer<LLViewerObject> mObject; LLObjectSelectionHandle mObjectSelection; static LLSidepanelTaskInfo* sActivePanel; + +private: + // Pointers cached here to speed up the "disableAll" function which gets called on idle + LLUICtrl* mDAPermModify; + LLView* mDACreator; + LLUICtrl* mDACreatorName; + LLView* mDAOwner; + LLUICtrl* mDAOwnerName; + LLView* mDAGroup; + LLUICtrl* mDAGroupName; + LLView* mDAButtonSetGroup; + LLUICtrl* mDAObjectName; + LLView* mDAName; + LLView* mDADescription; + LLUICtrl* mDAObjectDescription; + LLView* mDAPermissions; + LLUICtrl* mDACheckboxShareWithGroup; + LLView* mDAButtonDeed; + LLUICtrl* mDACheckboxAllowEveryoneMove; + LLUICtrl* mDACheckboxAllowEveryoneCopy; + LLView* mDANextOwnerCan; + LLUICtrl* mDACheckboxNextOwnerCanModify; + LLUICtrl* mDACheckboxNextOwnerCanCopy; + LLUICtrl* mDACheckboxNextOwnerCanTransfer; + LLUICtrl* mDACheckboxForSale; + LLUICtrl* mDASearchCheck; + LLComboBox* mDAComboSaleType; + LLUICtrl* mDACost; + LLUICtrl* mDAEditCost; + LLView* mDALabelClickAction; + LLComboBox* mDAComboClickAction; + LLTextBase* mDAPathfindingAttributes; + LLView* mDAB; + LLView* mDAO; + LLView* mDAG; + LLView* mDAE; + LLView* mDAN; + LLView* mDAF; }; diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp index a853726dea..3a82233320 100644 --- a/indra/newview/llslurl.cpp +++ b/indra/newview/llslurl.cpp @@ -56,14 +56,13 @@ LLSLURL::LLSLURL(const std::string& slurl) { // by default we go to agni. mType = INVALID; - LL_INFOS("AppInit") << "SLURL: " << slurl << LL_ENDL; + if(slurl == SIM_LOCATION_HOME) { mType = HOME_LOCATION; } else if(slurl.empty() || (slurl == SIM_LOCATION_LAST)) { - mType = LAST_LOCATION; } else @@ -80,6 +79,7 @@ LLSLURL::LLSLURL(const std::string& slurl) // these slurls are typically passed in from the 'starting location' box on the login panel, // where the user can type in <regionname>/<x>/<y>/<z> std::string fixed_slurl = LLGridManager::getInstance()->getSLURLBase(); + // the slurl that was passed in might have a prepended /, or not. So, // we strip off the prepended '/' so we don't end up with http://slurl.com/secondlife/<region>/<x>/<y>/<z> // or some such. @@ -138,7 +138,7 @@ LLSLURL::LLSLURL(const std::string& slurl) // so parse the grid name to derive the grid ID if (!slurl_uri.hostName().empty()) { - mGrid = LLGridManager::getInstance()->getGridByLabel(slurl_uri.hostName()); + mGrid = LLGridManager::getInstance()->getGridId(slurl_uri.hostName()); } else if(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH) { @@ -150,12 +150,13 @@ LLSLURL::LLSLURL(const std::string& slurl) { // for app style slurls, where no grid name is specified, assume the currently // selected or logged in grid. - mGrid = LLGridManager::getInstance()->getGrid(); + mGrid = LLGridManager::getInstance()->getGridId(); } if(mGrid.empty()) { // we couldn't find the grid in the grid manager, so bail + LL_WARNS("AppInit")<<"unable to find grid"<<LL_ENDL; return; } // set the type as appropriate. @@ -334,7 +335,7 @@ LLSLURL::LLSLURL(const std::string& grid, LLSLURL::LLSLURL(const std::string& region, const LLVector3& position) { - *this = LLSLURL(LLGridManager::getInstance()->getGrid(), + *this = LLSLURL(LLGridManager::getInstance()->getGridId(), region, position); } @@ -343,7 +344,7 @@ LLSLURL::LLSLURL(const std::string& grid, const std::string& region, const LLVector3d& global_position) { - *this = LLSLURL(grid, + *this = LLSLURL(LLGridManager::getInstance()->getGridId(grid), region, LLVector3(global_position.mdV[VX], global_position.mdV[VY], global_position.mdV[VZ])); @@ -353,7 +354,7 @@ LLSLURL::LLSLURL(const std::string& grid, LLSLURL::LLSLURL(const std::string& region, const LLVector3d& global_position) { - *this = LLSLURL(LLGridManager::getInstance()->getGrid(), + *this = LLSLURL(LLGridManager::getInstance()->getGridId(), region, global_position); } @@ -426,7 +427,7 @@ std::string LLSLURL::getLoginString() const unescaped_start << "last"; break; default: - LL_WARNS("AppInit") << "Unexpected SLURL type for login string" << (int)mType << LL_ENDL; + LL_WARNS("AppInit") << "Unexpected SLURL type ("<<(int)mType <<")for login string"<< LL_ENDL; break; } return xml_escape_string(unescaped_start.str()); @@ -465,18 +466,47 @@ std::string LLSLURL::getLocationString() const (int)llround(mPosition[1]), (int)llround(mPosition[2])); } + +// static +const std::string LLSLURL::typeName[NUM_SLURL_TYPES] = +{ + "INVALID", + "LOCATION", + "HOME_LOCATION", + "LAST_LOCATION", + "APP", + "HELP" +}; + +std::string LLSLURL::getTypeString(SLURL_TYPE type) +{ + std::string name; + if ( type >= INVALID && type < NUM_SLURL_TYPES ) + { + name = LLSLURL::typeName[type]; + } + else + { + name = llformat("Out of Range (%d)",type); + } + return name; +} + + std::string LLSLURL::asString() const { std::ostringstream result; - result << " mAppCmd:" << getAppCmd() << - " mAppPath:" + getAppPath().asString() << - " mAppQueryMap:" + getAppQueryMap().asString() << - " mAppQuery: " + getAppQuery() << - " mGrid: " + getGrid() << - " mRegion: " + getRegion() << - " mPosition: " << - " mType: " << mType << - " mPosition: " << mPosition; + result + << " mType: " << LLSLURL::getTypeString(mType) + << " mGrid: " + getGrid() + << " mRegion: " + getRegion() + << " mPosition: " << mPosition + << " mAppCmd:" << getAppCmd() + << " mAppPath:" + getAppPath().asString() + << " mAppQueryMap:" + getAppQueryMap().asString() + << " mAppQuery: " + getAppQuery() + ; + return result.str(); } diff --git a/indra/newview/llslurl.h b/indra/newview/llslurl.h index 1a3f0543dd..b86cf7949b 100644 --- a/indra/newview/llslurl.h +++ b/indra/newview/llslurl.h @@ -51,13 +51,15 @@ public: static const char* SLURL_APP_PATH; static const char* SLURL_REGION_PATH; + // if you modify this enumeration, update typeName as well enum SLURL_TYPE { INVALID, LOCATION, HOME_LOCATION, LAST_LOCATION, APP, - HELP + HELP, + NUM_SLURL_TYPES // must be last }; @@ -92,6 +94,10 @@ public: std::string asString() const ; protected: + static const std::string typeName[NUM_SLURL_TYPES]; + /// Get a human-readable version of the type for logging + static std::string getTypeString(SLURL_TYPE type); + SLURL_TYPE mType; // used for Apps and Help diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 3e16ccf3da..3ed6e24498 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" @@ -51,7 +55,7 @@ #include "llviewershadermgr.h" static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling"); -static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound"); +static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound Partition"); const F32 SG_OCCLUSION_FUDGE = 0.25f; #define SG_DISCARD_TOLERANCE 0.01f @@ -64,6 +68,7 @@ const F32 SG_OCCLUSION_FUDGE = 0.25f; #define assert_states_valid(x) #endif +extern bool gShiftFrame; static U32 sZombieGroups = 0; U32 LLSpatialGroup::sNodeCount = 0; @@ -81,12 +86,32 @@ static F32 sCurMaxTexPriority = 1.f; class LLOcclusionQueryPool : public LLGLNamePool { +public: + LLOcclusionQueryPool() + { + mCurQuery = 1; + } + protected: + + std::list<GLuint> mAvailableName; + GLuint mCurQuery; + virtual GLuint allocateName() { - GLuint name; - glGenQueriesARB(1, &name); - return name; + GLuint ret = 0; + + if (!mAvailableName.empty()) + { + ret = mAvailableName.front(); + mAvailableName.pop_front(); + } + else + { + ret = mCurQuery++; + } + + return ret; } virtual void releaseName(GLuint name) @@ -94,7 +119,8 @@ protected: #if LL_TRACK_PENDING_OCCLUSION_QUERIES LLSpatialGroup::sPendingQueries.erase(name); #endif - glDeleteQueriesARB(1, &name); + llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); + mAvailableName.push_back(name); } }; @@ -255,79 +281,39 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) return (U8*) (sOcclusionIndices+cypher*8); } - -static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion"); - -void LLSpatialGroup::buildOcclusion() +//create a vertex buffer for efficiently rendering cubes +LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage) { - 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. - mOcclusionVerts->allocateBuffer(8, 64, true); - - LLStrider<U16> idx; - mOcclusionVerts->getIndexStrider(idx); - for (U32 i = 0; i < 64; i++) - { - *idx++ = sOcclusionIndices[i]; - } - } + LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage); - LLVector4a fudge; - fudge.splat(SG_OCCLUSION_FUDGE); - - LLVector4a r; - r.setAdd(mBounds[1], fudge); + ret->allocateBuffer(8, 64, true); LLStrider<LLVector3> pos; - - { - LLFastTimer t(FTM_BUILD_OCCLUSION); - mOcclusionVerts->getVertexStrider(pos); - } + LLStrider<U16> idx; - { - LLVector4a* v = (LLVector4a*) pos.get(); + ret->getVertexStrider(pos); + ret->getIndexStrider(idx); - const LLVector4a& c = mBounds[0]; - const LLVector4a& s = r; - - static const LLVector4a octant[] = - { - LLVector4a(-1.f, -1.f, -1.f), - LLVector4a(-1.f, -1.f, 1.f), - LLVector4a(-1.f, 1.f, -1.f), - LLVector4a(-1.f, 1.f, 1.f), - - LLVector4a(1.f, -1.f, -1.f), - LLVector4a(1.f, -1.f, 1.f), - LLVector4a(1.f, 1.f, -1.f), - LLVector4a(1.f, 1.f, 1.f), - }; - - //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 - //meaning negative facing - - for (S32 i = 0; i < 8; ++i) - { - LLVector4a p; - p.setMul(s, octant[i]); - p.add(c); - v[i] = p; - } - } - + pos[0] = LLVector3(-1,-1,-1); + pos[1] = LLVector3(-1,-1, 1); + pos[2] = LLVector3(-1, 1,-1); + pos[3] = LLVector3(-1, 1, 1); + pos[4] = LLVector3( 1,-1,-1); + pos[5] = LLVector3( 1,-1, 1); + pos[6] = LLVector3( 1, 1,-1); + pos[7] = LLVector3( 1, 1, 1); + + for (U32 i = 0; i < 64; i++) { - mOcclusionVerts->flush(); - LLVertexBuffer::unbind(); + idx[i] = sOcclusionIndices[i]; } - clearState(LLSpatialGroup::OCCLUSION_DIRTY); + ret->flush(); + + return ret; } +static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion"); BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group); @@ -390,9 +376,6 @@ LLSpatialGroup::~LLSpatialGroup() } } - mOcclusionVerts = NULL; - - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); clearDrawMap(); clearAtlasList() ; } @@ -546,6 +529,7 @@ void LLSpatialGroup::setVisible() void LLSpatialGroup::validate() { + ll_assert_aligned(this,64); #if LL_OCTREE_PARANOIA_CHECK sg_assert(!isState(DIRTY)); @@ -558,7 +542,7 @@ void LLSpatialGroup::validate() validateDrawMap(); - for (element_iter i = getData().begin(); i != getData().end(); ++i) + for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) { LLDrawable* drawable = *i; sg_assert(drawable->getSpatialGroup() == this); @@ -630,8 +614,6 @@ void LLSpatialGroup::validateDrawMap() BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - drawablep->updateSpatialExtents(); OctreeNode* parent = mOctreeNode->getOctParent(); @@ -653,7 +635,6 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_octree) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); if (!from_octree) { mOctreeNode->insert(drawablep); @@ -679,10 +660,14 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc void LLSpatialGroup::rebuildGeom() { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); if (!isDead()) { mSpatialPartition->rebuildGeom(this); + + if (isState(LLSpatialGroup::MESH_DIRTY)) + { + gPipeline.markMeshDirty(this); + } } } @@ -695,6 +680,9 @@ void LLSpatialGroup::rebuildMesh() } static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt"); +static LLFastTimer::DeclareTimer FTM_ADD_GEOMETRY_COUNT("Add Geometry"); +static LLFastTimer::DeclareTimer FTM_CREATE_VB("Create VB"); +static LLFastTimer::DeclareTimer FTM_GET_GEOMETRY("Get Geometry"); void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { @@ -716,25 +704,36 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) //get geometry count U32 index_count = 0; U32 vertex_count = 0; - - addGeometryCount(group, vertex_count, index_count); + + { + LLFastTimer t(FTM_ADD_GEOMETRY_COUNT); + addGeometryCount(group, vertex_count, index_count); + } 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)) { - group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage); - group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true); - stop_glerror(); + LLFastTimer t(FTM_CREATE_VB); + group->mBuilt = 1.f; + 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); + stop_glerror(); + } + else + { + group->mVertexBuffer->resizeBuffer(vertex_count, index_count); + stop_glerror(); + } } - else + { - group->mVertexBuffer->resizeBuffer(vertex_count, index_count); - stop_glerror(); + LLFastTimer t(FTM_GET_GEOMETRY); + getGeometry(group); } - - getGeometry(group); } else { @@ -756,7 +755,7 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& ma { const OctreeNode* node = mOctreeNode; - if (node->getData().empty()) + if (node->isEmpty()) { //don't do anything if there are no objects if (empty && mOctreeNode->getParent()) { //only root is allowed to be empty @@ -773,14 +772,14 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& ma clearState(OBJECT_DIRTY); //initialize bounding box to first element - OctreeNode::const_element_iter i = node->getData().begin(); + OctreeNode::const_element_iter i = node->getDataBegin(); LLDrawable* drawablep = *i; const LLVector4a* minMax = drawablep->getSpatialExtents(); newMin = minMax[0]; newMax = minMax[1]; - for (++i; i != node->getData().end(); ++i) + for (++i; i != node->getDataEnd(); ++i) { drawablep = *i; minMax = drawablep->getSpatialExtents(); @@ -872,7 +871,6 @@ LLSpatialGroup* LLSpatialGroup::getParent() BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); unbound(); if (mOctreeNode && !from_octree) { @@ -909,7 +907,6 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) void LLSpatialGroup::shift(const LLVector4a &offset) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); LLVector4a t = mOctreeNode->getCenter(); t.add(offset); mOctreeNode->setCenter(t); @@ -921,16 +918,14 @@ void LLSpatialGroup::shift(const LLVector4a &offset) mObjectExtents[0].add(offset); mObjectExtents[1].add(offset); - //if (!mSpatialPartition->mRenderByGroup) + if (!mSpatialPartition->mRenderByGroup && + mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TREE && + mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && + mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_BRIDGE) { setState(GEOM_DIRTY); gPipeline.markRebuild(this, TRUE); } - - if (mOcclusionVerts.notNull()) - { - setState(OCCLUSION_DIRTY); - } } class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler @@ -966,8 +961,6 @@ void LLSpatialGroup::setState(U32 state) void LLSpatialGroup::setState(U32 state, S32 mode) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - llassert(state <= LLSpatialGroup::STATE_MASK); if (mode > STATE_MODE_SINGLE) @@ -1024,8 +1017,6 @@ void LLSpatialGroup::clearState(U32 state, S32 mode) { llassert(state <= LLSpatialGroup::STATE_MASK); - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - if (mode > STATE_MODE_SINGLE) { if (mode == STATE_MODE_DIFF) @@ -1082,8 +1073,6 @@ public: void LLSpatialGroup::setOcclusionState(U32 state, S32 mode) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - if (mode > STATE_MODE_SINGLE) { if (mode == STATE_MODE_DIFF) @@ -1148,8 +1137,6 @@ public: void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - if (mode > STATE_MODE_SINGLE) { if (mode == STATE_MODE_DIFF) @@ -1180,7 +1167,10 @@ void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode) //====================================== LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : + mObjectBoxSize(1.f), mState(0), + mGeometryBytes(0), + mSurfaceArea(0.f), mBuilt(0.f), mOctreeNode(node), mSpatialPartition(part), @@ -1195,8 +1185,9 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mCurUpdatingSlotp(NULL), mCurUpdatingTexture (NULL) { + ll_assert_aligned(this,16); + sNodeCount++; - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); mViewAngle.splat(0.f); mLastUpdateViewAngle.splat(-1.f); @@ -1221,12 +1212,11 @@ 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; } - mOcclusionVerts = NULL; - mRadius = 1; mPixelArea = 1024.f; } @@ -1239,13 +1229,18 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) return; } + if (gShiftFrame) + { + return; + } + #if !LL_RELEASE_FOR_DOWNLOAD if (isState(LLSpatialGroup::OBJECT_DIRTY)) { llerrs << "Spatial group dirty on distance update." << llendl; } #endif - if (!getData().empty()) + if (!isEmpty()) { mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() : (F32) mOctreeNode->getSize().getLength3().getF32(); @@ -1378,7 +1373,6 @@ BOOL LLSpatialGroup::changeLOD() void LLSpatialGroup::handleInsertion(const TreeNode* node, LLDrawable* drawablep) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); addObject(drawablep, FALSE, TRUE); unbound(); setState(OBJECT_DIRTY); @@ -1386,17 +1380,15 @@ void LLSpatialGroup::handleInsertion(const TreeNode* node, LLDrawable* drawablep void LLSpatialGroup::handleRemoval(const TreeNode* node, LLDrawable* drawable) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); removeObject(drawable, TRUE); setState(OBJECT_DIRTY); } void LLSpatialGroup::handleDestruction(const TreeNode* node) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); setState(DEAD); - for (element_iter i = getData().begin(); i != getData().end(); ++i) + for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) { LLDrawable* drawable = *i; if (drawable->getSpatialGroup() == this) @@ -1405,6 +1397,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(); @@ -1424,7 +1427,6 @@ void LLSpatialGroup::handleStateChange(const TreeNode* node) void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); if (child->getListenerCount() == 0) { new LLSpatialGroup(child, mSpatialPartition); @@ -1444,10 +1446,14 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo unbound(); } -void LLSpatialGroup::destroyGL() +void LLSpatialGroup::destroyGL(bool keep_occlusion) { setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); - gPipeline.markRebuild(this, TRUE); + + if (!keep_occlusion) + { //going to need a rebuild + gPipeline.markRebuild(this, TRUE); + } mLastUpdateTime = gFrameTimeSeconds; mVertexBuffer = NULL; @@ -1455,24 +1461,29 @@ void LLSpatialGroup::destroyGL() clearDrawMap(); - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + if (!keep_occlusion) { - if (mOcclusionQuery[i]) + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) { - sQueryPool.release(mOcclusionQuery[i]); - mOcclusionQuery[i] = 0; + if (mOcclusionQuery[i]) + { + sQueryPool.release(mOcclusionQuery[i]); + mOcclusionQuery[i] = 0; + } } } - mOcclusionVerts = NULL; - for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) + for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i) { LLDrawable* drawable = *i; for (S32 j = 0; j < drawable->getNumFaces(); j++) { LLFace* facep = drawable->getFace(j); - facep->clearVertexBuffer(); + if (facep) + { + facep->clearVertexBuffer(); + } } } } @@ -1535,14 +1546,14 @@ BOOL LLSpatialGroup::rebound() mBounds[1].mul(0.5f); } - setState(OCCLUSION_DIRTY); - clearState(DIRTY); return TRUE; } static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait"); + void LLSpatialGroup::checkOcclusion() { if (LLPipeline::sUseOcclusion > 1) @@ -1560,6 +1571,24 @@ void LLSpatialGroup::checkOcclusion() if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) { glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + + static LLCachedControl<bool> wait_for_query(gSavedSettings, "RenderSynchronousOcclusion"); + + if (wait_for_query && 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 { @@ -1596,7 +1625,9 @@ void LLSpatialGroup::checkOcclusion() else { assert_states_valid(this); + setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); + assert_states_valid(this); } @@ -1651,12 +1682,6 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); } - if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY)) - { - LLFastTimer t(FTM_OCCLUSION_BUILD); - buildOcclusion(); - } - // Depth clamp all water to avoid it being culled as a result of being // behind the far clip plane, and in the case of edge water to avoid // it being culled while still visible. @@ -1679,15 +1704,21 @@ 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]); } - { - LLFastTimer t(FTM_OCCLUSION_SET_BUFFER); - mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); - } + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(shader); + + shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr()); + shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE, + mBounds[1][1]+SG_OCCLUSION_FUDGE, + mBounds[1][2]+SG_OCCLUSION_FUDGE); if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) { @@ -1696,12 +1727,12 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) LLGLSquashToFarClip squash(glh_get_current_projection(), 1); if (camera->getOrigin().isExactlyZero()) { //origin is invalid, draw entire box - mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); - mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); } else { - mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); } } else @@ -1709,12 +1740,12 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) LLFastTimer t(FTM_OCCLUSION_DRAW); if (camera->getOrigin().isExactlyZero()) { //origin is invalid, draw entire box - mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); - mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); } else { - mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); } } @@ -1739,9 +1770,8 @@ 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; mDrawableType = 0; mPartitionType = LLViewerRegion::PARTITION_NONE; @@ -1765,8 +1795,6 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 LLSpatialPartition::~LLSpatialPartition() { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - delete mOctree; mOctree = NULL; } @@ -1774,8 +1802,6 @@ LLSpatialPartition::~LLSpatialPartition() LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - drawablep->updateSpatialExtents(); //keep drawable from being garbage collected @@ -1797,14 +1823,16 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - - drawablep->setSpatialGroup(NULL); - if (!curp->removeObject(drawablep)) { OCT_ERRS << "Failed to remove drawable from octree!" << llendl; } + else + { + drawablep->setSpatialGroup(NULL); + } + + drawablep->setSpatialGroup(NULL); assert_octree_valid(mOctree); @@ -1813,8 +1841,6 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - // sanity check submitted by open source user bushing Spatula // who was seeing crashing here. (See VWR-424 reported by Bunny Mayne) if (!drawablep) @@ -1871,7 +1897,6 @@ public: void LLSpatialPartition::shift(const LLVector4a &offset) { //shift octree node bounding boxes by offset - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); LLSpatialShift shifter(offset); shifter.traverse(mOctree); } @@ -2075,7 +2100,7 @@ public: virtual void processGroup(LLSpatialGroup* group) { - llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->getData().empty()) + llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->isEmpty()) if (mRes < 2) { @@ -2142,7 +2167,7 @@ public: { LLSpatialGroup::OctreeNode* branch = group->mOctreeNode; - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { LLDrawable* drawable = *i; @@ -2266,7 +2291,7 @@ public: LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); group->destroyGL(); - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { LLDrawable* drawable = *i; if (drawable->getVObj().notNull() && !group->mSpatialPartition->mRenderByGroup) @@ -2285,7 +2310,6 @@ public: void LLSpatialPartition::restoreGL() { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); } void LLSpatialPartition::resetVertexBuffers() @@ -2328,7 +2352,6 @@ BOOL LLSpatialPartition::visibleObjectsInFrustum(LLCamera& camera) S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); #if LL_OCTREE_PARANOIA_CHECK ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); #endif @@ -2438,18 +2461,21 @@ void pushVerts(LLSpatialGroup* group, U32 mask) void pushVerts(LLFace* face, U32 mask) { - llassert(face->verify()); + if (face) + { + llassert(face->verify()); - LLVertexBuffer* buffer = face->getVertexBuffer(); + LLVertexBuffer* buffer = face->getVertexBuffer(); - if (buffer && (face->getGeomCount() >= 3)) - { - buffer->setBuffer(mask); - U16 start = face->getGeomStart(); - U16 end = start + face->getGeomCount()-1; - U32 count = face->getIndicesCount(); - U16 offset = face->getIndicesStart(); - buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); + if (buffer && (face->getGeomCount() >= 3)) + { + buffer->setBuffer(mask); + U16 start = face->getGeomStart(); + U16 end = start + face->getGeomCount()-1; + U32 count = face->getIndicesCount(); + U16 offset = face->getIndicesStart(); + buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); + } } } @@ -2573,7 +2599,7 @@ void renderOctree(LLSpatialGroup* group) gGL.flush(); glLineWidth(1.f); gGL.flush(); - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { LLDrawable* drawable = *i; if (!group->mSpatialPartition->isBridge()) @@ -2586,7 +2612,7 @@ void renderOctree(LLSpatialGroup* group) for (S32 j = 0; j < drawable->getNumFaces(); j++) { LLFace* face = drawable->getFace(j); - if (face->getVertexBuffer()) + if (face && face->getVertexBuffer()) { if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f) { @@ -2619,7 +2645,7 @@ void renderOctree(LLSpatialGroup* group) } else { - if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->getData().empty() + if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->isEmpty() && group->mSpatialPartition->mRenderByGroup) { col.setVec(0.8f, 0.4f, 0.1f, 0.1f); @@ -2687,7 +2713,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() && - !group->getData().empty(); + !group->isEmpty(); if (render_objects) { @@ -2715,25 +2741,12 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) gGL.diffuseColor4f(0.f, 0.75f, 0.f, 0.5f); pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); } - /*else if (camera && group->mOcclusionVerts.notNull()) - { - LLVertexBuffer::unbind(); - group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); - - gGL.diffuseColor4f(1.0f, 0.f, 0.f, 0.5f); - group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0])); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - gGL.diffuseColor4f(1.0f, 1.f, 1.f, 1.0f); - group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0])); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - }*/ } } void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color) { - gGL.diffuseColor4fv(color.mV); + gGL.color4fv(color.mV); gGL.begin(LLRender::LINES); { gGL.vertex3fv((position - LLVector3(size, 0.f, 0.f)).mV); @@ -2957,15 +2970,17 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) for (S32 i = 0; i < drawable->getNumFaces(); i++) { LLFace* facep = drawable->getFace(i); + if (facep) + { + ext = facep->mExtents; - ext = facep->mExtents; - - pos.setAdd(ext[0], ext[1]); - pos.mul(0.5f); - size.setSub(ext[1], ext[0]); - size.mul(0.5f); + pos.setAdd(ext[0], ext[1]); + pos.mul(0.5f); + size.setSub(ext[1], ext[0]); + size.mul(0.5f); - drawBoxOutline(pos,size); + drawBoxOutline(pos,size); + } } //render drawable bounding box @@ -3429,7 +3444,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) void renderPhysicsShapes(LLSpatialGroup* group) { - for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { LLDrawable* drawable = *i; LLVOVolume* volume = drawable->getVOVolume(); @@ -3453,24 +3468,30 @@ void renderPhysicsShapes(LLSpatialGroup* group) LLViewerObject* object = drawable->getVObj(); if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) { + gGL.pushMatrix(); + gGL.multMatrix((F32*) object->getRegion()->mRenderMatrix.mMatrix); //push face vertices for terrain for (S32 i = 0; i < drawable->getNumFaces(); ++i) { LLFace* face = drawable->getFace(i); - LLVertexBuffer* buff = face->getVertexBuffer(); - if (buff) + if (face) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff) + { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); - gGL.diffuseColor3f(0.2f, 0.5f, 0.3f); - buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0); + buff->setBuffer(LLVertexBuffer::MAP_VERTEX); + gGL.diffuseColor3f(0.2f, 0.5f, 0.3f); + buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0); - gGL.diffuseColor3f(0.2f, 1.f, 0.3f); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0); + gGL.diffuseColor3f(0.2f, 1.f, 0.3f); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0); + } } } + gGL.popMatrix(); } } } @@ -3492,6 +3513,7 @@ void renderTexturePriority(LLDrawable* drawable) //LLViewerTexture* imagep = facep->getTexture(); //if (imagep) + if (facep) { //F32 vsize = imagep->mMaxVirtualSize; @@ -3544,7 +3566,11 @@ void renderPoints(LLDrawable* drawablep) gGL.diffuseColor3f(1,1,1); for (S32 i = 0; i < drawablep->getNumFaces(); i++) { - gGL.vertex3fv(drawablep->getFace(i)->mCenterLocal.mV); + LLFace * face = drawablep->getFace(i); + if (face) + { + gGL.vertex3fv(face->mCenterLocal.mV); + } } gGL.end(); } @@ -3606,6 +3632,110 @@ void renderShadowFrusta(LLDrawInfo* params) gGL.setSceneBlendType(LLRender::BT_ALPHA); } +void renderTexelDensity(LLDrawable* drawable) +{ + if (LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_OFF + || LLViewerTexture::sCheckerBoardImagep.isNull()) + { + return; + } + + LLGLEnable _(GL_BLEND); + //gObjectFullbrightProgram.bind(); + + LLMatrix4 checkerboard_matrix; + S32 discard_level = -1; + + for (S32 f = 0; f < drawable->getNumFaces(); f++) + { + LLFace* facep = drawable->getFace(f); + LLVertexBuffer* buffer = facep->getVertexBuffer(); + LLViewerTexture* texturep = facep->getTexture(); + + if (texturep == NULL) continue; + + switch(LLViewerTexture::sDebugTexelsMode) + { + case LLViewerTexture::DEBUG_TEXELS_CURRENT: + discard_level = -1; + break; + case LLViewerTexture::DEBUG_TEXELS_DESIRED: + { + LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep); + discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1; + break; + } + default: + case LLViewerTexture::DEBUG_TEXELS_FULL: + discard_level = 0; + break; + } + + checkerboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f)); + + gGL.getTexUnit(0)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadMatrix((GLfloat*)&checkerboard_matrix.mMatrix); + + if (buffer && (facep->getGeomCount() >= 3)) + { + buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); + U16 start = facep->getGeomStart(); + U16 end = start + facep->getGeomCount()-1; + U32 count = facep->getIndicesCount(); + U16 offset = facep->getIndicesStart(); + buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); + } + + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + } + + //S32 num_textures = llmax(1, (S32)params->mTextureList.size()); + + //for (S32 i = 0; i < num_textures; i++) + //{ + // LLViewerTexture* texturep = params->mTextureList.empty() ? params->mTexture.get() : params->mTextureList[i].get(); + // if (texturep == NULL) continue; + + // LLMatrix4 checkboard_matrix; + // S32 discard_level = -1; + // switch(LLViewerTexture::sDebugTexelsMode) + // { + // case LLViewerTexture::DEBUG_TEXELS_CURRENT: + // discard_level = -1; + // break; + // case LLViewerTexture::DEBUG_TEXELS_DESIRED: + // { + // LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep); + // discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1; + // break; + // } + // default: + // case LLViewerTexture::DEBUG_TEXELS_FULL: + // discard_level = 0; + // break; + // } + + // checkboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f)); + // gGL.getTexUnit(i)->activate(); + + // glMatrixMode(GL_TEXTURE); + // glPushMatrix(); + // glLoadIdentity(); + // //gGL.matrixMode(LLRender::MM_TEXTURE); + // glLoadMatrixf((GLfloat*) checkboard_matrix.mMatrix); + + // gGL.getTexUnit(i)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE); + + // pushVerts(params, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL ); + + // glPopMatrix(); + // glMatrixMode(GL_MODELVIEW); + // //gGL.matrixMode(LLRender::MM_MODELVIEW); + //} +} + void renderLights(LLDrawable* drawablep) { @@ -3621,7 +3751,11 @@ void renderLights(LLDrawable* drawablep) for (S32 i = 0; i < drawablep->getNumFaces(); i++) { - pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); + LLFace * face = drawablep->getFace(i); + if (face) + { + pushVerts(face, LLVertexBuffer::MAP_VERTEX); + } } const LLVector4a* ext = drawablep->getSpatialExtents(); @@ -3662,7 +3796,7 @@ public: LLVector3 center, size; - if (branch->getData().empty()) + if (branch->isEmpty()) { gGL.diffuseColor3f(1.f,0.2f,0.f); center.set(branch->getCenter().getF32ptr()); @@ -3698,8 +3832,8 @@ public: } gGL.begin(LLRender::TRIANGLES); - for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getData().begin(); - iter != branch->getData().end(); + for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin(); + iter != branch->getDataEnd(); ++iter) { const LLVolumeTriangle* tri = *iter; @@ -3749,11 +3883,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 +3906,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 +3917,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); } @@ -3857,7 +3997,7 @@ void renderAgentTarget(LLVOAvatar* avatar) if (avatar->isSelf()) { renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f)); - renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f)); + renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f)); renderCrossHairs(avatar->mRoot.getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f)); renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f)); } @@ -3930,7 +4070,7 @@ public: if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) { - if (!group->getData().empty()) + if (!group->isEmpty()) { gGL.diffuseColor3f(0,0,1); drawBoxOutline(group->mObjectBounds[0], @@ -3938,7 +4078,7 @@ public: } } - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { LLDrawable* drawable = *i; @@ -3995,6 +4135,10 @@ public: { renderComplexityDisplay(drawable); } + if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) + { + renderTexelDensity(drawable); + } LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get()); @@ -4013,18 +4157,21 @@ public: for (U32 i = 0; i < drawable->getNumFaces(); ++i) { LLFace* facep = drawable->getFace(i); - U8 index = facep->getTextureIndex(); - if (facep->mDrawInfo) + if (facep) { - if (index < 255) + U8 index = facep->getTextureIndex(); + if (facep->mDrawInfo) { - if (facep->mDrawInfo->mTextureList.size() <= index) - { - llerrs << "Face texture index out of bounds." << llendl; - } - else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture()) + if (index < 255) { - llerrs << "Face texture index incorrect." << llendl; + if (facep->mDrawInfo->mTextureList.size() <= index) + { + llerrs << "Face texture index out of bounds." << llendl; + } + else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture()) + { + llerrs << "Face texture index incorrect." << llendl; + } } } } @@ -4120,7 +4267,7 @@ public: return; } - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { LLDrawable* drawable = *i; @@ -4244,7 +4391,8 @@ void LLSpatialPartition::renderDebug() LLPipeline::RENDER_DEBUG_AGENT_TARGET | //LLPipeline::RENDER_DEBUG_BUILD_QUEUE | LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA | - LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY)) + LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY | + LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) { return; } @@ -4261,8 +4409,6 @@ void LLSpatialPartition::renderDebug() sCurMaxTexPriority = 0.f; } - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - LLGLDisable cullface(GL_CULL_FACE); LLGLEnable blend(GL_BLEND); gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -4343,7 +4489,7 @@ public: virtual void visit(const LLSpatialGroup::OctreeNode* branch) { - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { check(*i); } @@ -4529,28 +4675,70 @@ LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) LLCullResult::LLCullResult() { + mVisibleGroupsAllocated = 0; + mAlphaGroupsAllocated = 0; + mOcclusionGroupsAllocated = 0; + mDrawableGroupsAllocated = 0; + mVisibleListAllocated = 0; + mVisibleBridgeAllocated = 0; + + mVisibleGroups.clear(); + mVisibleGroups.push_back(NULL); + mVisibleGroupsEnd = &mVisibleGroups[0]; + mAlphaGroups.clear(); + mAlphaGroups.push_back(NULL); + mAlphaGroupsEnd = &mAlphaGroups[0]; + mOcclusionGroups.clear(); + mOcclusionGroups.push_back(NULL); + mOcclusionGroupsEnd = &mOcclusionGroups[0]; + mDrawableGroups.clear(); + mDrawableGroups.push_back(NULL); + mDrawableGroupsEnd = &mDrawableGroups[0]; + mVisibleList.clear(); + mVisibleList.push_back(NULL); + mVisibleListEnd = &mVisibleList[0]; + mVisibleBridge.clear(); + mVisibleBridge.push_back(NULL); + mVisibleBridgeEnd = &mVisibleBridge[0]; + + for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) + { + mRenderMap[i].clear(); + mRenderMap[i].push_back(NULL); + mRenderMapEnd[i] = &mRenderMap[i][0]; + mRenderMapAllocated[i] = 0; + } + clear(); } +template <class T, class V> +void LLCullResult::pushBack(T& head, U32& count, V* val) +{ + head[count] = val; + head.push_back(NULL); + count++; +} + void LLCullResult::clear() { mVisibleGroupsSize = 0; - mVisibleGroupsEnd = mVisibleGroups.begin(); + mVisibleGroupsEnd = &mVisibleGroups[0]; mAlphaGroupsSize = 0; - mAlphaGroupsEnd = mAlphaGroups.begin(); + mAlphaGroupsEnd = &mAlphaGroups[0]; mOcclusionGroupsSize = 0; - mOcclusionGroupsEnd = mOcclusionGroups.begin(); + mOcclusionGroupsEnd = &mOcclusionGroups[0]; mDrawableGroupsSize = 0; - mDrawableGroupsEnd = mDrawableGroups.begin(); + mDrawableGroupsEnd = &mDrawableGroups[0]; mVisibleListSize = 0; - mVisibleListEnd = mVisibleList.begin(); + mVisibleListEnd = &mVisibleList[0]; mVisibleBridgeSize = 0; - mVisibleBridgeEnd = mVisibleBridge.begin(); + mVisibleBridgeEnd = &mVisibleBridge[0]; for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) @@ -4560,176 +4748,176 @@ void LLCullResult::clear() mRenderMap[i][j] = 0; } mRenderMapSize[i] = 0; - mRenderMapEnd[i] = mRenderMap[i].begin(); + mRenderMapEnd[i] = &(mRenderMap[i][0]); } } -LLCullResult::sg_list_t::iterator LLCullResult::beginVisibleGroups() +LLCullResult::sg_iterator LLCullResult::beginVisibleGroups() { - return mVisibleGroups.begin(); + return &mVisibleGroups[0]; } -LLCullResult::sg_list_t::iterator LLCullResult::endVisibleGroups() +LLCullResult::sg_iterator LLCullResult::endVisibleGroups() { return mVisibleGroupsEnd; } -LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups() +LLCullResult::sg_iterator LLCullResult::beginAlphaGroups() { - return mAlphaGroups.begin(); + return &mAlphaGroups[0]; } -LLCullResult::sg_list_t::iterator LLCullResult::endAlphaGroups() +LLCullResult::sg_iterator LLCullResult::endAlphaGroups() { return mAlphaGroupsEnd; } -LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups() +LLCullResult::sg_iterator LLCullResult::beginOcclusionGroups() { - return mOcclusionGroups.begin(); + return &mOcclusionGroups[0]; } -LLCullResult::sg_list_t::iterator LLCullResult::endOcclusionGroups() +LLCullResult::sg_iterator LLCullResult::endOcclusionGroups() { return mOcclusionGroupsEnd; } -LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups() +LLCullResult::sg_iterator LLCullResult::beginDrawableGroups() { - return mDrawableGroups.begin(); + return &mDrawableGroups[0]; } -LLCullResult::sg_list_t::iterator LLCullResult::endDrawableGroups() +LLCullResult::sg_iterator LLCullResult::endDrawableGroups() { return mDrawableGroupsEnd; } -LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList() +LLCullResult::drawable_iterator LLCullResult::beginVisibleList() { - return mVisibleList.begin(); + return &mVisibleList[0]; } -LLCullResult::drawable_list_t::iterator LLCullResult::endVisibleList() +LLCullResult::drawable_iterator LLCullResult::endVisibleList() { return mVisibleListEnd; } -LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge() +LLCullResult::bridge_iterator LLCullResult::beginVisibleBridge() { - return mVisibleBridge.begin(); + return &mVisibleBridge[0]; } -LLCullResult::bridge_list_t::iterator LLCullResult::endVisibleBridge() +LLCullResult::bridge_iterator LLCullResult::endVisibleBridge() { return mVisibleBridgeEnd; } -LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLCullResult::beginRenderMap(U32 type) { - return mRenderMap[type].begin(); + return &mRenderMap[type][0]; } -LLCullResult::drawinfo_list_t::iterator LLCullResult::endRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLCullResult::endRenderMap(U32 type) { return mRenderMapEnd[type]; } void LLCullResult::pushVisibleGroup(LLSpatialGroup* group) { - if (mVisibleGroupsSize < mVisibleGroups.size()) + if (mVisibleGroupsSize < mVisibleGroupsAllocated) { mVisibleGroups[mVisibleGroupsSize] = group; } else { - mVisibleGroups.push_back(group); + pushBack(mVisibleGroups, mVisibleGroupsAllocated, group); } ++mVisibleGroupsSize; - mVisibleGroupsEnd = mVisibleGroups.begin()+mVisibleGroupsSize; + mVisibleGroupsEnd = &mVisibleGroups[mVisibleGroupsSize]; } void LLCullResult::pushAlphaGroup(LLSpatialGroup* group) { - if (mAlphaGroupsSize < mAlphaGroups.size()) + if (mAlphaGroupsSize < mAlphaGroupsAllocated) { mAlphaGroups[mAlphaGroupsSize] = group; } else { - mAlphaGroups.push_back(group); + pushBack(mAlphaGroups, mAlphaGroupsAllocated, group); } ++mAlphaGroupsSize; - mAlphaGroupsEnd = mAlphaGroups.begin()+mAlphaGroupsSize; + mAlphaGroupsEnd = &mAlphaGroups[mAlphaGroupsSize]; } void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group) { - if (mOcclusionGroupsSize < mOcclusionGroups.size()) + if (mOcclusionGroupsSize < mOcclusionGroupsAllocated) { mOcclusionGroups[mOcclusionGroupsSize] = group; } else { - mOcclusionGroups.push_back(group); + pushBack(mOcclusionGroups, mOcclusionGroupsAllocated, group); } ++mOcclusionGroupsSize; - mOcclusionGroupsEnd = mOcclusionGroups.begin()+mOcclusionGroupsSize; + mOcclusionGroupsEnd = &mOcclusionGroups[mOcclusionGroupsSize]; } void LLCullResult::pushDrawableGroup(LLSpatialGroup* group) { - if (mDrawableGroupsSize < mDrawableGroups.size()) + if (mDrawableGroupsSize < mDrawableGroupsAllocated) { mDrawableGroups[mDrawableGroupsSize] = group; } else { - mDrawableGroups.push_back(group); + pushBack(mDrawableGroups, mDrawableGroupsAllocated, group); } ++mDrawableGroupsSize; - mDrawableGroupsEnd = mDrawableGroups.begin()+mDrawableGroupsSize; + mDrawableGroupsEnd = &mDrawableGroups[mDrawableGroupsSize]; } void LLCullResult::pushDrawable(LLDrawable* drawable) { - if (mVisibleListSize < mVisibleList.size()) + if (mVisibleListSize < mVisibleListAllocated) { mVisibleList[mVisibleListSize] = drawable; } else { - mVisibleList.push_back(drawable); + pushBack(mVisibleList, mVisibleListAllocated, drawable); } ++mVisibleListSize; - mVisibleListEnd = mVisibleList.begin()+mVisibleListSize; + mVisibleListEnd = &mVisibleList[mVisibleListSize]; } void LLCullResult::pushBridge(LLSpatialBridge* bridge) { - if (mVisibleBridgeSize < mVisibleBridge.size()) + if (mVisibleBridgeSize < mVisibleBridgeAllocated) { mVisibleBridge[mVisibleBridgeSize] = bridge; } else { - mVisibleBridge.push_back(bridge); + pushBack(mVisibleBridge, mVisibleBridgeAllocated, bridge); } ++mVisibleBridgeSize; - mVisibleBridgeEnd = mVisibleBridge.begin()+mVisibleBridgeSize; + mVisibleBridgeEnd = &mVisibleBridge[mVisibleBridgeSize]; } void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info) { - if (mRenderMapSize[type] < mRenderMap[type].size()) + if (mRenderMapSize[type] < mRenderMapAllocated[type]) { mRenderMap[type][mRenderMapSize[type]] = draw_info; } else { - mRenderMap[type].push_back(draw_info); + pushBack(mRenderMap[type], mRenderMapAllocated[type], draw_info); } ++mRenderMapSize[type]; - mRenderMapEnd[type] = mRenderMap[type].begin() + mRenderMapSize[type]; + mRenderMapEnd[type] = &(mRenderMap[type][mRenderMapSize[type]]); } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index f0c8a372ee..b1706d9d35 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -68,6 +68,16 @@ protected: ~LLDrawInfo(); public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLDrawInfo(const LLDrawInfo& rhs) { @@ -106,7 +116,7 @@ public: F32 mPartSize; F32 mVSize; LLSpatialGroup* mGroup; - LLFace* mFace; //associated face + LL_ALIGN_16(LLFace* mFace); //associated face F32 mDistance; U32 mDrawMode; @@ -181,7 +191,7 @@ public: }; }; -LL_ALIGN_PREFIX(64) +LL_ALIGN_PREFIX(16) class LLSpatialGroup : public LLOctreeListener<LLDrawable> { friend class LLSpatialPartition; @@ -193,6 +203,16 @@ public: *this = rhs; } + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + const LLSpatialGroup& operator=(const LLSpatialGroup& rhs) { llerrs << "Illegal operation!" << llendl; @@ -263,11 +283,10 @@ public: SKIP_FRUSTUM_CHECK = 0x00000020, IN_IMAGE_QUEUE = 0x00000040, IMAGE_DIRTY = 0x00000080, - OCCLUSION_DIRTY = 0x00000100, - MESH_DIRTY = 0x00000200, - NEW_DRAWINFO = 0x00000400, - IN_BUILD_Q1 = 0x00000800, - IN_BUILD_Q2 = 0x00001000, + MESH_DIRTY = 0x00000100, + NEW_DRAWINFO = 0x00000200, + IN_BUILD_Q1 = 0x00000400, + IN_BUILD_Q2 = 0x00000800, STATE_MASK = 0x0000FFFF, } eSpatialState; @@ -313,10 +332,9 @@ public: BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax); void unbound(); BOOL rebound(); - void buildOcclusion(); //rebuild mOcclusionVerts void checkOcclusion(); //read back last occlusion query (if any) void doOcclusion(LLCamera* camera); //issue occlusion query - void destroyGL(); + void destroyGL(bool keep_occlusion = false); void updateDistance(LLCamera& camera); BOOL needsUpdate(); @@ -327,8 +345,15 @@ public: void dirtyGeom() { setState(GEOM_DIRTY); } void dirtyMesh() { setState(MESH_DIRTY); } + + //octree wrappers to make code more readable element_list& getData() { return mOctreeNode->getData(); } + element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } + element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } + bool hasElement(LLDrawable* drawablep) { return std::find(mOctreeNode->getDataBegin(), mOctreeNode->getDataEnd(), drawablep) != mOctreeNode->getDataEnd(); } + U32 getElementCount() const { return mOctreeNode->getElementCount(); } + bool isEmpty() const { return mOctreeNode->isEmpty(); } void drawObjectBox(LLColor4 col); @@ -372,12 +397,14 @@ public: V4_COUNT = 10 } eV4Index; - LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects) - LLVector4a mExtents[2]; // extents (min, max) of this node and all its children - LLVector4a mObjectExtents[2]; // extents (min, max) of objects in this node - LLVector4a mObjectBounds[2]; // bounding box (center, size) of objects in this node - LLVector4a mViewAngle; - LLVector4a mLastUpdateViewAngle; + LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) + LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children + LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node + LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node + LL_ALIGN_16(LLVector4a mViewAngle); + LL_ALIGN_16(LLVector4a mLastUpdateViewAngle); + + F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3() private: U32 mCurUpdatingTime ; @@ -396,6 +423,8 @@ protected: U32 mState; U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS]; + U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS]; + S32 mLODHash; static S32 sLODSeed; @@ -403,12 +432,14 @@ 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; LLPointer<LLVertexBuffer> mVertexBuffer; - LLPointer<LLVertexBuffer> mOcclusionVerts; GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; U32 mBufferUsage; @@ -472,8 +503,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 +516,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 +543,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 +556,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 @@ -538,29 +574,34 @@ public: typedef std::vector<LLSpatialBridge*> bridge_list_t; typedef std::vector<LLDrawInfo*> drawinfo_list_t; + typedef LLSpatialGroup** sg_iterator; + typedef LLSpatialBridge** bridge_iterator; + typedef LLDrawInfo** drawinfo_iterator; + typedef LLDrawable** drawable_iterator; + void clear(); - sg_list_t::iterator beginVisibleGroups(); - sg_list_t::iterator endVisibleGroups(); + sg_iterator beginVisibleGroups(); + sg_iterator endVisibleGroups(); - sg_list_t::iterator beginAlphaGroups(); - sg_list_t::iterator endAlphaGroups(); + sg_iterator beginAlphaGroups(); + sg_iterator endAlphaGroups(); bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; } - sg_list_t::iterator beginOcclusionGroups(); - sg_list_t::iterator endOcclusionGroups(); + sg_iterator beginOcclusionGroups(); + sg_iterator endOcclusionGroups(); - sg_list_t::iterator beginDrawableGroups(); - sg_list_t::iterator endDrawableGroups(); + sg_iterator beginDrawableGroups(); + sg_iterator endDrawableGroups(); - drawable_list_t::iterator beginVisibleList(); - drawable_list_t::iterator endVisibleList(); + drawable_iterator beginVisibleList(); + drawable_iterator endVisibleList(); - bridge_list_t::iterator beginVisibleBridge(); - bridge_list_t::iterator endVisibleBridge(); + bridge_iterator beginVisibleBridge(); + bridge_iterator endVisibleBridge(); - drawinfo_list_t::iterator beginRenderMap(U32 type); - drawinfo_list_t::iterator endRenderMap(U32 type); + drawinfo_iterator beginRenderMap(U32 type); + drawinfo_iterator endRenderMap(U32 type); void pushVisibleGroup(LLSpatialGroup* group); void pushAlphaGroup(LLSpatialGroup* group); @@ -580,28 +621,41 @@ public: void assertDrawMapsEmpty(); private: + + template <class T, class V> void pushBack(T &head, U32& count, V* val); + U32 mVisibleGroupsSize; U32 mAlphaGroupsSize; U32 mOcclusionGroupsSize; U32 mDrawableGroupsSize; U32 mVisibleListSize; U32 mVisibleBridgeSize; + + U32 mVisibleGroupsAllocated; + U32 mAlphaGroupsAllocated; + U32 mOcclusionGroupsAllocated; + U32 mDrawableGroupsAllocated; + U32 mVisibleListAllocated; + U32 mVisibleBridgeAllocated; + U32 mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES]; sg_list_t mVisibleGroups; - sg_list_t::iterator mVisibleGroupsEnd; + sg_iterator mVisibleGroupsEnd; sg_list_t mAlphaGroups; - sg_list_t::iterator mAlphaGroupsEnd; + sg_iterator mAlphaGroupsEnd; sg_list_t mOcclusionGroups; - sg_list_t::iterator mOcclusionGroupsEnd; + sg_iterator mOcclusionGroupsEnd; sg_list_t mDrawableGroups; - sg_list_t::iterator mDrawableGroupsEnd; + sg_iterator mDrawableGroupsEnd; drawable_list_t mVisibleList; - drawable_list_t::iterator mVisibleListEnd; + drawable_iterator mVisibleListEnd; bridge_list_t mVisibleBridge; - bridge_list_t::iterator mVisibleBridgeEnd; + bridge_iterator mVisibleBridgeEnd; drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES]; - drawinfo_list_t::iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES]; + U32 mRenderMapAllocated[LLRenderPass::NUM_RENDER_TYPES]; + drawinfo_iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES]; + }; @@ -645,6 +699,7 @@ class LLParticlePartition : public LLSpatialPartition { public: LLParticlePartition(); + virtual void rebuildGeom(LLSpatialGroup* group); virtual void getGeometry(LLSpatialGroup* group); virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count); virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera); @@ -659,10 +714,14 @@ public: }; //spatial partition for grass (implemented in LLVOGrass.cpp) -class LLGrassPartition : public LLParticlePartition +class LLGrassPartition : public LLSpatialPartition { public: LLGrassPartition(); + virtual void getGeometry(LLSpatialGroup* group); + virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count); +protected: + U32 mRenderPass; }; //class for wrangling geometry out of volumes (implemented in LLVOVolume.cpp) diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index c588bd8fb4..8783d99b11 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -31,12 +31,15 @@ #include "llagent.h" #include "llappviewer.h" #include "llimview.h" +#include "llgroupmgr.h" #include "llsdutil.h" #include "lluicolortable.h" #include "llviewerobjectlist.h" #include "llvoavatar.h" #include "llworld.h" +extern LLControlGroup gSavedSettings; + const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f); const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f); @@ -84,6 +87,19 @@ bool LLSpeaker::isInVoiceChannel() return mStatus <= LLSpeaker::STATUS_VOICE_ACTIVE || mStatus == LLSpeaker::STATUS_MUTED; } +LLSpeakerUpdateSpeakerEvent::LLSpeakerUpdateSpeakerEvent(LLSpeaker* source) +: LLEvent(source, "Speaker update speaker event"), + mSpeakerID (source->mID) +{ +} + +LLSD LLSpeakerUpdateSpeakerEvent::getValue() +{ + LLSD ret; + ret["id"] = mSpeakerID; + return ret; +} + LLSpeakerUpdateModeratorEvent::LLSpeakerUpdateModeratorEvent(LLSpeaker* source) : LLEvent(source, "Speaker add moderator event"), mSpeakerID (source->mID), @@ -241,16 +257,63 @@ bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_ return true; } +bool LLSpeakersDelayActionsStorage::isTimerStarted(const LLUUID& speaker_id) +{ + return (mActionTimersMap.size() > 0) && (mActionTimersMap.find(speaker_id) != mActionTimersMap.end()); +} + +// +// ModerationResponder +// + +class ModerationResponder : public LLHTTPClient::Responder +{ +public: + ModerationResponder(const LLUUID& session_id) + { + mSessionID = session_id; + } + + virtual void error(U32 status, const std::string& reason) + { + llwarns << status << ": " << reason << llendl; + + if ( gIMMgr ) + { + //403 == you're not a mod + //should be disabled if you're not a moderator + if ( 403 == status ) + { + gIMMgr->showSessionEventError( + "mute", + "not_a_mod_error", + mSessionID); + } + else + { + gIMMgr->showSessionEventError( + "mute", + "generic_request_error", + mSessionID); + } + } + } + +private: + LLUUID mSessionID; +}; // // LLSpeakerMgr // LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) : - mVoiceChannel(channelp) -, mVoiceModerated(false) -, mModerateModeHandledFirstTime(false) + mVoiceChannel(channelp), + mVoiceModerated(false), + mModerateModeHandledFirstTime(false), + mSpeakerListUpdated(false) { + mGetListTime.reset(); static LLUICachedControl<F32> remove_delay ("SpeakerParticipantRemoveDelay", 10.0); mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLSpeakerMgr::removeSpeaker, this, _1), remove_delay); @@ -263,7 +326,11 @@ LLSpeakerMgr::~LLSpeakerMgr() LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::string& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type) { - if (id.isNull()) return NULL; + LLUUID session_id = getSessionID(); + if (id.isNull() || (id == session_id)) + { + return NULL; + } LLPointer<LLSpeaker> speakerp; if (mSpeakers.find(id) == mSpeakers.end()) @@ -272,6 +339,7 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin speakerp->mStatus = status; mSpeakers.insert(std::make_pair(speakerp->mID, speakerp)); mSpeakersSorted.push_back(speakerp); + LL_DEBUGS("Speakers") << "Added speaker " << id << llendl; fireEvent(new LLSpeakerListChangeEvent(this, speakerp->mID), "add"); } else @@ -290,6 +358,10 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin speakerp->lookupName(); } } + else + { + LL_WARNS("Speakers") << "Speaker " << id << " not found" << llendl; + } } mSpeakerDelayRemover->unsetActionTimer(speakerp->mID); @@ -340,12 +412,10 @@ void LLSpeakerMgr::update(BOOL resort_ok) // update status of all current speakers BOOL voice_channel_active = (!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive()); - for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end();) + for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); speaker_it++) { LLUUID speaker_id = speaker_it->first; LLSpeaker* speakerp = speaker_it->second; - - speaker_map_t::iterator cur_speaker_it = speaker_it++; if (voice_channel_active && LLVoiceClient::getInstance()->getVoiceEnabled(speaker_id)) { @@ -354,6 +424,7 @@ void LLSpeakerMgr::update(BOOL resort_ok) if (moderator_muted_voice != speakerp->mModeratorMutedVoice) { speakerp->mModeratorMutedVoice = moderator_muted_voice; + LL_DEBUGS("Speakers") << (speakerp->mModeratorMutedVoice? "Muted" : "Umuted") << " speaker " << speaker_id<< llendl; speakerp->fireEvent(new LLSpeakerVoiceModerationEvent(speakerp)); } @@ -368,6 +439,7 @@ void LLSpeakerMgr::update(BOOL resort_ok) { speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32(); speakerp->mHasSpoken = TRUE; + fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker"); } speakerp->mStatus = LLSpeaker::STATUS_SPEAKING; // interpolate between active color and full speaking color based on power of speech output @@ -442,24 +514,89 @@ void LLSpeakerMgr::update(BOOL resort_ok) void LLSpeakerMgr::updateSpeakerList() { - // are we bound to the currently active voice channel? + // Are we bound to the currently active voice channel? if ((!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive())) { - std::set<LLUUID> participants; - LLVoiceClient::getInstance()->getParticipantList(participants); - // add new participants to our list of known speakers - for (std::set<LLUUID>::iterator participant_it = participants.begin(); - participant_it != participants.end(); - ++participant_it) + std::set<LLUUID> participants; + LLVoiceClient::getInstance()->getParticipantList(participants); + // If we are, add all voice client participants to our list of known speakers + for (std::set<LLUUID>::iterator participant_it = participants.begin(); participant_it != participants.end(); ++participant_it) { setSpeaker(*participant_it, LLVoiceClient::getInstance()->getDisplayName(*participant_it), LLSpeaker::STATUS_VOICE_ACTIVE, (LLVoiceClient::getInstance()->isParticipantAvatar(*participant_it)?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL)); - - } } + else + { + // If not, check if the list is empty, except if it's Nearby Chat (session_id NULL). + LLUUID session_id = getSessionID(); + if (!session_id.isNull() && !mSpeakerListUpdated) + { + // If the list is empty, we update it with whatever we have locally so that it doesn't stay empty too long. + // *TODO: Fix the server side code that sometimes forgets to send back the list of participants after a chat started. + // (IOW, fix why we get no ChatterBoxSessionAgentListUpdates message after the initial ChatterBoxSessionStartReply) + LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id); + if (session->isGroupSessionType() && (mSpeakers.size() <= 1)) + { + const F32 load_group_timeout = gSavedSettings.getF32("ChatLoadGroupTimeout"); + // For groups, we need to hit the group manager. + // Note: The session uuid and the group uuid are actually one and the same. If that was to change, this will fail. + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(session_id); + if (!gdatap && (mGetListTime.getElapsedTimeF32() >= load_group_timeout)) + { + // Request the data the first time around + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(session_id); + } + else if (gdatap && gdatap->isMemberDataComplete() && !gdatap->mMembers.empty()) + { + // Add group members when we get the complete list (note: can take a while before we get that list) + LLGroupMgrGroupData::member_list_t::iterator member_it = gdatap->mMembers.begin(); + const S32 load_group_max_members = gSavedSettings.getS32("ChatLoadGroupMaxMembers"); + S32 updated = 0; + while (member_it != gdatap->mMembers.end()) + { + LLGroupMemberData* member = member_it->second; + LLUUID id = member_it->first; + // Add only members who are online and not already in the list + if ((member->getOnlineStatus() == "Online") && (mSpeakers.find(id) == mSpeakers.end())) + { + LLPointer<LLSpeaker> speakerp = setSpeaker(id, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT); + speakerp->mIsModerator = ((member->getAgentPowers() & GP_SESSION_MODERATOR) == GP_SESSION_MODERATOR); + updated++; + } + ++member_it; + // Limit the number of "manually updated" participants to a reasonable number to avoid severe fps drop + // *TODO : solve the perf issue of having several hundreds of widgets in the conversation list + if (updated >= load_group_max_members) + break; + } + mSpeakerListUpdated = true; + } + } + else if (mSpeakers.size() == 0) + { + // For all other session type (ad-hoc, P2P, avaline), we use the initial participants targets list + for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it) + { + // Add buddies if they are on line, add any other avatar. + if (!LLAvatarTracker::instance().isBuddy(*it) || LLAvatarTracker::instance().isBuddyOnline(*it)) + { + setSpeaker(*it, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT); + } + } + mSpeakerListUpdated = true; + } + else + { + // The list has been updated the normal way (i.e. by a ChatterBoxSessionAgentListUpdates received from the server) + mSpeakerListUpdated = true; + } + } + } + // Always add the current agent (it has to be there...). Will do nothing if already there. + setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT); } void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp) @@ -484,6 +621,7 @@ bool LLSpeakerMgr::removeSpeaker(const LLUUID& speaker_id) } } + LL_DEBUGS("Speakers") << "Removed speaker " << speaker_id << llendl; fireEvent(new LLSpeakerListChangeEvent(this, speaker_id), "remove"); update(TRUE); @@ -523,6 +661,10 @@ const LLUUID LLSpeakerMgr::getSessionID() return mVoiceChannel->getSessionID(); } +bool LLSpeakerMgr::isSpeakerToBeRemoved(const LLUUID& speaker_id) +{ + return mSpeakerDelayRemover && mSpeakerDelayRemover->isTimerStarted(speaker_id); +} void LLSpeakerMgr::setSpeakerTyping(const LLUUID& speaker_id, BOOL typing) { @@ -541,6 +683,7 @@ void LLSpeakerMgr::speakerChatted(const LLUUID& speaker_id) { speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32(); speakerp->mHasSpoken = TRUE; + fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker"); } } @@ -595,7 +738,10 @@ void LLIMSpeakerMgr::setSpeakers(const LLSD& speakers) speaker_it->second["mutes"]["text"]; // Fire event only if moderator changed if ( is_moderator != speakerp->mIsModerator ) + { + LL_DEBUGS("Speakers") << "Speaker " << agent_id << (is_moderator ? "is now" : "no longer is") << " a moderator" << llendl; fireEvent(new LLSpeakerUpdateModeratorEvent(speakerp), "update_moderator"); + } } } } @@ -665,7 +811,10 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update) speakerp->mIsModerator = agent_info["is_moderator"]; // Fire event only if moderator changed if ( is_moderator != speakerp->mIsModerator ) + { + LL_DEBUGS("Speakers") << "Speaker " << agent_id << (is_moderator ? "is now" : "no longer is") << " a moderator" << llendl; fireEvent(new LLSpeakerUpdateModeratorEvent(speakerp), "update_moderator"); + } } if (agent_info.has("mutes")) @@ -705,43 +854,6 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update) } } -class ModerationResponder : public LLHTTPClient::Responder -{ -public: - ModerationResponder(const LLUUID& session_id) - { - mSessionID = session_id; - } - - virtual void error(U32 status, const std::string& reason) - { - llwarns << status << ": " << reason << llendl; - - if ( gIMMgr ) - { - //403 == you're not a mod - //should be disabled if you're not a moderator - if ( 403 == status ) - { - gIMMgr->showSessionEventError( - "mute", - "not_a_mod_error", - mSessionID); - } - else - { - gIMMgr->showSessionEventError( - "mute", - "generic_request_error", - mSessionID); - } - } - } - -private: - LLUUID mSessionID; -}; - void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id) { LLPointer<LLSpeaker> speakerp = findSpeaker(speaker_id); @@ -857,6 +969,7 @@ void LLActiveSpeakerMgr::updateSpeakerList() // always populate from active voice channel if (LLVoiceChannel::getCurrentVoiceChannel() != mVoiceChannel) //MA: seems this is always false { + LL_DEBUGS("Speakers") << "Removed all speakers" << llendl; fireEvent(new LLSpeakerListChangeEvent(this, LLUUID::null), "clear"); mSpeakers.clear(); mSpeakersSorted.clear(); diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index 35f2ee7056..e953dd0e1a 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -29,7 +29,6 @@ #include "llevent.h" #include "lleventtimer.h" -#include "llspeakers.h" #include "llvoicechannel.h" class LLSpeakerMgr; @@ -80,6 +79,15 @@ public: BOOL mModeratorMutedText; }; +class LLSpeakerUpdateSpeakerEvent : public LLOldEvents::LLEvent +{ +public: + LLSpeakerUpdateSpeakerEvent(LLSpeaker* source); + /*virtual*/ LLSD getValue(); +private: + const LLUUID& mSpeakerID; +}; + class LLSpeakerUpdateModeratorEvent : public LLOldEvents::LLEvent { public: @@ -185,6 +193,8 @@ public: void unsetActionTimer(const LLUUID& speaker_id); void removeAllTimers(); + + bool isTimerStarted(const LLUUID& speaker_id); private: /** * Callback of the each instance of LLSpeakerActionTimer. @@ -208,6 +218,8 @@ private: class LLSpeakerMgr : public LLOldEvents::LLObservable { + LOG_CLASS(LLSpeakerMgr); + public: LLSpeakerMgr(LLVoiceChannel* channelp); virtual ~LLSpeakerMgr(); @@ -227,6 +239,7 @@ public: void getSpeakerList(speaker_list_t* speaker_list, BOOL include_text); LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; } const LLUUID getSessionID(); + bool isSpeakerToBeRemoved(const LLUUID& speaker_id); /** * Removes avaline speaker. @@ -250,6 +263,8 @@ protected: typedef std::map<LLUUID, LLPointer<LLSpeaker> > speaker_map_t; speaker_map_t mSpeakers; + bool mSpeakerListUpdated; + LLTimer mGetListTime; speaker_list_t mSpeakersSorted; LLFrameTimer mSpeechTimer; @@ -271,6 +286,8 @@ protected: class LLIMSpeakerMgr : public LLSpeakerMgr { + LOG_CLASS(LLIMSpeakerMgr); + public: LLIMSpeakerMgr(LLVoiceChannel* channel); @@ -320,6 +337,8 @@ protected: class LLActiveSpeakerMgr : public LLSpeakerMgr, public LLSingleton<LLActiveSpeakerMgr> { + LOG_CLASS(LLActiveSpeakerMgr); + public: LLActiveSpeakerMgr(); protected: @@ -328,6 +347,7 @@ protected: class LLLocalSpeakerMgr : public LLSpeakerMgr, public LLSingleton<LLLocalSpeakerMgr> { + LOG_CLASS(LLLocalSpeakerMgr); public: LLLocalSpeakerMgr(); ~LLLocalSpeakerMgr (); diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp index 9b38bf22ff..07e9371124 100644 --- a/indra/newview/llspeakingindicatormanager.cpp +++ b/indra/newview/llspeakingindicatormanager.cpp @@ -74,6 +74,16 @@ public: */ void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator); + /** + * Callback of changing voice participant list (from LLVoiceClientParticipantObserver). + * + * Switches off indicators had been switched on and switches on indicators of current participants list. + * There is only a few indicators in lists should be switched off/on. + * So, method does not calculate difference between these list it only switches off already + * switched on indicators and switches on indicators of voice channel participants + */ + void onParticipantsChanged(); + private: typedef std::set<LLUUID> speaker_ids_t; typedef std::multimap<LLUUID, LLSpeakingIndicator*> speaking_indicators_mmap_t; @@ -94,16 +104,6 @@ private: void sOnCurrentChannelChanged(const LLUUID& session_id); /** - * Callback of changing voice participant list (from LLVoiceClientParticipantObserver). - * - * Switches off indicators had been switched on and switches on indicators of current participants list. - * There is only a few indicators in lists should be switched off/on. - * So, method does not calculate difference between these list it only switches off already - * switched on indicators and switches on indicators of voice channel participants - */ - void onParticipantsChanged(); - - /** * Changes state of indicators specified by LLUUIDs * * @param speakers_uuids - avatars' LLUUIDs whose speaking indicators should be switched @@ -237,28 +237,18 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea { was_found = true; LLSpeakingIndicator* indicator = (*it_indicator).second; + was_switched_on = was_switched_on || switch_on; - BOOL switch_current_on = switch_on; - - // we should show indicator for specified voice session only if this is current channel. EXT-5562. - if (switch_current_on && indicator->getTargetSessionID().notNull()) - { - switch_current_on = indicator->getTargetSessionID() == session_id; - LL_DEBUGS("SpeakingIndicator") << "Session: " << session_id << ", target: " << indicator->getTargetSessionID() << ", the same? = " << switch_current_on << LL_ENDL; - } - was_switched_on = was_switched_on || switch_current_on; - - indicator->switchIndicator(switch_current_on); - + indicator->switchIndicator(switch_on); } if (was_found) { - LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators where found" << LL_ENDL; + LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators were found" << LL_ENDL; if (switch_on && !was_switched_on) { - LL_DEBUGS("SpeakingIndicator") << "but non of them where switched on" << LL_ENDL; + LL_DEBUGS("SpeakingIndicator") << "but none of them were switched on" << LL_ENDL; } if (was_switched_on) @@ -314,5 +304,13 @@ void LLSpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speak } } +void LLSpeakingIndicatorManager::updateSpeakingIndicators() +{ + if(SpeakingIndicatorManager::instanceExists()) + { + SpeakingIndicatorManager::instance().onParticipantsChanged(); + } +} + // EOF diff --git a/indra/newview/llspeakingindicatormanager.h b/indra/newview/llspeakingindicatormanager.h index b0a147865b..e5afcd1cb7 100644 --- a/indra/newview/llspeakingindicatormanager.h +++ b/indra/newview/llspeakingindicatormanager.h @@ -78,6 +78,11 @@ namespace LLSpeakingIndicatorManager * @param speaking_indicator instance of the speaker indicator to be unregistered. */ void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator); + + /** + * Switch on/off registered speaking indicator according to the most current voice client status + */ + void updateSpeakingIndicators(); } #endif // LL_LLSPEAKINGINDICATORMANAGER_H diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 36d6ff3ef2..37e6ded986 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -54,7 +54,7 @@ #include "llfloaterreg.h" #include "llfocusmgr.h" #include "llhttpsender.h" -#include "llimfloater.h" +#include "llfloaterimsession.h" #include "lllocationhistory.h" #include "llimageworker.h" @@ -63,7 +63,8 @@ #include "llmemorystream.h" #include "llmessageconfig.h" #include "llmoveview.h" -#include "llnearbychat.h" +#include "llfloaterimcontainer.h" +#include "llfloaterimnearbychat.h" #include "llnotifications.h" #include "llnotificationsutil.h" #include "llteleporthistory.h" @@ -94,6 +95,7 @@ #include "llcallingcard.h" #include "llconsole.h" #include "llcontainerview.h" +#include "llconversationlog.h" #include "lldebugview.h" #include "lldrawable.h" #include "lleventnotifier.h" @@ -186,6 +188,7 @@ #include "llappearancemgr.h" #include "llavatariconctrl.h" #include "llvoicechannel.h" +#include "llpathfindingmanager.h" #include "lllogin.h" #include "llevents.h" @@ -240,6 +243,7 @@ static bool mLoginStatePastUI = false; boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState")); boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener()); +boost::scoped_ptr<LLViewerStats::PhaseMap> LLStartUp::sPhases(new LLViewerStats::PhaseMap); // // local function declaration @@ -310,8 +314,6 @@ void update_texture_fetch() // true when all initialization done. bool idle_startup() { - LLMemType mt1(LLMemType::MTYPE_STARTUP); - const F32 PRECACHING_DELAY = gSavedSettings.getF32("PrecachingDelay"); static LLTimer timeout; static S32 timeout_count = 0; @@ -360,6 +362,15 @@ bool idle_startup() if ( STATE_FIRST == LLStartUp::getStartupState() ) { + static bool first_call = true; + if (first_call) + { + // Other phases get handled when startup state changes, + // need to capture the initial state as well. + LLStartUp::getPhases().startPhase(LLStartUp::getStartupStateString()); + first_call = false; + } + gViewerWindow->showCursor(); gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT); @@ -719,12 +730,14 @@ bool idle_startup() if (STATE_LOGIN_SHOW == LLStartUp::getStartupState()) { - LL_DEBUGS("AppInit") << "Initializing Window" << LL_ENDL; + LL_DEBUGS("AppInit") << "Initializing Window, show_connect_box = " + << show_connect_box << LL_ENDL; // if we've gone backwards in the login state machine, to this state where we show the UI // AND the debug setting to exit in this case is true, then go ahead and bail quickly if ( mLoginStatePastUI && gSavedSettings.getBOOL("QuitOnLoginActivated") ) { + LL_DEBUGS("AppInit") << "taking QuitOnLoginActivated exit" << LL_ENDL; // no requirement for notification here - just exit LLAppViewer::instance()->earlyExitNoNotify(); } @@ -737,8 +750,10 @@ bool idle_startup() // this startup phase more than once. if (gLoginMenuBarView == NULL) { + LL_DEBUGS("AppInit") << "initializing menu bar" << LL_ENDL; display_startup(); initialize_edit_menu(); + initialize_spellcheck_menu(); display_startup(); init_menus(); display_startup(); @@ -746,11 +761,13 @@ bool idle_startup() if (show_connect_box) { + LL_DEBUGS("AppInit") << "show_connect_box on" << LL_ENDL; // Load all the name information out of the login view // NOTE: Hits "Attempted getFields with no login view shown" warning, since we don't // show the login view until login_show() is called below. if (gUserCredential.isNull()) { + LL_DEBUGS("AppInit") << "loading credentials from gLoginHandler" << LL_ENDL; display_startup(); gUserCredential = gLoginHandler.initializeLoginInfo(); display_startup(); @@ -767,17 +784,28 @@ bool idle_startup() login_show(); display_startup(); // connect dialog is already shown, so fill in the names - if (gUserCredential.notNull()) - { - LLPanelLogin::setFields( gUserCredential, gRememberPassword); - } + if (gUserCredential.notNull()) + { + LLPanelLogin::setFields( gUserCredential, gRememberPassword); + } display_startup(); LLPanelLogin::giveFocus(); + if (gSavedSettings.getBOOL("FirstLoginThisInstall")) + { + LL_INFOS("AppInit") << "FirstLoginThisInstall, calling show_first_run_dialog()" << LL_ENDL; + show_first_run_dialog(); + } + else + { + LL_DEBUGS("AppInit") << "FirstLoginThisInstall off" << LL_ENDL; + } + LLStartUp::setStartupState( STATE_LOGIN_WAIT ); // Wait for user input } else { + LL_DEBUGS("AppInit") << "show_connect_box off, skipping to STATE_LOGIN_CLEANUP" << LL_ENDL; // skip directly to message template verification LLStartUp::setStartupState( STATE_LOGIN_CLEANUP ); } @@ -804,9 +832,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; @@ -881,7 +908,6 @@ bool idle_startup() LLFile::mkdir(gDirUtilp->getLindenUserDir()); // Set PerAccountSettingsFile to the default value. - std::string per_account_settings_file = LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount"); gSavedSettings.setString("PerAccountSettingsFile", gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount"))); @@ -891,6 +917,13 @@ bool idle_startup() // Overwrite default user settings with user settings LLAppViewer::instance()->loadSettingsFromDirectory("Account"); + // Convert 'LogInstantMessages' into 'KeepConversationLogTranscripts' for backward compatibility (CHUI-743). + LLControlVariablePtr logInstantMessagesControl = gSavedPerAccountSettings.getControl("LogInstantMessages"); + if (logInstantMessagesControl.notNull()) + { + gSavedPerAccountSettings.setS32("KeepConversationLogTranscripts", logInstantMessagesControl->getValue() ? 2 : 1); + } + // Need to set the LastLogoff time here if we don't have one. LastLogoff is used for "Recent Items" calculation // and startup time is close enough if we don't have a real value. if (gSavedPerAccountSettings.getU32("LastLogoff") == 0) @@ -996,7 +1029,7 @@ bool idle_startup() if(STATE_LOGIN_AUTH_INIT == LLStartUp::getStartupState()) { - gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridLabel(); + gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridId(); // Update progress status and the display loop. auth_desc = LLTrans::getString("LoginInProgress"); @@ -1160,7 +1193,6 @@ bool idle_startup() LLVoiceClient::getInstance()->userAuthorized(gUserCredential->userID(), gAgentID); // create the default proximal channel LLVoiceChannel::initClass(); - LLGridManager::getInstance()->setFavorite(); LLStartUp::setStartupState( STATE_WORLD_INIT); } else @@ -1268,6 +1300,8 @@ bool idle_startup() display_startup(); LLStartUp::setStartupState( STATE_MULTIMEDIA_INIT ); + LLConversationLog::getInstance(); + return FALSE; } @@ -1378,14 +1412,9 @@ bool idle_startup() LLVoiceClient::getInstance()->updateSettings(); display_startup(); - //gCacheName is required for nearby chat history loading - //so I just moved nearby history loading a few states further - if (gSavedPerAccountSettings.getBOOL("LogShowHistory")) - { - LLNearbyChat* nearby_chat = LLNearbyChat::getInstance(); - if (nearby_chat) nearby_chat->loadHistory(); - } - display_startup(); + // create a container's instance for start a controlling conversation windows + // by the voice's events + LLFloaterIMContainer::getInstance(); // *Note: this is where gWorldMap used to be initialized. @@ -1395,7 +1424,7 @@ bool idle_startup() display_startup(); //reset statistics - LLViewerStats::getInstance()->resetStats(); + LLViewerStats::instance().resetStats(); display_startup(); // @@ -1496,7 +1525,7 @@ bool idle_startup() } //--------------------------------------------------------------------- - // Agent Send + // World Wait //--------------------------------------------------------------------- if(STATE_WORLD_WAIT == LLStartUp::getStartupState()) { @@ -1822,6 +1851,10 @@ bool idle_startup() // Set the show start location to true, now that the user has logged // on with this install. gSavedSettings.setBOOL("ShowStartLocation", TRUE); + + // Open Conversation floater on first login. + LLFloaterReg::toggleInstanceOrBringToFront("im_container"); + } display_startup(); @@ -1923,6 +1956,7 @@ bool idle_startup() { llinfos << "gAgentStartLocation : " << gAgentStartLocation << llendl; LLSLURL start_slurl = LLStartUp::getStartSLURL(); + LL_DEBUGS("AppInit") << "start slurl "<<start_slurl.asString()<<LL_ENDL; if (((start_slurl.getType() == LLSLURL::LOCATION) && (gAgentStartLocation == "url")) || ((start_slurl.getType() == LLSLURL::LAST_LOCATION) && (gAgentStartLocation == "last")) || @@ -2026,7 +2060,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 @@ -2143,7 +2177,6 @@ bool idle_startup() display_startup(); // Unmute audio if desired and setup volumes. - // Unmute audio if desired and setup volumes. // This is a not-uncommon crash site, so surround it with // llinfos output to aid diagnosis. LL_INFOS("AppInit") << "Doing first audio_update_volume..." << LL_ENDL; @@ -2164,9 +2197,11 @@ bool idle_startup() LLAgentPicksInfo::getInstance()->requestNumberOfPicks(); - LLIMFloater::initIMFloater(); display_startup(); + llassert(LLPathfindingManager::getInstance() != NULL); + LLPathfindingManager::getInstance()->initSystem(); + return TRUE; } @@ -2182,21 +2217,13 @@ void login_show() { LL_INFOS("AppInit") << "Initializing Login Screen" << LL_ENDL; -#ifdef LL_RELEASE_FOR_DOWNLOAD - BOOL bUseDebugLogin = gSavedSettings.getBOOL("UseDebugLogin"); -#else - BOOL bUseDebugLogin = TRUE; -#endif // Hide the toolbars: may happen to come back here if login fails after login agent but before login in region if (gToolBarView) { gToolBarView->setVisible(FALSE); } - LLPanelLogin::show( gViewerWindow->getWindowRectScaled(), - bUseDebugLogin || gSavedSettings.getBOOL("SecondLifeEnterprise"), - login_callback, NULL ); - + LLPanelLogin::show( gViewerWindow->getWindowRectScaled(), login_callback, NULL ); } // Callback for when login screen is closed. Option 0 = connect, option 1 = quit. @@ -2541,6 +2568,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 @@ -2701,7 +2734,11 @@ void LLStartUp::setStartupState( EStartupState state ) LL_INFOS("AppInit") << "Startup state changing from " << getStartupStateString() << " to " << startupStateToString(state) << LL_ENDL; + + getPhases().stopPhase(getStartupStateString()); gStartupState = state; + getPhases().startPhase(getStartupStateString()); + postStartupState(); } @@ -2774,7 +2811,7 @@ void LLStartUp::initNameCache() // Start cache in not-running state until we figure out if we have // capabilities for display name lookup - LLAvatarNameCache::initClass(false); + LLAvatarNameCache::initClass(false,gSavedSettings.getBOOL("UsePeopleAPI")); LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames")); } @@ -2818,25 +2855,33 @@ bool LLStartUp::dispatchURL() void LLStartUp::setStartSLURL(const LLSLURL& slurl) { - sStartSLURL = slurl; - switch(slurl.getType()) - { - case LLSLURL::HOME_LOCATION: - { - gSavedSettings.setString("LoginLocation", LLSLURL::SIM_LOCATION_HOME); - break; - } - case LLSLURL::LAST_LOCATION: - { - gSavedSettings.setString("LoginLocation", LLSLURL::SIM_LOCATION_LAST); - break; - } - default: - LLGridManager::getInstance()->setGridChoice(slurl.getGrid()); - break; - } + LL_DEBUGS("AppInit")<<slurl.asString()<<LL_ENDL; + + if ( slurl.isSpatial() ) + { + std::string new_start = slurl.getSLURLString(); + LL_DEBUGS("AppInit")<<new_start<<LL_ENDL; + sStartSLURL = slurl; + LLPanelLogin::onUpdateStartSLURL(slurl); // updates grid if needed + + // remember that this is where we wanted to log in...if the login fails, + // the next attempt will default to the same place. + gSavedSettings.setString("NextLoginLocation", new_start); + // following a successful login, this is cleared + // and the default reverts to LoginLocation + } + else + { + LL_WARNS("AppInit")<<"Invalid start SLURL (ignored): "<<slurl.asString()<<LL_ENDL; + } } +// static +LLSLURL& LLStartUp::getStartSLURL() +{ + return sStartSLURL; +} + /** * Read all proxy configuration settings and set up both the HTTP proxy and * SOCKS proxy as needed. @@ -3207,17 +3252,6 @@ bool process_login_success_response() gSavedSettings.setU32("PreferredMaturity", preferredMaturity); } - // During the AO transition, this flag will be true. Then the flag will - // go away. After the AO transition, this code and all the code that - // uses it can be deleted. - text = response["ao_transition"].asString(); - if (!text.empty()) - { - if (text == "1") - { - gAgent.setAOTransition(); - } - } text = response["start_location"].asString(); if(!text.empty()) @@ -3279,11 +3313,8 @@ bool process_login_success_response() { // replace the default help URL format gSavedSettings.setString("HelpURLFormat",text); - - // don't fall back to Standalone's pre-connection static help - gSavedSettings.setBOOL("HelpUseLocal", false); } - + std::string home_location = response["home"]; if(!home_location.empty()) { diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 0a18ef1b2d..760e38890b 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -34,6 +34,8 @@ class LLEventPump; class LLStartupListener; class LLSLURL; +#include "llviewerstats.h" + // functions bool idle_startup(); void release_start_screen(); @@ -109,10 +111,11 @@ public: static void postStartupState(); static void setStartSLURL(const LLSLURL& slurl); - static LLSLURL& getStartSLURL() { return sStartSLURL; } + static LLSLURL& getStartSLURL(); static bool startLLProxy(); // Initialize the SOCKS 5 proxy + static LLViewerStats::PhaseMap& getPhases() { return *sPhases; } private: static LLSLURL sStartSLURL; @@ -120,6 +123,7 @@ private: static EStartupState gStartupState; // Do not set directly, use LLStartup::setStartupState static boost::scoped_ptr<LLEventPump> sStateWatcher; static boost::scoped_ptr<LLStartupListener> sListener; + static boost::scoped_ptr<LLViewerStats::PhaseMap> sPhases; }; diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 75db269bde..ff69c6e9fd 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -114,6 +114,7 @@ LLStatusBar::LLStatusBar(const LLRect& rect) mTextTime(NULL), mSGBandwidth(NULL), mSGPacketLoss(NULL), + mBtnStats(NULL), mBtnVolume(NULL), mBoxBalance(NULL), mBalance(0), @@ -173,6 +174,8 @@ BOOL LLStatusBar::postBuild() mBoxBalance = getChild<LLTextBox>("balance"); mBoxBalance->setClickedCallback( &LLStatusBar::onClickBalance, this ); + + mBtnStats = getChildView("stat_btn"); mBtnVolume = getChild<LLButton>( "volume_btn" ); mBtnVolume->setClickedCallback( onClickVolume, this ); @@ -288,7 +291,7 @@ void LLStatusBar::refresh() mSGBandwidth->setVisible(net_stats_visible); mSGPacketLoss->setVisible(net_stats_visible); - getChildView("stat_btn")->setEnabled(net_stats_visible); + mBtnStats->setEnabled(net_stats_visible); // update the master volume button state bool mute_audio = LLAppViewer::instance()->getMasterSystemAudioMute(); @@ -466,7 +469,7 @@ void LLStatusBar::onMouseEnterVolume() LLRect vol_btn_rect = volbtn->getRect(); LLRect volume_pulldown_rect = mPanelVolumePulldown->getRect(); volume_pulldown_rect.setLeftTopAndSize(vol_btn_rect.mLeft - - (volume_pulldown_rect.getWidth() - vol_btn_rect.getWidth())/2, + (volume_pulldown_rect.getWidth() - vol_btn_rect.getWidth()), vol_btn_rect.mBottom, volume_pulldown_rect.getWidth(), volume_pulldown_rect.getHeight()); diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index 4ea3183d18..9d28e6c2bc 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -102,10 +102,11 @@ private: LLStatGraph *mSGBandwidth; LLStatGraph *mSGPacketLoss; + LLView *mBtnStats; LLButton *mBtnVolume; LLTextBox *mBoxBalance; LLButton *mMediaToggle; - LLView* mScriptOut; + LLView *mScriptOut; LLFrameTimer mClockUpdateTimer; S32 mBalance; diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index 66df7dae3e..ec11a23eb8 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -56,13 +56,12 @@ #include "lldrawable.h" extern LLPipeline gPipeline; +extern bool gShiftFrame; LLColor4U MAX_WATER_COLOR(0, 48, 96, 240); S32 LLSurface::sTextureSize = 256; -S32 LLSurface::sTexelsUpdated = 0; -F32 LLSurface::sTextureUpdateTime = 0.f; // ---------------- LLSurface:: Public Members --------------- @@ -294,7 +293,7 @@ void LLSurface::initTextures() mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp); gPipeline.createObject(mWaterObjp); LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle()); - water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT); + water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT); // region doesn't have a valid water height yet mWaterObjp->setPositionGlobal(water_pos_global); } } @@ -346,6 +345,19 @@ void LLSurface::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegio } } + +void LLSurface::getNeighboringRegionsStatus( std::vector<S32>& regions ) +{ + S32 i; + for (i = 0; i < 8; i++) + { + if ( mNeighbors[i] != NULL ) + { + regions.push_back( i ); + } + } +} + void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) { S32 i; @@ -608,6 +620,11 @@ void LLSurface::moveZ(const S32 x, const S32 y, const F32 delta) void LLSurface::updatePatchVisibilities(LLAgent &agent) { + if (gShiftFrame) + { + return; + } + LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal()); LLSurfacePatch *patchp; @@ -628,7 +645,6 @@ void LLSurface::updatePatchVisibilities(LLAgent &agent) BOOL LLSurface::idleUpdate(F32 max_update_time) { - LLMemType mt_ius(LLMemType::MTYPE_IDLE_UPDATE_SURFACE); if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TERRAIN)) { return FALSE; diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index a4ef4fe2de..9d24bf8771 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -142,6 +142,7 @@ public: friend std::ostream& operator<<(std::ostream &s, const LLSurface &S); void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ); + void getNeighboringRegionsStatus( std::vector<S32>& regions ); public: // Number of grid points on one side of a region, including +1 buffer for @@ -168,9 +169,6 @@ public: F32 mDetailTextureScale; // Number of times to repeat detail texture across this surface - static F32 sTextureUpdateTime; - static S32 sTexelsUpdated; - protected: void createSTexture(); void createWaterTexture(); diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 5077c2c7e1..a9ba2bce9c 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -43,6 +43,7 @@ #include "lldrawpool.h" #include "noise.h" +extern bool gShiftFrame; extern U64 gFrameTime; extern LLPipeline gPipeline; @@ -218,7 +219,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 pos_agent.mV[VX] += x * mSurfacep->getMetersPerGrid(); pos_agent.mV[VY] += y * mSurfacep->getMetersPerGrid(); pos_agent.mV[VZ] = *(mDataZ + point_offset); - *vertex = pos_agent; + *vertex = pos_agent-mVObjp->getRegion()->getOriginAgent(); LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent(); LLVector3 tex_pos = rel_pos * (1.f/surface_stride); @@ -366,10 +367,13 @@ void LLSurfacePatch::updateCameraDistanceRegion(const LLVector3 &pos_region) { if (LLPipeline::sDynamicLOD) { - LLVector3 dv = pos_region; - dv -= mCenterRegion; - mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/ - llmax(LLVOSurfacePatch::sLODFactor, 0.1f); + if (!gShiftFrame) + { + LLVector3 dv = pos_region; + dv -= mCenterRegion; + mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/ + llmax(LLVOSurfacePatch::sLODFactor, 0.1f); + } } else { diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 3aa6a3b7e5..e92bd766ca 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -23,29 +23,18 @@ * $/LicenseInfo$ */ - #include "llviewerprecompiledheaders.h" // must be first include - #include "llsyswellwindow.h" -#include "llagent.h" -#include "llavatarnamecache.h" - -#include "llflatlistview.h" -#include "llfloaterreg.h" -#include "llnotifications.h" - -#include "llscriptfloater.h" -#include "llviewercontrol.h" -#include "llviewerwindow.h" - #include "llchiclet.h" #include "llchicletbar.h" -#include "lltoastpanel.h" +#include "llflatlistview.h" +#include "llfloaterreg.h" #include "llnotificationmanager.h" #include "llnotificationsutil.h" +#include "llscriptfloater.h" #include "llspeakers.h" -#include "lltoolbarview.h" +#include "lltoastpanel.h" //--------------------------------------------------------------------------------- LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLTransientDockableFloater(NULL, true, key), @@ -68,10 +57,6 @@ BOOL LLSysWellWindow::postBuild() // get a corresponding channel initChannel(); - // click on SysWell Window should clear "new message" state (and 'Lit' status). EXT-3147. - // mouse up callback is not called in this case. - setMouseDownCallback(boost::bind(&LLSysWellWindow::releaseNewMessagesState, this)); - return LLTransientDockableFloater::postBuild(); } @@ -98,9 +83,12 @@ void LLSysWellWindow::onStartUpToastClick(S32 x, S32 y, MASK mask) void LLSysWellWindow::setSysWellChiclet(LLSysWellChiclet* chiclet) { mSysWellChiclet = chiclet; - if(mSysWellChiclet) - mSysWellChiclet->updateWidget(isWindowEmpty()); + if(NULL != mSysWellChiclet) + { + mSysWellChiclet->updateWidget(isWindowEmpty()); + } } + //--------------------------------------------------------------------------------- LLSysWellWindow::~LLSysWellWindow() { @@ -111,7 +99,10 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id) { if(mMessageList->removeItemByValue(id)) { - mSysWellChiclet->updateWidget(isWindowEmpty()); + if (NULL != mSysWellChiclet) + { + mSysWellChiclet->updateWidget(isWindowEmpty()); + } reshapeWindow(); } else @@ -159,16 +150,12 @@ void LLSysWellWindow::setVisible(BOOL visible) LLTransientDockableFloater::setVisible(visible); // update notification channel state + initChannel(); // make sure the channel still exists if(mChannel) { mChannel->updateShowToastsState(); mChannel->redrawToasts(); } - - if (visible) - { - releaseNewMessagesState(); - } } //--------------------------------------------------------------------------------- @@ -218,14 +205,6 @@ void LLSysWellWindow::reshapeWindow() } } -void LLSysWellWindow::releaseNewMessagesState() -{ - if (NULL != mSysWellChiclet) - { - mSysWellChiclet->setNewMessagesState(false); - } -} - //--------------------------------------------------------------------------------- bool LLSysWellWindow::isWindowEmpty() { @@ -233,121 +212,6 @@ bool LLSysWellWindow::isWindowEmpty() } /************************************************************************/ -/* RowPanel implementation */ -/************************************************************************/ - -//--------------------------------------------------------------------------------- -LLIMWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId, - S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) : - LLPanel(LLPanel::Params()), mChiclet(NULL), mParent(parent) -{ - buildFromFile( "panel_activeim_row.xml", NULL); - - // Choose which of the pre-created chiclets (IM/group) to use. - // The other one gets hidden. - - LLIMChiclet::EType im_chiclet_type = LLIMChiclet::getIMSessionType(sessionId); - switch (im_chiclet_type) - { - case LLIMChiclet::TYPE_GROUP: - mChiclet = getChild<LLIMGroupChiclet>("group_chiclet"); - break; - case LLIMChiclet::TYPE_AD_HOC: - mChiclet = getChild<LLAdHocChiclet>("adhoc_chiclet"); - break; - case LLIMChiclet::TYPE_UNKNOWN: // assign mChiclet a non-null value anyway - case LLIMChiclet::TYPE_IM: - mChiclet = getChild<LLIMP2PChiclet>("p2p_chiclet"); - break; - } - - // Initialize chiclet. - mChiclet->setChicletSizeChangedCallback(boost::bind(&LLIMWellWindow::RowPanel::onChicletSizeChanged, this, mChiclet, _2)); - mChiclet->enableCounterControl(true); - mChiclet->setCounter(chicletCounter); - mChiclet->setSessionId(sessionId); - mChiclet->setIMSessionName(name); - mChiclet->setOtherParticipantId(otherParticipantId); - mChiclet->setVisible(true); - - if (im_chiclet_type == LLIMChiclet::TYPE_IM) - { - LLAvatarNameCache::get(otherParticipantId, - boost::bind(&LLIMWellWindow::RowPanel::onAvatarNameCache, - this, _1, _2)); - } - else - { - LLTextBox* contactName = getChild<LLTextBox>("contact_name"); - contactName->setValue(name); - } - - mCloseBtn = getChild<LLButton>("hide_btn"); - mCloseBtn->setCommitCallback(boost::bind(&LLIMWellWindow::RowPanel::onClosePanel, this)); -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::RowPanel::onAvatarNameCache(const LLUUID& agent_id, - const LLAvatarName& av_name) -{ - LLTextBox* contactName = getChild<LLTextBox>("contact_name"); - contactName->setValue( av_name.getCompleteName() ); -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::RowPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param) -{ - LLTextBox* text = getChild<LLTextBox>("contact_name"); - S32 new_text_left = mChiclet->getRect().mRight + CHICLET_HPAD; - LLRect text_rect = text->getRect(); - text_rect.mLeft = new_text_left; - text->setShape(text_rect); -} - -//--------------------------------------------------------------------------------- -LLIMWellWindow::RowPanel::~RowPanel() -{ -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::RowPanel::onClosePanel() -{ - gIMMgr->leaveSession(mChiclet->getSessionId()); - // This row panel will be removed from the list in LLSysWellWindow::sessionRemoved(). -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::RowPanel::onMouseEnter(S32 x, S32 y, MASK mask) -{ - setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemSelected")); -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::RowPanel::onMouseLeave(S32 x, S32 y, MASK mask) -{ - setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemUnselected")); -} - -//--------------------------------------------------------------------------------- -// virtual -BOOL LLIMWellWindow::RowPanel::handleMouseDown(S32 x, S32 y, MASK mask) -{ - // Pass the mouse down event to the chiclet (EXT-596). - if (!mChiclet->pointInView(x, y) && !mCloseBtn->getRect().pointInRect(x, y)) // prevent double call of LLIMChiclet::onMouseDown() - { - mChiclet->onMouseDown(); - return TRUE; - } - - return LLPanel::handleMouseDown(x, y, mask); -} - -// virtual -BOOL LLIMWellWindow::RowPanel::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ - return mChiclet->handleRightMouseDown(x, y, mask); -} -/************************************************************************/ /* ObjectRowPanel implementation */ /************************************************************************/ @@ -355,7 +219,7 @@ LLIMWellWindow::ObjectRowPanel::ObjectRowPanel(const LLUUID& notification_id, bo : LLPanel() , mChiclet(NULL) { - buildFromFile( "panel_active_object_row.xml", NULL); + buildFromFile( "panel_active_object_row.xml"); initChiclet(notification_id); @@ -432,13 +296,19 @@ BOOL LLIMWellWindow::ObjectRowPanel::handleRightMouseDown(S32 x, S32 y, MASK mas ////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS +LLNotificationWellWindow::WellNotificationChannel::WellNotificationChannel(LLNotificationWellWindow* well_window) +: LLNotificationChannel(LLNotificationChannel::Params().name(well_window->getPathname())), + mWellWindow(well_window) +{ + connectToChannel("Notifications"); + connectToChannel("Group Notifications"); + connectToChannel("Offer"); +} + LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key) -: LLSysWellWindow(key) +: LLSysWellWindow(key) { - // init connections to the list's update events - connectListUpdaterToSignal("notify"); - connectListUpdaterToSignal("groupnotify"); - connectListUpdaterToSignal("offer"); + mNotificationUpdates.reset(new WellNotificationChannel(this)); } // static @@ -480,7 +350,6 @@ void LLNotificationWellWindow::addItem(LLSysWellItem::Params p) { mSysWellChiclet->updateWidget(isWindowEmpty()); reshapeWindow(); - new_item->setOnItemCloseCallback(boost::bind(&LLNotificationWellWindow::onItemClose, this, _1)); new_item->setOnItemClickCallback(boost::bind(&LLNotificationWellWindow::onItemClick, this, _1)); } @@ -518,7 +387,7 @@ void LLNotificationWellWindow::initChannel() LLSysWellWindow::initChannel(); if(mChannel) { - mChannel->setOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2)); + mChannel->addOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2)); } } @@ -545,20 +414,6 @@ void LLNotificationWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id) addItem(p); } -void LLNotificationWellWindow::connectListUpdaterToSignal(std::string notification_type) -{ - LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance(); - LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type); - if(n_handler) - { - n_handler->setNotificationIDCallback(boost::bind(&LLNotificationWellWindow::removeItemByID, this, _1)); - } - else - { - llwarns << "LLSysWellWindow::connectListUpdaterToSignal() - could not get a handler for '" << notification_type <<"' type of notifications" << llendl; - } -} - void LLNotificationWellWindow::onItemClick(LLSysWellItem* item) { LLUUID id = item->getID(); @@ -573,7 +428,10 @@ void LLNotificationWellWindow::onItemClose(LLSysWellItem* item) mChannel->killToastByNotificationID(id); } - +void LLNotificationWellWindow::onAdd( LLNotificationPtr notify ) +{ + removeItemByID(notify->getID()); +} /************************************************************************/ /* LLIMWellWindow implementation */ @@ -584,12 +442,10 @@ void LLNotificationWellWindow::onItemClose(LLSysWellItem* item) LLIMWellWindow::LLIMWellWindow(const LLSD& key) : LLSysWellWindow(key) { - LLIMMgr::getInstance()->addSessionObserver(this); } LLIMWellWindow::~LLIMWellWindow() { - LLIMMgr::getInstance()->removeSessionObserver(this); } // static @@ -598,52 +454,23 @@ 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(); setTitle(getString("title_im_well_window")); - LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findIMChiclet, this, _1)); LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findObjectChiclet, this, _1)); return rv; } -//virtual -void LLIMWellWindow::sessionAdded(const LLUUID& session_id, - const std::string& name, const LLUUID& other_participant_id) -{ - LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id); - if (!session) return; - - // no need to spawn chiclets for participants in P2P calls called through Avaline - if (session->isP2P() && session->isOtherParticipantAvaline()) return; - - if (mMessageList->getItemByValue(session_id)) return; - - addIMRow(session_id, 0, name, other_participant_id); - reshapeWindow(); -} - -//virtual -void LLIMWellWindow::sessionRemoved(const LLUUID& sessionId) -{ - delIMRow(sessionId); - reshapeWindow(); -} - -//virtual -void LLIMWellWindow::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) -{ - //for outgoing ad-hoc and group im sessions only - LLChiclet* chiclet = findIMChiclet(old_session_id); - if (chiclet) - { - chiclet->setSessionId(new_session_id); - mMessageList->updateValue(old_session_id, new_session_id); - } -} - LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id) { if (!mMessageList) return NULL; @@ -660,85 +487,13 @@ LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id) ////////////////////////////////////////////////////////////////////////// // PRIVATE METHODS -LLChiclet* LLIMWellWindow::findIMChiclet(const LLUUID& sessionId) -{ - if (!mMessageList) return NULL; - - LLChiclet* res = NULL; - RowPanel* panel = mMessageList->getTypedItemByValue<RowPanel>(sessionId); - if (panel != NULL) - { - res = panel->mChiclet; - } - - return res; -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter, - const std::string& name, const LLUUID& otherParticipantId) -{ - RowPanel* item = new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId); - if (mMessageList->addItem(item, sessionId)) - { - mSysWellChiclet->updateWidget(isWindowEmpty()); - } - else - { - llwarns << "Unable to add IM Row into the list, sessionID: " << sessionId - << ", name: " << name - << ", other participant ID: " << otherParticipantId - << llendl; - - item->die(); - } -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::delIMRow(const LLUUID& sessionId) -{ - //fix for EXT-3252 - //without this line LLIMWellWindow receive onFocusLost - //and hide itself. It was becaue somehow LLIMChicklet was in focus group for - //LLIMWellWindow... - //But I didn't find why this happen.. - gFocusMgr.clearLastFocusForGroup(this); - - if (mMessageList->removeItemByValue(sessionId)) - { - mSysWellChiclet->updateWidget(isWindowEmpty()); - } - else - { - llwarns << "Unable to remove IM Row from the list, sessionID: " << sessionId - << llendl; - } - - // remove all toasts that belong to this session from a screen - if(mChannel) - mChannel->removeToastsBySessionID(sessionId); - - // hide chiclet window if there are no items left - if(isWindowEmpty()) - { - setVisible(FALSE); - } - else - { - setFocus(true); - } -} void LLIMWellWindow::addObjectRow(const LLUUID& notification_id, bool new_message/* = false*/) { if (mMessageList->getItemByValue(notification_id) == NULL) { ObjectRowPanel* item = new ObjectRowPanel(notification_id, new_message); - if (mMessageList->addItem(item, notification_id)) - { - mSysWellChiclet->updateWidget(isWindowEmpty()); - } - else + if (!mMessageList->addItem(item, notification_id)) { llwarns << "Unable to add Object Row into the list, notificationID: " << notification_id << llendl; item->die(); @@ -749,11 +504,7 @@ void LLIMWellWindow::addObjectRow(const LLUUID& notification_id, bool new_messag void LLIMWellWindow::removeObjectRow(const LLUUID& notification_id) { - if (mMessageList->removeItemByValue(notification_id)) - { - mSysWellChiclet->updateWidget(isWindowEmpty()); - } - else + if (!mMessageList->removeItemByValue(notification_id)) { llwarns << "Unable to remove Object Row from the list, notificationID: " << notification_id << llendl; } @@ -766,21 +517,6 @@ void LLIMWellWindow::removeObjectRow(const LLUUID& notification_id) } } - -void LLIMWellWindow::addIMRow(const LLUUID& session_id) -{ - if (hasIMRow(session_id)) return; - - LLIMModel* im_model = LLIMModel::getInstance(); - addIMRow(session_id, 0, im_model->getName(session_id), im_model->getOtherParticipantID(session_id)); - reshapeWindow(); -} - -bool LLIMWellWindow::hasIMRow(const LLUUID& session_id) -{ - return mMessageList->getItemByValue(session_id); -} - void LLIMWellWindow::closeAll() { // Generate an ignorable alert dialog if there is an active voice IM sesion @@ -825,13 +561,6 @@ void LLIMWellWindow::closeAllImpl() { LLPanel* panel = mMessageList->getItemByValue(*iter); - RowPanel* im_panel = dynamic_cast <RowPanel*> (panel); - if (im_panel) - { - gIMMgr->leaveSession(*iter); - continue; - } - ObjectRowPanel* obj_panel = dynamic_cast <ObjectRowPanel*> (panel); if (obj_panel) { @@ -856,4 +585,4 @@ bool LLIMWellWindow::confirmCloseAll(const LLSD& notification, const LLSD& respo return false; } -// EOF + diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index 52e5370505..cc5c057d8b 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -27,29 +27,26 @@ #ifndef LL_LLSYSWELLWINDOW_H #define LL_LLSYSWELLWINDOW_H +#include "llimview.h" +#include "llnotifications.h" +#include "llscreenchannel.h" #include "llsyswellitem.h" - #include "lltransientdockablefloater.h" -#include "llbutton.h" -#include "llscreenchannel.h" -#include "llscrollcontainer.h" -#include "llimview.h" - -#include "boost/shared_ptr.hpp" class LLAvatarName; -class LLFlatListView; class LLChiclet; +class LLFlatListView; class LLIMChiclet; class LLScriptChiclet; class LLSysWellChiclet; - class LLSysWellWindow : public LLTransientDockableFloater { public: + LOG_CLASS(LLSysWellWindow); + LLSysWellWindow(const LLSD& key); - ~LLSysWellWindow(); + virtual ~LLSysWellWindow(); BOOL postBuild(); // other interface functions @@ -84,7 +81,6 @@ protected: virtual const std::string& getAnchorViewName() = 0; void reshapeWindow(); - void releaseNewMessagesState(); // pointer to a corresponding channel's instance LLNotificationsUI::LLScreenChannel* mChannel; @@ -111,7 +107,7 @@ public: /*virtual*/ BOOL postBuild(); /*virtual*/ void setVisible(BOOL visible); - + /*virtual*/ void onAdd(LLNotificationPtr notify); // Operating with items void addItem(LLSysWellItem::Params p); @@ -119,6 +115,18 @@ public: void closeAll(); protected: + struct WellNotificationChannel : public LLNotificationChannel + { + WellNotificationChannel(LLNotificationWellWindow*); + void onDelete(LLNotificationPtr notify) + { + mWellWindow->removeItemByID(notify->getID()); + } + + LLNotificationWellWindow* mWellWindow; + }; + + LLNotificationChannelPtr mNotificationUpdates; /*virtual*/ const std::string& getAnchorViewName() { return NOTIFICATION_WELL_ANCHOR_NAME; } private: @@ -126,12 +134,8 @@ private: void initChannel(); void clearScreenChannels(); - void onStoreToast(LLPanel* info_panel, LLUUID id); - // connect counter and list updaters to the corresponding signals - void connectListUpdaterToSignal(std::string notification_type); - // Handlers void onItemClick(LLSysWellItem* item); void onItemClose(LLSysWellItem* item); @@ -146,68 +150,31 @@ private: * * It contains a list list of all active IM sessions. */ -class LLIMWellWindow : public LLSysWellWindow, LLIMSessionObserver, LLInitClass<LLIMWellWindow> +class LLIMWellWindow : public LLSysWellWindow, LLInitClass<LLIMWellWindow> { public: LLIMWellWindow(const LLSD& key); ~LLIMWellWindow(); static LLIMWellWindow* getInstance(const LLSD& key = LLSD()); + static LLIMWellWindow* findInstance(const LLSD& key = LLSD()); static void initClass() { getInstance(); } /*virtual*/ BOOL postBuild(); - // LLIMSessionObserver observe triggers - /*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id); - /*virtual*/ void sessionRemoved(const LLUUID& session_id); - /*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id); - void addObjectRow(const LLUUID& notification_id, bool new_message = false); void removeObjectRow(const LLUUID& notification_id); - - void addIMRow(const LLUUID& session_id); - bool hasIMRow(const LLUUID& session_id); - void closeAll(); protected: /*virtual*/ const std::string& getAnchorViewName() { return IM_WELL_ANCHOR_NAME; } private: - LLChiclet * findIMChiclet(const LLUUID& sessionId); LLChiclet* findObjectChiclet(const LLUUID& notification_id); - void addIMRow(const LLUUID& sessionId, S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId); - void delIMRow(const LLUUID& sessionId); bool confirmCloseAll(const LLSD& notification, const LLSD& response); void closeAllImpl(); - /** - * Scrolling row panel. - */ - class RowPanel: public LLPanel - { - public: - RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId, S32 chicletCounter, - const std::string& name, const LLUUID& otherParticipantId); - virtual ~RowPanel(); - void onMouseEnter(S32 x, S32 y, MASK mask); - void onMouseLeave(S32 x, S32 y, MASK mask); - BOOL handleMouseDown(S32 x, S32 y, MASK mask); - BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - - private: - static const S32 CHICLET_HPAD = 10; - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); - void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param); - void onClosePanel(); - public: - LLIMChiclet* mChiclet; - private: - LLButton* mCloseBtn; - const LLSysWellWindow* mParent; - }; - class ObjectRowPanel: public LLPanel { public: diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 6f6d5dbf12..ad09af6594 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -55,6 +55,9 @@ using namespace LLVOAvatarDefines; static const S32 BAKE_UPLOAD_ATTEMPTS = 7; static const F32 BAKE_UPLOAD_RETRY_DELAY = 2.f; // actual delay grows by power of 2 each attempt +// runway consolidate +extern std::string self_av_string(); + class LLTexLayerInfo { friend class LLTexLayer; @@ -494,7 +497,6 @@ void LLTexLayerSetBuffer::doUpload() } LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C; - compressedImage->setRate(0.f); const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask) if (compressedImage->encode(baked_image, comment_text)) { @@ -508,7 +510,13 @@ void LLTexLayerSetBuffer::doUpload() BOOL valid = FALSE; LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C; S32 file_size = 0; - U8* data = LLVFile::readFile(gVFS, asset_id, LLAssetType::AT_TEXTURE, &file_size); + + //data buffer MUST be allocated using LLImageBase + LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE); + file_size = file.getSize(); + U8* data = integrity_test->allocateData(file_size); + file.read(data, file_size); + if (data) { valid = integrity_test->validate(data, file_size); // integrity_test will delete 'data' @@ -577,7 +585,7 @@ void LLTexLayerSetBuffer::doUpload() args["BODYREGION"] = mTexLayerSet->getBodyRegionName(); args["RESOLUTION"] = lod_str; LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args); - llinfos << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL; } } else @@ -631,7 +639,7 @@ void LLTexLayerSetBuffer::doUpdate() args["BODYREGION"] = mTexLayerSet->getBodyRegionName(); args["RESOLUTION"] = lod_str; LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args); - llinfos << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL; } } 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/lltexlayerparams.h b/indra/newview/lltexlayerparams.h index 74c22b0cdf..c812199796 100644 --- a/indra/newview/lltexlayerparams.h +++ b/indra/newview/lltexlayerparams.h @@ -58,6 +58,7 @@ protected: // LLTexLayerParamAlpha // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL_ALIGN_PREFIX(16) class LLTexLayerParamAlpha : public LLTexLayerParam { public: @@ -65,6 +66,16 @@ public: LLTexLayerParamAlpha( LLVOAvatar* avatar ); /*virtual*/ ~LLTexLayerParamAlpha(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const; // LLVisualParam Virtual functions @@ -76,11 +87,11 @@ public: // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion() { return 1.f; } - /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; } + /*virtual*/ const LLVector4a& getAvgDistortion() { return mAvgDistortionVec; } /*virtual*/ F32 getMaxDistortion() { return 3.f; } - /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f);} - /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; - /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;}; + /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector4a(1.f, 1.f, 1.f);} + /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; + /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;}; // New functions BOOL render( S32 x, S32 y, S32 width, S32 height ); @@ -94,7 +105,7 @@ private: LLPointer<LLImageRaw> mStaticImageRaw; BOOL mNeedsCreateTexture; BOOL mStaticImageInvalid; - LLVector3 mAvgDistortionVec; + LL_ALIGN_16(LLVector4a mAvgDistortionVec); F32 mCachedEffectiveWeight; public: @@ -104,7 +115,7 @@ public: typedef std::list< LLTexLayerParamAlpha* > param_alpha_ptr_list_t; static param_alpha_ptr_list_t sInstances; -}; +} LL_ALIGN_POSTFIX(16); class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo { friend class LLTexLayerParamAlpha; @@ -128,6 +139,8 @@ private: // LLTexLayerParamColor // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +LL_ALIGN_PREFIX(16) class LLTexLayerParamColor : public LLTexLayerParam { public: @@ -141,6 +154,17 @@ public: LLTexLayerParamColor( LLTexLayerInterface* layer ); LLTexLayerParamColor( LLVOAvatar* avatar ); + + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + /* virtual */ ~LLTexLayerParamColor(); /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const; @@ -155,19 +179,19 @@ public: // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion() { return 1.f; } - /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; } + /*virtual*/ const LLVector4a& getAvgDistortion() { return mAvgDistortionVec; } /*virtual*/ F32 getMaxDistortion() { return 3.f; } - /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f); } - /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; - /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;}; + /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector4a(1.f, 1.f, 1.f); } + /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; + /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;}; // New functions LLColor4 getNetColor() const; protected: virtual void onGlobalColorChanged(bool upload_bake) {} private: - LLVector3 mAvgDistortionVec; -}; + LL_ALIGN_16(LLVector4a mAvgDistortionVec); +} LL_ALIGN_POSTFIX(16); class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo { diff --git a/indra/newview/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp index d2e4b01732..f8c1bca8ae 100644 --- a/indra/newview/lltextureatlas.cpp +++ b/indra/newview/lltextureatlas.cpp @@ -116,7 +116,6 @@ LLGLuint LLTextureAtlas::insertSubTexture(LLImageGL* source_gl_tex, S32 discard_ return 0 ; } - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, TRUE); glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h, mGLTexturep->getPrimaryFormat(), mGLTexturep->getFormatType(), raw_image->getData()); diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index e7a176f4f9..305f6fca0f 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -50,6 +50,8 @@ const S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE;//1024; const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by when it exceeds its limit const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate) +const S32 TEXTURE_FAST_CACHE_ENTRY_OVERHEAD = sizeof(S32) * 4; //w, h, c, level +const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = 16 * 16 * 4 + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD; class LLTextureCacheWorker : public LLWorkerClass { @@ -283,9 +285,12 @@ public: LLTextureCacheRemoteWorker(LLTextureCache* cache, U32 priority, const LLUUID& id, U8* data, S32 datasize, S32 offset, S32 imagesize, // for writes + LLPointer<LLImageRaw> raw, S32 discardlevel, LLTextureCache::Responder* responder) : LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder), - mState(INIT) + mState(INIT), + mRawImage(raw), + mRawDiscardLevel(discardlevel) { } @@ -303,6 +308,8 @@ private: }; e_state mState; + LLPointer<LLImageRaw> mRawImage; + S32 mRawDiscardLevel; }; @@ -559,6 +566,11 @@ bool LLTextureCacheRemoteWorker::doWrite() if(idx < 0) { idx = mCache->setHeaderCacheEntry(mID, entry, mImageSize, mDataSize); // create the new entry. + if(idx >= 0) + { + //write to the fast cache. + llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel)); + } } else { @@ -658,6 +670,7 @@ bool LLTextureCacheRemoteWorker::doWrite() // Nothing else to do at that point... done = true; } + mRawImage = NULL; // Clean up and exit return done; @@ -744,10 +757,14 @@ LLTextureCache::LLTextureCache(bool threaded) mWorkersMutex(NULL), mHeaderMutex(NULL), mListMutex(NULL), + mFastCacheMutex(NULL), mHeaderAPRFile(NULL), mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called. mTexturesSizeTotal(0), - mDoPurge(FALSE) + mDoPurge(FALSE), + mFastCachep(NULL), + mFastCachePoolp(NULL), + mFastCachePadBuffer(NULL) { } @@ -755,12 +772,15 @@ LLTextureCache::~LLTextureCache() { clearDeleteList() ; writeUpdatedEntries() ; + delete mFastCachep; + delete mFastCachePoolp; + FREE_MEM(LLImageBase::getPrivatePool(), mFastCachePadBuffer); } ////////////////////////////////////////////////////////////////////////////// //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. @@ -879,15 +899,15 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id) ////////////////////////////////////////////////////////////////////////////// //static -const S32 MAX_REASONABLE_FILE_SIZE = 512*1024*1024; // 512 MB -F32 LLTextureCache::sHeaderCacheVersion = 1.4f; -U32 LLTextureCache::sCacheMaxEntries = MAX_REASONABLE_FILE_SIZE / TEXTURE_CACHE_ENTRY_SIZE; +F32 LLTextureCache::sHeaderCacheVersion = 1.7f; +U32 LLTextureCache::sCacheMaxEntries = 1024 * 1024; //~1 million textures. S64 LLTextureCache::sCacheMaxTexturesSize = 0; // no limit const char* entries_filename = "texture.entries"; const char* cache_filename = "texture.cache"; const char* old_textures_dirname = "textures"; //change the location of the texture cache to prevent from being deleted by old version viewers. const char* textures_dirname = "texturecache"; +const char* fast_cache_filename = "FastCache.cache"; void LLTextureCache::setDirNames(ELLPath location) { @@ -896,6 +916,7 @@ void LLTextureCache::setDirNames(ELLPath location) mHeaderEntriesFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, entries_filename); mHeaderDataFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, cache_filename); mTexturesDirName = gDirUtilp->getExpandedFilename(location, textures_dirname); + mFastCacheFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, fast_cache_filename); } void LLTextureCache::purgeCache(ELLPath location) @@ -938,8 +959,8 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache { llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. - S64 header_size = (max_size * 2) / 10; - S64 max_entries = header_size / TEXTURE_CACHE_ENTRY_SIZE; + S64 header_size = (max_size / 100) * 36; //0.36 * max_size + S64 max_entries = header_size / (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE); sCacheMaxEntries = (S32)(llmin((S64)sCacheMaxEntries, max_entries)); header_size = sCacheMaxEntries * TEXTURE_CACHE_ENTRY_SIZE; max_size -= header_size; @@ -981,6 +1002,7 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache purgeTextures(true); // calc mTexturesSize and make some room in the texture cache if we need it llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. + openFastCache(true); return max_size; // unused cache space } @@ -1751,7 +1773,7 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 pri LLMutexLock lock(&mWorkersMutex); LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id, NULL, size, offset, - 0, responder); + 0, NULL, 0, responder); handle_t handle = worker->read(); mReaders[handle] = worker; return handle; @@ -1789,6 +1811,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort) LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, + LLPointer<LLImageRaw> rawimage, S32 discardlevel, WriteResponder* responder) { if (mReadOnly) @@ -1807,12 +1830,174 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio LLMutexLock lock(&mWorkersMutex); LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id, data, datasize, 0, - imagesize, responder); + imagesize, rawimage, discardlevel, responder); handle_t handle = worker->write(); mWriters[handle] = worker; return handle; } +//called in the main thread +LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& discardlevel) +{ + U32 offset; + { + LLMutexLock lock(&mHeaderMutex); + id_map_t::const_iterator iter = mHeaderIDMap.find(id); + if(iter == mHeaderIDMap.end()) + { + return NULL; //not in the cache + } + + offset = iter->second; + } + offset *= TEXTURE_FAST_CACHE_ENTRY_SIZE; + + U8* data; + S32 head[4]; + { + LLMutexLock lock(&mFastCacheMutex); + + openFastCache(); + + mFastCachep->seek(APR_SET, offset); + + if(mFastCachep->read(head, TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) != TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) + { + //cache corrupted or under thread race condition + closeFastCache(); + return NULL; + } + + S32 image_size = head[0] * head[1] * head[2]; + if(!image_size) //invalid + { + closeFastCache(); + return NULL; + } + discardlevel = head[3]; + + data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), image_size); + if(mFastCachep->read(data, image_size) != image_size) + { + FREE_MEM(LLImageBase::getPrivatePool(), data); + closeFastCache(); + return NULL; + } + + closeFastCache(); + } + LLPointer<LLImageRaw> raw = new LLImageRaw(data, head[0], head[1], head[2], true); + + return raw; +} + +//return the fast cache location +bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel) +{ + //rescale image if needed + S32 w, h, c; + w = raw->getWidth(); + h = raw->getHeight(); + c = raw->getComponents(); + S32 i = 0 ; + + while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) + { + ++i ; + } + + if(i) + { + w >>= i; + h >>= i; + if(w * h *c > 0) //valid + { + LLPointer<LLImageRaw> newraw = new LLImageRaw(raw->getData(), raw->getWidth(), raw->getHeight(), raw->getComponents()); + newraw->scale(w, h) ; + raw = newraw; + + discardlevel += i ; + } + } + + //copy data + memcpy(mFastCachePadBuffer, &w, sizeof(S32)); + memcpy(mFastCachePadBuffer + sizeof(S32), &h, sizeof(S32)); + memcpy(mFastCachePadBuffer + sizeof(S32) * 2, &c, sizeof(S32)); + memcpy(mFastCachePadBuffer + sizeof(S32) * 3, &discardlevel, sizeof(S32)); + if(w * h * c > 0) //valid + { + memcpy(mFastCachePadBuffer + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD, raw->getData(), w * h * c); + } + S32 offset = id * TEXTURE_FAST_CACHE_ENTRY_SIZE; + + { + LLMutexLock lock(&mFastCacheMutex); + + openFastCache(); + + mFastCachep->seek(APR_SET, offset); + + //no need to do this assertion check. When it fails, let it fail quietly. + //this failure could happen because other viewer removes the fast cache file when clearing cache. + //--> llassert_always(mFastCachep->write(mFastCachePadBuffer, TEXTURE_FAST_CACHE_ENTRY_SIZE) == TEXTURE_FAST_CACHE_ENTRY_SIZE); + mFastCachep->write(mFastCachePadBuffer, TEXTURE_FAST_CACHE_ENTRY_SIZE); + + closeFastCache(true); + } + + return true; +} + +void LLTextureCache::openFastCache(bool first_time) +{ + if(!mFastCachep) + { + if(first_time) + { + if(!mFastCachePadBuffer) + { + mFastCachePadBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_FAST_CACHE_ENTRY_SIZE); + } + mFastCachePoolp = new LLVolatileAPRPool(); + if (LLAPRFile::isExist(mFastCacheFileName, mFastCachePoolp)) + { + mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ; + } + else + { + mFastCachep = new LLAPRFile(mFastCacheFileName, APR_CREATE|APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ; + } + } + else + { + mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ; + } + + mFastCacheTimer.reset(); + } + return; +} + +void LLTextureCache::closeFastCache(bool forced) +{ + static const F32 timeout = 10.f ; //seconds + + if(!mFastCachep) + { + return ; + } + + if(!forced && mFastCacheTimer.getElapsedTimeF32() < timeout) + { + return ; + } + + delete mFastCachep; + mFastCachep = NULL; + return; +} + bool LLTextureCache::writeComplete(handle_t handle, bool abort) { lockWorkers(); diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index 64e3a2658c..e3fc957fd2 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -36,6 +36,7 @@ class LLImageFormatted; class LLTextureCacheWorker; +class LLImageRaw; class LLTextureCache : public LLWorkerThread { @@ -101,7 +102,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) ; @@ -113,8 +114,9 @@ public: handle_t readFromCache(const LLUUID& id, U32 priority, S32 offset, S32 size, ReadResponder* responder); bool readComplete(handle_t handle, bool abort); - handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, + handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel, WriteResponder* responder); + LLPointer<LLImageRaw> readFromFastCache(const LLUUID& id, S32& discardlevel); bool writeComplete(handle_t handle, bool abort = false); void prioritizeWrite(handle_t handle); @@ -171,12 +173,18 @@ private: void lockHeaders() { mHeaderMutex.lock(); } void unlockHeaders() { mHeaderMutex.unlock(); } + void openFastCache(bool first_time = false); + void closeFastCache(bool forced = false); + bool writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel); + private: // Internal LLMutex mWorkersMutex; LLMutex mHeaderMutex; LLMutex mListMutex; + LLMutex mFastCacheMutex; LLAPRFile* mHeaderAPRFile; + LLVolatileAPRPool* mFastCachePoolp; typedef std::map<handle_t, LLTextureCacheWorker*> handle_map_t; handle_map_t mReaders; @@ -193,12 +201,17 @@ private: // HEADERS (Include first mip) std::string mHeaderEntriesFileName; std::string mHeaderDataFileName; + std::string mFastCacheFileName; EntriesInfo mHeaderEntriesInfo; std::set<S32> mFreeList; // deleted entries std::set<LLUUID> mLRU; - typedef std::map<LLUUID,S32> id_map_t; + typedef std::map<LLUUID, S32> id_map_t; id_map_t mHeaderIDMap; + LLAPRFile* mFastCachep; + LLFrameTimer mFastCacheTimer; + U8* mFastCachePadBuffer; + // BODIES (TEXTURES minus headers) std::string mTexturesDirName; typedef std::map<LLUUID,S32> size_map_t; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index de22f2ae6b..007eb8e33f 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -39,7 +39,7 @@ #include "llfocusmgr.h" #include "llviewertexture.h" #include "llfolderview.h" -#include "llfoldervieweventlistener.h" +#include "llfolderviewmodel.h" #include "llinventory.h" #include "llinventoryfunctions.h" #include "llinventorymodelbackgroundfetch.h" @@ -58,6 +58,7 @@ #include "lltoolmgr.h" #include "lltoolpipette.h" #include "llfiltereditor.h" +#include "llwindow.h" #include "lltool.h" #include "llviewerwindow.h" @@ -67,6 +68,9 @@ #include "lluictrlfactory.h" #include "lltrans.h" +#include "llradiogroup.h" +#include "llfloaterreg.h" +#include "lllocalbitmaps.h" static const S32 HPAD = 4; static const S32 VPAD = 4; @@ -78,6 +82,8 @@ static const F32 CONTEXT_CONE_IN_ALPHA = 0.0f; static const F32 CONTEXT_CONE_OUT_ALPHA = 1.f; static const F32 CONTEXT_FADE_TIME = 0.08f; +static const S32 LOCAL_TRACKING_ID_COLUMN = 1; + //static const char CURRENT_IMAGE_NAME[] = "Current Texture"; //static const char WHITE_IMAGE_NAME[] = "Blank Texture"; //static const char NO_IMAGE_NAME[] = "None"; @@ -92,6 +98,7 @@ public: LLTextureCtrl* owner, const std::string& label, PermissionMask immediate_filter_perm_mask, + PermissionMask dnd_filter_perm_mask, PermissionMask non_immediate_filter_perm_mask, BOOL can_apply_immediately, LLUIImagePtr fallback_image_name); @@ -129,6 +136,9 @@ public: void onFilterEdit(const std::string& search_string ); + void setCanApply(bool can_preview, bool can_apply); + void setTextureSelectedCallback(texture_selected_callback cb) {mTextureSelectedCallback = cb;} + static void onBtnSetToDefault( void* userdata ); static void onBtnSelect( void* userdata ); static void onBtnCancel( void* userdata ); @@ -142,6 +152,12 @@ public: static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata); void onTextureSelect( const LLTextureEntry& te ); + static void onModeSelect(LLUICtrl* ctrl, void *userdata); + static void onBtnAdd(void* userdata); + static void onBtnRemove(void* userdata); + static void onBtnUpload(void* userdata); + static void onLocalScrollCommit(LLUICtrl* ctrl, void* userdata); + protected: LLPointer<LLViewerTexture> mTexturep; LLTextureCtrl* mOwner; @@ -164,19 +180,28 @@ protected: LLFilterEditor* mFilterEdit; LLInventoryPanel* mInventoryPanel; PermissionMask mImmediateFilterPermMask; + PermissionMask mDnDFilterPermMask; PermissionMask mNonImmediateFilterPermMask; BOOL mCanApplyImmediately; BOOL mNoCopyTextureSelected; F32 mContextConeOpacity; LLSaveFolderState mSavedFolderState; - BOOL mSelectedItemPinned; + + LLRadioGroup* mModeSelector; + LLScrollListCtrl* mLocalScrollCtrl; + +private: + bool mCanApply; + bool mCanPreview; + texture_selected_callback mTextureSelectedCallback; }; LLFloaterTexturePicker::LLFloaterTexturePicker( LLTextureCtrl* owner, const std::string& label, PermissionMask immediate_filter_perm_mask, + PermissionMask dnd_filter_perm_mask, PermissionMask non_immediate_filter_perm_mask, BOOL can_apply_immediately, LLUIImagePtr fallback_image) @@ -192,9 +217,12 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mActive( TRUE ), mFilterEdit(NULL), mImmediateFilterPermMask(immediate_filter_perm_mask), + mDnDFilterPermMask(dnd_filter_perm_mask), mNonImmediateFilterPermMask(non_immediate_filter_perm_mask), mContextConeOpacity(0.f), - mSelectedItemPinned( FALSE ) + mSelectedItemPinned( FALSE ), + mCanApply(true), + mCanPreview(true) { buildFromFile("floater_texture_ctrl.xml"); mCanApplyImmediately = can_apply_immediately; @@ -306,7 +334,7 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop( if (xfer) item_perm_mask |= PERM_TRANSFER; //PermissionMask filter_perm_mask = getFilterPermMask(); Commented out due to no-copy texture loss. - PermissionMask filter_perm_mask = mImmediateFilterPermMask; + PermissionMask filter_perm_mask = mDnDFilterPermMask; if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask ) { if (drop) @@ -345,7 +373,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask) { if (!root_folder->getCurSelectedItem()) { - LLFolderViewItem* itemp = root_folder->getItemByID(gInventory.getRootFolderID()); + LLFolderViewItem* itemp = mInventoryPanel->getItemByID(gInventory.getRootFolderID()); if (itemp) { root_folder->setSelection(itemp, FALSE, FALSE); @@ -427,7 +455,7 @@ BOOL LLFloaterTexturePicker::postBuild() // Commented out to scroll to currently selected texture. See EXT-5403. // // store this filter as the default one - // mInventoryPanel->getRootFolder()->getFilter()->markDefault(); + // mInventoryPanel->getRootFolder()->getFilter().markDefault(); // Commented out to stop opening all folders with textures // mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_TEXTURE); @@ -437,10 +465,21 @@ BOOL LLFloaterTexturePicker::postBuild() mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO); } + mModeSelector = getChild<LLRadioGroup>("mode_selection"); + mModeSelector->setCommitCallback(onModeSelect, this); + mModeSelector->setSelectedIndex(0, 0); + + childSetAction("l_add_btn", LLFloaterTexturePicker::onBtnAdd, this); + childSetAction("l_rem_btn", LLFloaterTexturePicker::onBtnRemove, this); + childSetAction("l_upl_btn", LLFloaterTexturePicker::onBtnUpload, this); + + mLocalScrollCtrl = getChild<LLScrollListCtrl>("l_name_list"); + mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit, this); + LLLocalBitmapMgr::feedScrollList(mLocalScrollCtrl); mNoCopyTextureSelected = FALSE; - getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("ApplyTextureImmediately")); + getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("TextureLivePreview")); childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this); if (!mCanApplyImmediately) @@ -464,7 +503,6 @@ BOOL LLFloaterTexturePicker::postBuild() // virtual void LLFloaterTexturePicker::draw() { - S32 floater_header_size = getHeaderHeight(); if (mOwner) { // draw cone of context pointing back to texture swatch @@ -523,7 +561,7 @@ void LLFloaterTexturePicker::draw() // if we're inactive, gray out "apply immediate" checkbox getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected); - getChildView("Select")->setEnabled(mActive); + getChildView("Select")->setEnabled(mActive && mCanApply); getChildView("Pipette")->setEnabled(mActive); getChild<LLUICtrl>("Pipette")->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); @@ -554,10 +592,7 @@ void LLFloaterTexturePicker::draw() } // Border - LLRect border( BORDER_PAD, - getRect().getHeight() - floater_header_size - BORDER_PAD, - ((getMinWidth() / 2) - TEXTURE_INVENTORY_PADDING - HPAD) - BORDER_PAD, - BORDER_PAD + FOOTER_HEIGHT + (getRect().getHeight() - getMinHeight())); + LLRect border = getChildView("preview_widget")->getRect(); gl_rect_2d( border, LLColor4::black, FALSE ); @@ -603,11 +638,10 @@ void LLFloaterTexturePicker::draw() LLFolderView* folder_view = mInventoryPanel->getRootFolder(); if (!folder_view) return; - LLInventoryFilter* filter = folder_view->getFilter(); - if (!filter) return; + LLFolderViewFilter& filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter(); - bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() && - filter->isNotDefault(); + bool is_filter_active = folder_view->getViewModelItem()->getLastFilterGeneration() < filter.getCurrentGeneration() && + filter.isNotDefault(); // After inventory panel filter is applied we have to update // constraint rect for the selected item because of folder view @@ -617,26 +651,12 @@ void LLFloaterTexturePicker::draw() if (!is_filter_active && !mSelectedItemPinned) { folder_view->setPinningSelectedItem(mSelectedItemPinned); - folder_view->dirtyFilter(); - folder_view->arrangeFromRoot(); - + folder_view->getViewModelItem()->dirtyFilter(); mSelectedItemPinned = TRUE; } } } -// static -/* -void LLFloaterTexturePicker::onSaveAnotherCopyDialog( S32 option, void* userdata ) -{ - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - if( 0 == option ) - { - self->copyToInventoryFinal(); - } -} -*/ - const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only) { LLViewerInventoryCategory::cat_array_t cats; @@ -682,8 +702,7 @@ PermissionMask LLFloaterTexturePicker::getFilterPermMask() void LLFloaterTexturePicker::commitIfImmediateSet() { - bool apply_immediate = getChild<LLUICtrl>("apply_immediate_check")->getValue().asBoolean(); - if (!mNoCopyTextureSelected && apply_immediate && mOwner) + if (!mNoCopyTextureSelected && mOwner && mCanApply) { mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE); } @@ -693,6 +712,7 @@ void LLFloaterTexturePicker::commitIfImmediateSet() void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + self->setCanApply(true, true); if (self->mOwner) { self->setImageID( self->mOwner->getDefaultImageAssetID() ); @@ -704,6 +724,7 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata) void LLFloaterTexturePicker::onBtnWhite(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + self->setCanApply(true, true); self->setImageID( self->mWhiteImageAssetID ); self->commitIfImmediateSet(); } @@ -748,7 +769,15 @@ void LLFloaterTexturePicker::onBtnSelect(void* userdata) LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; if (self->mOwner) { - self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_SELECT); + LLUUID local_id = LLUUID::null; + + if (self->mLocalScrollCtrl->getVisible() && !self->mLocalScrollCtrl->getAllSelected().empty()) + { + LLUUID temp_id = self->mLocalScrollCtrl->getFirstSelected()->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID(); + local_id = LLLocalBitmapMgr::getWorldID(temp_id); + } + + self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_SELECT, local_id); } self->closeFloater(); } @@ -772,17 +801,21 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem if (items.size()) { LLFolderViewItem* first_item = items.front(); - LLInventoryItem* itemp = gInventory.getItem(first_item->getListener()->getUUID()); + LLInventoryItem* itemp = gInventory.getItem(static_cast<LLFolderViewModelItemInventory*>(first_item->getViewModelItem())->getUUID()); mNoCopyTextureSelected = FALSE; if (itemp) { + if (!mTextureSelectedCallback.empty()) + { + mTextureSelectedCallback(itemp); + } if (!itemp->getPermissions().allowCopyBy(gAgent.getID())) { mNoCopyTextureSelected = TRUE; } mImageAssetID = itemp->getAssetUUID(); mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? - if (user_action) + if (user_action && mCanPreview) { // only commit intentional selections, not implicit ones commitIfImmediateSet(); @@ -792,6 +825,112 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem } // static +void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + bool mode = (self->mModeSelector->getSelectedIndex() == 0); + + self->getChild<LLButton>("Default")->setVisible(mode); + self->getChild<LLButton>("Blank")->setVisible(mode); + self->getChild<LLButton>("None")->setVisible(mode); + self->getChild<LLButton>("Pipette")->setVisible(mode); + self->getChild<LLFilterEditor>("inventory search editor")->setVisible(mode); + self->getChild<LLInventoryPanel>("inventory panel")->setVisible(mode); + + /*self->getChild<LLCheckBox>("show_folders_check")->setVisible(mode); + no idea under which conditions the above is even shown, needs testing. */ + + self->getChild<LLButton>("l_add_btn")->setVisible(!mode); + self->getChild<LLButton>("l_rem_btn")->setVisible(!mode); + self->getChild<LLButton>("l_upl_btn")->setVisible(!mode); + self->getChild<LLScrollListCtrl>("l_name_list")->setVisible(!mode); +} + +// static +void LLFloaterTexturePicker::onBtnAdd(void* userdata) +{ + if (LLLocalBitmapMgr::addUnit() == true) + { + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + LLLocalBitmapMgr::feedScrollList(self->mLocalScrollCtrl); + } +} + +// static +void LLFloaterTexturePicker::onBtnRemove(void* userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected(); + + if (!selected_items.empty()) + { + for(std::vector<LLScrollListItem*>::iterator iter = selected_items.begin(); + iter != selected_items.end(); iter++) + { + LLScrollListItem* list_item = *iter; + if (list_item) + { + LLUUID tracking_id = list_item->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID(); + LLLocalBitmapMgr::delUnit(tracking_id); + } + } + + self->getChild<LLButton>("l_rem_btn")->setEnabled(false); + self->getChild<LLButton>("l_upl_btn")->setEnabled(false); + LLLocalBitmapMgr::feedScrollList(self->mLocalScrollCtrl); + } + +} + +// static +void LLFloaterTexturePicker::onBtnUpload(void* userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected(); + + if (selected_items.empty()) + { + return; + } + + /* currently only allows uploading one by one, picks the first item from the selection list. (not the vector!) + in the future, it might be a good idea to check the vector size and if more than one units is selected - opt for multi-image upload. */ + + LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN); + std::string filename = LLLocalBitmapMgr::getFilename(tracking_id); + + if (!filename.empty()) + { + LLFloaterReg::showInstance("upload_image", LLSD(filename)); + } + +} + +//static +void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected(); + bool has_selection = !selected_items.empty(); + + self->getChild<LLButton>("l_rem_btn")->setEnabled(has_selection); + self->getChild<LLButton>("l_upl_btn")->setEnabled(has_selection && (selected_items.size() < 2)); + /* since multiple-localbitmap upload is not implemented, upl button gets disabled if more than one is selected. */ + + if (has_selection) + { + LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN); + LLUUID inworld_id = LLLocalBitmapMgr::getWorldID(tracking_id); + self->mOwner->setImageAssetID(inworld_id); + + if (self->childGetValue("apply_immediate_check").asBoolean()) + { + self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE, inworld_id); + } + } +} + +// static void LLFloaterTexturePicker::onShowFolders(LLUICtrl* ctrl, void *user_data) { LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl; @@ -813,7 +952,7 @@ void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_da LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data; LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl; - gSavedSettings.setBOOL("ApplyTextureImmediately", check_box->get()); + gSavedSettings.setBOOL("TextureLivePreview", check_box->get()); picker->updateFilterPermMask(); picker->commitIfImmediateSet(); @@ -824,6 +963,16 @@ void LLFloaterTexturePicker::updateFilterPermMask() //mInventoryPanel->setFilterPermMask( getFilterPermMask() ); Commented out due to no-copy texture loss. } +void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply) +{ + getChildRef<LLUICtrl>("Select").setEnabled(can_apply); + getChildRef<LLUICtrl>("preview_disabled").setVisible(!can_preview); + getChildRef<LLUICtrl>("apply_immediate_check").setVisible(can_preview); + + mCanApply = can_apply; + mCanPreview = can_preview ? gSavedSettings.getBOOL("TextureLivePreview") : false; +} + void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string ) { std::string upper_case_search_string = search_string; @@ -848,7 +997,7 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string ) else if (mInventoryPanel->getFilterSubString().empty()) { // first letter in search term, save existing folder open state - if (!mInventoryPanel->getRootFolder()->isFilterModified()) + if (!mInventoryPanel->getFilter().isNotDefault()) { mSavedFolderState.setApply(FALSE); mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState); @@ -922,13 +1071,20 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) S32 image_top = getRect().getHeight(); S32 image_bottom = BTN_HEIGHT_SMALL; S32 image_middle = (image_top + image_bottom) / 2; - S32 line_height = llround(LLFontGL::getFontSansSerifSmall()->getLineHeight()); + S32 line_height = LLFontGL::getFontSansSerifSmall()->getLineHeight(); LLTextBox::Params tentative_label_p(p.multiselect_text); tentative_label_p.name("Multiple"); tentative_label_p.rect(LLRect (0, image_middle + line_height / 2, getRect().getWidth(), image_middle - line_height / 2 )); tentative_label_p.follows.flags(FOLLOWS_ALL); mTentativeLabel = LLUICtrlFactory::create<LLTextBox> (tentative_label_p); + + // It is no longer possible to associate a style with a textbox, so it has to be done in this fashion + LLStyle::Params style_params; + style_params.color = LLColor4::white; + + mTentativeLabel->setText(LLTrans::getString("multiple_textures"), style_params); + mTentativeLabel->setHAlign(LLFontGL::HCENTER); addChild( mTentativeLabel ); LLRect border_rect = getLocalRect(); @@ -967,6 +1123,15 @@ void LLTextureCtrl::setCanApplyImmediately(BOOL b) } } +void LLTextureCtrl::setCanApply(bool can_preview, bool can_apply) +{ + LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get()); + if( floaterp ) + { + floaterp->setCanApply(can_preview, can_apply); + } +} + void LLTextureCtrl::setVisible( BOOL visible ) { if( !visible ) @@ -1047,12 +1212,19 @@ void LLTextureCtrl::showPicker(BOOL take_focus) this, mLabel, mImmediateFilterPermMask, + mDnDFilterPermMask, mNonImmediateFilterPermMask, mCanApplyImmediately, mFallbackImage); mFloaterHandle = floaterp->getHandle(); + LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp); + if (texture_floaterp && mOnTextureSelectedCallback) + { + texture_floaterp->setTextureSelectedCallback(mOnTextureSelectedCallback); + } + LLFloater* root_floater = gFloaterView->getParentFloater(this); if (root_floater) root_floater->addDependentFloater(floaterp); @@ -1126,7 +1298,7 @@ void LLTextureCtrl::onFloaterClose() mFloaterHandle.markDead(); } -void LLTextureCtrl::onFloaterCommit(ETexturePickOp op) +void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id) { LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); @@ -1140,13 +1312,23 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op) else if (mCommitOnSelection || op == TEXTURE_SELECT) mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? - if( floaterp->isDirty() ) + if(floaterp->isDirty() || id.notNull()) // mModelView->setDirty does not work. { setTentative( FALSE ); + + if (id.notNull()) + { + mImageItemID = id; + mImageAssetID = id; + } + else + { mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE); lldebugs << "mImageItemID: " << mImageItemID << llendl; mImageAssetID = floaterp->getAssetID(); lldebugs << "mImageAssetID: " << mImageAssetID << llendl; + } + if (op == TEXTURE_SELECT && mOnSelectCallback) { mOnSelectCallback( this, LLSD() ); @@ -1167,6 +1349,16 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op) } } +void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb) +{ + mOnTextureSelectedCallback = cb; + LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get()); + if (floaterp) + { + floaterp->setTextureSelectedCallback(cb); + } +} + void LLTextureCtrl::setImageAssetName(const std::string& name) { LLPointer<LLUIImage> imagep = LLUI::getUIImage(name); diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index b1312d641f..599d9c70c5 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -43,6 +43,7 @@ class LLViewerFetchedTexture; // used for setting drag & drop callbacks. typedef boost::function<BOOL (LLUICtrl*, LLInventoryItem*)> drag_n_drop_callback; +typedef boost::function<void (LLInventoryItem*)> texture_selected_callback; ////////////////////////////////////////////////////////////////////////////////////////// @@ -147,8 +148,12 @@ public: void setCaption(const std::string& caption); void setCanApplyImmediately(BOOL b); + void setCanApply(bool can_preview, bool can_apply); + void setImmediateFilterPermMask(PermissionMask mask) { mImmediateFilterPermMask = mask; } + void setDnDFilterPermMask(PermissionMask mask) + { mDnDFilterPermMask = mask; } void setNonImmediateFilterPermMask(PermissionMask mask) { mNonImmediateFilterPermMask = mask; } PermissionMask getImmediateFilterPermMask() { return mImmediateFilterPermMask; } @@ -157,7 +162,7 @@ public: void closeDependentFloater(); void onFloaterClose(); - void onFloaterCommit(ETexturePickOp op); + void onFloaterCommit(ETexturePickOp op, LLUUID id = LLUUID::null); // This call is returned when a drag is detected. Your callback // should return TRUE if the drag is acceptable. @@ -172,6 +177,11 @@ public: void setOnSelectCallback(commit_callback_t cb) { mOnSelectCallback = cb; } + /* + * callback for changing texture selection in inventory list of texture floater + */ + void setOnTextureSelectedCallback(texture_selected_callback cb); + void setShowLoadingPlaceholder(BOOL showLoadingPlaceholder); LLViewerFetchedTexture* getTexture() { return mTexturep; } @@ -185,6 +195,7 @@ private: drag_n_drop_callback mDropCallback; commit_callback_t mOnCancelCallback; commit_callback_t mOnSelectCallback; + texture_selected_callback mOnTextureSelectedCallback; LLPointer<LLViewerFetchedTexture> mTexturep; LLUIColor mBorderColor; LLUUID mImageItemID; @@ -198,6 +209,7 @@ private: std::string mLabel; BOOL mAllowNoTexture; // If true, the user can select "none" as an option PermissionMask mImmediateFilterPermMask; + PermissionMask mDnDFilterPermMask; PermissionMask mNonImmediateFilterPermMask; BOOL mCanApplyImmediately; BOOL mCommitOnSelection; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 56dfb61c4f..7de66b139f 100644..100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2012, 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 @@ -28,12 +28,12 @@ #include <iostream> #include <map> +#include <algorithm> #include "llstl.h" #include "lltexturefetch.h" -#include "llcurl.h" #include "lldir.h" #include "llhttpclient.h" #include "llhttpstatuscodes.h" @@ -50,24 +50,219 @@ #include "llviewertexture.h" #include "llviewerregion.h" #include "llviewerstats.h" +#include "llviewerstatsrecorder.h" #include "llviewerassetstats.h" #include "llworld.h" +#include "llsdutil.h" +#include "llstartup.h" +#include "llsdserialize.h" + +#include "httprequest.h" +#include "httphandler.h" +#include "httpresponse.h" +#include "bufferarray.h" +#include "bufferstream.h" + +bool LLTextureFetchDebugger::sDebuggerEnabled = false ; +LLStat LLTextureFetch::sCacheHitRate("texture_cache_hits", 128); +LLStat LLTextureFetch::sCacheReadLatency("texture_cache_read_latency", 128); + + +////////////////////////////////////////////////////////////////////////////// +// +// Introduction +// +// This is an attempt to document what's going on in here after-the-fact. +// It's a sincere attempt to be accurate but there will be mistakes. +// +// +// Purpose +// +// What is this module trying to do? It accepts requests to load textures +// at a given priority and discard level and notifies the caller when done +// (successfully or not). Additional constraints are: +// +// * Support a local texture cache. Don't hit network when possible +// to avoid it. +// * Use UDP or HTTP as directed or as fallback. HTTP is tried when +// not disabled and a URL is available. UDP when a URL isn't +// available or HTTP attempts fail. +// * Asynchronous (using threads). Main thread is not to be blocked or +// burdened. +// * High concurrency. Many requests need to be in-flight and at various +// stages of completion. +// * Tolerate frequent re-prioritizations of requests. Priority is +// a reflection of a camera's viewpoint and as that viewpoint changes, +// objects and textures become more and less relevant and that is +// expressed at this level by priority changes and request cancelations. +// +// The caller interfaces that fall out of the above and shape the +// implementation are: +// * createRequest - Load j2c image via UDP or HTTP at given discard level and priority +// * deleteRequest - Request removal of prior request +// * getRequestFinished - Test if request is finished returning data to caller +// * updateRequestPriority - Change priority of existing request +// * getFetchState - Retrieve progress on existing request +// +// Everything else in here is mostly plumbing, metrics and debug. +// +// +// The Work Queue +// +// The two central classes are LLTextureFetch and LLTextureFetchWorker. +// LLTextureFetch combines threading with a priority queue of work +// requests. The priority queue is sorted by a U32 priority derived +// from the F32 priority in the APIs. The *only* work request that +// receives service time by this thread is the highest priority +// request. All others wait until it is complete or a dynamic priority +// change has re-ordered work. +// +// LLTextureFetchWorker implements the work request and is 1:1 with +// texture fetch requests. Embedded in each is a state machine that +// walks it through the cache, HTTP, UDP, image decode and retry +// steps of texture acquisition. +// +// +// Threads +// +// Several threads are actively invoking code in this module. They +// include: +// +// 1. Tmain Main thread of execution +// 2. Ttf LLTextureFetch's worker thread provided by LLQueuedThread +// 3. Tcurl LLCurl's worker thread (should disappear over time) +// 4. Ttc LLTextureCache's worker thread +// 5. Tid Image decoder's worker thread +// 6. Thl HTTP library's worker thread +// +// +// Mutexes/Condition Variables +// +// 1. Mt Mutex defined for LLThread's condition variable (base class of +// LLTextureFetch) +// 2. Ct Condition variable for LLThread and used by lock/unlockData(). +// 3. Mwtd Special LLWorkerThread mutex used for request deletion +// operations (base class of LLTextureFetch) +// 4. Mfq LLTextureFetch's mutex covering request and command queue +// data. +// 5. Mfnq LLTextureFetch's mutex covering udp and http request +// queue data. +// 6. Mwc Mutex covering LLWorkerClass's members (base class of +// LLTextureFetchWorker). One per request. +// 7. Mw LLTextureFetchWorker's mutex. One per request. +// +// +// Lock Ordering Rules +// +// Not an exhaustive list but shows the order of lock acquisition +// needed to prevent deadlocks. 'A < B' means acquire 'A' before +// acquiring 'B'. +// +// 1. Mw < Mfnq +// (there are many more...) +// +// +// Method and Member Definitions +// +// With the above, we'll try to document what threads can call what +// methods (using T* for any), what locks must be held on entry and +// are taken out during execution and what data is covered by which +// lock (if any). This latter category will be especially prone to +// error so be skeptical. +// +// A line like: "// Locks: M<xxx>" indicates a method that must +// be invoked by a caller holding the 'M<xxx>' lock. Similarly, +// "// Threads: T<xxx>" means that a caller should be running in +// the indicated thread. +// +// For data members, a trailing comment like "// M<xxx>" means that +// the data member is covered by the specified lock. Absence of a +// comment can mean the member is unlocked or that I didn't bother +// to do the archaeology. In the case of LLTextureFetchWorker, +// most data members added by the leaf class are actually covered +// by the Mw lock. You may also see "// T<xxx>" which means that +// the member's usage is restricted to one thread (except for +// perhaps construction and destruction) and so explicit locking +// isn't used. +// +// In code, a trailing comment like "// [-+]M<xxx>" indicates a +// lock acquision or release point. +// +// +// Worker Lifecycle +// +// The threading and responder model makes it very likely that +// other components are holding on to a pointer to a worker request. +// So, uncoordinated deletions of requests is a guarantee of memory +// corruption in a short time. So destroying a request involves +// invocations's of LLQueuedThread/LLWorkerThread's abort/stop +// logic that removes workers and puts them ona delete queue for +// 2-phase destruction. That second phase is deferrable by calls +// to deleteOK() which only allow final destruction (via dtor) +// once deleteOK has determined that the request is in a safe +// state. +// +// +// Worker State Machine +// +// (ASCII art needed) +// +// +// Priority Scheme +// +// [PRIORITY_LOW, PRIORITY_NORMAL) - for WAIT_HTTP_RESOURCE state +// and other wait states +// [PRIORITY_HIGH, PRIORITY_URGENT) - External event delivered, +// rapidly transitioning through states, +// no waiting allowed +// +// By itself, the above work queue model would fail the concurrency +// and liveness requirements of the interface. A high priority +// request could find itself on the head and stalled for external +// reasons (see VWR-28996). So a few additional constraints are +// required to keep things running: +// * Anything that can make forward progress must be kept at a +// higher priority than anything that can't. +// * On completion of external events, the associated request +// needs to be elevated beyond the normal range to handle +// any data delivery and release any external resource. +// +// This effort is made to keep higher-priority entities moving +// forward in their state machines at every possible step of +// processing. It's not entirely proven that this produces the +// experiencial benefits promised. +// + + +////////////////////////////////////////////////////////////////////////////// + +// Tuning/Parameterization Constants + +static const S32 HTTP_REQUESTS_IN_QUEUE_HIGH_WATER = 40; // Maximum requests to have active in HTTP +static const S32 HTTP_REQUESTS_IN_QUEUE_LOW_WATER = 20; // Active level at which to refill + ////////////////////////////////////////////////////////////////////////////// -class LLTextureFetchWorker : public LLWorkerClass + +class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler + { friend class LLTextureFetch; - friend class HTTPGetResponder; + friend class LLTextureFetchDebugger; private: class CacheReadResponder : public LLTextureCache::ReadResponder { public: + + // Threads: Ttf CacheReadResponder(LLTextureFetch* fetcher, const LLUUID& id, LLImageFormatted* image) : mFetcher(fetcher), mID(id) { setImage(image); } + + // Threads: Ttc virtual void completed(bool success) { LLTextureFetchWorker* worker = mFetcher->getWorker(mID); @@ -84,10 +279,14 @@ private: class CacheWriteResponder : public LLTextureCache::WriteResponder { public: + + // Threads: Ttf CacheWriteResponder(LLTextureFetch* fetcher, const LLUUID& id) : mFetcher(fetcher), mID(id) { } + + // Threads: Ttc virtual void completed(bool success) { LLTextureFetchWorker* worker = mFetcher->getWorker(mID); @@ -104,10 +303,14 @@ private: class DecodeResponder : public LLImageDecodeThread::Responder { public: + + // Threads: Ttf DecodeResponder(LLTextureFetch* fetcher, const LLUUID& id, LLTextureFetchWorker* worker) : mFetcher(fetcher), mID(id), mWorker(worker) { } + + // Threads: Tid virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) { LLTextureFetchWorker* worker = mFetcher->getWorker(mID); @@ -140,22 +343,35 @@ private: }; public: + + // Threads: Ttf /*virtual*/ bool doWork(S32 param); // Called from LLWorkerThread::processRequest() + + // Threads: Ttf /*virtual*/ void finishWork(S32 param, bool completed); // called from finishRequest() (WORK THREAD) - /*virtual*/ bool deleteOK(); // called from update() (WORK THREAD) + + // Threads: Tmain + /*virtual*/ bool deleteOK(); // called from update() ~LLTextureFetchWorker(); - // void relese() { --mActiveCount; } - S32 callbackHttpGet(const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer, - bool partial, bool success); + // Threads: Ttf + // Locks: Mw + S32 callbackHttpGet(LLCore::HttpResponse * response, + bool partial, bool success); + + // Threads: Ttc void callbackCacheRead(bool success, LLImageFormatted* image, S32 imagesize, BOOL islocal); + + // Threads: Ttc void callbackCacheWrite(bool success); + + // Threads: Tid void callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux); - void setGetStatus(U32 status, const std::string& reason) + // Threads: T* + void setGetStatus(LLCore::HttpStatus status, const std::string& reason) { LLMutexLock lock(&mWorkMutex); @@ -167,33 +383,93 @@ public: bool getCanUseHTTP() const { return mCanUseHTTP; } LLTextureFetch & getFetcher() { return *mFetcher; } + + // Inherited from LLCore::HttpHandler + // Threads: Ttf + virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); protected: LLTextureFetchWorker(LLTextureFetch* fetcher, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 discard, S32 size); private: + + // Threads: Tmain /*virtual*/ void startWork(S32 param); // called from addWork() (MAIN THREAD) + + // Threads: Tmain /*virtual*/ void endWork(S32 param, bool aborted); // called from doWork() (MAIN THREAD) + // Locks: Mw void resetFormattedData(); + // Locks: Mw void setImagePriority(F32 priority); + + // Locks: Mw (ctor invokes without lock) void setDesiredDiscard(S32 discard, S32 size); + + // Threads: T* + // Locks: Mw bool insertPacket(S32 index, U8* data, S32 size); + + // Locks: Mw void clearPackets(); + + // Locks: Mw void setupPacketData(); + + // Locks: Mw (ctor invokes without lock) U32 calcWorkPriority(); + + // Locks: Mw void removeFromCache(); + + // Threads: Ttf + // Locks: Mw bool processSimulatorPackets(); + + // Threads: Ttf bool writeToCacheComplete(); + // Threads: Ttf + void recordTextureStart(bool is_http); + + // Threads: Ttf + void recordTextureDone(bool is_http); + void lockWorkMutex() { mWorkMutex.lock(); } void unlockWorkMutex() { mWorkMutex.unlock(); } + // Threads: Ttf + // Locks: Mw + bool acquireHttpSemaphore() + { + llassert(! mHttpHasResource); + if (mFetcher->mHttpSemaphore <= 0) + { + return false; + } + mHttpHasResource = true; + mFetcher->mHttpSemaphore--; + return true; + } + + // Threads: Ttf + // Locks: Mw + void releaseHttpSemaphore() + { + llassert(mHttpHasResource); + mHttpHasResource = false; + mFetcher->mHttpSemaphore++; + } + private: enum e_state // mState { + // *NOTE: Do not change the order/value of state variables, some code + // depends upon specific ordering/adjacency. + // NOTE: Affects LLTextureBar::draw in lltextureview.cpp (debug hack) INVALID = 0, INIT, @@ -201,8 +477,10 @@ private: CACHE_POST, LOAD_FROM_NETWORK, LOAD_FROM_SIMULATOR, - SEND_HTTP_REQ, - WAIT_HTTP_REQ, + WAIT_HTTP_RESOURCE, // Waiting for HTTP resources + WAIT_HTTP_RESOURCE2, // Waiting for HTTP resources + SEND_HTTP_REQ, // Commit to sending as HTTP + WAIT_HTTP_REQ, // Request sent, wait for completion DECODE_IMAGE, DECODE_IMAGE_UPDATE, WRITE_TO_CACHE, @@ -242,11 +520,12 @@ private: S32 mDecodedDiscard; LLFrameTimer mRequestedTimer; LLFrameTimer mFetchTimer; + LLTimer mCacheReadTimer; + F32 mCacheReadTime; LLTextureCache::handle_t mCacheReadHandle; LLTextureCache::handle_t mCacheWriteHandle; - U8* mBuffer; - S32 mBufferSize; S32 mRequestedSize; + S32 mRequestedOffset; S32 mDesiredSize; S32 mFileSize; S32 mCachedSize; @@ -258,12 +537,12 @@ private: BOOL mNeedsAux; BOOL mHaveAllData; BOOL mInLocalCache; + BOOL mInCache; bool mCanUseHTTP ; bool mCanUseNET ; //can get from asset server. - S32 mHTTPFailCount; S32 mRetryAttempt; S32 mActiveCount; - U32 mGetStatus; + LLCore::HttpStatus mGetStatus; std::string mGetReason; // Work Data @@ -283,105 +562,19 @@ private: U8 mImageCodec; LLViewerAssetStats::duration_t mMetricsStartTime; -}; - -////////////////////////////////////////////////////////////////////////////// - -class HTTPGetResponder : public LLCurl::Responder -{ - LOG_CLASS(HTTPGetResponder); -public: - HTTPGetResponder(LLTextureFetch* fetcher, const LLUUID& id, U64 startTime, S32 requestedSize, U32 offset, bool redir) - : mFetcher(fetcher), mID(id), mStartTime(startTime), mRequestedSize(requestedSize), mOffset(offset), mFollowRedir(redir) - { - } - ~HTTPGetResponder() - { - } - - virtual void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) - { - static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog"); - static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator"); - static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic") ; - - if (log_to_viewer_log || log_to_sim) - { - mFetcher->mTextureInfo.setRequestStartTime(mID, mStartTime); - U64 timeNow = LLTimer::getTotalTime(); - mFetcher->mTextureInfo.setRequestType(mID, LLTextureInfoDetails::REQUEST_TYPE_HTTP); - mFetcher->mTextureInfo.setRequestSize(mID, mRequestedSize); - mFetcher->mTextureInfo.setRequestOffset(mID, mOffset); - mFetcher->mTextureInfo.setRequestCompleteTimeAndLog(mID, timeNow); - } - - lldebugs << "HTTP COMPLETE: " << mID << llendl; - LLTextureFetchWorker* worker = mFetcher->getWorker(mID); - if (worker) - { - bool success = false; - bool partial = false; - if (HTTP_OK <= status && status < HTTP_MULTIPLE_CHOICES) - { - success = true; - if (HTTP_PARTIAL_CONTENT == status) // partial information - { - partial = true; - } - } - if (!success) - { - worker->setGetStatus(status, reason); -// llwarns << "CURL GET FAILED, status:" << status << " reason:" << reason << llendl; - } - - S32 data_size = worker->callbackHttpGet(channels, buffer, partial, success); - - if(log_texture_traffic && data_size > 0) - { - LLViewerTexture* tex = LLViewerTextureManager::findTexture(mID) ; - if(tex) - { - gTotalTextureBytesPerBoostLevel[tex->getBoostLevel()] += data_size ; - } - } - - mFetcher->removeFromHTTPQueue(mID, data_size); - - if (worker->mMetricsStartTime) - { - LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE, - true, - LLImageBase::TYPE_AVATAR_BAKE == worker->mType, - LLViewerAssetStatsFF::get_timestamp() - worker->mMetricsStartTime); - worker->mMetricsStartTime = 0; - } - LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE, - true, - LLImageBase::TYPE_AVATAR_BAKE == worker->mType); - } - else - { - mFetcher->removeFromHTTPQueue(mID); - llwarns << "Worker not found: " << mID << llendl; - } - } - - virtual bool followRedir() - { - return mFollowRedir; - } - -private: - LLTextureFetch* mFetcher; - LLUUID mID; - U64 mStartTime; - S32 mRequestedSize; - U32 mOffset; - bool mFollowRedir; + LLCore::HttpHandle mHttpHandle; // Handle of any active request + LLCore::BufferArray * mHttpBufferArray; // Refcounted pointer to response data + int mHttpPolicyClass; + bool mHttpActive; // Active request to http library + unsigned int mHttpReplySize; // Actual received data size + unsigned int mHttpReplyOffset; // Actual received data offset + bool mHttpHasResource; // Counts against Fetcher's mHttpSemaphore + + // State history + U32 mCacheReadCount; + U32 mCacheWriteCount; + U32 mResourceWaitCount; // Requests entering WAIT_HTTP_RESOURCE2 }; ////////////////////////////////////////////////////////////////////////////// @@ -617,13 +810,15 @@ const char* LLTextureFetchWorker::sStateDescs[] = { "CACHE_POST", "LOAD_FROM_NETWORK", "LOAD_FROM_SIMULATOR", + "WAIT_HTTP_RESOURCE", + "WAIT_HTTP_RESOURCE2", "SEND_HTTP_REQ", "WAIT_HTTP_REQ", "DECODE_IMAGE", "DECODE_IMAGE_UPDATE", "WRITE_TO_CACHE", "WAIT_ON_WRITE", - "DONE", + "DONE" }; // static @@ -639,6 +834,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, S32 discard, // Desired discard S32 size) // Desired size : LLWorkerClass(fetcher, "TextureFetch"), + LLCore::HttpHandler(), mState(INIT), mWriteToCacheState(NOT_WRITE), mFetcher(fetcher), @@ -653,11 +849,11 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mRequestedDiscard(-1), mLoadedDiscard(-1), mDecodedDiscard(-1), + mCacheReadTime(0.f), mCacheReadHandle(LLTextureCache::nullHandle()), mCacheWriteHandle(LLTextureCache::nullHandle()), - mBuffer(NULL), - mBufferSize(0), mRequestedSize(0), + mRequestedOffset(0), mDesiredSize(TEXTURE_CACHE_ENTRY_SIZE), mFileSize(0), mCachedSize(0), @@ -669,20 +865,29 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mNeedsAux(FALSE), mHaveAllData(FALSE), mInLocalCache(FALSE), + mInCache(FALSE), mCanUseHTTP(true), - mHTTPFailCount(0), mRetryAttempt(0), mActiveCount(0), - mGetStatus(0), mWorkMutex(NULL), mFirstPacket(0), mLastPacket(-1), mTotalPackets(0), mImageCodec(IMG_CODEC_INVALID), - mMetricsStartTime(0) + mMetricsStartTime(0), + mHttpHandle(LLCORE_HTTP_HANDLE_INVALID), + mHttpBufferArray(NULL), + mHttpPolicyClass(mFetcher->mHttpPolicyClass), + mHttpActive(false), + mHttpReplySize(0U), + mHttpReplyOffset(0U), + mHttpHasResource(false), + mCacheReadCount(0U), + mCacheWriteCount(0U), + mResourceWaitCount(0U) { mCanUseNET = mUrl.empty() ; - + calcWorkPriority(); mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL; // llinfos << "Create: " << mID << " mHost:" << host << " Discard=" << discard << llendl; @@ -701,7 +906,20 @@ LLTextureFetchWorker::~LLTextureFetchWorker() // << " Requested=" << mRequestedDiscard // << " Desired=" << mDesiredDiscard << llendl; llassert_always(!haveWork()); - lockWorkMutex(); + + lockWorkMutex(); // +Mw (should be useless) + if (mHttpHasResource) + { + // Last-chance catchall to recover the resource. Using an + // atomic datatype solely because this can be running in + // another thread. + releaseHttpSemaphore(); + } + if (mHttpActive) + { + // Issue a cancel on a live request... + mFetcher->getHttpRequest().requestCancel(mHttpHandle, NULL); + } if (mCacheReadHandle != LLTextureCache::nullHandle() && mFetcher->mTextureCache) { mFetcher->mTextureCache->readComplete(mCacheReadHandle, true); @@ -712,10 +930,18 @@ LLTextureFetchWorker::~LLTextureFetchWorker() } mFormattedImage = NULL; clearPackets(); - unlockWorkMutex(); - mFetcher->removeFromHTTPQueue(mID); + if (mHttpBufferArray) + { + mHttpBufferArray->release(); + mHttpBufferArray = NULL; + } + unlockWorkMutex(); // -Mw + mFetcher->removeFromHTTPQueue(mID, 0); + mFetcher->removeHttpWaiter(mID); + mFetcher->updateStateStats(mCacheReadCount, mCacheWriteCount, mResourceWaitCount); } +// Locks: Mw void LLTextureFetchWorker::clearPackets() { for_each(mPackets.begin(), mPackets.end(), DeletePointer()); @@ -725,6 +951,7 @@ void LLTextureFetchWorker::clearPackets() mFirstPacket = 0; } +// Locks: Mw void LLTextureFetchWorker::setupPacketData() { S32 data_size = 0; @@ -757,6 +984,7 @@ void LLTextureFetchWorker::setupPacketData() } } +// Locks: Mw (ctor invokes without lock) U32 LLTextureFetchWorker::calcWorkPriority() { //llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerFetchedTexture::maxDecodePriority()); @@ -766,7 +994,7 @@ U32 LLTextureFetchWorker::calcWorkPriority() return mWorkPriority; } -// mWorkMutex is locked +// Locks: Mw (ctor invokes without lock) void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size) { bool prioritize = false; @@ -802,6 +1030,7 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size) } } +// Locks: Mw void LLTextureFetchWorker::setImagePriority(F32 priority) { // llassert_always(priority >= 0 && priority <= LLViewerTexture::maxDecodePriority()); @@ -815,30 +1044,37 @@ void LLTextureFetchWorker::setImagePriority(F32 priority) } } +// Locks: Mw void LLTextureFetchWorker::resetFormattedData() { - FREE_MEM(LLImageBase::getPrivatePool(), mBuffer); - mBuffer = NULL; - mBufferSize = 0; + if (mHttpBufferArray) + { + mHttpBufferArray->release(); + mHttpBufferArray = NULL; + } if (mFormattedImage.notNull()) { mFormattedImage->deleteData(); } + mHttpReplySize = 0; + mHttpReplyOffset = 0; mHaveAllData = FALSE; } -// Called from MAIN thread +// Threads: Tmain void LLTextureFetchWorker::startWork(S32 param) { llassert(mFormattedImage.isNull()); } -#include "llviewertexturelist.h" // debug - -// Called from LLWorkerThread::processRequest() +// Threads: Ttf bool LLTextureFetchWorker::doWork(S32 param) { - LLMutexLock lock(&mWorkMutex); + static const LLCore::HttpStatus http_not_found(HTTP_NOT_FOUND); // 404 + static const LLCore::HttpStatus http_service_unavail(HTTP_SERVICE_UNAVAILABLE); // 503 + static const LLCore::HttpStatus http_not_sat(HTTP_REQUESTED_RANGE_NOT_SATISFIABLE); // 416; + + LLMutexLock lock(&mWorkMutex); // +Mw if ((mFetcher->isQuitting() || getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) { @@ -882,20 +1118,26 @@ bool LLTextureFetchWorker::doWork(S32 param) mLoadedDiscard = -1; mDecodedDiscard = -1; mRequestedSize = 0; + mRequestedOffset = 0; mFileSize = 0; mCachedSize = 0; mLoaded = FALSE; mSentRequest = UNSENT; mDecoded = FALSE; mWritten = FALSE; - FREE_MEM(LLImageBase::getPrivatePool(), mBuffer); - mBuffer = NULL; - mBufferSize = 0; + if (mHttpBufferArray) + { + mHttpBufferArray->release(); + mHttpBufferArray = NULL; + } + mHttpReplySize = 0; + mHttpReplyOffset = 0; mHaveAllData = FALSE; clearPackets(); // TODO: Shouldn't be necessary mCacheReadHandle = LLTextureCache::nullHandle(); mCacheWriteHandle = LLTextureCache::nullHandle(); mState = LOAD_FROM_TEXTURE_CACHE; + mInCache = FALSE; mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); // min desired size is TEXTURE_CACHE_ENTRY_SIZE LL_DEBUGS("Texture") << mID << ": Priority: " << llformat("%8.0f",mImagePriority) << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; @@ -922,20 +1164,24 @@ bool LLTextureFetchWorker::doWork(S32 param) setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it // read file from local disk + ++mCacheReadCount; std::string filename = mUrl.substr(7, std::string::npos); CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage); mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority, offset, size, responder); + mCacheReadTimer.reset(); } - else if (mUrl.empty()) + else if (mUrl.empty() && mFetcher->canLoadFromCache()) { setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it + ++mCacheReadCount; CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage); mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority, offset, size, responder); + mCacheReadTimer.reset(); } - else if(mCanUseHTTP) + else if(!mUrl.empty() && mCanUseHTTP) { if (!(mUrl.compare(0, 7, "http://") == 0)) { @@ -943,7 +1189,7 @@ bool LLTextureFetchWorker::doWork(S32 param) llwarns << "Unknown URL Type: " << mUrl << llendl; } setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); - mState = SEND_HTTP_REQ; + mState = WAIT_HTTP_RESOURCE; } else { @@ -963,6 +1209,9 @@ bool LLTextureFetchWorker::doWork(S32 param) } else { + // + //This should never happen + // return false; } } @@ -982,11 +1231,12 @@ bool LLTextureFetchWorker::doWork(S32 param) llassert_always(mFormattedImage->getDataSize() > 0); mLoadedDiscard = mDesiredDiscard; mState = DECODE_IMAGE; + mInCache = TRUE; mWriteToCacheState = NOT_WRITE ; LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize() << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight()) << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; - // fall through + LLTextureFetch::sCacheHitRate.addValue(100.f); } else { @@ -1001,7 +1251,9 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_DEBUGS("Texture") << mID << ": Not in Cache" << LL_ENDL; mState = LOAD_FROM_NETWORK; } + // fall through + LLTextureFetch::sCacheHitRate.addValue(0.f); } } @@ -1040,7 +1292,7 @@ bool LLTextureFetchWorker::doWork(S32 param) } if (mCanUseHTTP && !mUrl.empty()) { - mState = LLTextureFetchWorker::SEND_HTTP_REQ; + mState = WAIT_HTTP_RESOURCE; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); if(mWriteToCacheState != NOT_WRITE) { @@ -1057,13 +1309,7 @@ bool LLTextureFetchWorker::doWork(S32 param) mRequestedDiscard = mDesiredDiscard; mSentRequest = QUEUED; mFetcher->addToNetworkQueue(this); - if (! mMetricsStartTime) - { - mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); - } - LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, - false, - LLImageBase::TYPE_AVATAR_BAKE == mType); + recordTextureStart(false); setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return false; @@ -1074,12 +1320,7 @@ bool LLTextureFetchWorker::doWork(S32 param) //llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end()); // Make certain this is in the network queue //mFetcher->addToNetworkQueue(this); - //if (! mMetricsStartTime) - //{ - // mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); - //} - //LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, false, - // LLImageBase::TYPE_AVATAR_BAKE == mType); + //recordTextureStart(false); //setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return false; } @@ -1104,194 +1345,250 @@ bool LLTextureFetchWorker::doWork(S32 param) setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); mState = DECODE_IMAGE; mWriteToCacheState = SHOULD_WRITE; - - if (mMetricsStartTime) - { - LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE, - false, - LLImageBase::TYPE_AVATAR_BAKE == mType, - LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime); - mMetricsStartTime = 0; - } - LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE, - false, - LLImageBase::TYPE_AVATAR_BAKE == mType); + recordTextureDone(false); } else { mFetcher->addToNetworkQueue(this); // failsafe - if (! mMetricsStartTime) - { - mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); - } - LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, - false, - LLImageBase::TYPE_AVATAR_BAKE == mType); setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); + recordTextureStart(false); } return false; } + if (mState == WAIT_HTTP_RESOURCE) + { + // NOTE: + // control the number of the http requests issued for: + // 1, not openning too many file descriptors at the same time; + // 2, control the traffic of http so udp gets bandwidth. + // + // If it looks like we're busy, keep this request here. + // Otherwise, advance into the HTTP states. + if (mFetcher->getHttpWaitersCount() || ! acquireHttpSemaphore()) + { + mState = WAIT_HTTP_RESOURCE2; + setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); + mFetcher->addHttpWaiter(this->mID); + ++mResourceWaitCount; + return false; + } + + mState = SEND_HTTP_REQ; + // *NOTE: You must invoke releaseHttpSemaphore() if you transition + // to a state other than SEND_HTTP_REQ or WAIT_HTTP_REQ or abort + // the request. + } + + if (mState == WAIT_HTTP_RESOURCE2) + { + // Just idle it if we make it to the head... + return false; + } + if (mState == SEND_HTTP_REQ) { - if(mCanUseHTTP) + if (! mCanUseHTTP) { - //NOTE: - //control the number of the http requests issued for: - //1, not openning too many file descriptors at the same time; - //2, control the traffic of http so udp gets bandwidth. - // - static const S32 MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE = 8 ; - if(mFetcher->getNumHTTPRequests() > MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE) - { - return false ; //wait. - } + releaseHttpSemaphore(); + return true; // abort + } - mFetcher->removeFromNetworkQueue(this, false); + mFetcher->removeFromNetworkQueue(this, false); - S32 cur_size = 0; - if (mFormattedImage.notNull()) + S32 cur_size = 0; + if (mFormattedImage.notNull()) + { + cur_size = mFormattedImage->getDataSize(); // amount of data we already have + if (mFormattedImage->getDiscardLevel() == 0) { - cur_size = mFormattedImage->getDataSize(); // amount of data we already have - if (mFormattedImage->getDiscardLevel() == 0) + if (cur_size > 0) { - if(cur_size > 0) - { - // We already have all the data, just decode it - mLoadedDiscard = mFormattedImage->getDiscardLevel(); - mState = DECODE_IMAGE; - return false; - } - else - { - return true ; //abort. - } + // We already have all the data, just decode it + mLoadedDiscard = mFormattedImage->getDiscardLevel(); + setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); + mState = DECODE_IMAGE; + releaseHttpSemaphore(); + return false; } - } - mRequestedSize = mDesiredSize; - mRequestedDiscard = mDesiredDiscard; - mRequestedSize -= cur_size; - S32 offset = cur_size; - mBufferSize = cur_size; // This will get modified by callbackHttpGet() - - bool res = false; - if (!mUrl.empty()) - { - mLoaded = FALSE; - mGetStatus = 0; - mGetReason.clear(); - LL_DEBUGS("Texture") << "HTTP GET: " << mID << " Offset: " << offset - << " Bytes: " << mRequestedSize - << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << mFetcher->mMaxBandwidth - << LL_ENDL; - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); - mState = WAIT_HTTP_REQ; - - mFetcher->addToHTTPQueue(mID); - if (! mMetricsStartTime) + else { - mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); + releaseHttpSemaphore(); + return true; // abort. } - LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, - true, - LLImageBase::TYPE_AVATAR_BAKE == mType); - - // Will call callbackHttpGet when curl request completes - std::vector<std::string> headers; - headers.push_back("Accept: image/x-j2c"); - res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize, - new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true)); } - if (!res) - { - llwarns << "HTTP GET request failed for " << mID << llendl; - resetFormattedData(); - ++mHTTPFailCount; - return true; // failed - } - // fall through } - else //can not use http fetch. + mRequestedSize = mDesiredSize; + mRequestedDiscard = mDesiredDiscard; + mRequestedSize -= cur_size; + mRequestedOffset = cur_size; + if (mRequestedOffset) { - return true ; //abort + // Texture fetching often issues 'speculative' loads that + // start beyond the end of the actual asset. Some cache/web + // systems, e.g. Varnish, will respond to this not with a + // 416 but with a 200 and the entire asset in the response + // body. By ensuring that we always have a partially + // satisfiable Range request, we avoid that hit to the network. + // We just have to deal with the overlapping data which is made + // somewhat harder by the fact that grid services don't necessarily + // return the Content-Range header on 206 responses. *Sigh* + mRequestedOffset -= 1; + mRequestedSize += 1; } + + mHttpHandle = LLCORE_HTTP_HANDLE_INVALID; + if (!mUrl.empty()) + { + mRequestedTimer.reset(); + mLoaded = FALSE; + mGetStatus = LLCore::HttpStatus(); + mGetReason.clear(); + LL_DEBUGS("Texture") << "HTTP GET: " << mID << " Offset: " << mRequestedOffset + << " Bytes: " << mRequestedSize + << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << mFetcher->mMaxBandwidth + << LL_ENDL; + + // Will call callbackHttpGet when curl request completes + mHttpHandle = mFetcher->mHttpRequest->requestGetByteRange(mHttpPolicyClass, + mWorkPriority, + mUrl, + mRequestedOffset, + mRequestedSize, + mFetcher->mHttpOptions, + mFetcher->mHttpHeaders, + this); + } + if (LLCORE_HTTP_HANDLE_INVALID == mHttpHandle) + { + llwarns << "HTTP GET request failed for " << mID << llendl; + resetFormattedData(); + releaseHttpSemaphore(); + return true; // failed + } + + mHttpActive = true; + mFetcher->addToHTTPQueue(mID); + recordTextureStart(true); + setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); + mState = WAIT_HTTP_REQ; + + // fall through } if (mState == WAIT_HTTP_REQ) { + // *NOTE: As stated above, all transitions out of this state should + // call releaseHttpSemaphore(). if (mLoaded) { S32 cur_size = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0; if (mRequestedSize < 0) { - S32 max_attempts; - if (mGetStatus == HTTP_NOT_FOUND) + if (http_not_found == mGetStatus) { - mHTTPFailCount = max_attempts = 1; // Don't retry + if(mWriteToCacheState == NOT_WRITE) //map tiles + { + mState = DONE; + releaseHttpSemaphore(); + return true; // failed, means no map tile on the empty region. + } + llwarns << "Texture missing from server (404): " << mUrl << llendl; - //roll back to try UDP - if(mCanUseNET) + // roll back to try UDP + if (mCanUseNET) { - mState = INIT ; - mCanUseHTTP = false ; + mState = INIT; + mCanUseHTTP = false; + mUrl.clear(); setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); - return false ; + releaseHttpSemaphore(); + return false; } } - else if (mGetStatus == HTTP_SERVICE_UNAVAILABLE) + else if (http_service_unavail == mGetStatus) { - // *TODO: Should probably introduce a timer here to delay future HTTP requsts - // for a short time (~1s) to ease server load? Ideally the server would queue - // requests instead of returning 503... we already limit the number pending. - ++mHTTPFailCount; - max_attempts = mHTTPFailCount+1; // Keep retrying LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL; } + else if (http_not_sat == mGetStatus) + { + // Allowed, we'll accept whatever data we have as complete. + mHaveAllData = TRUE; + } else { - const S32 HTTP_MAX_RETRY_COUNT = 3; - max_attempts = HTTP_MAX_RETRY_COUNT + 1; - ++mHTTPFailCount; llinfos << "HTTP GET failed for: " << mUrl - << " Status: " << mGetStatus << " Reason: '" << mGetReason << "'" - << " Attempt:" << mHTTPFailCount+1 << "/" << max_attempts << llendl; + << " Status: " << mGetStatus.toHex() + << " Reason: '" << mGetReason << "'" + << llendl; } - if (mHTTPFailCount >= max_attempts) + mUrl.clear(); + if (cur_size > 0) { - if (cur_size > 0) - { - // Use available data - mLoadedDiscard = mFormattedImage->getDiscardLevel(); - mState = DECODE_IMAGE; - return false; - } - else - { - resetFormattedData(); - mState = DONE; - return true; // failed - } - } - else - { - mState = SEND_HTTP_REQ; - return false; // retry + // Use available data + mLoadedDiscard = mFormattedImage->getDiscardLevel(); + setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); + mState = DECODE_IMAGE; + releaseHttpSemaphore(); + return false; } + + // Fail harder + resetFormattedData(); + mState = DONE; + releaseHttpSemaphore(); + return true; // failed + } + + // Clear the url since we're done with the fetch + // Note: mUrl is used to check is fetching is required so failure to clear it will force an http fetch + // next time the texture is requested, even if the data have already been fetched. + if(mWriteToCacheState != NOT_WRITE) + { + mUrl.clear(); } - llassert_always(mBufferSize == cur_size + mRequestedSize); - if(!mBufferSize)//no data received. + if (! mHttpBufferArray || ! mHttpBufferArray->size()) { - FREE_MEM(LLImageBase::getPrivatePool(), mBuffer); - mBuffer = NULL; + // no data received. + if (mHttpBufferArray) + { + mHttpBufferArray->release(); + mHttpBufferArray = NULL; + } - //abort. + // abort. mState = DONE; + releaseHttpSemaphore(); return true; } + S32 append_size(mHttpBufferArray->size()); + S32 total_size(cur_size + append_size); + S32 src_offset(0); + llassert_always(append_size == mRequestedSize); + if (mHttpReplyOffset && mHttpReplyOffset != cur_size) + { + // In case of a partial response, our offset may + // not be trivially contiguous with the data we have. + // Get back into alignment. + if (mHttpReplyOffset > cur_size) + { + LL_WARNS("Texture") << "Partial HTTP response produces break in image data for texture " + << mID << ". Aborting load." << LL_ENDL; + mState = DONE; + releaseHttpSemaphore(); + return true; + } + src_offset = cur_size - mHttpReplyOffset; + append_size -= src_offset; + total_size -= src_offset; + mRequestedSize -= src_offset; // Make requested values reflect useful part + mRequestedOffset += src_offset; + } + if (mFormattedImage.isNull()) { // For now, create formatted image based on extension @@ -1303,38 +1600,50 @@ bool LLTextureFetchWorker::doWork(S32 param) } } - if (mHaveAllData && mRequestedDiscard == 0) //the image file is fully loaded. + if (mHaveAllData) //the image file is fully loaded. { - mFileSize = mBufferSize; + mFileSize = total_size; } else //the file size is unknown. { - mFileSize = mBufferSize + 1 ; //flag the file is not fully loaded. + mFileSize = total_size + 1 ; //flag the file is not fully loaded. } - U8* buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mBufferSize); + U8 * buffer = (U8 *) ALLOCATE_MEM(LLImageBase::getPrivatePool(), total_size); if (cur_size > 0) { memcpy(buffer, mFormattedImage->getData(), cur_size); } - memcpy(buffer + cur_size, mBuffer, mRequestedSize); // append + mHttpBufferArray->read(src_offset, (char *) buffer + cur_size, append_size); + // NOTE: setData releases current data and owns new data (buffer) - mFormattedImage->setData(buffer, mBufferSize); - // delete temp data - FREE_MEM(LLImageBase::getPrivatePool(), mBuffer); // Note: not 'buffer' (assigned in setData()) - mBuffer = NULL; - mBufferSize = 0; + mFormattedImage->setData(buffer, total_size); + + // Done with buffer array + mHttpBufferArray->release(); + mHttpBufferArray = NULL; + mHttpReplySize = 0; + mHttpReplyOffset = 0; + mLoadedDiscard = mRequestedDiscard; mState = DECODE_IMAGE; - if(mWriteToCacheState != NOT_WRITE) + if (mWriteToCacheState != NOT_WRITE) { mWriteToCacheState = SHOULD_WRITE ; } setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); + releaseHttpSemaphore(); return false; } else { + // *HISTORY: There was a texture timeout test here originally that + // would cancel a request that was over 120 seconds old. That's + // probably not a good idea. Particularly rich regions can take + // an enormous amount of time to load textures. We'll revisit the + // various possible timeout components (total request time, connection + // time, I/O time, with and without retries, etc.) in the future. + setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return false; } @@ -1343,11 +1652,12 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == DECODE_IMAGE) { static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled"); - if(textures_decode_disabled) + + setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it + if (textures_decode_disabled) { // for debug use, don't decode mState = DONE; - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return true; } @@ -1355,7 +1665,6 @@ bool LLTextureFetchWorker::doWork(S32 param) { // We aborted, don't decode mState = DONE; - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return true; } @@ -1365,7 +1674,6 @@ bool LLTextureFetchWorker::doWork(S32 param) //abort, don't decode mState = DONE; - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return true; } if (mLoadedDiscard < 0) @@ -1374,10 +1682,9 @@ bool LLTextureFetchWorker::doWork(S32 param) //abort, don't decode mState = DONE; - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return true; } - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it + mRawImage = NULL; mAuxImage = NULL; llassert_always(mFormattedImage.notNull()); @@ -1396,6 +1703,11 @@ bool LLTextureFetchWorker::doWork(S32 param) { if (mDecoded) { + if(mFetcher->getFetchDebugger() && !mInLocalCache) + { + mFetcher->getFetchDebugger()->addHistoryEntry(this); + } + if (mDecodedDiscard < 0) { LL_DEBUGS("Texture") << mID << ": Failed to Decode." << LL_ENDL; @@ -1458,10 +1770,11 @@ bool LLTextureFetchWorker::doWork(S32 param) U32 cache_priority = mWorkPriority; mWritten = FALSE; mState = WAIT_ON_WRITE; + ++mCacheWriteCount; CacheWriteResponder* responder = new CacheWriteResponder(mFetcher, mID); mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority, mFormattedImage->getData(), datasize, - mFileSize, responder); + mFileSize, mRawImage, mDecodedDiscard, responder); // fall through } @@ -1502,9 +1815,84 @@ bool LLTextureFetchWorker::doWork(S32 param) } return false; -} +} // -Mw + +// Threads: Ttf +// virtual +void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) +{ + static LLCachedControl<bool> log_to_viewer_log(gSavedSettings, "LogTextureDownloadsToViewerLog"); + static LLCachedControl<bool> log_to_sim(gSavedSettings, "LogTextureDownloadsToSimulator"); + static LLCachedControl<bool> log_texture_traffic(gSavedSettings, "LogTextureNetworkTraffic") ; + + LLMutexLock lock(&mWorkMutex); // +Mw + + mHttpActive = false; + + if (log_to_viewer_log || log_to_sim) + { + U64 timeNow = LLTimer::getTotalTime(); + mFetcher->mTextureInfo.setRequestStartTime(mID, mMetricsStartTime); + mFetcher->mTextureInfo.setRequestType(mID, LLTextureInfoDetails::REQUEST_TYPE_HTTP); + mFetcher->mTextureInfo.setRequestSize(mID, mRequestedSize); + mFetcher->mTextureInfo.setRequestOffset(mID, mRequestedOffset); + mFetcher->mTextureInfo.setRequestCompleteTimeAndLog(mID, timeNow); + } -// Called from MAIN thread + bool success = true; + bool partial = false; + LLCore::HttpStatus status(response->getStatus()); + + lldebugs << "HTTP COMPLETE: " << mID + << " status: " << status.toHex() + << " '" << status.toString() << "'" + << llendl; +// unsigned int offset(0), length(0), full_length(0); +// response->getRange(&offset, &length, &full_length); +// llwarns << "HTTP COMPLETE: " << mID << " handle: " << handle +// << " status: " << status.toULong() << " '" << status.toString() << "'" +// << " req offset: " << mRequestedOffset << " req length: " << mRequestedSize +// << " offset: " << offset << " length: " << length +// << llendl; + + if (! status) + { + success = false; + std::string reason(status.toString()); + setGetStatus(status, reason); + llwarns << "CURL GET FAILED, status: " << status.toHex() + << " reason: " << reason << llendl; + } + else + { + // A warning about partial (HTTP 206) data. Some grid services + // do *not* return a 'Content-Range' header in the response to + // Range requests with a 206 status. We're forced to assume + // we get what we asked for in these cases until we can fix + // the services. + static const LLCore::HttpStatus par_status(HTTP_PARTIAL_CONTENT); + + partial = (par_status == status); + } + + S32 data_size = callbackHttpGet(response, partial, success); + + if (log_texture_traffic && data_size > 0) + { + LLViewerTexture* tex = LLViewerTextureManager::findTexture(mID); + if (tex) + { + gTotalTextureBytesPerBoostLevel[tex->getBoostLevel()] += data_size ; + } + } + + mFetcher->removeFromHTTPQueue(mID, data_size); + + recordTextureDone(true); +} // -Mw + + +// Threads: Tmain void LLTextureFetchWorker::endWork(S32 param, bool aborted) { if (mDecodeHandle != 0) @@ -1517,6 +1905,8 @@ void LLTextureFetchWorker::endWork(S32 param, bool aborted) ////////////////////////////////////////////////////////////////////////////// +// Threads: Ttf + // virtual void LLTextureFetchWorker::finishWork(S32 param, bool completed) { @@ -1533,10 +1923,37 @@ void LLTextureFetchWorker::finishWork(S32 param, bool completed) } } +// LLQueuedThread's update() method is asking if it's okay to +// delete this worker. You'll notice we're not locking in here +// which is a slight concern. Caller is expected to have made +// this request 'quiet' by whatever means... +// +// Threads: Tmain + // virtual bool LLTextureFetchWorker::deleteOK() { bool delete_ok = true; + + if (mHttpActive) + { + // HTTP library has a pointer to this worker + // and will dereference it to do notification. + delete_ok = false; + } + + if (WAIT_HTTP_RESOURCE2 == mState) + { + if (mFetcher->isHttpWaiter(mID)) + { + // Don't delete the worker out from under the releaseHttpWaiters() + // method. Keep the pointers valid, clean up after that method + // has recognized the cancelation and removed the UUID from the + // waiter list. + delete_ok = false; + } + } + // Allow any pending reads or writes to complete if (mCacheReadHandle != LLTextureCache::nullHandle()) { @@ -1571,6 +1988,7 @@ bool LLTextureFetchWorker::deleteOK() return delete_ok; } +// Threads: Ttf void LLTextureFetchWorker::removeFromCache() { if (!mInLocalCache) @@ -1582,6 +2000,8 @@ void LLTextureFetchWorker::removeFromCache() ////////////////////////////////////////////////////////////////////////////// +// Threads: Ttf +// Locks: Mw bool LLTextureFetchWorker::processSimulatorPackets() { if (mFormattedImage.isNull() || mRequestedSize < 0) @@ -1642,14 +2062,13 @@ bool LLTextureFetchWorker::processSimulatorPackets() ////////////////////////////////////////////////////////////////////////////// -S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer, - bool partial, bool success) +// Threads: Ttf +// Locks: Mw +S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response, + bool partial, bool success) { S32 data_size = 0 ; - LLMutexLock lock(&mWorkMutex); - if (mState != WAIT_HTTP_REQ) { llwarns << "callbackHttpGet for unrequested fetch worker: " << mID @@ -1664,27 +2083,69 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, if (success) { // get length of stream: - data_size = buffer->countAfter(channels.in(), NULL); - + LLCore::BufferArray * body(response->getBody()); + data_size = body ? body->size() : 0; + LL_DEBUGS("Texture") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << LL_ENDL; if (data_size > 0) { + LLViewerStatsRecorder::instance().textureFetch(data_size); // *TODO: set the formatted image data here directly to avoid the copy - mBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size); - buffer->readAfter(channels.in(), NULL, mBuffer, data_size); - mBufferSize += data_size; - if (data_size < mRequestedSize && mRequestedDiscard == 0) + + // Hold on to body for later copy + llassert_always(NULL == mHttpBufferArray); + body->addRef(); + mHttpBufferArray = body; + + if (partial) + { + unsigned int offset(0), length(0), full_length(0); + response->getRange(&offset, &length, &full_length); + if (! offset && ! length) + { + // This is the case where we receive a 206 status but + // there wasn't a useful Content-Range header in the response. + // This could be because it was badly formatted but is more + // likely due to capabilities services which scrub headers + // from responses. Assume we got what we asked for... + mHttpReplySize = data_size; + mHttpReplyOffset = mRequestedOffset; + } + else + { + mHttpReplySize = length; + mHttpReplyOffset = offset; + } + } + + if (! partial) + { + // Response indicates this is the entire asset regardless + // of our asking for a byte range. Mark it so and drop + // any partial data we might have so that the current + // response body becomes the entire dataset. + if (data_size <= mRequestedOffset) + { + LL_WARNS("Texture") << "Fetched entire texture " << mID + << " when it was expected to be marked complete. mImageSize: " + << mFileSize << " datasize: " << mFormattedImage->getDataSize() + << LL_ENDL; + } + mHaveAllData = TRUE; + llassert_always(mDecodeHandle == 0); + mFormattedImage = NULL; // discard any previous data we had + } + else if (data_size < mRequestedSize) { mHaveAllData = TRUE; } else if (data_size > mRequestedSize) { - // *TODO: This shouldn't be happening any more + // *TODO: This shouldn't be happening any more (REALLY don't expect this anymore) llwarns << "data_size = " << data_size << " > requested: " << mRequestedSize << llendl; mHaveAllData = TRUE; llassert_always(mDecodeHandle == 0); mFormattedImage = NULL; // discard any previous data we had - mBufferSize = data_size; } } else @@ -1699,18 +2160,21 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, { mRequestedSize = -1; // error } + mLoaded = TRUE; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); + LLViewerStatsRecorder::instance().log(0.2f); return data_size ; } ////////////////////////////////////////////////////////////////////////////// +// Threads: Ttc void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* image, S32 imagesize, BOOL islocal) { - LLMutexLock lock(&mWorkMutex); + LLMutexLock lock(&mWorkMutex); // +Mw if (mState != LOAD_FROM_TEXTURE_CACHE) { // llwarns << "Read callback for " << mID << " with state = " << mState << llendl; @@ -1730,11 +2194,12 @@ void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* ima } mLoaded = TRUE; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); -} +} // -Mw +// Threads: Ttc void LLTextureFetchWorker::callbackCacheWrite(bool success) { - LLMutexLock lock(&mWorkMutex); + LLMutexLock lock(&mWorkMutex); // +Mw if (mState != WAIT_ON_WRITE) { // llwarns << "Write callback for " << mID << " with state = " << mState << llendl; @@ -1742,13 +2207,14 @@ void LLTextureFetchWorker::callbackCacheWrite(bool success) } mWritten = TRUE; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); -} +} // -Mw ////////////////////////////////////////////////////////////////////////////// +// Threads: Tid void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux) { - LLMutexLock lock(&mWorkMutex); + LLMutexLock lock(&mWorkMutex); // +Mw if (mDecodeHandle == 0) { return; // aborted, ignore @@ -1780,10 +2246,12 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag mDecoded = TRUE; // llinfos << mID << " : DECODE COMPLETE " << llendl; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); -} + mCacheReadTime = mCacheReadTimer.getElapsedTimeF32(); +} // -Mw ////////////////////////////////////////////////////////////////////////////// +// Threads: Ttf bool LLTextureFetchWorker::writeToCacheComplete() { // Complete write to cache @@ -1806,6 +2274,36 @@ bool LLTextureFetchWorker::writeToCacheComplete() } +// Threads: Ttf +void LLTextureFetchWorker::recordTextureStart(bool is_http) +{ + if (! mMetricsStartTime) + { + mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); + } + LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, + is_http, + LLImageBase::TYPE_AVATAR_BAKE == mType); +} + + +// Threads: Ttf +void LLTextureFetchWorker::recordTextureDone(bool is_http) +{ + if (mMetricsStartTime) + { + LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE, + is_http, + LLImageBase::TYPE_AVATAR_BAKE == mType, + LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime); + mMetricsStartTime = 0; + } + LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE, + is_http, + LLImageBase::TYPE_AVATAR_BAKE == mType); +} + + ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // public @@ -1823,17 +2321,49 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image mTextureBandwidth(0), mHTTPTextureBits(0), mTotalHTTPRequests(0), - mCurlGetRequest(NULL), - mQAMode(qa_mode) + mQAMode(qa_mode), + mHttpRequest(NULL), + mHttpOptions(NULL), + mHttpHeaders(NULL), + mHttpMetricsHeaders(NULL), + mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), + mHttpSemaphore(HTTP_REQUESTS_IN_QUEUE_HIGH_WATER), + mTotalCacheReadCount(0U), + mTotalCacheWriteCount(0U), + mTotalResourceWaitCount(0U), + mFetchDebugger(NULL), + mFetchSource(LLTextureFetch::FROM_ALL), + mOriginFetchSource(LLTextureFetch::FROM_ALL), + mFetcherLocked(FALSE) { - mCurlPOSTRequestCount = 0; mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS"); mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold")); + + LLTextureFetchDebugger::sDebuggerEnabled = gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"); + if(LLTextureFetchDebugger::isEnabled()) + { + mFetchDebugger = new LLTextureFetchDebugger(this, cache, imagedecodethread) ; + mFetchSource = (e_tex_source)gSavedSettings.getS32("TextureFetchSource"); + if(mFetchSource < 0 && mFetchSource >= INVALID_SOURCE) + { + mFetchSource = LLTextureFetch::FROM_ALL; + gSavedSettings.setS32("TextureFetchSource", 0); + } + mOriginFetchSource = mFetchSource; + } + + mHttpRequest = new LLCore::HttpRequest; + mHttpOptions = new LLCore::HttpOptions; + mHttpHeaders = new LLCore::HttpHeaders; + mHttpHeaders->mHeaders.push_back("Accept: image/x-j2c"); + mHttpMetricsHeaders = new LLCore::HttpHeaders; + mHttpMetricsHeaders->mHeaders.push_back("Content-Type: application/llsd+xml"); + mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicyDefault(); } LLTextureFetch::~LLTextureFetch() { - clearDeleteList() ; + clearDeleteList(); while (! mCommands.empty()) { @@ -1841,6 +2371,32 @@ LLTextureFetch::~LLTextureFetch() mCommands.erase(mCommands.begin()); delete req; } + + if (mHttpOptions) + { + mHttpOptions->release(); + mHttpOptions = NULL; + } + + if (mHttpHeaders) + { + mHttpHeaders->release(); + mHttpHeaders = NULL; + } + + if (mHttpMetricsHeaders) + { + mHttpMetricsHeaders->release(); + mHttpMetricsHeaders = NULL; + } + + mHttpWaitResource.clear(); + + delete mHttpRequest; + mHttpRequest = NULL; + + delete mFetchDebugger; + mFetchDebugger = NULL; // ~LLQueuedThread() called here } @@ -1848,6 +2404,10 @@ LLTextureFetch::~LLTextureFetch() bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http) { + if(mFetcherLocked) + { + return false; + } if (mDebugPause) { return false; @@ -1891,6 +2451,8 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con } else { + // If the requester knows nothing about the file, we fetch the smallest + // amount of data at the lowest resolution (highest discard level) possible. desired_size = TEXTURE_CACHE_ENTRY_SIZE; desired_discard = MAX_DISCARD_LEVEL; } @@ -1902,7 +2464,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con { return false; // need to wait for previous aborted request to complete } - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw worker->mActiveCount++; worker->mNeedsAux = needs_aux; worker->setImagePriority(priority); @@ -1911,41 +2473,44 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con if (!worker->haveWork()) { worker->mState = LLTextureFetchWorker::INIT; - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); } else { - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw } } else { worker = new LLTextureFetchWorker(this, url, id, host, priority, desired_discard, desired_size); - lockQueue() ; + lockQueue(); // +Mfq mRequestMap[id] = worker; - unlockQueue() ; + unlockQueue(); // -Mfq - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw worker->mActiveCount++; worker->mNeedsAux = needs_aux; worker->setCanUseHTTP(can_use_http) ; - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw } // llinfos << "REQUESTED: " << id << " Discard: " << desired_discard << llendl; return true; } + +// Threads: T* (but Ttf in practice) + // protected void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker) { - lockQueue() ; + lockQueue(); // +Mfq bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ; - unlockQueue() ; + unlockQueue(); // -Mfq - LLMutexLock lock(&mNetworkQueueMutex); + LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq if (in_request_map) { // only add to the queue if in the request map @@ -1957,44 +2522,52 @@ void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker) { iter1->second.erase(worker->mID); } -} +} // -Mfnq +// Threads: T* void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel) { - LLMutexLock lock(&mNetworkQueueMutex); + LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq size_t erased = mNetworkQueue.erase(worker->mID); if (cancel && erased > 0) { mCancelQueue[worker->mHost].insert(worker->mID); } -} +} // -Mfnq +// Threads: T* +// // protected void LLTextureFetch::addToHTTPQueue(const LLUUID& id) { - LLMutexLock lock(&mNetworkQueueMutex); + LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq mHTTPTextureQueue.insert(id); mTotalHTTPRequests++; -} +} // -Mfnq +// Threads: T* void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32 received_size) { - LLMutexLock lock(&mNetworkQueueMutex); + LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq mHTTPTextureQueue.erase(id); mHTTPTextureBits += received_size * 8; // Approximate - does not include header bits -} +} // -Mfnq +// NB: If you change deleteRequest() you should probably make +// parallel changes in removeRequest(). They're functionally +// identical with only argument variations. +// +// Threads: T* void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) { - lockQueue() ; + lockQueue(); // +Mfq LLTextureFetchWorker* worker = getWorkerAfterLock(id); if (worker) { size_t erased_1 = mRequestMap.erase(worker->mID); - unlockQueue() ; + unlockQueue(); // -Mfq llassert_always(erased_1 > 0) ; - removeFromNetworkQueue(worker, cancel); llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; @@ -2002,15 +2575,25 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) } else { - unlockQueue() ; + unlockQueue(); // -Mfq } } +// NB: If you change removeRequest() you should probably make +// parallel changes in deleteRequest(). They're functionally +// identical with only argument variations. +// +// Threads: T* void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) { - lockQueue() ; + if(!worker) + { + return; + } + + lockQueue(); // +Mfq size_t erased_1 = mRequestMap.erase(worker->mID); - unlockQueue() ; + unlockQueue(); // -Mfq llassert_always(erased_1 > 0) ; removeFromNetworkQueue(worker, cancel); @@ -2019,34 +2602,57 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) worker->scheduleDelete(); } +void LLTextureFetch::deleteAllRequests() +{ + while(1) + { + lockQueue(); + if(mRequestMap.empty()) + { + unlockQueue() ; + break; + } + + LLTextureFetchWorker* worker = mRequestMap.begin()->second; + unlockQueue() ; + + removeRequest(worker, true); + } +} + +// Threads: T* S32 LLTextureFetch::getNumRequests() { - lockQueue() ; + lockQueue(); // +Mfq S32 size = (S32)mRequestMap.size(); - unlockQueue() ; + unlockQueue(); // -Mfq - return size ; + return size; } +// Threads: T* S32 LLTextureFetch::getNumHTTPRequests() { - mNetworkQueueMutex.lock() ; + mNetworkQueueMutex.lock(); // +Mfq S32 size = (S32)mHTTPTextureQueue.size(); - mNetworkQueueMutex.unlock() ; + mNetworkQueueMutex.unlock(); // -Mfq - return size ; + return size; } +// Threads: T* U32 LLTextureFetch::getTotalNumHTTPRequests() { - mNetworkQueueMutex.lock() ; - U32 size = mTotalHTTPRequests ; - mNetworkQueueMutex.unlock() ; + mNetworkQueueMutex.lock(); // +Mfq + U32 size = mTotalHTTPRequests; + mNetworkQueueMutex.unlock(); // -Mfq - return size ; + return size; } // call lockQueue() first! +// Threads: T* +// Locks: Mfq LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id) { LLTextureFetchWorker* res = NULL; @@ -2058,14 +2664,16 @@ LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id) return res; } +// Threads: T* LLTextureFetchWorker* LLTextureFetch::getWorker(const LLUUID& id) { - LLMutexLock lock(&mQueueMutex) ; + LLMutexLock lock(&mQueueMutex); // +Mfq - return getWorkerAfterLock(id) ; -} + return getWorkerAfterLock(id); +} // -Mfq +// Threads: T* bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux) { @@ -2088,17 +2696,22 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, } else if (worker->checkWork()) { - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw discard_level = worker->mDecodedDiscard; raw = worker->mRawImage; aux = worker->mAuxImage; + F32 cache_read_time = worker->mCacheReadTime; + if (cache_read_time != 0.f) + { + sCacheReadLatency.addValue(cache_read_time * 1000.f); + } res = true; LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL; - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw } else { - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw if ((worker->mDecodedDiscard >= 0) && (worker->mDecodedDiscard < discard_level || discard_level < 0) && (worker->mState >= LLTextureFetchWorker::WAIT_ON_WRITE)) @@ -2108,7 +2721,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, raw = worker->mRawImage; aux = worker->mAuxImage; } - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw } } else @@ -2118,15 +2731,16 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, return res; } +// Threads: T* bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority) { bool res = false; LLTextureFetchWorker* worker = getWorker(id); if (worker) { - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw worker->setImagePriority(priority); - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw res = true; } return res; @@ -2141,24 +2755,24 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority) // in step, at least until this can be refactored and // the redundancy eliminated. // -// May be called from any thread +// Threads: T* //virtual S32 LLTextureFetch::getPending() { S32 res; - lockData(); + lockData(); // +Ct { - LLMutexLock lock(&mQueueMutex); + LLMutexLock lock(&mQueueMutex); // +Mfq res = mRequestQueue.size(); - res += mCurlPOSTRequestCount; res += mCommands.size(); - } - unlockData(); + } // -Mfq + unlockData(); // -Ct return res; } +// Locks: Ct // virtual bool LLTextureFetch::runCondition() { @@ -2173,56 +2787,65 @@ bool LLTextureFetch::runCondition() bool have_no_commands(false); { - LLMutexLock lock(&mQueueMutex); + LLMutexLock lock(&mQueueMutex); // +Mfq have_no_commands = mCommands.empty(); - } - - bool have_no_curl_requests(0 == mCurlPOSTRequestCount); + } // -Mfq return ! (have_no_commands - && have_no_curl_requests && (mRequestQueue.empty() && mIdleThread)); // From base class } ////////////////////////////////////////////////////////////////////////////// -// MAIN THREAD (unthreaded envs), WORKER THREAD (threaded envs) +// Threads: Ttf void LLTextureFetch::commonUpdate() { + // Release waiters + releaseHttpWaiters(); + // Run a cross-thread command, if any. cmdDoWork(); - // Update Curl on same thread as mCurlGetRequest was constructed - S32 processed = mCurlGetRequest->process(); - if (processed > 0) + // Deliver all completion notifications + LLCore::HttpStatus status = mHttpRequest->update(0); + if (! status) { - lldebugs << "processed: " << processed << " messages." << llendl; + LL_INFOS_ONCE("Texture") << "Problem during HTTP servicing. Reason: " + << status.toString() + << LL_ENDL; } } -// MAIN THREAD +// Threads: Tmain + //virtual -S32 LLTextureFetch::update(U32 max_time_ms) +S32 LLTextureFetch::update(F32 max_time_ms) { static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS"); { - mNetworkQueueMutex.lock() ; - mMaxBandwidth = band_width ; + mNetworkQueueMutex.lock(); // +Mfnq + mMaxBandwidth = band_width; - gTextureList.sTextureBits += mHTTPTextureBits ; - mHTTPTextureBits = 0 ; + gTextureList.sTextureBits += mHTTPTextureBits; + mHTTPTextureBits = 0; - mNetworkQueueMutex.unlock() ; + mNetworkQueueMutex.unlock(); // -Mfnq } S32 res = LLWorkerThread::update(max_time_ms); if (!mDebugPause) { - sendRequestListToSimulators(); + // this is the startup state when send_complete_agent_movement() message is sent. + // Before this, the RequestImages message sent by sendRequestListToSimulators + // won't work so don't bother trying + if (LLStartUp::getStartupState() > STATE_AGENT_SEND) + { + sendRequestListToSimulators(); + } } if (!mThreaded) @@ -2230,10 +2853,17 @@ S32 LLTextureFetch::update(U32 max_time_ms) commonUpdate(); } + if (mFetchDebugger) + { + mFetchDebugger->tryToStopDebug(); //check if need to stop debugger. + } + return res; } -//called in the MAIN thread after the TextureCacheThread shuts down. +// called in the MAIN thread after the TextureCacheThread shuts down. +// +// Threads: Tmain void LLTextureFetch::shutDownTextureCacheThread() { if(mTextureCache) @@ -2243,7 +2873,9 @@ void LLTextureFetch::shutDownTextureCacheThread() } } -//called in the MAIN thread after the ImageDecodeThread shuts down. +// called in the MAIN thread after the ImageDecodeThread shuts down. +// +// Threads: Tmain void LLTextureFetch::shutDownImageDecodeThread() { if(mImageDecodeThread) @@ -2253,26 +2885,27 @@ void LLTextureFetch::shutDownImageDecodeThread() } } -// WORKER THREAD +// Threads: Ttf void LLTextureFetch::startThread() { - // Construct mCurlGetRequest from Worker Thread - mCurlGetRequest = new LLCurlRequest(); } -// WORKER THREAD +// Threads: Ttf void LLTextureFetch::endThread() { - // Destroy mCurlGetRequest from Worker Thread - delete mCurlGetRequest; - mCurlGetRequest = NULL; + LL_INFOS("Texture") << "CacheReads: " << mTotalCacheReadCount + << ", CacheWrites: " << mTotalCacheWriteCount + << ", ResWaits: " << mTotalResourceWaitCount + << ", TotalHTTPReq: " << getTotalNumHTTPRequests() + << LL_ENDL; } -// WORKER THREAD +// Threads: Ttf void LLTextureFetch::threadedUpdate() { - llassert_always(mCurlGetRequest); - + llassert_always(mHttpRequest); + +#if 0 // Limit update frequency const F32 PROCESS_TIME = 0.05f; static LLFrameTimer process_timer; @@ -2281,9 +2914,10 @@ void LLTextureFetch::threadedUpdate() return; } process_timer.reset(); +#endif commonUpdate(); - + #if 0 const F32 INFO_TIME = 1.0f; static LLFrameTimer info_timer; @@ -2297,11 +2931,11 @@ void LLTextureFetch::threadedUpdate() } } #endif - } ////////////////////////////////////////////////////////////////////////////// +// Threads: Tmain void LLTextureFetch::sendRequestListToSimulators() { // All requests @@ -2327,48 +2961,48 @@ void LLTextureFetch::sendRequestListToSimulators() typedef std::map< LLHost, request_list_t > work_request_map_t; work_request_map_t requests; { - LLMutexLock lock2(&mNetworkQueueMutex); - for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); ) - { - queue_t::iterator curiter = iter++; - LLTextureFetchWorker* req = getWorker(*curiter); - if (!req) + LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq + for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); ) { - mNetworkQueue.erase(curiter); - continue; // paranoia - } - if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) && - (req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR)) - { - // We already received our URL, remove from the queue - llwarns << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << llendl; - mNetworkQueue.erase(curiter); - continue; - } - if (req->mID == mDebugID) - { - mDebugCount++; // for setting breakpoints - } - if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM && - req->mTotalPackets > 0 && - req->mLastPacket >= req->mTotalPackets-1) - { - // We have all the packets... make sure this is high priority + queue_t::iterator curiter = iter++; + LLTextureFetchWorker* req = getWorker(*curiter); + if (!req) + { + mNetworkQueue.erase(curiter); + continue; // paranoia + } + if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) && + (req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR)) + { + // We already received our URL, remove from the queue + llwarns << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << llendl; + mNetworkQueue.erase(curiter); + continue; + } + if (req->mID == mDebugID) + { + mDebugCount++; // for setting breakpoints + } + if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM && + req->mTotalPackets > 0 && + req->mLastPacket >= req->mTotalPackets-1) + { + // We have all the packets... make sure this is high priority // req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority); - continue; - } - F32 elapsed = req->mRequestedTimer.getElapsedTimeF32(); - { - F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority); - if ((req->mSimRequestedDiscard != req->mDesiredDiscard) || - (delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) || - (elapsed >= SIM_LAZY_FLUSH_TIMEOUT)) + continue; + } + F32 elapsed = req->mRequestedTimer.getElapsedTimeF32(); { - requests[req->mHost].insert(req); + F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority); + if ((req->mSimRequestedDiscard != req->mDesiredDiscard) || + (delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) || + (elapsed >= SIM_LAZY_FLUSH_TIMEOUT)) + { + requests[req->mHost].insert(req); + } } } - } - } + } // -Mfnq for (work_request_map_t::iterator iter1 = requests.begin(); iter1 != requests.end(); ++iter1) @@ -2391,9 +3025,9 @@ void LLTextureFetch::sendRequestListToSimulators() if (req->mSentRequest != LLTextureFetchWorker::SENT_SIM) { // Initialize packet data based on data read from cache - req->lockWorkMutex(); + req->lockWorkMutex(); // +Mw req->setupPacketData(); - req->unlockWorkMutex(); + req->unlockWorkMutex(); // -Mw } if (0 == sim_request_count) { @@ -2422,12 +3056,12 @@ void LLTextureFetch::sendRequestListToSimulators() mTextureInfo.setRequestType(req->mID, LLTextureInfoDetails::REQUEST_TYPE_UDP); } - req->lockWorkMutex(); + req->lockWorkMutex(); // +Mw req->mSentRequest = LLTextureFetchWorker::SENT_SIM; req->mSimRequestedDiscard = req->mDesiredDiscard; req->mRequestedPriority = req->mImagePriority; req->mRequestedTimer.reset(); - req->unlockWorkMutex(); + req->unlockWorkMutex(); // -Mw sim_request_count++; if (sim_request_count >= IMAGES_PER_REQUEST) { @@ -2448,55 +3082,57 @@ void LLTextureFetch::sendRequestListToSimulators() // Send cancelations { - LLMutexLock lock2(&mNetworkQueueMutex); - if (gMessageSystem && !mCancelQueue.empty()) - { - for (cancel_queue_t::iterator iter1 = mCancelQueue.begin(); - iter1 != mCancelQueue.end(); ++iter1) + LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq + if (gMessageSystem && !mCancelQueue.empty()) { - LLHost host = iter1->first; - if (host == LLHost::invalid) - { - host = gAgent.getRegionHost(); - } - S32 request_count = 0; - for (queue_t::iterator iter2 = iter1->second.begin(); - iter2 != iter1->second.end(); ++iter2) + for (cancel_queue_t::iterator iter1 = mCancelQueue.begin(); + iter1 != mCancelQueue.end(); ++iter1) { - if (0 == request_count) + LLHost host = iter1->first; + if (host == LLHost::invalid) { - gMessageSystem->newMessageFast(_PREHASH_RequestImage); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + host = gAgent.getRegionHost(); } - gMessageSystem->nextBlockFast(_PREHASH_RequestImage); - gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2); - gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1); - gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0); - gMessageSystem->addU32Fast(_PREHASH_Packet, 0); - gMessageSystem->addU8Fast(_PREHASH_Type, 0); + S32 request_count = 0; + for (queue_t::iterator iter2 = iter1->second.begin(); + iter2 != iter1->second.end(); ++iter2) + { + if (0 == request_count) + { + gMessageSystem->newMessageFast(_PREHASH_RequestImage); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + } + gMessageSystem->nextBlockFast(_PREHASH_RequestImage); + gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2); + gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1); + gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0); + gMessageSystem->addU32Fast(_PREHASH_Packet, 0); + gMessageSystem->addU8Fast(_PREHASH_Type, 0); // llinfos << "CANCELING IMAGE REQUEST: " << (*iter2) << llendl; - request_count++; - if (request_count >= IMAGES_PER_REQUEST) + request_count++; + if (request_count >= IMAGES_PER_REQUEST) + { + gMessageSystem->sendSemiReliable(host, NULL, NULL); + request_count = 0; + } + } + if (request_count > 0 && request_count < IMAGES_PER_REQUEST) { gMessageSystem->sendSemiReliable(host, NULL, NULL); - request_count = 0; } } - if (request_count > 0 && request_count < IMAGES_PER_REQUEST) - { - gMessageSystem->sendSemiReliable(host, NULL, NULL); - } + mCancelQueue.clear(); } - mCancelQueue.clear(); - } - } + } // -Mfnq } ////////////////////////////////////////////////////////////////////////////// +// Threads: T* +// Locks: Mw bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size) { mRequestedTimer.reset(); @@ -2529,6 +3165,7 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size) return true; } +// Threads: T* bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data) { @@ -2563,15 +3200,19 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 } if (!res) { + mNetworkQueueMutex.lock(); // +Mfnq ++mBadPacketCount; - mNetworkQueueMutex.lock() ; mCancelQueue[host].insert(id); - mNetworkQueueMutex.unlock() ; + mNetworkQueueMutex.unlock(); // -Mfnq return false; } + LLViewerStatsRecorder::instance().textureFetch(data_size); + LLViewerStatsRecorder::instance().log(0.1f); + worker->lockWorkMutex(); + // Copy header data into image object worker->mImageCodec = codec; worker->mTotalPackets = packets; @@ -2581,10 +3222,12 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 res = worker->insertPacket(0, data, data_size); worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); worker->mState = LLTextureFetchWorker::LOAD_FROM_SIMULATOR; - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw return res; } + +// Threads: T* bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data) { LLTextureFetchWorker* worker = getWorker(id); @@ -2609,14 +3252,18 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 } if (!res) { + mNetworkQueueMutex.lock(); // +Mfnq ++mBadPacketCount; - mNetworkQueueMutex.lock() ; mCancelQueue[host].insert(id); - mNetworkQueueMutex.unlock() ; + mNetworkQueueMutex.unlock(); // -Mfnq return false; } + + LLViewerStatsRecorder::instance().textureFetch(data_size); + LLViewerStatsRecorder::instance().log(0.1f); worker->lockWorkMutex(); + res = worker->insertPacket(packet_num, data, data_size); @@ -2633,7 +3280,7 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 removeFromNetworkQueue(worker, true); // failsafe } - if(packet_num >= (worker->mTotalPackets - 1)) + if (packet_num >= (worker->mTotalPackets - 1)) { static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog"); static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator"); @@ -2645,12 +3292,14 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 mTextureInfo.setRequestCompleteTimeAndLog(id, timeNow); } } - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw return res; } ////////////////////////////////////////////////////////////////////////////// + +// Threads: T* BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id) { BOOL from_cache = FALSE ; @@ -2658,14 +3307,15 @@ BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id) LLTextureFetchWorker* worker = getWorker(id); if (worker) { - worker->lockWorkMutex() ; - from_cache = worker->mInLocalCache ; - worker->unlockWorkMutex() ; + worker->lockWorkMutex(); // +Mw + from_cache = worker->mInLocalCache; + worker->unlockWorkMutex(); // -Mw } return from_cache ; } +// Threads: T* S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& requested_priority_p, U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http) { @@ -2679,7 +3329,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r LLTextureFetchWorker* worker = getWorker(id); if (worker && worker->haveWork()) { - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw state = worker->mState; fetch_dtime = worker->mFetchTimer.getElapsedTimeF32(); request_dtime = worker->mRequestedTimer.getElapsedTimeF32(); @@ -2706,7 +3356,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r } fetch_priority = worker->getPriority(); can_use_http = worker->getCanUseHTTP() ; - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw } data_progress_p = data_progress; requested_priority_p = requested_priority; @@ -2730,12 +3380,219 @@ void LLTextureFetch::dump() << " STATE: " << worker->sStateDescs[worker->mState] << llendl; } + + llinfos << "LLTextureFetch ACTIVE_HTTP:" << llendl; + for (queue_t::const_iterator iter(mHTTPTextureQueue.begin()); + mHTTPTextureQueue.end() != iter; + ++iter) + { + llinfos << " ID: " << (*iter) << llendl; + } + + llinfos << "LLTextureFetch WAIT_HTTP_RESOURCE:" << llendl; + for (wait_http_res_queue_t::const_iterator iter(mHttpWaitResource.begin()); + mHttpWaitResource.end() != iter; + ++iter) + { + llinfos << " ID: " << (*iter) << llendl; + } +} + +////////////////////////////////////////////////////////////////////////////// + +// HTTP Resource Waiting Methods + +// Threads: Ttf +void LLTextureFetch::addHttpWaiter(const LLUUID & tid) +{ + mNetworkQueueMutex.lock(); // +Mfnq + mHttpWaitResource.insert(tid); + mNetworkQueueMutex.unlock(); // -Mfnq +} + +// Threads: Ttf +void LLTextureFetch::removeHttpWaiter(const LLUUID & tid) +{ + mNetworkQueueMutex.lock(); // +Mfnq + wait_http_res_queue_t::iterator iter(mHttpWaitResource.find(tid)); + if (mHttpWaitResource.end() != iter) + { + mHttpWaitResource.erase(iter); + } + mNetworkQueueMutex.unlock(); // -Mfnq +} + +// Threads: T* +bool LLTextureFetch::isHttpWaiter(const LLUUID & tid) +{ + mNetworkQueueMutex.lock(); // +Mfnq + wait_http_res_queue_t::iterator iter(mHttpWaitResource.find(tid)); + const bool ret(mHttpWaitResource.end() != iter); + mNetworkQueueMutex.unlock(); // -Mfnq + return ret; +} + +// Release as many requests as permitted from the WAIT_HTTP_RESOURCE2 +// state to the SEND_HTTP_REQ state based on their current priority. +// +// This data structures and code associated with this looks a bit +// indirect and naive but it's done in the name of safety. An +// ordered container may become invalid from time to time due to +// priority changes caused by actions in other threads. State itself +// could also suffer the same fate with canceled operations. Even +// done this way, I'm not fully trusting we're truly safe. This +// module is due for a major refactoring and we'll deal with it then. +// +// Threads: Ttf +// Locks: -Mw (must not hold any worker when called) +void LLTextureFetch::releaseHttpWaiters() +{ + // Use mHttpSemaphore rather than mHTTPTextureQueue.size() + // to avoid a lock. + if (mHttpSemaphore < (HTTP_REQUESTS_IN_QUEUE_HIGH_WATER - HTTP_REQUESTS_IN_QUEUE_LOW_WATER)) + return; + + // Quickly make a copy of all the LLUIDs. Get off the + // mutex as early as possible. + typedef std::vector<LLUUID> uuid_vec_t; + uuid_vec_t tids; + + { + LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq + + if (mHttpWaitResource.empty()) + return; + tids.reserve(mHttpWaitResource.size()); + tids.assign(mHttpWaitResource.begin(), mHttpWaitResource.end()); + } // -Mfnq + + // Now lookup the UUUIDs to find valid requests and sort + // them in priority order, highest to lowest. We're going + // to modify priority later as a side-effect of releasing + // these objects. That, in turn, would violate the partial + // ordering assumption of std::set, std::map, etc. so we + // don't use those containers. We use a vector and an explicit + // sort to keep the containers valid later. + typedef std::vector<LLTextureFetchWorker *> worker_list_t; + worker_list_t tids2; + + tids2.reserve(tids.size()); + for (uuid_vec_t::iterator iter(tids.begin()); + tids.end() != iter; + ++iter) + { + LLTextureFetchWorker * worker(getWorker(* iter)); + if (worker) + { + tids2.push_back(worker); + } + else + { + // If worker isn't found, this should be due to a request + // for deletion. We signal our recognition that this + // uuid shouldn't be used for resource waiting anymore by + // erasing it from the resource waiter list. That allows + // deleteOK to do final deletion on the worker. + removeHttpWaiter(* iter); + } + } + tids.clear(); + + // Sort into priority order, if necessary and only as much as needed + if (tids2.size() > mHttpSemaphore) + { + LLTextureFetchWorker::Compare compare; + std::partial_sort(tids2.begin(), tids2.begin() + mHttpSemaphore, tids2.end(), compare); + } + + // Release workers up to the high water mark. Since we aren't + // holding any locks at this point, we can be in competition + // with other callers. Do defensive things like getting + // refreshed counts of requests and checking if someone else + // has moved any worker state around.... + for (worker_list_t::iterator iter2(tids2.begin()); tids2.end() != iter2; ++iter2) + { + LLTextureFetchWorker * worker(* iter2); + + worker->lockWorkMutex(); // +Mw + if (LLTextureFetchWorker::WAIT_HTTP_RESOURCE2 != worker->mState) + { + // Not in expected state, remove it, try the next one + worker->unlockWorkMutex(); // -Mw + LL_WARNS("Texture") << "Resource-waited texture " << worker->mID + << " in unexpected state: " << worker->mState + << ". Removing from wait list." + << LL_ENDL; + removeHttpWaiter(worker->mID); + continue; + } + + if (! worker->acquireHttpSemaphore()) + { + // Out of active slots, quit + worker->unlockWorkMutex(); // -Mw + break; + } + + worker->mState = LLTextureFetchWorker::SEND_HTTP_REQ; + worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); + worker->unlockWorkMutex(); // -Mw + + removeHttpWaiter(worker->mID); + } +} + +// Threads: T* +void LLTextureFetch::cancelHttpWaiters() +{ + mNetworkQueueMutex.lock(); // +Mfnq + mHttpWaitResource.clear(); + mNetworkQueueMutex.unlock(); // -Mfnq +} + +// Threads: T* +int LLTextureFetch::getHttpWaitersCount() +{ + mNetworkQueueMutex.lock(); // +Mfnq + int ret(mHttpWaitResource.size()); + mNetworkQueueMutex.unlock(); // -Mfnq + return ret; +} + + +// Threads: T* +void LLTextureFetch::updateStateStats(U32 cache_read, U32 cache_write, U32 res_wait) +{ + LLMutexLock lock(&mQueueMutex); // +Mfq + + mTotalCacheReadCount += cache_read; + mTotalCacheWriteCount += cache_write; + mTotalResourceWaitCount += res_wait; +} // -Mfq + + +// Threads: T* +void LLTextureFetch::getStateStats(U32 * cache_read, U32 * cache_write, U32 * res_wait) +{ + U32 ret1(0U), ret2(0U), ret3(0U); + + { + LLMutexLock lock(&mQueueMutex); // +Mfq + ret1 = mTotalCacheReadCount; + ret2 = mTotalCacheWriteCount; + ret3 = mTotalResourceWaitCount; + } // -Mfq + + *cache_read = ret1; + *cache_write = ret2; + *res_wait = ret3; } ////////////////////////////////////////////////////////////////////////////// // cross-thread command methods +// Threads: T* void LLTextureFetch::commandSetRegion(U64 region_handle) { TFReqSetRegion * req = new TFReqSetRegion(region_handle); @@ -2743,6 +3600,7 @@ void LLTextureFetch::commandSetRegion(U64 region_handle) cmdEnqueue(req); } +// Threads: T* void LLTextureFetch::commandSendMetrics(const std::string & caps_url, const LLUUID & session_id, const LLUUID & agent_id, @@ -2753,6 +3611,7 @@ void LLTextureFetch::commandSendMetrics(const std::string & caps_url, cmdEnqueue(req); } +// Threads: T* void LLTextureFetch::commandDataBreak() { // The pedantically correct way to implement this is to create a command @@ -2763,30 +3622,33 @@ void LLTextureFetch::commandDataBreak() LLTextureFetch::svMetricsDataBreak = true; } +// Threads: T* void LLTextureFetch::cmdEnqueue(TFRequest * req) { - lockQueue(); + lockQueue(); // +Mfq mCommands.push_back(req); - unlockQueue(); + unlockQueue(); // -Mfq unpause(); } +// Threads: T* LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue() { TFRequest * ret = 0; - lockQueue(); + lockQueue(); // +Mfq if (! mCommands.empty()) { ret = mCommands.front(); mCommands.erase(mCommands.begin()); } - unlockQueue(); + unlockQueue(); // -Mfq return ret; } +// Threads: Ttf void LLTextureFetch::cmdDoWork() { if (mDebugPause) @@ -2803,7 +3665,6 @@ void LLTextureFetch::cmdDoWork() } } - ////////////////////////////////////////////////////////////////////////////// // Private (anonymous) class methods implementing the command scheme. @@ -2811,6 +3672,38 @@ void LLTextureFetch::cmdDoWork() namespace { + +// Example of a simple notification handler for metrics +// delivery notification. Earlier versions of the code used +// a Responder that tried harder to detect delivery breaks +// but it really isn't that important. If someone wants to +// revisit that effort, here is a place to start. +class AssetReportHandler : public LLCore::HttpHandler +{ +public: + + // Threads: Ttf + virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) + { + LLCore::HttpStatus status(response->getStatus()); + + if (status) + { + LL_DEBUGS("Texture") << "Successfully delivered asset metrics to grid." + << LL_ENDL; + } + else + { + LL_WARNS("Texture") << "Error delivering asset metrics to grid. Status: " + << status.toHex() + << ", Reason: " << status.toString() << LL_ENDL; + } + } +}; // end class AssetReportHandler + +AssetReportHandler stats_handler; + + /** * Implements the 'Set Region' command. * @@ -2841,73 +3734,8 @@ TFReqSendMetrics::~TFReqSendMetrics() bool TFReqSendMetrics::doWork(LLTextureFetch * fetcher) { - /* - * HTTP POST responder. Doesn't do much but tries to - * detect simple breaks in recording the metrics stream. - * - * The 'volatile' modifiers don't indicate signals, - * mmap'd memory or threads, really. They indicate that - * the referenced data is part of a pseudo-closure for - * this responder rather than being required for correct - * operation. - * - * We don't try very hard with the POST request. We give - * it one shot and that's more-or-less it. With a proper - * refactoring of the LLQueuedThread usage, these POSTs - * could be put in a request object and made more reliable. - */ - class lcl_responder : public LLCurl::Responder - { - public: - lcl_responder(LLTextureFetch * fetcher, - S32 expected_sequence, - volatile const S32 & live_sequence, - volatile bool & reporting_break, - volatile bool & reporting_started) - : LLCurl::Responder(), - mFetcher(fetcher), - mExpectedSequence(expected_sequence), - mLiveSequence(live_sequence), - mReportingBreak(reporting_break), - mReportingStarted(reporting_started) - { - mFetcher->incrCurlPOSTCount(); - } - - ~lcl_responder() - { - mFetcher->decrCurlPOSTCount(); - } - - // virtual - void error(U32 status_num, const std::string & reason) - { - if (mLiveSequence == mExpectedSequence) - { - mReportingBreak = true; - } - LL_WARNS("Texture") << "Break in metrics stream due to POST failure to metrics collection service. Reason: " - << reason << LL_ENDL; - } - - // virtual - void result(const LLSD & content) - { - if (mLiveSequence == mExpectedSequence) - { - mReportingBreak = false; - mReportingStarted = true; - } - } - - private: - LLTextureFetch * mFetcher; - S32 mExpectedSequence; - volatile const S32 & mLiveSequence; - volatile bool & mReportingBreak; - volatile bool & mReportingStarted; - - }; // class lcl_responder + static const U32 report_priority(1); + static LLCore::HttpHandler * const handler(fetcher->isQAMode() || true ? &stats_handler : NULL); if (! gViewerAssetStatsThread1) return true; @@ -2935,21 +3763,26 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) // Update sequence number if (S32_MAX == ++report_sequence) report_sequence = 0; - + reporting_started = true; + // Limit the size of the stats report if necessary. merged_llsd["truncated"] = truncate_viewer_metrics(10, merged_llsd); if (! mCapsURL.empty()) { - LLCurlRequest::headers_t headers; - fetcher->getCurlRequest().post(mCapsURL, - headers, - merged_llsd, - new lcl_responder(fetcher, - report_sequence, - report_sequence, - LLTextureFetch::svMetricsDataBreak, - reporting_started)); + LLCore::BufferArray * ba = new LLCore::BufferArray; + LLCore::BufferArrayStream bas(ba); + LLSDSerialize::toXML(merged_llsd, bas); + + fetcher->getHttpRequest().requestPost(fetcher->getPolicyClass(), + report_priority, + mCapsURL, + ba, + NULL, + fetcher->getMetricsHeaders(), + handler); + ba->release(); + LLTextureFetch::svMetricsDataBreak = false; } else { @@ -2959,7 +3792,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) // In QA mode, Metrics submode, log the result for ease of testing if (fetcher->isQAMode()) { - LL_INFOS("Textures") << merged_llsd << LL_ENDL; + LL_INFOS("Textures") << ll_pretty_print_sd(merged_llsd) << LL_ENDL; } gViewerAssetStatsThread1->reset(); @@ -3008,4 +3841,951 @@ truncate_viewer_metrics(int max_regions, LLSD & metrics) } // end of anonymous namespace +/////////////////////////////////////////////////////////////////////////////////////////// +//Start LLTextureFetchDebugger +/////////////////////////////////////////////////////////////////////////////////////////// +//--------------------- +class LLDebuggerCacheReadResponder : public LLTextureCache::ReadResponder +{ +public: + LLDebuggerCacheReadResponder(LLTextureFetchDebugger* debugger, S32 id, LLImageFormatted* image) + : mDebugger(debugger), mID(id) + { + setImage(image); + } + virtual void completed(bool success) + { + mDebugger->callbackCacheRead(mID, success, mFormattedImage, mImageSize, mImageLocal); + } +private: + LLTextureFetchDebugger* mDebugger; + S32 mID; +}; + +class LLDebuggerCacheWriteResponder : public LLTextureCache::WriteResponder +{ +public: + LLDebuggerCacheWriteResponder(LLTextureFetchDebugger* debugger, S32 id) + : mDebugger(debugger), mID(id) + { + } + virtual void completed(bool success) + { + mDebugger->callbackCacheWrite(mID, success); + } +private: + LLTextureFetchDebugger* mDebugger; + S32 mID; +}; + +class LLDebuggerDecodeResponder : public LLImageDecodeThread::Responder +{ +public: + LLDebuggerDecodeResponder(LLTextureFetchDebugger* debugger, S32 id) + : mDebugger(debugger), mID(id) + { + } + virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) + { + mDebugger->callbackDecoded(mID, success, raw, aux); + } +private: + LLTextureFetchDebugger* mDebugger; + S32 mID; +}; + + +LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) : + LLCore::HttpHandler(), + mFetcher(fetcher), + mTextureCache(cache), + mImageDecodeThread(imagedecodethread), + mHttpHeaders(NULL), + mHttpPolicyClass(fetcher->getPolicyClass()), + mNbCurlCompleted(0), + mTempIndex(0), + mHistoryListIndex(0) +{ + init(); +} + +LLTextureFetchDebugger::~LLTextureFetchDebugger() +{ + mFetchingHistory.clear(); + mStopDebug = TRUE; + tryToStopDebug(); + if (mHttpHeaders) + { + mHttpHeaders->release(); + mHttpHeaders = NULL; + } +} + +void LLTextureFetchDebugger::init() +{ + mState = IDLE; + + mCacheReadTime = -1.f; + mCacheWriteTime = -1.f; + mDecodingTime = -1.f; + mHTTPTime = -1.f; + mGLCreationTime = -1.f; + + mTotalFetchingTime = 0.f; + mRefetchVisCacheTime = -1.f; + mRefetchVisHTTPTime = -1.f; + mRefetchAllCacheTime = -1.f; + mRefetchAllHTTPTime = -1.f; + + mNumFetchedTextures = 0; + mNumCacheHits = 0; + mNumVisibleFetchedTextures = 0; + mNumVisibleFetchingRequests = 0; + mFetchedData = 0; + mDecodedData = 0; + mVisibleFetchedData = 0; + mVisibleDecodedData = 0; + mRenderedData = 0; + mRenderedDecodedData = 0; + mFetchedPixels = 0; + mRenderedPixels = 0; + mRefetchedVisData = 0; + mRefetchedVisPixels = 0; + mRefetchedAllData = 0; + mRefetchedAllPixels = 0; + + mFreezeHistory = FALSE; + mStopDebug = FALSE; + mClearHistory = FALSE; + mRefetchNonVis = FALSE; + + mNbCurlRequests = 0; + + if (! mHttpHeaders) + { + mHttpHeaders = new LLCore::HttpHeaders; + mHttpHeaders->mHeaders.push_back("Accept: image/x-j2c"); + } +} + +void LLTextureFetchDebugger::startWork(e_debug_state state) +{ + switch(state) + { + case IDLE: + break; + case START_DEBUG: + startDebug(); + break; + case READ_CACHE: + debugCacheRead(); + break; + case WRITE_CACHE: + debugCacheWrite(); + break; + case DECODING: + debugDecoder(); + break; + case HTTP_FETCHING: + debugHTTP(); + break; + case GL_TEX: + debugGLTextureCreation(); + break; + case REFETCH_VIS_CACHE: + debugRefetchVisibleFromCache(); + break; + case REFETCH_VIS_HTTP: + debugRefetchVisibleFromHTTP(); + break; + case REFETCH_ALL_CACHE: + debugRefetchAllFromCache(); + break; + case REFETCH_ALL_HTTP: + debugRefetchAllFromHTTP(); + break; + default: + break; + } + return; +} + +void LLTextureFetchDebugger::startDebug() +{ + //lock the fetcher + mFetcher->lockFetcher(true); + mFreezeHistory = TRUE; + mFetcher->resetLoadSource(); + + //clear the current fetching queue + gTextureList.clearFetchingRequests(); + + mState = START_DEBUG; +} + +bool LLTextureFetchDebugger::processStartDebug(F32 max_time) +{ + mTimer.reset(); + + //wait for all works to be done + while(1) + { + S32 pending = 0; + pending += LLAppViewer::getTextureCache()->update(1); + pending += LLAppViewer::getImageDecodeThread()->update(1); + // pending += LLAppViewer::getTextureFetch()->update(1); // This causes infinite recursion in some cases + pending += mNbCurlRequests; + if(!pending) + { + break; + } + + if(mTimer.getElapsedTimeF32() > max_time) + { + return false; + } + } + + //collect statistics + mTotalFetchingTime = gTextureTimer.getElapsedTimeF32() - mTotalFetchingTime; + + std::set<LLUUID> fetched_textures; + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size; i++) + { + bool in_list = true; + if(fetched_textures.find(mFetchingHistory[i].mID) == fetched_textures.end()) + { + fetched_textures.insert(mFetchingHistory[i].mID); + in_list = false; + } + + LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(mFetchingHistory[i].mID); + if(tex && tex->isJustBound()) //visible + { + if(!in_list) + { + mNumVisibleFetchedTextures++; + } + mNumVisibleFetchingRequests++; + + mVisibleFetchedData += mFetchingHistory[i].mFetchedSize; + mVisibleDecodedData += mFetchingHistory[i].mDecodedSize; + + if(tex->getDiscardLevel() >= mFetchingHistory[i].mDecodedLevel) + { + mRenderedData += mFetchingHistory[i].mFetchedSize; + mRenderedDecodedData += mFetchingHistory[i].mDecodedSize; + mRenderedPixels += tex->getWidth() * tex->getHeight(); + } + } + } + + mNumFetchedTextures = fetched_textures.size(); + + return true; +} + +void LLTextureFetchDebugger::tryToStopDebug() +{ + if(!mStopDebug) + { + return; + } + + //clear the current debug work + S32 size = mFetchingHistory.size(); + switch(mState) + { + case READ_CACHE: + for(S32 i = 0 ; i < size; i++) + { + if (mFetchingHistory[i]. mCacheHandle != LLTextureCache::nullHandle()) + { + mTextureCache->readComplete(mFetchingHistory[i].mCacheHandle, true); + } + } + break; + case WRITE_CACHE: + for(S32 i = 0 ; i < size; i++) + { + if (mFetchingHistory[i].mCacheHandle != LLTextureCache::nullHandle()) + { + mTextureCache->writeComplete(mFetchingHistory[i].mCacheHandle, true); + } + } + break; + case DECODING: + break; + case HTTP_FETCHING: + break; + case GL_TEX: + break; + case REFETCH_VIS_CACHE: + break; + case REFETCH_VIS_HTTP: + break; + case REFETCH_ALL_CACHE: + mRefetchList.clear(); + break; + case REFETCH_ALL_HTTP: + mRefetchList.clear(); + break; + default: + break; + } + + if(update(0.005f)) + { + //unlock the fetcher + mFetcher->lockFetcher(false); + mFetcher->resetLoadSource(); + mFreezeHistory = FALSE; + mStopDebug = FALSE; + + if(mClearHistory) + { + mFetchingHistory.clear(); + mHandleToFetchIndex.clear(); + init(); + mTotalFetchingTime = gTextureTimer.getElapsedTimeF32(); //reset + } + } +} + +//called in the main thread and when the fetching queue is empty +void LLTextureFetchDebugger::clearHistory() +{ + mClearHistory = TRUE; +} + +void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker) +{ + if(worker->mRawImage.isNull() || worker->mFormattedImage.isNull()) + { + return; + } + + if(mFreezeHistory) + { + if(mState == REFETCH_VIS_CACHE || mState == REFETCH_VIS_HTTP) + { + mRefetchedVisPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); + mRefetchedVisData += worker->mFormattedImage->getDataSize(); + } + else + { + mRefetchedAllPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); + mRefetchedAllData += worker->mFormattedImage->getDataSize(); + + LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID); + if(tex && mRefetchList[tex].begin() != mRefetchList[tex].end()) + { + if(worker->mDecodedDiscard == mFetchingHistory[mRefetchList[tex][0]].mDecodedLevel) + { + mRefetchList[tex].erase(mRefetchList[tex].begin()); + } + } + } + return; + } + + if(worker->mInCache) + { + mNumCacheHits++; + } + mFetchedData += worker->mFormattedImage->getDataSize(); + mDecodedData += worker->mRawImage->getDataSize(); + mFetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); + + mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard, + worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); +} + +void LLTextureFetchDebugger::lockCache() +{ +} + +void LLTextureFetchDebugger::unlockCache() +{ +} + +void LLTextureFetchDebugger::debugCacheRead() +{ + lockCache(); + llassert_always(mState == IDLE); + mTimer.reset(); + mState = READ_CACHE; + mCacheReadTime = -1.f; + + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size ; i++) + { + mFetchingHistory[i].mFormattedImage = NULL; + mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, 0, mFetchingHistory[i].mFetchedSize, + new LLDebuggerCacheReadResponder(this, i, mFetchingHistory[i].mFormattedImage)); + } +} + +void LLTextureFetchDebugger::clearCache() +{ + S32 size = mFetchingHistory.size(); + { + std::set<LLUUID> deleted_list; + for(S32 i = 0 ; i < size ; i++) + { + if(deleted_list.find(mFetchingHistory[i].mID) == deleted_list.end()) + { + deleted_list.insert(mFetchingHistory[i].mID); + mTextureCache->removeFromCache(mFetchingHistory[i].mID); + } + } + } +} + +void LLTextureFetchDebugger::debugCacheWrite() +{ + //remove from cache + clearCache(); + + lockCache(); + llassert_always(mState == IDLE); + mTimer.reset(); + mState = WRITE_CACHE; + mCacheWriteTime = -1.f; + + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size ; i++) + { + if(mFetchingHistory[i].mFormattedImage.notNull()) + { + mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, + mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize, + mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1, + NULL, 0, new LLDebuggerCacheWriteResponder(this, i)); + } + } +} + +void LLTextureFetchDebugger::lockDecoder() +{ +} + +void LLTextureFetchDebugger::unlockDecoder() +{ +} + +void LLTextureFetchDebugger::debugDecoder() +{ + lockDecoder(); + llassert_always(mState == IDLE); + mTimer.reset(); + mState = DECODING; + mDecodingTime = -1.f; + + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size ; i++) + { + if(mFetchingHistory[i].mFormattedImage.isNull()) + { + continue; + } + + mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage, LLWorkerThread::PRIORITY_NORMAL, + mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mNeedsAux, + new LLDebuggerDecodeResponder(this, i)); + } +} + +void LLTextureFetchDebugger::debugHTTP() +{ + llassert_always(mState == IDLE); + + LLViewerRegion* region = gAgent.getRegion(); + if (!region) + { + llinfos << "Fetch Debugger : Current region undefined. Cannot fetch textures through HTTP." << llendl; + return; + } + + mHTTPUrl = region->getHttpUrl(); + if (mHTTPUrl.empty()) + { + llinfos << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << llendl; + return; + } + + mTimer.reset(); + mState = HTTP_FETCHING; + mHTTPTime = -1.f; + + S32 size = mFetchingHistory.size(); + for (S32 i = 0 ; i < size ; i++) + { + mFetchingHistory[i].mCurlState = FetchEntry::CURL_NOT_DONE; + mFetchingHistory[i].mCurlReceivedSize = 0; + mFetchingHistory[i].mFormattedImage = NULL; + } + mNbCurlRequests = 0; + mNbCurlCompleted = 0; + + fillCurlQueue(); +} + +S32 LLTextureFetchDebugger::fillCurlQueue() +{ + if(mStopDebug) //stop + { + mNbCurlCompleted = mFetchingHistory.size(); + return 0; + } + if (mNbCurlRequests > HTTP_REQUESTS_IN_QUEUE_LOW_WATER) + { + return mNbCurlRequests; + } + + S32 size = mFetchingHistory.size(); + for (S32 i = 0 ; i < size ; i++) + { + if (mFetchingHistory[i].mCurlState != FetchEntry::CURL_NOT_DONE) + { + continue; + } + std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[i].mID.asString().c_str(); + S32 requestedSize = mFetchingHistory[i].mRequestedSize; + // We request the whole file if the size was not set. + requestedSize = llmax(0,requestedSize); + // We request the whole file if the size was set to an absurdly high value (meaning all file) + requestedSize = (requestedSize == 33554432 ? 0 : requestedSize); + + LLCore::HttpHandle handle = mFetcher->getHttpRequest().requestGetByteRange(mHttpPolicyClass, + LLWorkerThread::PRIORITY_LOWBITS, + texture_url, + 0, + requestedSize, + NULL, + mHttpHeaders, + this); + if (LLCORE_HTTP_HANDLE_INVALID != handle) + { + mHandleToFetchIndex[handle] = i; + mFetchingHistory[i].mHttpHandle = handle; + mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS; + mNbCurlRequests++; + if (mNbCurlRequests >= HTTP_REQUESTS_IN_QUEUE_HIGH_WATER) // emulate normal pipeline + { + break; + } + } + else + { + // Failed to queue request, log it and mark it done. + LLCore::HttpStatus status(mFetcher->getHttpRequest().getStatus()); + + LL_WARNS("Texture") << "Couldn't issue HTTP request in debugger for texture " + << mFetchingHistory[i].mID + << ", status: " << status.toHex() + << " reason: " << status.toString() + << LL_ENDL; + mFetchingHistory[i].mCurlState = FetchEntry::CURL_DONE; + } + } + //llinfos << "Fetch Debugger : Having " << mNbCurlRequests << " requests through the curl thread." << llendl; + return mNbCurlRequests; +} + +void LLTextureFetchDebugger::debugGLTextureCreation() +{ + llassert_always(mState == IDLE); + mState = GL_TEX; + mTempTexList.clear(); + + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size ; i++) + { + if(mFetchingHistory[i].mRawImage.notNull()) + { + LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ; + if(tex && !tex->isForSculptOnly()) + { + tex->destroyGLTexture() ; + mTempTexList.push_back(tex); + } + } + } + + mGLCreationTime = -1.f; + mTempIndex = 0; + mHistoryListIndex = 0; + + return; +} + +bool LLTextureFetchDebugger::processGLCreation(F32 max_time) +{ + mTimer.reset(); + + bool done = true; + S32 size = mFetchingHistory.size(); + S32 size1 = mTempTexList.size(); + for(; mHistoryListIndex < size && mTempIndex < size1; mHistoryListIndex++) + { + if(mFetchingHistory[mHistoryListIndex].mRawImage.notNull()) + { + if(mFetchingHistory[mHistoryListIndex].mID == mTempTexList[mTempIndex]->getID()) + { + mTempTexList[mTempIndex]->createGLTexture(mFetchingHistory[mHistoryListIndex].mDecodedLevel, + mFetchingHistory[mHistoryListIndex].mRawImage, 0, TRUE, mTempTexList[mTempIndex]->getBoostLevel()); + mTempIndex++; + } + } + + if(mTimer.getElapsedTimeF32() > max_time) + { + done = false; + break; + } + } + + if(mGLCreationTime < 0.f) + { + mGLCreationTime = mTimer.getElapsedTimeF32() ; + } + else + { + mGLCreationTime += mTimer.getElapsedTimeF32() ; + } + + return done; +} + +//clear fetching results of all textures. +void LLTextureFetchDebugger::clearTextures() +{ + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size ; i++) + { + LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ; + if(tex) + { + tex->clearFetchedResults() ; + } + } +} + +void LLTextureFetchDebugger::makeRefetchList() +{ + mRefetchList.clear(); + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size; i++) + { + LLViewerFetchedTexture* tex = LLViewerTextureManager::getFetchedTexture(mFetchingHistory[i].mID); + if(tex && tex->isJustBound()) //visible + { + continue; //the texture fetch pipeline will take care of visible textures. + } + + mRefetchList[tex].push_back(i); + } +} + +void LLTextureFetchDebugger::scanRefetchList() +{ + if(mStopDebug) + { + return; + } + if(!mRefetchNonVis) + { + return; + } + + for(std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> >::iterator iter = mRefetchList.begin(); + iter != mRefetchList.end(); ) + { + if(iter->second.empty()) + { + gTextureList.setDebugFetching(iter->first, -1); + mRefetchList.erase(iter++); // This is the correct method to "erase and move on" in an std::map + } + else + { + gTextureList.setDebugFetching(iter->first, mFetchingHistory[iter->second[0]].mDecodedLevel); + ++iter; + } + } +} + +void LLTextureFetchDebugger::debugRefetchVisibleFromCache() +{ + llassert_always(mState == IDLE); + mState = REFETCH_VIS_CACHE; + + clearTextures(); + mFetcher->setLoadSource(LLTextureFetch::FROM_ALL); + + mTimer.reset(); + mFetcher->lockFetcher(false); + mRefetchVisCacheTime = -1.f; + mRefetchedVisData = 0; + mRefetchedVisPixels = 0; +} + +void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP() +{ + llassert_always(mState == IDLE); + mState = REFETCH_VIS_HTTP; + + clearTextures(); + mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY); + + mTimer.reset(); + mFetcher->lockFetcher(false); + mRefetchVisHTTPTime = -1.f; + mRefetchedVisData = 0; + mRefetchedVisPixels = 0; +} + +void LLTextureFetchDebugger::debugRefetchAllFromCache() +{ + llassert_always(mState == IDLE); + mState = REFETCH_ALL_CACHE; + + clearTextures(); + makeRefetchList(); + mFetcher->setLoadSource(LLTextureFetch::FROM_ALL); + + mTimer.reset(); + mFetcher->lockFetcher(false); + mRefetchAllCacheTime = -1.f; + mRefetchedAllData = 0; + mRefetchedAllPixels = 0; + mRefetchNonVis = FALSE; +} + +void LLTextureFetchDebugger::debugRefetchAllFromHTTP() +{ + llassert_always(mState == IDLE); + mState = REFETCH_ALL_HTTP; + + clearTextures(); + makeRefetchList(); + mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY); + + mTimer.reset(); + mFetcher->lockFetcher(false); + mRefetchAllHTTPTime = -1.f; + mRefetchedAllData = 0; + mRefetchedAllPixels = 0; + mRefetchNonVis = TRUE; +} + +bool LLTextureFetchDebugger::update(F32 max_time) +{ + switch(mState) + { + case START_DEBUG: + if(processStartDebug(max_time)) + { + mState = IDLE; + } + break; + case READ_CACHE: + if(!mTextureCache->update(1)) + { + mCacheReadTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + unlockCache(); + } + break; + case WRITE_CACHE: + if(!mTextureCache->update(1)) + { + mCacheWriteTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + unlockCache(); + } + break; + case DECODING: + if(!mImageDecodeThread->update(1)) + { + mDecodingTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + unlockDecoder(); + } + break; + case HTTP_FETCHING: + // Do some notifications... + mFetcher->getHttpRequest().update(10); + if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size()) + { + mHTTPTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + } + break; + case GL_TEX: + if(processGLCreation(max_time)) + { + mState = IDLE; + mTempTexList.clear(); + } + break; + case REFETCH_VIS_CACHE: + if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) + { + mRefetchVisCacheTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + mFetcher->lockFetcher(true); + mFetcher->resetLoadSource(); + } + break; + case REFETCH_VIS_HTTP: + if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) + { + mRefetchVisHTTPTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + mFetcher->lockFetcher(true); + mFetcher->resetLoadSource(); + } + break; + case REFETCH_ALL_CACHE: + scanRefetchList(); + if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) + { + if(!mRefetchNonVis) + { + mRefetchNonVis = TRUE; //start to fetch non-vis + scanRefetchList(); + break; + } + + mRefetchAllCacheTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + mFetcher->lockFetcher(true); + mFetcher->resetLoadSource(); + mRefetchList.clear(); + mRefetchNonVis = FALSE; + } + break; + case REFETCH_ALL_HTTP: + scanRefetchList(); + if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) + { + mRefetchAllHTTPTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + mFetcher->lockFetcher(true); + mFetcher->resetLoadSource(); + mRefetchList.clear(); + mRefetchNonVis = FALSE; + } + break; + default: + mState = IDLE; + break; + } + + return mState == IDLE; +} + +void LLTextureFetchDebugger::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) +{ + handle_fetch_map_t::iterator iter(mHandleToFetchIndex.find(handle)); + if (mHandleToFetchIndex.end() == iter) + { + llinfos << "Fetch Debugger : Couldn't find handle " << handle << " in fetch list." << llendl; + return; + } + + S32 fetch_ind(iter->second); + mHandleToFetchIndex.erase(iter); + if (fetch_ind >= mFetchingHistory.size() || mFetchingHistory[fetch_ind].mHttpHandle != handle) + { + llinfos << "Fetch Debugger : Handle and fetch object in disagreement. Punting." << llendl; + } + else + { + callbackHTTP(mFetchingHistory[fetch_ind], response); + mFetchingHistory[fetch_ind].mHttpHandle = LLCORE_HTTP_HANDLE_INVALID; // Not valid after notification + } +} + +void LLTextureFetchDebugger::callbackCacheRead(S32 id, bool success, LLImageFormatted* image, + S32 imagesize, BOOL islocal) +{ + if (success) + { + mFetchingHistory[id].mFormattedImage = image; + } + mTextureCache->readComplete(mFetchingHistory[id].mCacheHandle, false); + mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle(); +} + +void LLTextureFetchDebugger::callbackCacheWrite(S32 id, bool success) +{ + mTextureCache->writeComplete(mFetchingHistory[id].mCacheHandle); + mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle(); +} + +void LLTextureFetchDebugger::callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux) +{ + if (success) + { + llassert_always(raw); + mFetchingHistory[id].mRawImage = raw; + } +} + +void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response) +{ + static const LLCore::HttpStatus par_status(HTTP_PARTIAL_CONTENT); + + LLCore::HttpStatus status(response->getStatus()); + mNbCurlRequests--; + mNbCurlCompleted++; + fetch.mCurlState = FetchEntry::CURL_DONE; + if (status) + { + const bool partial(par_status == status); + LLCore::BufferArray * ba(response->getBody()); // *Not* holding reference to body + + S32 data_size = ba ? ba->size() : 0; + fetch.mCurlReceivedSize += data_size; + //llinfos << "Fetch Debugger : got results for " << fetch.mID << ", data_size = " << data_size << ", received = " << fetch.mCurlReceivedSize << ", requested = " << fetch.mRequestedSize << ", partial = " << partial << llendl; + if ((fetch.mCurlReceivedSize >= fetch.mRequestedSize) || !partial || (fetch.mRequestedSize == 600)) + { + U8* d_buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size); + if (ba) + { + ba->read(0, d_buffer, data_size); + } + + llassert_always(fetch.mFormattedImage.isNull()); + { + // For now, create formatted image based on extension + std::string texture_url = mHTTPUrl + "/?texture_id=" + fetch.mID.asString().c_str(); + std::string extension = gDirUtilp->getExtension(texture_url); + fetch.mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension)); + if (fetch.mFormattedImage.isNull()) + { + fetch.mFormattedImage = new LLImageJ2C; // default + } + } + + fetch.mFormattedImage->setData(d_buffer, data_size); + } + } + else //failed + { + llinfos << "Fetch Debugger : CURL GET FAILED, ID = " << fetch.mID + << ", status: " << status.toHex() + << " reason: " << status.toString() << llendl; + } +} + + +//--------------------- +/////////////////////////////////////////////////////////////////////////////////////////// +//End LLTextureFetchDebugger +/////////////////////////////////////////////////////////////////////////////////////////// + diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index d101da1f4b..5ea3c14e1a 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2012, 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 @@ -27,27 +27,37 @@ #ifndef LL_LLTEXTUREFETCH_H #define LL_LLTEXTUREFETCH_H +#include <vector> +#include <map> + #include "lldir.h" #include "llimage.h" #include "lluuid.h" #include "llworkerthread.h" -#include "llcurl.h" #include "lltextureinfo.h" #include "llapr.h" +#include "llimageworker.h" +#include "llstat.h" +#include "llcurl.h" +#include "llstat.h" +#include "httprequest.h" +#include "httpoptions.h" +#include "httpheaders.h" +#include "httphandler.h" class LLViewerTexture; class LLTextureFetchWorker; -class HTTPGetResponder; -class LLTextureCache; class LLImageDecodeThread; class LLHost; class LLViewerAssetStats; +class LLTextureFetchDebugger; +class LLTextureCache; // Interface class + class LLTextureFetch : public LLWorkerThread { friend class LLTextureFetchWorker; - friend class HTTPGetResponder; public: LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode); @@ -55,72 +65,201 @@ public: class TFRequest; - /*virtual*/ S32 update(U32 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. + // Threads: Tmain + /*virtual*/ S32 update(F32 max_time_ms); + + // called in the main thread after the TextureCacheThread shuts down. + // Threads: Tmain + void shutDownTextureCacheThread(); + //called in the main thread after the ImageDecodeThread shuts down. + // Threads: Tmain + void shutDownImageDecodeThread(); + + // Threads: T* (but Tmain mostly) bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http); + + // Requests that a fetch operation be deleted from the queue. + // If @cancel is true, also stops any I/O operations pending. + // Actual delete will be scheduled and performed later. + // + // Note: This *looks* like an override/variant of the + // base class's deleteRequest() but is functionally quite + // different. + // + // Threads: T* void deleteRequest(const LLUUID& id, bool cancel); + + void deleteAllRequests(); + + // Threads: T* bool getRequestFinished(const LLUUID& id, S32& discard_level, LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux); + + // Threads: T* bool updateRequestPriority(const LLUUID& id, F32 priority); + // Threads: T* bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data); + + // Threads: T* bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data); + // Threads: T* (but not safe) void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; } + + // Threads: T* (but not safe) F32 getTextureBandwidth() { return mTextureBandwidth; } - // Debug + // Threads: T* BOOL isFromLocalCache(const LLUUID& id); + + // @return Magic number giving the internal state of the + // request. We should make these codes public if we're + // going to return them as a status value. + // + // Threads: T* S32 getFetchState(const LLUUID& id, F32& decode_progress_p, F32& requested_priority_p, U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http); + + // Debug utility - generally not safe void dump(); - S32 getNumRequests() ; - S32 getNumHTTPRequests() ; - U32 getTotalNumHTTPRequests() ; + + // Threads: T* + S32 getNumRequests(); + + // Threads: T* + S32 getNumHTTPRequests(); + + // Threads: T* + U32 getTotalNumHTTPRequests(); - // Public for access by callbacks + // Threads: T* S32 getPending(); + + // Threads: T* void lockQueue() { mQueueMutex.lock(); } + + // Threads: T* void unlockQueue() { mQueueMutex.unlock(); } + + // Threads: T* LLTextureFetchWorker* getWorker(const LLUUID& id); + + // Threads: T* + // Locks: Mfq LLTextureFetchWorker* getWorkerAfterLock(const LLUUID& id); - LLTextureInfo* getTextureInfo() { return &mTextureInfo; } - // Commands available to other threads to control metrics gathering operations. + + // Threads: T* void commandSetRegion(U64 region_handle); + + // Threads: T* void commandSendMetrics(const std::string & caps_url, const LLUUID & session_id, const LLUUID & agent_id, LLViewerAssetStats * main_stats); + + // Threads: T* void commandDataBreak(); - LLCurlRequest & getCurlRequest() { return *mCurlGetRequest; } + // Threads: T* + LLCore::HttpRequest & getHttpRequest() { return *mHttpRequest; } + + // Threads: T* + LLCore::HttpRequest::policy_t getPolicyClass() const { return mHttpPolicyClass; } + + // Return a pointer to the shared metrics headers definition. + // Does not increment the reference count, caller is required + // to do that to hold a reference for any length of time. + // + // Threads: T* + LLCore::HttpHeaders * getMetricsHeaders() const { return mHttpMetricsHeaders; } bool isQAMode() const { return mQAMode; } - // Curl POST counter maintenance - inline void incrCurlPOSTCount() { mCurlPOSTRequestCount++; } - inline void decrCurlPOSTCount() { mCurlPOSTRequestCount--; } + // ---------------------------------- + // HTTP resource waiting methods + + // Threads: T* + void addHttpWaiter(const LLUUID & tid); + + // Threads: T* + void removeHttpWaiter(const LLUUID & tid); + + // Threads: T* + bool isHttpWaiter(const LLUUID & tid); + + // If there are slots, release one or more LLTextureFetchWorker + // requests from resource wait state (WAIT_HTTP_RESOURCE) to + // active (SEND_HTTP_REQ). + // + // Because this will modify state of many workers, you may not + // hold any Mw lock while calling. This makes it a little + // inconvenient to use but that's the rule. + // + // Threads: T* + // Locks: -Mw (must not hold any worker when called) + void releaseHttpWaiters(); + // Threads: T* + void cancelHttpWaiters(); + + // Threads: T* + int getHttpWaitersCount(); + // ---------------------------------- + // Stats management + + // Add given counts to the global totals for the states/requests + // Threads: T* + void updateStateStats(U32 cache_read, U32 cache_write, U32 res_wait); + + // Return the global counts + // Threads: T* + void getStateStats(U32 * cache_read, U32 * cache_write, U32 * res_wait); + + // ---------------------------------- + protected: + // Threads: T* (but Ttf in practice) void addToNetworkQueue(LLTextureFetchWorker* worker); + + // Threads: T* void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); + + // Threads: T* void addToHTTPQueue(const LLUUID& id); - void removeFromHTTPQueue(const LLUUID& id, S32 received_size = 0); - void removeRequest(LLTextureFetchWorker* worker, bool cancel); + // XXX possible delete + // Threads: T* + void removeFromHTTPQueue(const LLUUID& id, S32 received_size); + + // Identical to @deleteRequest but with different arguments + // (caller already has the worker pointer). + // + // Threads: T* + void removeRequest(LLTextureFetchWorker* worker, bool cancel); + // Overrides from the LLThread tree + // Locks: Ct bool runCondition(); private: + // Threads: Tmain void sendRequestListToSimulators(); + + // Threads: Ttf /*virtual*/ void startThread(void); + + // Threads: Ttf /*virtual*/ void endThread(void); + + // Threads: Ttf /*virtual*/ void threadedUpdate(void); + + // Threads: Ttf void commonUpdate(); // Metrics command helpers @@ -131,6 +270,8 @@ private: * Takes ownership of the TFRequest object. * * Method locks the command queue. + * + * Threads: T* */ void cmdEnqueue(TFRequest *); @@ -141,6 +282,8 @@ private: * Caller acquires ownership of the object and must dispose of it. * * Method locks the command queue. + * + * Threads: T* */ TFRequest * cmdDequeue(); @@ -150,6 +293,8 @@ private: * additional commands. * * Method locks the command queue. + * + * Threads: Ttf */ void cmdDoWork(); @@ -164,52 +309,311 @@ private: LLMutex mQueueMutex; //to protect mRequestMap and mCommands only LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. + static LLStat sCacheHitRate; + static LLStat sCacheReadLatency; + LLTextureCache* mTextureCache; LLImageDecodeThread* mImageDecodeThread; - LLCurlRequest* mCurlGetRequest; // Map of all requests by UUID typedef std::map<LLUUID,LLTextureFetchWorker*> map_t; - map_t mRequestMap; + map_t mRequestMap; // Mfq // Set of requests that require network data typedef std::set<LLUUID> queue_t; - queue_t mNetworkQueue; - queue_t mHTTPTextureQueue; + queue_t mNetworkQueue; // Mfnq + queue_t mHTTPTextureQueue; // Mfnq typedef std::map<LLHost,std::set<LLUUID> > cancel_queue_t; - cancel_queue_t mCancelQueue; - F32 mTextureBandwidth; - F32 mMaxBandwidth; + cancel_queue_t mCancelQueue; // Mfnq + F32 mTextureBandwidth; // <none> + F32 mMaxBandwidth; // Mfnq LLTextureInfo mTextureInfo; - U32 mHTTPTextureBits; + // XXX possible delete + U32 mHTTPTextureBits; // Mfnq + // XXX possible delete //debug use - U32 mTotalHTTPRequests ; + U32 mTotalHTTPRequests; // Out-of-band cross-thread command queue. This command queue // is logically tied to LLQueuedThread's list of // QueuedRequest instances and so must be covered by the // same locks. typedef std::vector<TFRequest *> command_queue_t; - command_queue_t mCommands; + command_queue_t mCommands; // Mfq // If true, modifies some behaviors that help with QA tasks. const bool mQAMode; - // Count of POST requests outstanding. We maintain the count - // indirectly in the CURL request responder's ctor and dtor and - // use it when determining whether or not to sleep the thread. Can't - // use the LLCurl module's request counter as it isn't thread compatible. - // *NOTE: Don't mix Atomic and static, apr_initialize must be called first. - LLAtomic32<S32> mCurlPOSTRequestCount; + // Interfaces and objects into the core http library used + // to make our HTTP requests. These replace the various + // LLCurl interfaces used in the past. + LLCore::HttpRequest * mHttpRequest; // Ttf + LLCore::HttpOptions * mHttpOptions; // Ttf + LLCore::HttpHeaders * mHttpHeaders; // Ttf + LLCore::HttpHeaders * mHttpMetricsHeaders; // Ttf + LLCore::HttpRequest::policy_t mHttpPolicyClass; // T* + + // We use a resource semaphore to keep HTTP requests in + // WAIT_HTTP_RESOURCE2 if there aren't sufficient slots in the + // transport. This keeps them near where they can be cheaply + // reprioritized rather than dumping them all across a thread + // where it's more expensive to get at them. Requests in either + // SEND_HTTP_REQ or WAIT_HTTP_REQ charge against the semaphore + // and tracking state transitions is critical to liveness. + LLAtomicS32 mHttpSemaphore; // Ttf + Tmain + + typedef std::set<LLUUID> wait_http_res_queue_t; + wait_http_res_queue_t mHttpWaitResource; // Mfnq + + // Cumulative stats on the states/requests issued by + // textures running through here. + U32 mTotalCacheReadCount; // Mfq + U32 mTotalCacheWriteCount; // Mfq + U32 mTotalResourceWaitCount; // Mfq public: // A probabilistically-correct indicator that the current // attempt to log metrics follows a break in the metrics stream // reporting due to either startup or a problem POSTing data. static volatile bool svMetricsDataBreak; + +public: + //debug use + enum e_tex_source + { + FROM_ALL = 0, + FROM_HTTP_ONLY, + INVALID_SOURCE + }; +private: + //debug use + LLTextureFetchDebugger* mFetchDebugger; + bool mFetcherLocked; + + e_tex_source mFetchSource; + e_tex_source mOriginFetchSource; + +public: + //debug use + LLTextureFetchDebugger* getFetchDebugger() { return mFetchDebugger;} + void lockFetcher(bool lock) { mFetcherLocked = lock;} + + void setLoadSource(e_tex_source source) {mFetchSource = source;} + void resetLoadSource() {mFetchSource = mOriginFetchSource;} + bool canLoadFromCache() { return mFetchSource != FROM_HTTP_ONLY;} }; +//debug use +class LLViewerFetchedTexture; +class LLTextureFetchDebugger : public LLCore::HttpHandler +{ + friend class LLTextureFetch; +public: + LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) ; + ~LLTextureFetchDebugger(); + +public: + enum e_debug_state + { + IDLE = 0, + START_DEBUG, + READ_CACHE, + WRITE_CACHE, + DECODING, + HTTP_FETCHING, + GL_TEX, + REFETCH_VIS_CACHE, + REFETCH_VIS_HTTP, + REFETCH_ALL_CACHE, + REFETCH_ALL_HTTP, + INVALID + }; + +private: + struct FetchEntry + { + enum e_curl_state + { + CURL_NOT_DONE = 0, + CURL_IN_PROGRESS, + CURL_DONE + }; + LLUUID mID; + S32 mRequestedSize; + S32 mDecodedLevel; + S32 mFetchedSize; + S32 mDecodedSize; + BOOL mNeedsAux; + U32 mCacheHandle; + LLPointer<LLImageFormatted> mFormattedImage; + LLPointer<LLImageRaw> mRawImage; + e_curl_state mCurlState; + S32 mCurlReceivedSize; + LLCore::HttpHandle mHttpHandle; + + FetchEntry() : + mDecodedLevel(-1), + mFetchedSize(0), + mDecodedSize(0), + mHttpHandle(LLCORE_HTTP_HANDLE_INVALID) + {} + FetchEntry(LLUUID& id, S32 r_size, /*S32 f_discard, S32 c,*/ S32 level, S32 f_size, S32 d_size) : + mID(id), + mRequestedSize(r_size), + mDecodedLevel(level), + mFetchedSize(f_size), + mDecodedSize(d_size), + mNeedsAux(false), + mHttpHandle(LLCORE_HTTP_HANDLE_INVALID) + {} + }; + typedef std::vector<FetchEntry> fetch_list_t; + fetch_list_t mFetchingHistory; + + typedef std::map<LLCore::HttpHandle, S32> handle_fetch_map_t; + handle_fetch_map_t mHandleToFetchIndex; + + e_debug_state mState; + + F32 mCacheReadTime; + F32 mCacheWriteTime; + F32 mDecodingTime; + F32 mHTTPTime; + F32 mGLCreationTime; + + F32 mTotalFetchingTime; + F32 mRefetchVisCacheTime; + F32 mRefetchVisHTTPTime; + F32 mRefetchAllCacheTime; + F32 mRefetchAllHTTPTime; + + LLTimer mTimer; + + LLTextureFetch* mFetcher; + LLTextureCache* mTextureCache; + LLImageDecodeThread* mImageDecodeThread; + LLCore::HttpHeaders* mHttpHeaders; + LLCore::HttpRequest::policy_t mHttpPolicyClass; + + S32 mNumFetchedTextures; + S32 mNumCacheHits; + S32 mNumVisibleFetchedTextures; + S32 mNumVisibleFetchingRequests; + U32 mFetchedData; + U32 mDecodedData; + U32 mVisibleFetchedData; + U32 mVisibleDecodedData; + U32 mRenderedData; + U32 mRenderedDecodedData; + U32 mFetchedPixels; + U32 mRenderedPixels; + U32 mRefetchedVisData; + U32 mRefetchedVisPixels; + U32 mRefetchedAllData; + U32 mRefetchedAllPixels; + + BOOL mFreezeHistory; + BOOL mStopDebug; + BOOL mClearHistory; + BOOL mRefetchNonVis; + + std::string mHTTPUrl; + S32 mNbCurlRequests; + S32 mNbCurlCompleted; + + std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> > mRefetchList; + std::vector< LLPointer<LLViewerFetchedTexture> > mTempTexList; + S32 mTempIndex; + S32 mHistoryListIndex; + +public: + bool update(F32 max_time); //called in the main thread once per frame + + //fetching history + void clearHistory(); + void addHistoryEntry(LLTextureFetchWorker* worker); + + // Inherited from LLCore::HttpHandler + // Threads: Ttf + virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); + + void startWork(e_debug_state state); + void setStopDebug() {mStopDebug = TRUE;} + void tryToStopDebug(); //stop everything + void callbackCacheRead(S32 id, bool success, LLImageFormatted* image, + S32 imagesize, BOOL islocal); + void callbackCacheWrite(S32 id, bool success); + void callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux); + void callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response); + + e_debug_state getState() {return mState;} + S32 getNumFetchedTextures() {return mNumFetchedTextures;} + S32 getNumFetchingRequests() {return mFetchingHistory.size();} + S32 getNumCacheHits() {return mNumCacheHits;} + S32 getNumVisibleFetchedTextures() {return mNumVisibleFetchedTextures;} + S32 getNumVisibleFetchingRequests() {return mNumVisibleFetchingRequests;} + U32 getFetchedData() {return mFetchedData;} + U32 getDecodedData() {return mDecodedData;} + U32 getVisibleFetchedData() {return mVisibleFetchedData;} + U32 getVisibleDecodedData() {return mVisibleDecodedData;} + U32 getRenderedData() {return mRenderedData;} + U32 getRenderedDecodedData() {return mRenderedDecodedData;} + U32 getFetchedPixels() {return mFetchedPixels;} + U32 getRenderedPixels() {return mRenderedPixels;} + U32 getRefetchedVisData() {return mRefetchedVisData;} + U32 getRefetchedVisPixels() {return mRefetchedVisPixels;} + U32 getRefetchedAllData() {return mRefetchedAllData;} + U32 getRefetchedAllPixels() {return mRefetchedAllPixels;} + + F32 getCacheReadTime() {return mCacheReadTime;} + F32 getCacheWriteTime() {return mCacheWriteTime;} + F32 getDecodeTime() {return mDecodingTime;} + F32 getGLCreationTime() {return mGLCreationTime;} + F32 getHTTPTime() {return mHTTPTime;} + F32 getTotalFetchingTime() {return mTotalFetchingTime;} + F32 getRefetchVisCacheTime() {return mRefetchVisCacheTime;} + F32 getRefetchVisHTTPTime() {return mRefetchVisHTTPTime;} + F32 getRefetchAllCacheTime() {return mRefetchAllCacheTime;} + F32 getRefetchAllHTTPTime() {return mRefetchAllHTTPTime;} + +private: + void init(); + void clearTextures();//clear fetching results of all textures. + void clearCache(); + void makeRefetchList(); + void scanRefetchList(); + + void lockFetcher(); + void unlockFetcher(); + + void lockCache(); + void unlockCache(); + + void lockDecoder(); + void unlockDecoder(); + + S32 fillCurlQueue(); + + void startDebug(); + void debugCacheRead(); + void debugCacheWrite(); + void debugHTTP(); + void debugDecoder(); + void debugGLTextureCreation(); + void debugRefetchVisibleFromCache(); + void debugRefetchVisibleFromHTTP(); + void debugRefetchAllFromCache(); + void debugRefetchAllFromHTTP(); + + bool processStartDebug(F32 max_time); + bool processGLCreation(F32 max_time); + +private: + static bool sDebuggerEnabled; +public: + static bool isEnabled() {return sDebuggerEnabled;} +}; #endif // LL_LLTEXTUREFETCH_H diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 1c89766b26..16c42dbd43 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2012, 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 @@ -57,8 +57,6 @@ extern F32 texmem_lower_bound_scale; LLTextureView *gTextureView = NULL; -LLTextureSizeView *gTextureSizeView = NULL; -LLTextureSizeView *gTextureCategoryView = NULL; #define HIGH_PRIORITY 100000000.f @@ -76,7 +74,7 @@ static std::string title_string4(" W x H (Dis) Mem"); static S32 title_x1 = 0; static S32 title_x2 = 460; static S32 title_x3 = title_x2 + 40; -static S32 title_x4 = title_x3 + 50; +static S32 title_x4 = title_x3 + 46; static S32 texture_bar_height = 8; //////////////////////////////////////////////////////////////////////////// @@ -234,6 +232,8 @@ void LLTextureBar::draw() { "DSK", LLColor4::blue }, // CACHE_POST { "NET", LLColor4::green }, // LOAD_FROM_NETWORK { "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR + { "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE + { "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE2 { "REQ", LLColor4::yellow },// SEND_HTTP_REQ { "HTP", LLColor4::green }, // WAIT_HTTP_REQ { "DEC", LLColor4::yellow },// DECODE_IMAGE @@ -241,7 +241,7 @@ void LLTextureBar::draw() { "WRT", LLColor4::purple },// WRITE_TO_CACHE { "WRT", LLColor4::orange },// WAIT_ON_WRITE { "END", LLColor4::red }, // DONE -#define LAST_STATE 12 +#define LAST_STATE 14 { "CRE", LLColor4::magenta }, // LAST_STATE+1 { "FUL", LLColor4::green }, // LAST_STATE+2 { "BAD", LLColor4::red }, // LAST_STATE+3 @@ -347,7 +347,7 @@ void LLTextureBar::draw() // draw the image size at the end { - std::string num_str = llformat("%3dx%3d (%d) %7d", mImagep->getWidth(), mImagep->getHeight(), + std::string num_str = llformat("%3dx%3d (%2d) %7d", mImagep->getWidth(), mImagep->getHeight(), mImagep->getDiscardLevel(), mImagep->hasGLTexture() ? mImagep->getTextureMemory() : 0); LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, title_x4, getRect().getHeight(), color, LLFontGL::LEFT, LLFontGL::TOP); @@ -386,7 +386,7 @@ public: Params() : texture_view("texture_view") { - S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); + S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); changeDefault(rect, LLRect(0,0,100,line_height * 4)); } }; @@ -411,7 +411,7 @@ void LLAvatarTexBar::draw() LLVOAvatarSelf* avatarp = gAgentAvatarp; if (!avatarp) return; - const S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); + const S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); const S32 v_offset = 0; const S32 l_offset = 3; @@ -485,7 +485,7 @@ public: Params() : texture_view("texture_view") { - S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); + S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); changeDefault(rect, LLRect(0,0,100,line_height * 4)); } }; @@ -512,95 +512,55 @@ void LLGLTexMemBar::draw() F32 discard_bias = LLViewerTexture::sDesiredDiscardBias; F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ; F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ; - S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - S32 v_offset = (S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f); + S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); + S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f); F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024); F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024); - U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ; + U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests(); //---------------------------------------------------------------------------- LLGLSUIDefault gls_ui; LLColor4 text_color(1.f, 1.f, 1.f, 0.75f); LLColor4 color; - - std::string text = ""; + // Gray background using completely magic numbers + gGL.color4f(0.f, 0.f, 0.f, 0.25f); + // const LLRect & rect(getRect()); + // gl_rect_2d(-4, v_offset, rect.mRight - rect.mLeft + 2, v_offset + line_height*4); + + std::string text = ""; LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6, text_color, LLFontGL::LEFT, LLFontGL::TOP); - text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d", + text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB", total_mem, max_total_mem, bound_mem, max_bound_mem, LLRenderTarget::sBytesAllocated/(1024*1024), - LLImageRaw::sGlobalRawMemory >> 20, discard_bias, - cache_usage, cache_max_usage, total_texture_downloaded, total_object_downloaded, total_http_requests); + LLImageRaw::sGlobalRawMemory >> 20, + discard_bias, + cache_usage, + cache_max_usage); //, cache_entries, cache_max_entries - LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3, + LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4, text_color, LLFontGL::LEFT, LLFontGL::TOP); - //---------------------------------------------------------------------------- -#if 0 - S32 bar_left = 400; - S32 bar_width = 200; - S32 top = line_height*3 - 2 + v_offset; - S32 bottom = top - 6; - S32 left = bar_left; - S32 right = left + bar_width; - F32 bar_scale; + U32 cache_read(0U), cache_write(0U), res_wait(0U); + LLAppViewer::getTextureFetch()->getStateStats(&cache_read, &cache_write, &res_wait); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u", + total_texture_downloaded, + total_object_downloaded, + total_http_requests, + cache_read, + cache_write, + res_wait); - // GL Mem Bar - - left = bar_left; - text = "GL"; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3, + LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3, text_color, LLFontGL::LEFT, LLFontGL::TOP); - - left = bar_left+20; - right = left + bar_width; - - gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f); // grey - gl_rect_2d(left, top, right, bottom); - - bar_scale = (F32)bar_width / (max_total_mem * 1.5f); - right = left + llfloor(total_mem * bar_scale); - right = llclamp(right, bar_left, bar_left + bar_width); - - color = (total_mem < llfloor(max_total_mem * texmem_lower_bound_scale)) ? LLColor4::green : - (total_mem < max_total_mem) ? LLColor4::yellow : LLColor4::red; - color[VALPHA] = .75f; - gGL.diffuseColor4fv(color.mV); - - gl_rect_2d(left, top, right, bottom); // red/yellow/green - - // - bar_left += bar_width + bar_space; - //top = bottom - 2; bottom = top - 6; - - // Bound Mem Bar - left = bar_left; - text = "GL"; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - left = bar_left + 20; - right = left + bar_width; - - gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f); - gl_rect_2d(left, top, right, bottom); - - color = (bound_mem < llfloor(max_bound_mem * texmem_lower_bound_scale)) ? LLColor4::green : - (bound_mem < max_bound_mem) ? LLColor4::yellow : LLColor4::red; - color[VALPHA] = .75f; - gGL.diffuseColor4fv(color.mV); - - gl_rect_2d(left, top, right, bottom); -#else S32 left = 0 ; -#endif //---------------------------------------------------------------------------- text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d", @@ -669,8 +629,7 @@ BOOL LLGLTexMemBar::handleMouseDown(S32 x, S32 y, MASK mask) LLRect LLGLTexMemBar::getRequiredRect() { LLRect rect; - //rect.mTop = 50; - rect.mTop = 0; + rect.mTop = 50; //LLFontGL::getFontMonospace()->getLineHeight() * 6; return rect; } @@ -954,9 +913,11 @@ void LLTextureView::draw() LLRect tmbr; tmbp.name("gl texmem bar"); tmbp.rect(tmbr); + tmbp.follows.flags = FOLLOWS_LEFT|FOLLOWS_TOP; tmbp.texture_view(this); mGLTexMemBar = LLUICtrlFactory::create<LLGLTexMemBar>(tmbp); - addChildInBack(mGLTexMemBar); + addChild(mGLTexMemBar); + sendChildToFront(mGLTexMemBar); LLAvatarTexBar::Params atbp; LLRect atbr; @@ -965,16 +926,13 @@ void LLTextureView::draw() atbp.rect(atbr); mAvatarTexBar = LLUICtrlFactory::create<LLAvatarTexBar>(atbp); addChild(mAvatarTexBar); + sendChildToFront(mAvatarTexBar); reshape(getRect().getWidth(), getRect().getHeight(), TRUE); - /* - count = gTextureList.getNumImages(); - std::string info_string; - info_string = llformat("Global Info:\nTexture Count: %d", count); - mInfoTextp->setText(info_string); - */ - + LLUI::popMatrix(); + LLUI::pushMatrix(); + LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom); for (child_list_const_iter_t child_iter = getChildList()->begin(); child_iter != getChildList()->end(); ++child_iter) @@ -1049,302 +1007,4 @@ BOOL LLTextureView::handleKey(KEY key, MASK mask, BOOL called_from_parent) return FALSE; } -//----------------------------------------------------------------- -LLTextureSizeView::LLTextureSizeView(const LLTextureSizeView::Params& p) : LLContainerView(p) -{ - setVisible(FALSE) ; - - mTextureSizeBarWidth = 30 ; -} - -LLTextureSizeView::~LLTextureSizeView() -{ - if(mTextureSizeBar.size()) - { - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - delete mTextureSizeBar[i] ; - } - mTextureSizeBar.clear() ; - } -} -void LLTextureSizeView::draw() -{ - if(mType == TEXTURE_MEM_OVER_SIZE) - { - drawTextureSizeGraph(); - } - else - { - drawTextureCategoryGraph() ; - } - - LLView::draw(); -} - -BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask) -{ - if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight) - { - mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask, (mType == TEXTURE_MEM_OVER_SIZE)) ; - } - - return TRUE ; -} - -//draw real-time texture mem bar over size -void LLTextureSizeView::drawTextureSizeGraph() -{ - if(mTextureSizeBar.size() == 0) - { - S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - mTextureSizeBar.resize(LLImageGL::sTextureLoadedCounter.size()) ; - mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ; - - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth , - line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ; - } - } - - F32 size_bar_scale = drawTextureSizeDistributionGraph() ; - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - mTextureSizeBar[i]->setTop(LLImageGL::sTextureLoadedCounter[i], LLImageGL::sTextureBoundCounter[i], size_bar_scale) ; - mTextureSizeBar[i]->draw() ; - } - LLImageGL::resetCurTexSizebar(); -} - -//draw background of texture size bar graph -F32 LLTextureSizeView::drawTextureSizeDistributionGraph() -{ - //scale - F32 scale = 1.0f ; - - LLGLSUIDefault gls_ui; - - { - S32 count = 0 ; - for(U32 i = 0 ; i < LLImageGL::sTextureLoadedCounter.size() ; i++) - { - if(LLImageGL::sTextureLoadedCounter[i] > count) - { - count = LLImageGL::sTextureLoadedCounter[i] ; - } - } - if(count > mTextureSizeBarRect.getHeight()) - { - scale = (F32)mTextureSizeBarRect.getHeight() / count ; - } - } - - S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - S32 left = mTextureSizeBarRect.mLeft ; - S32 bottom = mTextureSizeBarRect.mBottom ; - S32 right = mTextureSizeBarRect.mRight ; - S32 top = mTextureSizeBarRect.mTop ; - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - //background rect - gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ; - - //-------------------------------------------------- - gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f); - gl_line_2d(left, bottom, right, bottom) ; //x axis - gl_line_2d(left, bottom, left, top) ; //y axis - - //ruler - //-------------------------------------------------- - gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f); - for(S32 i = bottom + 50 ; i <= top ; i += 50) - { - gl_line_2d(left, i, right, i) ; - } - - //texts - //-------------------------------------------------- - F32 text_color[] = {1.f, 1.f, 1.f, 0.75f}; - std::string text; - - //------- - //x axis: size label - text = llformat("%d", 0) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++) - { - text = llformat("%d", (1 << (i / 2)) + ((i & 1) ? ((1 << (i / 2)) >> 1) : 0)) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - } - text = llformat("(w + h)/2") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 10, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - //------- - - //y axis: number label - for(S32 i = bottom + 50 ; i <= top ; i += 50) - { - text = llformat("%d", (S32)((i - bottom) / scale)) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - } - - //-------------------------------------------------- - F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f}; - gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ; - text = llformat("Loaded") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2, - loaded_color, LLFontGL::LEFT, LLFontGL::TOP); - - F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; - gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ; - text = llformat("Bound") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2, - bound_color, LLFontGL::LEFT, LLFontGL::TOP); - - //-------------------------------------------------- - - //title - text = llformat("Texture Size Distribution") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - return scale ; -} - -//draw real-time texture mem bar over category -void LLTextureSizeView::drawTextureCategoryGraph() -{ - if(mTextureSizeBar.size() == 0) - { - S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - mTextureSizeBar.resize(LLViewerTexture::getTotalNumOfCategories()) ; - mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ; - - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth , - line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ; - } - } - - F32 size_bar_scale = drawTextureCategoryDistributionGraph() ; - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - U32 k = LLViewerTexture::getIndexFromCategory(i) ; - mTextureSizeBar[i]->setTop(LLImageGL::sTextureMemByCategory[k] >> 20, LLImageGL::sTextureMemByCategoryBound[k] >> 20, size_bar_scale) ; - mTextureSizeBar[i]->draw() ; - } - LLImageGL::resetCurTexSizebar(); -} - -//draw background for TEXTURE_MEM_OVER_CATEGORY -F32 LLTextureSizeView::drawTextureCategoryDistributionGraph() -{ - //scale - F32 scale = 4.0f ; - - LLGLSUIDefault gls_ui; - - { - S32 count = 0 ; - for(U32 i = 0 ; i < LLImageGL::sTextureMemByCategory.size() ; i++) - { - S32 tmp = LLImageGL::sTextureMemByCategory[i] >> 20 ; - if(tmp > count) - { - count = tmp ; - } - } - if(count > mTextureSizeBarRect.getHeight() * 0.25f) - { - scale = (F32)mTextureSizeBarRect.getHeight() * 0.25f / count ; - } - } - - S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - S32 left = mTextureSizeBarRect.mLeft ; - S32 bottom = mTextureSizeBarRect.mBottom ; - S32 right = mTextureSizeBarRect.mRight ; - S32 top = mTextureSizeBarRect.mTop ; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - //background rect - gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ; - - //-------------------------------------------------- - gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f); - gl_line_2d(left, bottom, right, bottom) ; //x axis - gl_line_2d(left, bottom, left, top) ; //y axis - - //ruler - //-------------------------------------------------- - gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f); - for(S32 i = bottom + 50 ; i <= top ; i += 50) - { - gl_line_2d(left, i, right, i) ; - } - - //texts - //-------------------------------------------------- - F32 text_color[] = {1.f, 1.f, 1.f, 0.75f}; - std::string text; - - //------- - //x axis: size label - static char category[LLViewerTexture::MAX_GL_IMAGE_CATEGORY][4] = - {"Non", "Bak", "Av", "Cld", "Scp", "Hi", "Trn", "Slt", "Hud", "Bsf", "UI", "Pvw", "Map", "Mvs", "Slf", "Loc", "Scr", "Dyn", "Mdi", "ALT", "Oth" } ; - - text = llformat("%s", category[0]) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++) - { - text = llformat("%s", category[i]) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - } - //------- - - //y axis: number label - for(S32 i = bottom + 50 ; i <= top ; i += 50) - { - text = llformat("%d", (S32)((i - bottom) / scale)) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - } - - text = llformat("MB") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, top + line_height * 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - //-------------------------------------------------- - F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f}; - gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ; - text = llformat("Loaded") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2, - loaded_color, - LLFontGL::LEFT, LLFontGL::TOP); - - F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; - gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ; - text = llformat("Bound") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2, - bound_color, LLFontGL::LEFT, LLFontGL::TOP); - - //-------------------------------------------------- - - //title - text = llformat("Texture Category Distribution") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - - return scale ; -} diff --git a/indra/newview/lltextureview.h b/indra/newview/lltextureview.h index 3723eb737b..900b4e17d8 100644 --- a/indra/newview/lltextureview.h +++ b/indra/newview/lltextureview.h @@ -75,41 +75,6 @@ public: }; class LLGLTexSizeBar; -class LLTextureSizeView : public LLContainerView -{ -protected: - LLTextureSizeView(const Params&); - friend class LLUICtrlFactory; -public: - ~LLTextureSizeView(); - - /*virtual*/ void draw(); - /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) ; - - void setType(S32 type) {mType = type ;} - enum - { - TEXTURE_MEM_OVER_SIZE, - TEXTURE_MEM_OVER_CATEGORY - }; -private: - //draw background for TEXTURE_MEM_OVER_SIZE - F32 drawTextureSizeDistributionGraph() ; - //draw real-time texture mem bar over size - void drawTextureSizeGraph(); - - //draw background for TEXTURE_MEM_OVER_CATEGORY - F32 drawTextureCategoryDistributionGraph() ; - //draw real-time texture mem bar over category - void drawTextureCategoryGraph(); -private: - std::vector<LLGLTexSizeBar*> mTextureSizeBar ; - LLRect mTextureSizeBarRect ; - S32 mTextureSizeBarWidth ; - S32 mType ; -}; extern LLTextureView *gTextureView; -extern LLTextureSizeView *gTextureSizeView; -extern LLTextureSizeView *gTextureCategoryView; #endif // LL_TEXTURE_VIEW_H diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index e0b07ed408..9dfb29b905 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -113,17 +113,16 @@ LLToast::LLToast(const LLToast::Params& p) mHideBtnPressed(false), mIsTip(p.is_tip), mWrapperPanel(NULL), - mIsFading(false) + mIsFading(false), + mIsHovered(false) { mTimer.reset(new LLToastLifeTimer(this, p.lifetime_secs)); - buildFromFile("panel_toast.xml", NULL); + buildFromFile("panel_toast.xml"); setCanDrag(FALSE); mWrapperPanel = getChild<LLPanel>("wrapper_panel"); - mWrapperPanel->setMouseEnterCallback(boost::bind(&LLToast::onToastMouseEnter, this)); - mWrapperPanel->setMouseLeaveCallback(boost::bind(&LLToast::onToastMouseLeave, this)); setBackgroundOpaque(TRUE); // *TODO: obsolete updateTransparency(); @@ -137,13 +136,13 @@ LLToast::LLToast(const LLToast::Params& p) { mHideBtn = getChild<LLButton>("hide_btn"); mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this)); - mHideBtn->setMouseEnterCallback(boost::bind(&LLToast::onToastMouseEnter, this)); - mHideBtn->setMouseLeaveCallback(boost::bind(&LLToast::onToastMouseLeave, this)); } // init callbacks if present if(!p.on_delete_toast().empty()) + { mOnDeleteToastSignal.connect(p.on_delete_toast()); + } } void LLToast::reshape(S32 width, S32 height, BOOL called_from_parent) @@ -181,11 +180,14 @@ LLToast::~LLToast() //-------------------------------------------------------------------------- void LLToast::hide() { - setVisible(FALSE); - setFading(false); - mTimer->stop(); - mIsHidden = true; - mOnFadeSignal(this); + if (!mIsHidden) + { + setVisible(FALSE); + setFading(false); + mTimer->stop(); + mIsHidden = true; + mOnFadeSignal(this); + } } void LLToast::onFocusLost() @@ -216,6 +218,13 @@ void LLToast::setFadingTime(S32 seconds) mToastFadingTime = seconds; } +void LLToast::closeToast() +{ + mOnDeleteToastSignal(this); + + closeFloater(); +} + S32 LLToast::getTopPad() { if(mWrapperPanel) @@ -239,7 +248,9 @@ void LLToast::setCanFade(bool can_fade) { mCanFade = can_fade; if(!mCanFade) + { mTimer->stop(); + } } //-------------------------------------------------------------------------- @@ -295,9 +306,7 @@ void LLToast::reshapeToPanel() if(!panel) return; - LLRect panel_rect = panel->getRect(); - - panel_rect.setLeftTopAndSize(0, panel_rect.getHeight(), panel_rect.getWidth(), panel_rect.getHeight()); + LLRect panel_rect = panel->getLocalRect(); panel->setShape(panel_rect); LLRect toast_rect = getRect(); @@ -378,8 +387,11 @@ void LLToast::setVisible(BOOL show) } } -void LLToast::onToastMouseEnter() +void LLToast::updateHoveredState() { + S32 x, y; + LLUI::getMousePositionScreen(&x, &y); + LLRect panel_rc = mWrapperPanel->calcScreenRect(); LLRect button_rc; if(mHideBtn) @@ -387,56 +399,83 @@ void LLToast::onToastMouseEnter() button_rc = mHideBtn->calcScreenRect(); } - S32 x, y; - LLUI::getMousePositionScreen(&x, &y); - - if(panel_rc.pointInRect(x, y) || button_rc.pointInRect(x, y)) + if (!panel_rc.pointInRect(x, y) && !button_rc.pointInRect(x, y)) { - mOnToastHoverSignal(this, MOUSE_ENTER); - - updateTransparency(); + // mouse is not over this toast + mIsHovered = false; + } + else + { + bool is_overlapped_by_other_floater = false; - //toasts fading is management by Screen Channel + const child_list_t* child_list = gFloaterView->getChildList(); - sendChildToFront(mHideBtn); - if(mHideBtn && mHideBtn->getEnabled()) + // find this toast in gFloaterView child list to check whether any floater + // with higher Z-order is visible under the mouse pointer overlapping this toast + child_list_const_reverse_iter_t r_iter = std::find(child_list->rbegin(), child_list->rend(), this); + if (r_iter != child_list->rend()) { - mHideBtn->setVisible(TRUE); + // skip this toast and proceed to views above in Z-order + for (++r_iter; r_iter != child_list->rend(); ++r_iter) + { + LLView* view = *r_iter; + is_overlapped_by_other_floater = view->isInVisibleChain() && view->calcScreenRect().pointInRect(x, y); + if (is_overlapped_by_other_floater) + { + break; + } + } } - mToastMouseEnterSignal(this, getValue()); - } -} -void LLToast::onToastMouseLeave() -{ - LLRect panel_rc = mWrapperPanel->calcScreenRect(); - LLRect button_rc; - if(mHideBtn) - { - button_rc = mHideBtn->calcScreenRect(); + mIsHovered = !is_overlapped_by_other_floater; } - S32 x, y; - LLUI::getMousePositionScreen(&x, &y); - - if( !panel_rc.pointInRect(x, y) && !button_rc.pointInRect(x, y)) - { - mOnToastHoverSignal(this, MOUSE_LEAVE); - - updateTransparency(); - - //toasts fading is management by Screen Channel - - if(mHideBtn && mHideBtn->getEnabled()) + LLToastLifeTimer* timer = getTimer(); + + if (timer) + { + // Started timer means the mouse had left the toast previously. + // If toast is hovered in the current frame we should handle + // a mouse enter event. + if(timer->getStarted() && mIsHovered) { - if( mHideBtnPressed ) + mOnToastHoverSignal(this, MOUSE_ENTER); + + updateTransparency(); + + //toasts fading is management by Screen Channel + + sendChildToFront(mHideBtn); + if(mHideBtn && mHideBtn->getEnabled()) { - mHideBtnPressed = false; - return; + mHideBtn->setVisible(TRUE); } - mHideBtn->setVisible(FALSE); + + mToastMouseEnterSignal(this, getValue()); + } + // Stopped timer means the mouse had entered the toast previously. + // If the toast is not hovered in the current frame we should handle + // a mouse leave event. + else if(!timer->getStarted() && !mIsHovered) + { + mOnToastHoverSignal(this, MOUSE_LEAVE); + + updateTransparency(); + + //toasts fading is management by Screen Channel + + if(mHideBtn && mHideBtn->getEnabled()) + { + if( mHideBtnPressed ) + { + mHideBtnPressed = false; + return; + } + mHideBtn->setVisible(FALSE); + } + + mToastMouseLeaveSignal(this, getValue()); } - mToastMouseLeaveSignal(this, getValue()); } } @@ -495,13 +534,6 @@ void LLNotificationsUI::LLToast::startTimer() } } -bool LLToast::isHovered() -{ - S32 x, y; - LLUI::getMousePositionScreen(&x, &y); - return mWrapperPanel->calcScreenRect().pointInRect(x, y); -} - //-------------------------------------------------------------------------- BOOL LLToast::handleMouseDown(S32 x, S32 y, MASK mask) @@ -536,3 +568,14 @@ S32 LLToast::notifyParent(const LLSD& info) return LLModalDialog::notifyParent(info); } + +//static +void LLToast::updateClass() +{ + for (LLInstanceTracker<LLToast>::instance_iter iter = LLInstanceTracker<LLToast>::beginInstances(); iter != LLInstanceTracker<LLToast>::endInstances(); ) + { + LLToast& toast = *iter++; + + toast.updateHoveredState(); + } +} diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index 242f786bf2..ea62f758f8 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -27,7 +27,7 @@ #ifndef LL_LLTOAST_H #define LL_LLTOAST_H - +#include "llinstancetracker.h" #include "llpanel.h" #include "llmodaldialog.h" #include "lleventtimer.h" @@ -69,12 +69,13 @@ private : * Represents toast pop-up. * This is a parent view for all toast panels. */ -class LLToast : public LLModalDialog +class LLToast : public LLModalDialog, public LLInstanceTracker<LLToast> { friend class LLToastLifeTimer; public: typedef boost::function<void (LLToast* toast)> toast_callback_t; typedef boost::signals2::signal<void (LLToast* toast)> toast_signal_t; + typedef boost::signals2::signal<void (LLToast* toast, bool mouse_enter)> toast_hover_check_signal_t; struct Params : public LLInitParam::Block<Params> { @@ -102,6 +103,8 @@ public: Params(); }; + + static void updateClass(); LLToast(const LLToast::Params& p); virtual ~LLToast(); @@ -120,7 +123,7 @@ public: /** Start lifetime/fading timer */ virtual void startTimer(); - bool isHovered(); + bool isHovered() { return mIsHovered; } // Operating with toasts // insert a panel to a toast @@ -129,7 +132,7 @@ public: void reshapeToPanel(); // get toast's panel - LLPanel* getPanel() { return mPanel; } + LLPanel* getPanel() const { return mPanel; } // enable/disable Toast's Hide button void setHideButtonEnabled(bool enabled); // @@ -153,6 +156,8 @@ public: void setFadingTime(S32 seconds); + void closeToast(); + /** * Returns padding between floater top and wrapper_panel top. * This padding should be taken into account when positioning or reshaping toasts @@ -164,10 +169,11 @@ public: // get/set Toast's flags or states // get information whether the notification corresponding to the toast is valid or not bool isNotificationValid(); + // get toast's Notification ID - const LLUUID getNotificationID() { return mNotificationID;} + const LLUUID getNotificationID() const { return mNotificationID;} // get toast's Session ID - const LLUUID getSessionID() { return mSessionID;} + const LLUUID getSessionID() const { return mSessionID;} // void setCanFade(bool can_fade); // @@ -177,35 +183,25 @@ public: // set whether this toast considered as hidden or not void setIsHidden( bool is_toast_hidden ) { mIsHidden = is_toast_hidden; } - const LLNotificationPtr& getNotification() { return mNotification;} + const LLNotificationPtr& getNotification() const { return mNotification;} // Registers signals/callbacks for events - toast_signal_t mOnFadeSignal; - toast_signal_t mOnDeleteToastSignal; - toast_signal_t mOnToastDestroyedSignal; - boost::signals2::connection setOnFadeCallback(toast_callback_t cb) { return mOnFadeSignal.connect(cb); } - boost::signals2::connection setOnToastDestroyedCallback(toast_callback_t cb) { return mOnToastDestroyedSignal.connect(cb); } - - typedef boost::function<void (LLToast* toast, bool mouse_enter)> toast_hover_check_callback_t; - typedef boost::signals2::signal<void (LLToast* toast, bool mouse_enter)> toast_hover_check_signal_t; - toast_hover_check_signal_t mOnToastHoverSignal; - boost::signals2::connection setOnToastHoverCallback(toast_hover_check_callback_t cb) { return mOnToastHoverSignal.connect(cb); } + boost::signals2::connection setOnFadeCallback(const toast_signal_t::slot_type& cb) { return mOnFadeSignal.connect(cb); } + boost::signals2::connection setOnToastDestroyedCallback(const toast_signal_t::slot_type& cb) { return mOnToastDestroyedSignal.connect(cb); } + boost::signals2::connection setOnToastHoverCallback(const toast_hover_check_signal_t::slot_type& cb) { return mOnToastHoverSignal.connect(cb); } boost::signals2::connection setMouseEnterCallback( const commit_signal_t::slot_type& cb ) { return mToastMouseEnterSignal.connect(cb); }; boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb ) { return mToastMouseLeaveSignal.connect(cb); }; virtual S32 notifyParent(const LLSD& info); - LLHandle<LLToast> getHandle() { mHandle.bind(this); return mHandle; } + LLHandle<LLToast> getHandle() const { return getDerivedHandle<LLToast>(); } protected: void updateTransparency(); private: - - void onToastMouseEnter(); - - void onToastMouseLeave(); + void updateHoveredState(); void expire(); @@ -215,18 +211,18 @@ private: LLUUID mSessionID; LLNotificationPtr mNotification; - LLRootHandle<LLToast> mHandle; + //LLRootHandle<LLToast> mHandle; - LLPanel* mWrapperPanel; + LLPanel* mWrapperPanel; // timer counts a lifetime of a toast std::auto_ptr<LLToastLifeTimer> mTimer; F32 mToastLifetime; // in seconds F32 mToastFadingTime; // in seconds - - LLPanel* mPanel; - LLButton* mHideBtn; + + LLPanel* mPanel; + LLButton* mHideBtn; LLColor4 mBgColor; bool mCanFade; @@ -236,6 +232,12 @@ private: bool mIsHidden; // this flag is TRUE when a toast has faded or was hidden with (x) button (EXT-1849) bool mIsTip; bool mIsFading; + bool mIsHovered; + + toast_signal_t mOnFadeSignal; + toast_signal_t mOnDeleteToastSignal; + toast_signal_t mOnToastDestroyedSignal; + toast_hover_check_signal_t mOnToastHoverSignal; commit_signal_t mToastMouseEnterSignal; commit_signal_t mToastMouseLeaveSignal; diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 0f337825e9..3f75f8da5e 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -69,8 +69,22 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal mLabel(notification->getName()), mLineEditor(NULL) { + // EXP-1822 + // save currently focused view, so that return focus to it + // on destroying this toast. + LLView* current_selection = dynamic_cast<LLView*>(gFocusMgr.getKeyboardFocus()); + while(current_selection) + { + if (current_selection->isFocusRoot()) + { + mPreviouslyFocusedView = current_selection->getHandle(); + break; + } + current_selection = current_selection->getParent(); + } + const LLFontGL* font = LLFontGL::getFontSansSerif(); - const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f); + const S32 LINE_HEIGHT = font->getLineHeight(); const S32 EDITOR_HEIGHT = 20; LLNotificationFormPtr form = mNotification->getForm(); @@ -343,6 +357,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal if (mLineEditor) { mLineEditor->selectAll(); + mLineEditor->setFocus(TRUE); } if(mDefaultOption >= 0) { @@ -365,7 +380,7 @@ bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std:: } const LLFontGL* font = mCheck->getFont(); - const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f); + const S32 LINE_HEIGHT = font->getLineHeight(); // Extend dialog for "check next time" S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * HPAD; @@ -408,6 +423,13 @@ LLToastAlertPanel::~LLToastAlertPanel() { LLTransientFloaterMgr::instance().removeControlView( LLTransientFloaterMgr::GLOBAL, this); + + // EXP-1822 + // return focus to the previously focused view if the viewer is not exiting + if (mPreviouslyFocusedView.get() && !LLApp::isExiting()) + { + mPreviouslyFocusedView.get()->setFocus(TRUE); + } } BOOL LLToastAlertPanel::hasTitleBar() const diff --git a/indra/newview/lltoastalertpanel.h b/indra/newview/lltoastalertpanel.h index 7b157f19bb..d1be5e018e 100644 --- a/indra/newview/lltoastalertpanel.h +++ b/indra/newview/lltoastalertpanel.h @@ -113,6 +113,7 @@ private: LLFrameTimer mDefaultBtnTimer; // For Dialogs that take a line as text as input: LLLineEditor* mLineEditor; + LLHandle<LLView> mPreviouslyFocusedView; }; diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index 75178a6ef8..4dc0d424ac 100644 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -51,7 +51,7 @@ const S32 LLToastGroupNotifyPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT = 7; -LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification) +LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notification) : LLToastPanel(notification), mInventoryOffer(NULL) { @@ -69,10 +69,8 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification //header title std::string from_name = payload["sender_name"].asString(); - if (LLAvatarNameCache::useDisplayNames()) - { - from_name = LLCacheName::buildUsername(from_name); - } + from_name = LLCacheName::buildUsername(from_name); + std::stringstream from; from << from_name << "/" << groupData.mName; LLTextBox* pTitleText = getChild<LLTextBox>("title"); @@ -112,7 +110,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification style.font = date_font; pMessageText->appendText(timeStr + "\n", TRUE, style); - style.font = pMessageText->getDefaultFont(); + style.font = pMessageText->getFont(); pMessageText->appendText(message, TRUE, style); //attachment diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h index 7794ec9f63..dfdc6ae559 100644 --- a/indra/newview/lltoastgroupnotifypanel.h +++ b/indra/newview/lltoastgroupnotifypanel.h @@ -47,13 +47,10 @@ class LLToastGroupNotifyPanel public: void close(); - static bool onNewNotification(const LLSD& notification); - - // Non-transient messages. You can specify non-default button // layouts (like one for script dialogs) by passing various // numbers in for "layout". - LLToastGroupNotifyPanel(LLNotificationPtr& notification); + LLToastGroupNotifyPanel(const LLNotificationPtr& notification); /*virtual*/ ~LLToastGroupNotifyPanel(); protected: diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp index e0cb200ef5..75e6e3d13a 100644 --- a/indra/newview/lltoastimpanel.cpp +++ b/indra/newview/lltoastimpanel.cpp @@ -104,9 +104,9 @@ LLToastIMPanel::~LLToastIMPanel() } //virtual -BOOL LLToastIMPanel::handleMouseDown(S32 x, S32 y, MASK mask) +BOOL LLToastIMPanel::handleMouseUp(S32 x, S32 y, MASK mask) { - if (LLPanel::handleMouseDown(x,y,mask) == FALSE) + if (LLPanel::handleMouseUp(x,y,mask) == FALSE) { mNotification->respond(mNotification->getResponseTemplate()); } diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h index a803387576..3eb11fb3bc 100644 --- a/indra/newview/lltoastimpanel.h +++ b/indra/newview/lltoastimpanel.h @@ -41,18 +41,18 @@ public: struct Params { LLNotificationPtr notification; - LLUUID avatar_id; - LLUUID session_id; - std::string from; - std::string time; - std::string message; + LLUUID avatar_id, + session_id; + std::string from, + time, + message; Params() {} }; LLToastIMPanel(LLToastIMPanel::Params &p); virtual ~LLToastIMPanel(); - /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); private: void showInspector(); diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index de305bf3d9..4ef5ad845c 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -40,11 +40,14 @@ #include "lltrans.h" #include "llnotificationsutil.h" #include "llviewermessage.h" -#include "llimfloater.h" +#include "llfloaterimsession.h" const S32 BOTTOM_PAD = VPAD * 3; const S32 IGNORE_BTN_TOP_DELTA = 3*VPAD;//additional ignore_btn padding S32 BUTTON_WIDTH = 90; +// *TODO: magic numbers(???) - copied from llnotify.cpp(250) +const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; + //static const LLFontGL* LLToastNotifyPanel::sFont = NULL; @@ -52,172 +55,12 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL; LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal; -LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification, const LLRect& rect, bool show_images) : -LLToastPanel(notification), -mTextBox(NULL), -mInfoPanel(NULL), -mControlPanel(NULL), -mNumOptions(0), -mNumButtons(0), -mAddedDefaultBtn(false), -mCloseNotificationOnDestroy(true) +LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images) +: LLToastPanel(notification), + LLInstanceTracker<LLToastNotifyPanel, LLUUID>(notification->getID()) { - buildFromFile( "panel_notification.xml"); - if(rect != LLRect::null) - { - this->setShape(rect); - } - mInfoPanel = getChild<LLPanel>("info_panel"); - mControlPanel = getChild<LLPanel>("control_panel"); - BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth"); - // customize panel's attributes - // is it intended for displaying a tip? - mIsTip = notification->getType() == "notifytip"; - // is it a script dialog? - mIsScriptDialog = (notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup"); - // is it a caution? - // - // caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the - // notify xml template specifies that it is a caution - // tip-style notification handle 'caution' differently -they display the tip in a different color - mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH; - - // setup parameters - // get a notification message - mMessage = notification->getMessage(); - // init font variables - if (!sFont) - { - sFont = LLFontGL::getFontSansSerif(); - sFontSmall = LLFontGL::getFontSansSerifSmall(); - } - // initialize - setFocusRoot(!mIsTip); - // get a form for the notification - LLNotificationFormPtr form(notification->getForm()); - // get number of elements - mNumOptions = form->getNumElements(); - - // customize panel's outfit - // preliminary adjust panel's layout - //move to the end - //mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form); - - // adjust text options according to the notification type - // add a caution textbox at the top of a caution notification - if (mIsCaution && !mIsTip) - { - mTextBox = getChild<LLTextBox>("caution_text_box"); - } - else - { - mTextBox = getChild<LLTextEditor>("text_editor_box"); - } - - // *TODO: magic numbers(???) - copied from llnotify.cpp(250) - const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; - - mTextBox->setMaxTextLength(MAX_LENGTH); - mTextBox->setVisible(TRUE); - mTextBox->setPlainText(!show_images); - mTextBox->setValue(notification->getMessage()); - - // add buttons for a script notification - if (mIsTip) - { - adjustPanelForTipNotice(); + init(rect, show_images); } - else - { - std::vector<index_button_pair_t> buttons; - buttons.reserve(mNumOptions); - S32 buttons_width = 0; - // create all buttons and accumulate they total width to reshape mControlPanel - for (S32 i = 0; i < mNumOptions; i++) - { - LLSD form_element = form->getElement(i); - if (form_element["type"].asString() != "button") - { - // not a button. - continue; - } - if (form_element["name"].asString() == TEXTBOX_MAGIC_TOKEN) - { - // a textbox pretending to be a button. - continue; - } - LLButton* new_button = createButton(form_element, TRUE); - buttons_width += new_button->getRect().getWidth(); - S32 index = form_element["index"].asInteger(); - buttons.push_back(index_button_pair_t(index,new_button)); - } - if (buttons.empty()) - { - addDefaultButton(); - } - else - { - const S32 button_panel_width = mControlPanel->getRect().getWidth();// do not change width of the panel - S32 button_panel_height = mControlPanel->getRect().getHeight(); - //try get an average h_pad to spread out buttons - S32 h_pad = (button_panel_width - buttons_width) / (S32(buttons.size())); - if(h_pad < 2*HPAD) - { - /* - * Probably it is a scriptdialog toast - * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons. - * In last case set default h_pad to avoid heaping of buttons - */ - S32 button_per_row = button_panel_width / BUTTON_WIDTH; - h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1 because we do not need space after last button in a row - if(h_pad < 2*HPAD) // still not enough space between buttons ? - { - h_pad = 2*HPAD; - } - } - if (mIsScriptDialog) - { - // we are using default width for script buttons so we can determinate button_rows - //to get a number of rows we divide the required width of the buttons to button_panel_width - S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width); - //S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width; - //reserve one row for the ignore_btn - button_rows++; - //calculate required panel height for scripdialog notification. - button_panel_height = button_rows * (BTN_HEIGHT + VPAD) + IGNORE_BTN_TOP_DELTA + BOTTOM_PAD; - } - else - { - // in common case buttons can have different widths so we need to calculate button_rows according to buttons_width - //S32 button_rows = llceil(F32(buttons.size()) * (buttons_width + h_pad) / button_panel_width); - S32 button_rows = llceil(F32((buttons.size() - 1) * h_pad + buttons_width) / button_panel_width); - //calculate required panel height - button_panel_height = button_rows * (BTN_HEIGHT + VPAD) + BOTTOM_PAD; - } - - // we need to keep min width and max height to make visible all buttons, because width of the toast can not be changed - adjustPanelForScriptNotice(button_panel_width, button_panel_height); - updateButtonsLayout(buttons, h_pad); - // save buttons for later use in disableButtons() - mButtons.assign(buttons.begin(), buttons.end()); - } - } - // adjust panel's height to the text size - mInfoPanel->setFollowsAll(); - snapToMessageHeight(mTextBox, MAX_LENGTH); - - if(notification->isReusable()) - { - mButtonClickConnection = sButtonClickSignal.connect( - boost::bind(&LLToastNotifyPanel::onToastPanelButtonClicked, this, _1, _2)); - - if(notification->isRespondedTo()) - { - // User selected an option in toast, now disable required buttons in IM window - disableRespondedOptions(notification); - } - } -} void LLToastNotifyPanel::addDefaultButton() { LLSD form_element; @@ -235,7 +78,6 @@ void LLToastNotifyPanel::addDefaultButton() } LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_option) { - InstanceAndS32* userdata = new InstanceAndS32; userdata->mSelf = this; userdata->mButtonName = is_option ? form_element["name"].asString() : ""; @@ -243,16 +85,17 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt mBtnCallbackData.push_back(userdata); LLButton::Params p; - bool is_ignore_btn = form_element["index"].asInteger() == -1; - const LLFontGL* font = is_ignore_btn ? sFontSmall: sFont; // for ignore button in script dialog - p.name(form_element["name"].asString()); - p.label(form_element["text"].asString()); - p.font(font); + bool make_small_btn = form_element["index"].asInteger() == -1 || form_element["index"].asInteger() == -2; + const LLFontGL* font = make_small_btn ? sFontSmall: sFont; // for block and ignore buttons in script dialog + p.name = form_element["name"].asString(); + p.label = form_element["text"].asString(); + p.font = font; p.rect.height = BTN_HEIGHT; p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata)); p.rect.width = BUTTON_WIDTH; p.auto_resize = false; p.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM); + p.enabled = !form_element.has("enabled") || form_element["enabled"].asBoolean(); if (mIsCaution) { p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); @@ -264,7 +107,7 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt p.rect.width = 1; p.auto_resize = true; } - else if (mIsScriptDialog && is_ignore_btn) + else if (mIsScriptDialog && make_small_btn) { // this is ignore button, make it smaller p.rect.height = BTN_HEIGHT_SMALL; @@ -287,16 +130,11 @@ LLToastNotifyPanel::~LLToastNotifyPanel() mButtonClickConnection.disconnect(); std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer()); - if (mCloseNotificationOnDestroy && LLNotificationsUtil::find(mNotification->getID()) != NULL) - { - // let reusable notification be deleted - mNotification->setReusable(false); - if (!mNotification->isPersistent()) + if (mIsTip) { LLNotifications::getInstance()->cancel(mNotification); } } -} void LLToastNotifyPanel::updateButtonsLayout(const std::vector<index_button_pair_t>& buttons, S32 h_pad) { @@ -334,32 +172,24 @@ void LLToastNotifyPanel::updateButtonsLayout(const std::vector<index_button_pair } U32 ignore_btn_width = 0; + U32 mute_btn_pad = 0; if (mIsScriptDialog && ignore_btn != NULL) { LLRect ignore_btn_rect(ignore_btn->getRect()); - S32 buttons_per_row = max_width / BUTTON_WIDTH; //assume that h_pad far less than BUTTON_WIDTH - S32 ignore_btn_left = buttons_per_row * BUTTON_WIDTH + (buttons_per_row - 1) * h_pad - ignore_btn_rect.getWidth(); - if (ignore_btn_left + ignore_btn_rect.getWidth() > max_width)// make sure that the ignore button is in panel - { - ignore_btn_left = max_width - ignore_btn_rect.getWidth() - 2 * HPAD; - } + S32 ignore_btn_left = max_width - ignore_btn_rect.getWidth(); ignore_btn_rect.setOriginAndSize(ignore_btn_left, BOTTOM_PAD,// always move ignore button at the bottom ignore_btn_rect.getWidth(), ignore_btn_rect.getHeight()); ignore_btn->setRect(ignore_btn_rect); ignore_btn_width = ignore_btn_rect.getWidth(); mControlPanel->addChild(ignore_btn, -1); + mute_btn_pad = 4 * HPAD; //only use a 4 * HPAD padding if an ignore button exists } if (mIsScriptDialog && mute_btn != NULL) { LLRect mute_btn_rect(mute_btn->getRect()); - S32 buttons_per_row = max_width / BUTTON_WIDTH; //assume that h_pad far less than BUTTON_WIDTH // Place mute (Block) button to the left of the ignore button. - S32 mute_btn_left = buttons_per_row * BUTTON_WIDTH + (buttons_per_row - 1) * h_pad - mute_btn_rect.getWidth() - ignore_btn_width - (h_pad / 2); - if (mute_btn_left + mute_btn_rect.getWidth() > max_width) // make sure that the mute button is in panel - { - mute_btn_left = max_width - mute_btn_rect.getWidth() - 2 * HPAD; - } + S32 mute_btn_left = max_width - mute_btn_rect.getWidth() - ignore_btn_width - mute_btn_pad; mute_btn_rect.setOriginAndSize(mute_btn_left, BOTTOM_PAD,// always move mute button at the bottom mute_btn_rect.getWidth(), mute_btn_rect.getHeight()); mute_btn->setRect(mute_btn_rect); @@ -393,210 +223,278 @@ void LLToastNotifyPanel::adjustPanelForTipNotice() } } -typedef std::set<std::string> button_name_set_t; -typedef std::map<std::string, button_name_set_t> disable_button_map_t; - -disable_button_map_t initUserGiveItemDisableButtonMap() +// static +void LLToastNotifyPanel::onClickButton(void* data) { - // see EXT-5905 for disable rules - - disable_button_map_t disable_map; - button_name_set_t buttons; - - buttons.insert("Show"); - disable_map.insert(std::make_pair("Show", buttons)); + InstanceAndS32* self_and_button = (InstanceAndS32*)data; + LLToastNotifyPanel* self = self_and_button->mSelf; + std::string button_name = self_and_button->mButtonName; - buttons.insert("Discard"); - disable_map.insert(std::make_pair("Discard", buttons)); + LLSD response = self->mNotification->getResponseTemplate(); + if (!self->mAddedDefaultBtn && !button_name.empty()) + { + response[button_name] = true; + } - buttons.insert("Mute"); - disable_map.insert(std::make_pair("Mute", buttons)); + // disable all buttons + self->mControlPanel->setEnabled(FALSE); - return disable_map; + // this might repost notification with new form data/enabled buttons + self->mNotification->respond(response); } -disable_button_map_t initTeleportOfferedDisableButtonMap() +void LLToastNotifyPanel::init( LLRect rect, bool show_images ) { - disable_button_map_t disable_map; - button_name_set_t buttons; - - buttons.insert("Teleport"); - buttons.insert("Cancel"); - - disable_map.insert(std::make_pair("Teleport", buttons)); - disable_map.insert(std::make_pair("Cancel", buttons)); + deleteAllChildren(); + + mTextBox = NULL; + mInfoPanel = NULL; + mControlPanel = NULL; + mNumOptions = 0; + mNumButtons = 0; + mAddedDefaultBtn = false; + + LLRect current_rect = getRect(); + + setXMLFilename(""); + buildFromFile("panel_notification.xml"); + + if(rect != LLRect::null) + { + this->setShape(rect); + } + mInfoPanel = getChild<LLPanel>("info_panel"); + + mControlPanel = getChild<LLPanel>("control_panel"); + BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth"); + // customize panel's attributes + // is it intended for displaying a tip? + mIsTip = mNotification->getType() == "notifytip"; + // is it a script dialog? + mIsScriptDialog = (mNotification->getName() == "ScriptDialog" || mNotification->getName() == "ScriptDialogGroup"); + // is it a caution? + // + // caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the + // notify xml template specifies that it is a caution + // tip-style notification handle 'caution' differently -they display the tip in a different color + mIsCaution = mNotification->getPriority() >= NOTIFICATION_PRIORITY_HIGH; + + // setup parameters + // get a notification message + mMessage = mNotification->getMessage(); + // init font variables + if (!sFont) + { + sFont = LLFontGL::getFontSansSerif(); + sFontSmall = LLFontGL::getFontSansSerifSmall(); + } + // initialize + setFocusRoot(!mIsTip); + // get a form for the notification + LLNotificationFormPtr form(mNotification->getForm()); + // get number of elements + mNumOptions = form->getNumElements(); + + // customize panel's outfit + // preliminary adjust panel's layout + //move to the end + //mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form); + + // adjust text options according to the notification type + // add a caution textbox at the top of a caution notification + if (mIsCaution && !mIsTip) + { + mTextBox = getChild<LLTextBox>("caution_text_box"); + } + else + { + mTextBox = getChild<LLTextEditor>("text_editor_box"); + } + + mTextBox->setMaxTextLength(MAX_LENGTH); + mTextBox->setVisible(TRUE); + mTextBox->setPlainText(!show_images); + mTextBox->setValue(mNotification->getMessage()); + + // add buttons for a script notification + if (mIsTip) + { + adjustPanelForTipNotice(); + } + else + { + std::vector<index_button_pair_t> buttons; + buttons.reserve(mNumOptions); + S32 buttons_width = 0; + // create all buttons and accumulate they total width to reshape mControlPanel + for (S32 i = 0; i < mNumOptions; i++) + { + LLSD form_element = form->getElement(i); + if (form_element["type"].asString() != "button") + { + // not a button. + continue; + } + if (form_element["name"].asString() == TEXTBOX_MAGIC_TOKEN) + { + // a textbox pretending to be a button. + continue; + } + LLButton* new_button = createButton(form_element, TRUE); + buttons_width += new_button->getRect().getWidth(); + S32 index = form_element["index"].asInteger(); + buttons.push_back(index_button_pair_t(index,new_button)); + } + if (buttons.empty()) + { + addDefaultButton(); + } + else + { + const S32 button_panel_width = mControlPanel->getRect().getWidth();// do not change width of the panel + S32 button_panel_height = mControlPanel->getRect().getHeight(); + //try get an average h_pad to spread out buttons + S32 h_pad = (button_panel_width - buttons_width) / (S32(buttons.size())); + if(h_pad < 2*HPAD) + { + /* + * Probably it is a scriptdialog toast + * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons. + * In last case set default h_pad to avoid heaping of buttons + */ + S32 button_per_row = button_panel_width / BUTTON_WIDTH; + h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1 because we do not need space after last button in a row + if(h_pad < 2*HPAD) // still not enough space between buttons ? + { + h_pad = 2*HPAD; + } + } + if (mIsScriptDialog) + { + // we are using default width for script buttons so we can determinate button_rows + //to get a number of rows we divide the required width of the buttons to button_panel_width + S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width); + //S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width; + //reserve one row for the ignore_btn + button_rows++; + //calculate required panel height for scripdialog notification. + button_panel_height = button_rows * (BTN_HEIGHT + VPAD) + IGNORE_BTN_TOP_DELTA + BOTTOM_PAD; + } + else + { + // in common case buttons can have different widths so we need to calculate button_rows according to buttons_width + //S32 button_rows = llceil(F32(buttons.size()) * (buttons_width + h_pad) / button_panel_width); + S32 button_rows = llceil(F32((buttons.size() - 1) * h_pad + buttons_width) / button_panel_width); + //calculate required panel height + button_panel_height = button_rows * (BTN_HEIGHT + VPAD) + BOTTOM_PAD; + } + + // we need to keep min width and max height to make visible all buttons, because width of the toast can not be changed + adjustPanelForScriptNotice(button_panel_width, button_panel_height); + updateButtonsLayout(buttons, h_pad); + // save buttons for later use in disableButtons() + //mButtons.assign(buttons.begin(), buttons.end()); + } + } + + //.xml file intially makes info panel only follow left/right/top. This is so that when control buttons are added the info panel + //can shift upward making room for the buttons inside mControlPanel. After the buttons are added, the info panel can then be set to follow 'all'. + mInfoPanel->setFollowsAll(); + snapToMessageHeight(mTextBox, MAX_LENGTH); - return disable_map; + // reshape the panel to its previous size + if (current_rect.notEmpty()) + { + reshape(current_rect.getWidth(), current_rect.getHeight()); + } } -disable_button_map_t initFriendshipOfferedDisableButtonMap() -{ - disable_button_map_t disable_map; - button_name_set_t buttons; - - buttons.insert("Accept"); - buttons.insert("Decline"); - - disable_map.insert(std::make_pair("Accept", buttons)); - disable_map.insert(std::make_pair("Decline", buttons)); +////////////////////////////////////////////////////////////////////////// - return disable_map; +LLIMToastNotifyPanel::LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect /* = LLRect::null */, + bool show_images /* = true */, LLTextBase* parent_text) +: mSessionID(session_id), LLToastNotifyPanel(pNotification, rect, show_images), + mParentText(parent_text) +{ + compactButtons(); } -button_name_set_t getButtonDisableList(const std::string& notification_name, const std::string& button_name) +LLIMToastNotifyPanel::~LLIMToastNotifyPanel() { - static disable_button_map_t user_give_item_disable_map = initUserGiveItemDisableButtonMap(); - static disable_button_map_t teleport_offered_disable_map = initTeleportOfferedDisableButtonMap(); - static disable_button_map_t friendship_offered_disable_map = initFriendshipOfferedDisableButtonMap(); - - disable_button_map_t::const_iterator it; - disable_button_map_t::const_iterator it_end; - disable_button_map_t search_map; - - if("UserGiveItem" == notification_name) - { - search_map = user_give_item_disable_map; - } - else if("TeleportOffered" == notification_name) - { - search_map = teleport_offered_disable_map; - } - else if("OfferFriendship" == notification_name) - { - search_map = friendship_offered_disable_map; - } - - it = search_map.find(button_name); - it_end = search_map.end(); - - if(it_end != it) - { - return it->second; - } - return button_name_set_t(); } -void LLToastNotifyPanel::disableButtons(const std::string& notification_name, const std::string& selected_button) +void LLIMToastNotifyPanel::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */) { - button_name_set_t buttons = getButtonDisableList(notification_name, selected_button); - - std::vector<index_button_pair_t>::const_iterator it = mButtons.begin(); - for ( ; it != mButtons.end(); it++) - { - LLButton* btn = it->second; - if(buttons.find(btn->getName()) != buttons.end()) - { - btn->setEnabled(FALSE); - } - } + LLToastPanel::reshape(width, height, called_from_parent); + snapToMessageHeight(); } -// static -void LLToastNotifyPanel::onClickButton(void* data) +void LLIMToastNotifyPanel::snapToMessageHeight() { - InstanceAndS32* self_and_button = (InstanceAndS32*)data; - LLToastNotifyPanel* self = self_and_button->mSelf; - std::string button_name = self_and_button->mButtonName; - - LLSD response = self->mNotification->getResponseTemplate(); - if (!self->mAddedDefaultBtn && !button_name.empty()) + if(!mTextBox) { - response[button_name] = true; + return; } - - bool is_reusable = self->mNotification->isReusable(); - // When we call respond(), LLOfferInfo will delete itself in inventory_offer_callback(), - // lets copy it while it's still valid. - LLOfferInfo* old_info = static_cast<LLOfferInfo*>(self->mNotification->getResponder()); - LLOfferInfo* new_info = NULL; - if(is_reusable && old_info) - { - new_info = new LLOfferInfo(*old_info); - self->mNotification->setResponder(new_info); - } - - self->mNotification->respond(response); - if(is_reusable) - { - sButtonClickSignal(self->mNotification->getID(), button_name); - } - else + //Add message height if it is visible + if (mTextBox->getVisible()) { - // disable all buttons - self->mControlPanel->setEnabled(FALSE); - } -} + S32 new_panel_height = computeSnappedToMessageHeight(mTextBox, MAX_LENGTH); -void LLToastNotifyPanel::onToastPanelButtonClicked(const LLUUID& notification_id, const std::string btn_name) -{ - if(mNotification->getID() == notification_id) - { - disableButtons(mNotification->getName(), btn_name); + //reshape the panel with new height + if (new_panel_height != getRect().getHeight()) + { + LLToastNotifyPanel::reshape( getRect().getWidth(), new_panel_height); + } } } -void LLToastNotifyPanel::disableRespondedOptions(LLNotificationPtr& notification) +void LLIMToastNotifyPanel::compactButtons() { - LLSD response = notification->getResponse(); - for (LLSD::map_const_iterator response_it = response.beginMap(); - response_it != response.endMap(); ++response_it) + //we can't set follows in xml since it broke toasts behavior + setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP); + + const child_list_t* children = getControlPanel()->getChildList(); + S32 offset = 0; + // Children were added by addChild() which uses push_front to insert them into list, + // so to get buttons in correct order reverse iterator is used (EXT-5906) + for (child_list_t::const_reverse_iterator it = children->rbegin(); it != children->rend(); it++) { - if (response_it->second.isBoolean() && response_it->second.asBoolean()) + LLButton * button = dynamic_cast<LLButton*> (*it); + if (button != NULL) { - // that after multiple responses there can be many pressed buttons - // need to process them all - disableButtons(notification->getName(), response_it->first); + button->setOrigin( offset,button->getRect().mBottom); + button->setLeftHPad(2 * HPAD); + button->setRightHPad(2 * HPAD); + // set zero width before perform autoResize() + button->setRect(LLRect(button->getRect().mLeft, + button->getRect().mTop, + button->getRect().mLeft, + button->getRect().mBottom)); + button->setAutoResize(true); + button->autoResize(); + offset += HPAD + button->getRect().getWidth(); + button->setFollowsNone(); } } -} - - -////////////////////////////////////////////////////////////////////////// -LLIMToastNotifyPanel::LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect /* = LLRect::null */, - bool show_images /* = true */) - : mSessionID(session_id), LLToastNotifyPanel(pNotification, rect, show_images) -{ - mTextBox->setFollowsAll(); + if (mParentText) + { + mParentText->needsReflow(); + } } -LLIMToastNotifyPanel::~LLIMToastNotifyPanel() -{ - // We shouldn't delete notification when IM floater exists - // since that notification will be reused by IM floater. - // This may happened when IM floater reloads messages, exactly when user - // changes layout of IM chat log(disable/enable plaintext mode). - // See EXT-6500 - LLIMFloater* im_floater = LLIMFloater::findInstance(mSessionID); - if (im_floater != NULL && !im_floater->isDead()) +void LLIMToastNotifyPanel::updateNotification() { - mCloseNotificationOnDestroy = false; + init(LLRect(), true); } -} -void LLIMToastNotifyPanel::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */) +void LLIMToastNotifyPanel::init( LLRect rect, bool show_images ) { - S32 text_height = mTextBox->getTextBoundingRect().getHeight(); - S32 widget_height = mTextBox->getRect().getHeight(); - S32 delta = text_height - widget_height; - LLRect rc = getRect(); + LLToastNotifyPanel::init(LLRect(), show_images); - rc.setLeftTopAndSize(rc.mLeft, rc.mTop, width, height + delta); - height = rc.getHeight(); - width = rc.getWidth(); - - bool is_width_changed = width != getRect().getWidth(); - - LLToastPanel::reshape(width, height, called_from_parent); - - // Notification height required to display the text message depends on - // the width of the text box thus if panel width is changed the text box - // width is also changed then reshape() is called to adjust proper height. - if (is_width_changed) - { - reshape(width, height, called_from_parent); - } + compactButtons(); } // EOF + diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h index 57711b3d80..d02171b512 100644 --- a/indra/newview/lltoastnotifypanel.h +++ b/indra/newview/lltoastnotifypanel.h @@ -47,7 +47,7 @@ class LLNotificationForm; * @deprecated this class will be removed after all toast panel types are * implemented in separate classes. */ -class LLToastNotifyPanel: public LLToastPanel +class LLToastNotifyPanel: public LLToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID> { public: /** @@ -60,11 +60,15 @@ public: * @deprecated if you intend to instantiate LLToastNotifyPanel - it's point to * implement right class for desired toast panel. @see LLGenericTipPanel as example. */ - LLToastNotifyPanel(LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true); + LLToastNotifyPanel(const LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true); + + virtual void init( LLRect rect, bool show_images ); + virtual ~LLToastNotifyPanel(); LLPanel * getControlPanel() { return mControlPanel; } - void setCloseNotificationOnDestroy(bool close) { mCloseNotificationOnDestroy = close; } + virtual void updateNotification() {} + protected: LLButton* createButton(const LLSD& form_element, BOOL is_option); @@ -76,8 +80,6 @@ protected: }; std::vector<InstanceAndS32*> mBtnCallbackData; - bool mCloseNotificationOnDestroy; - typedef std::pair<int,LLButton*> index_button_pair_t; void adjustPanelForScriptNotice(S32 max_width, S32 max_height); void adjustPanelForTipNotice(); @@ -93,9 +95,9 @@ protected: /** * Disable specific button(s) based on notification name and clicked button */ - void disableButtons(const std::string& notification_name, const std::string& selected_button); + //void disableButtons(const std::string& notification_name, const std::string& selected_button); - std::vector<index_button_pair_t> mButtons; + //std::vector<index_button_pair_t> mButtons; // panel elements LLTextBase* mTextBox; @@ -118,7 +120,7 @@ protected: /** * Process response data. Will disable selected options */ - void disableRespondedOptions(LLNotificationPtr& notification); + //void disableRespondedOptions(const LLNotificationPtr& notification); bool mIsTip; bool mAddedDefaultBtn; @@ -137,14 +139,27 @@ class LLIMToastNotifyPanel : public LLToastNotifyPanel { public: - LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect = LLRect::null, bool show_images = true); + LLIMToastNotifyPanel(LLNotificationPtr& pNotification, + const LLUUID& session_id, + const LLRect& rect = LLRect::null, + bool show_images = true, + LLTextBase* parent_text = NULL); + + void compactButtons(); + + virtual void updateNotification(); + virtual void init( LLRect rect, bool show_images ); ~LLIMToastNotifyPanel(); /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); protected: + LLTextBase* mParentText; LLUUID mSessionID; + +private: + void snapToMessageHeight(); }; #endif /* LLTOASTNOTIFYPANEL_H_ */ diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp index fc69157a40..a30f841980 100644 --- a/indra/newview/lltoastpanel.cpp +++ b/indra/newview/lltoastpanel.cpp @@ -29,7 +29,9 @@ #include "llpanelgenerictip.h" #include "llpanelonlinestatus.h" #include "llnotifications.h" +#include "lltoastnotifypanel.h" #include "lltoastpanel.h" +#include "lltoastscriptquestion.h" //static const S32 LLToastPanel::MIN_PANEL_HEIGHT = 40; // VPAD(4)*2 + ICON_HEIGHT(32) @@ -56,6 +58,25 @@ const LLUUID& LLToastPanel::getID() return mNotification->id(); } +S32 LLToastPanel::computeSnappedToMessageHeight(LLTextBase* message, S32 maxLineCount) +{ + S32 heightDelta = 0; + S32 maxTextHeight = message->getFont()->getLineHeight() * maxLineCount; + + LLRect messageRect = message->getRect(); + S32 oldTextHeight = messageRect.getHeight(); + + //Knowing the height is set to max allowed, getTextPixelHeight returns needed text height + //Perhaps we need to pass maxLineCount as parameter to getTextPixelHeight to avoid previous reshape. + S32 requiredTextHeight = message->getTextBoundingRect().getHeight(); + S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight); + + heightDelta = newTextHeight - oldTextHeight; + S32 new_panel_height = llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT); + + return new_panel_height; +} + //snap to the message height if it is visible void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount) { @@ -67,22 +88,13 @@ void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount) //Add message height if it is visible if (message->getVisible()) { - S32 heightDelta = 0; - S32 maxTextHeight = (S32)(message->getDefaultFont()->getLineHeight() * maxLineCount); - - LLRect messageRect = message->getRect(); - S32 oldTextHeight = messageRect.getHeight(); - - //Knowing the height is set to max allowed, getTextPixelHeight returns needed text height - //Perhaps we need to pass maxLineCount as parameter to getTextPixelHeight to avoid previous reshape. - S32 requiredTextHeight = message->getTextBoundingRect().getHeight(); - S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight); - - //Calculate last delta height deducting previous heightDelta - heightDelta = newTextHeight - oldTextHeight - heightDelta; + S32 new_panel_height = computeSnappedToMessageHeight(message, maxLineCount); //reshape the panel with new height - reshape( getRect().getWidth(), llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT)); + if (new_panel_height != getRect().getHeight()) + { + reshape( getRect().getWidth(), new_panel_height); + } } } @@ -96,7 +108,7 @@ LLToastPanel* LLToastPanel::buidPanelFromNotification( if ("notifytip" == notification->getType()) { // if it is online/offline notification - if ("FriendOffline" == notification->getName() || "FriendOnline" == notification->getName()) + if ("FriendOnlineOffline" == notification->getName()) { res = new LLPanelOnlineStatus(notification); } @@ -106,6 +118,17 @@ LLToastPanel* LLToastPanel::buidPanelFromNotification( res = new LLPanelGenericTip(notification); } } + else if("notify" == notification->getType()) + { + if (notification->getPriority() == NOTIFICATION_PRIORITY_CRITICAL) + { + res = new LLToastScriptQuestion(notification); + } + else + { + res = new LLToastNotifyPanel(notification); + } + } /* else if(...) create all other specific non-public toast panel diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h index 346e014d73..e4ab95007e 100644 --- a/indra/newview/lltoastpanel.h +++ b/indra/newview/lltoastpanel.h @@ -33,19 +33,13 @@ #include <string> -class LLToastPanelBase: public LLPanel -{ -public: - virtual void init(LLSD& data){}; -}; - /** * Base class for all panels that can be added to the toast. * All toast panels should contain necessary logic for representing certain notification * but shouldn't contain logic related to this panel lifetime control and positioning * on the parent view. */ -class LLToastPanel: public LLPanel { +class LLToastPanel : public LLPanel { public: LLToastPanel(const LLNotificationPtr&); virtual ~LLToastPanel() = 0; @@ -65,6 +59,7 @@ public: protected: LLNotificationPtr mNotification; void snapToMessageHeight(LLTextBase* message, S32 maxLineCount); + S32 computeSnappedToMessageHeight(LLTextBase* message, S32 maxLineCount); }; #endif /* LL_TOASTPANEL_H */ diff --git a/indra/newview/lltoastscriptquestion.cpp b/indra/newview/lltoastscriptquestion.cpp new file mode 100644 index 0000000000..91ba8c0247 --- /dev/null +++ b/indra/newview/lltoastscriptquestion.cpp @@ -0,0 +1,130 @@ +/** + * @file lltoastscriptquestion.cpp + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "llbutton.h" +#include "llnotifications.h" +#include "lltoastscriptquestion.h" + +const int LEFT_PAD = 10; +const int BUTTON_HEIGHT = 27; +const int MAX_LINES_COUNT = 50; + +LLToastScriptQuestion::LLToastScriptQuestion(const LLNotificationPtr& notification) +: +LLToastPanel(notification) +{ + buildFromFile("panel_script_question_toast.xml"); +} + +BOOL LLToastScriptQuestion::postBuild() +{ + createButtons(); + + LLTextBox* mMessage = getChild<LLTextBox>("top_info_message"); + LLTextBox* mFooter = getChild<LLTextBox>("bottom_info_message"); + + mMessage->setValue(mNotification->getMessage()); + mFooter->setValue(mNotification->getFooter()); + + snapToMessageHeight(); + + return TRUE; +} +void LLToastScriptQuestion::snapToMessageHeight() +{ + LLTextBox* mMessage = getChild<LLTextBox>("top_info_message"); + LLTextBox* mFooter = getChild<LLTextBox>("bottom_info_message"); + if (!mMessage || !mFooter) + { + return; + } + + if (mMessage->getVisible() && mFooter->getVisible()) + { + S32 heightDelta = 0; + S32 maxTextHeight = (mMessage->getFont()->getLineHeight() * MAX_LINES_COUNT) + + (mFooter->getFont()->getLineHeight() * MAX_LINES_COUNT); + + LLRect messageRect = mMessage->getRect(); + LLRect footerRect = mFooter->getRect(); + + S32 oldTextHeight = messageRect.getHeight() + footerRect.getHeight(); + + S32 requiredTextHeight = mMessage->getTextBoundingRect().getHeight() + mFooter->getTextBoundingRect().getHeight(); + S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight); + + heightDelta = newTextHeight - oldTextHeight - heightDelta; + + reshape( getRect().getWidth(), llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT)); + } +} + +void LLToastScriptQuestion::createButtons() +{ + LLNotificationFormPtr form = mNotification->getForm(); + int num_elements = form->getNumElements(); + int buttons_width = 0; + + for (int i = 0; i < num_elements; ++i) + { + LLSD form_element = form->getElement(i); + if ("button" == form_element["type"].asString()) + { + LLButton::Params p; + const LLFontGL* font = LLFontGL::getFontSansSerif(); + p.name(form_element["name"].asString()); + p.label(form_element["text"].asString()); + p.layout("topleft"); + p.font(font); + p.rect.height(BUTTON_HEIGHT); + p.click_callback.function(boost::bind(&LLToastScriptQuestion::onButtonClicked, this, form_element["name"].asString())); + p.rect.left = LEFT_PAD; + p.rect.width = font->getWidth(form_element["text"].asString()); + p.auto_resize = true; + p.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM); + p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); + p.image_color_disabled(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); + + LLButton* button = LLUICtrlFactory::create<LLButton>(p); + button->autoResize(); + getChild<LLPanel>("buttons_panel")->addChild(button); + + LLRect rect = button->getRect(); + rect.setLeftTopAndSize(buttons_width, rect.mTop, rect.getWidth(), rect.getHeight()); + button->setRect(rect); + + buttons_width += rect.getWidth() + LEFT_PAD; + } + } +} + +void LLToastScriptQuestion::onButtonClicked(std::string btn_name) +{ + LLSD response = mNotification->getResponseTemplate(); + response[btn_name] = true; + mNotification->respond(response); +} diff --git a/indra/newview/lltoastscriptquestion.h b/indra/newview/lltoastscriptquestion.h new file mode 100644 index 0000000000..3a557f60f6 --- /dev/null +++ b/indra/newview/lltoastscriptquestion.h @@ -0,0 +1,49 @@ +/** + * @file lltoastscriptquestion.h + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "lltoastpanel.h" + +#ifndef LLTOASTSCRIPTQUESTION_H_ +#define LLTOASTSCRIPTQUESTION_H_ + +class LLToastScriptQuestion : public LLToastPanel +{ + LOG_CLASS(LLToastScriptQuestion); + +public: + LLToastScriptQuestion(const LLNotificationPtr& notification); + virtual BOOL postBuild(); + virtual ~LLToastScriptQuestion(){}; + +private: + void snapToMessageHeight(); + + void createButtons(); + void onButtonClicked(std::string btn_name); +}; + +#endif /* LLTOASTSCRIPTQUESTION_H_ */ diff --git a/indra/newview/lltoastscripttextbox.cpp b/indra/newview/lltoastscripttextbox.cpp index 2529ec865a..45fbabad59 100644 --- a/indra/newview/lltoastscripttextbox.cpp +++ b/indra/newview/lltoastscripttextbox.cpp @@ -65,7 +65,7 @@ LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification pMessageText->clear(); LLStyle::Params style; - style.font = pMessageText->getDefaultFont(); + style.font = pMessageText->getFont(); pMessageText->appendText(message, TRUE, style); //submit button diff --git a/indra/newview/lltoastscripttextbox.h b/indra/newview/lltoastscripttextbox.h index 8e69d8834d..7d33446248 100644 --- a/indra/newview/lltoastscripttextbox.h +++ b/indra/newview/lltoastscripttextbox.h @@ -39,8 +39,6 @@ class LLToastScriptTextbox public: void close(); - static bool onNewNotification(const LLSD& notification); - // Non-transient messages. You can specify non-default button // layouts (like one for script dialogs) by passing various // numbers in for "layout". diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index 5ff0ccfeb2..b2318f9158 100644 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -73,8 +73,11 @@ LLToolBarView::ToolbarSet::ToolbarSet() LLToolBarView::LLToolBarView(const LLToolBarView::Params& p) : LLUICtrl(p), mDragStarted(false), + mShowToolbars(true), mDragToolbarButton(NULL), - mToolbarsLoaded(false) + mDragItem(NULL), + mToolbarsLoaded(false), + mBottomToolbarPanel(NULL) { for (S32 i = 0; i < TOOLBAR_COUNT; i++) { @@ -98,6 +101,7 @@ BOOL LLToolBarView::postBuild() mToolbars[TOOLBAR_LEFT] = getChild<LLToolBar>("toolbar_left"); mToolbars[TOOLBAR_RIGHT] = getChild<LLToolBar>("toolbar_right"); mToolbars[TOOLBAR_BOTTOM] = getChild<LLToolBar>("toolbar_bottom"); + mBottomToolbarPanel = getChild<LLView>("bottom_toolbar_panel"); for (int i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++) { @@ -237,8 +241,9 @@ bool LLToolBarView::loadToolbars(bool force_default) LLXUIParser parser; if (!err) { - parser.readXUI(root, toolbar_set, toolbar_file); + parser.readXUI(root, toolbar_set, toolbar_file); } + if (!err && !toolbar_set.validateBlock()) { llwarns << "Unable to validate toolbars from file: " << toolbar_file << llendl; @@ -250,8 +255,9 @@ bool LLToolBarView::loadToolbars(bool force_default) if (force_default) { llerrs << "Unable to load toolbars from default file : " << toolbar_file << llendl; - return false; - } + return false; + } + // Try to load the default toolbars return loadToolbars(true); } @@ -530,6 +536,13 @@ void LLToolBarView::draw() } } + for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++) + { + mToolbars[i]->getParent()->setVisible(mShowToolbars + && (mToolbars[i]->hasButtons() + || isToolDragged())); + } + // Draw drop zones if drop of a tool is active if (isToolDragged()) { @@ -571,7 +584,6 @@ BOOL LLToolBarView::handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetTyp uuid_vec_t cargo_ids; types.push_back(DAD_WIDGET); cargo_ids.push_back(uuid); - gClipboard.setSourceObject(uuid,LLAssetType::AT_WIDGET); LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_VIEWER; LLUUID srcID; LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src, srcID); @@ -595,7 +607,7 @@ BOOL LLToolBarView::handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetTyp BOOL LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* toolbar) { BOOL handled = FALSE; - LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data; + LLInventoryObject* inv_item = static_cast<LLInventoryObject*>(cargo_data); LLAssetType::EType type = inv_item->getType(); if (type == LLAssetType::AT_WIDGET) @@ -654,12 +666,21 @@ void LLToolBarView::resetDragTool(LLToolBarButton* toolbarButton) gToolBarView->mDragToolbarButton = toolbarButton; } -void LLToolBarView::setToolBarsVisible(bool visible) +// Provide a handle on a free standing inventory item containing references to the tool. +// This might be used by Drag and Drop to move around references to tool items. +LLInventoryObject* LLToolBarView::getDragItem() { - for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++) + if (mDragToolbarButton) { - mToolbars[i]->getParent()->setVisible(visible); + LLUUID item_uuid = mDragToolbarButton->getCommandId().uuid(); + mDragItem = new LLInventoryObject (item_uuid, LLUUID::null, LLAssetType::AT_WIDGET, ""); } + return mDragItem; +} + +void LLToolBarView::setToolBarsVisible(bool visible) +{ + mShowToolbars = visible; } bool LLToolBarView::isModified() const diff --git a/indra/newview/lltoolbarview.h b/indra/newview/lltoolbarview.h index b99e8bc28d..7125dd9990 100644 --- a/indra/newview/lltoolbarview.h +++ b/indra/newview/lltoolbarview.h @@ -31,6 +31,7 @@ #include "lluictrl.h" #include "lltoolbar.h" #include "llcommandmanager.h" +#include "llinventory.h" class LLUICtrlFactory; @@ -106,7 +107,9 @@ public: static BOOL handleDragTool(S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type); static BOOL handleDropTool(void* cargo_data, S32 x, S32 y, LLToolBar* toolbar); static void resetDragTool(LLToolBarButton* toolbarButton); - + LLInventoryObject* getDragItem(); + LLView* getBottomToolbar() { return mBottomToolbarPanel; } + LLToolBar* getToolbar(EToolBarLocation toolbar) { return mToolbars[toolbar]; } bool isModified() const; protected: @@ -129,6 +132,9 @@ private: bool mDragStarted; LLToolBarButton* mDragToolbarButton; + LLInventoryObject* mDragItem; + bool mShowToolbars; + LLView* mBottomToolbarPanel; }; extern LLToolBarView* gToolBarView; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 6910b8eced..94c97158a8 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -48,6 +48,7 @@ #include "llpreviewnotecard.h" #include "llrootview.h" #include "llselectmgr.h" +#include "lltoolbarview.h" #include "lltoolmgr.h" #include "lltooltip.h" #include "lltrans.h" @@ -57,7 +58,6 @@ #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llworld.h" -#include "llclipboard.h" // syntactic sugar #define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember)) @@ -282,6 +282,8 @@ void LLCategoryDropDescendentsObserver::done() } */ +S32 LLToolDragAndDrop::sOperationId = 0; + LLToolDragAndDrop::DragAndDropEntry::DragAndDropEntry(dragOrDrop3dImpl f_none, dragOrDrop3dImpl f_self, dragOrDrop3dImpl f_avatar, @@ -331,14 +333,15 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary() }; LLToolDragAndDrop::LLToolDragAndDrop() -: LLTool(std::string("draganddrop"), NULL), - mDragStartX(0), - mDragStartY(0), - mSource(SOURCE_AGENT), - mCursor(UI_CURSOR_NO), - mLastAccept(ACCEPT_NO), - mDrop(FALSE), - mCurItemIndex(0) +: LLTool(std::string("draganddrop"), NULL), + mCargoCount(0), + mDragStartX(0), + mDragStartY(0), + mSource(SOURCE_AGENT), + mCursor(UI_CURSOR_NO), + mLastAccept(ACCEPT_NO), + mDrop(FALSE), + mCurItemIndex(0) { } @@ -626,6 +629,8 @@ BOOL LLToolDragAndDrop::handleToolTip(S32 x, S32 y, MASK mask) void LLToolDragAndDrop::handleDeselect() { mToolTipMsg.clear(); + + LLToolTipMgr::instance().blockToolTips(); } // protected @@ -642,33 +647,47 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop, mToolTipMsg.clear(); + // Increment the operation id for every drop + if (drop) + { + sOperationId++; + } + + // For people drag and drop we don't need an actual inventory object, + // instead we need the current cargo id, which should be a person id. + bool is_uuid_dragged = (mSource == SOURCE_PEOPLE); + if (top_view) { handled = TRUE; for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) { - LLInventoryObject* cargo = locateInventory(item, cat); + S32 local_x, local_y; + top_view->screenPointToLocal( x, y, &local_x, &local_y ); + EAcceptance item_acceptance = ACCEPT_NO; + LLInventoryObject* cargo = locateInventory(item, cat); if (cargo) { - S32 local_x, local_y; - top_view->screenPointToLocal( x, y, &local_x, &local_y ); - EAcceptance item_acceptance = ACCEPT_NO; handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE, mCargoTypes[mCurItemIndex], (void*)cargo, &item_acceptance, mToolTipMsg); - if (handled) - { - // use sort order to determine priority of acceptance - *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance); - } } - else + else if (is_uuid_dragged) { - return; + handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE, + mCargoTypes[mCurItemIndex], + (void*)&mCargoIDs[mCurItemIndex], + &item_acceptance, + mToolTipMsg); + } + if (handled) + { + // use sort order to determine priority of acceptance + *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance); } } @@ -685,20 +704,27 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop, for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) { - LLInventoryObject* cargo = locateInventory(item, cat); + S32 local_x, local_y; + EAcceptance item_acceptance; + top_view->screenPointToLocal( x, y, &local_x, &local_y ); + LLInventoryObject* cargo = locateInventory(item, cat); if (cargo) { - S32 local_x, local_y; - - EAcceptance item_acceptance; - top_view->screenPointToLocal( x, y, &local_x, &local_y ); handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, TRUE, mCargoTypes[mCurItemIndex], (void*)cargo, &item_acceptance, mToolTipMsg); } + else if (is_uuid_dragged) + { + handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE, + mCargoTypes[mCurItemIndex], + (void*)&mCargoIDs[mCurItemIndex], + &item_acceptance, + mToolTipMsg); + } } } if (handled) @@ -715,17 +741,27 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop, for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) { + EAcceptance item_acceptance = ACCEPT_NO; + LLInventoryObject* cargo = locateInventory(item, cat); // fix for EXT-3191 - if (NULL == cargo) return; - - EAcceptance item_acceptance = ACCEPT_NO; - handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE, - mCargoTypes[mCurItemIndex], - (void*)cargo, - &item_acceptance, - mToolTipMsg); + if (cargo) + { + handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE, + mCargoTypes[mCurItemIndex], + (void*)cargo, + &item_acceptance, + mToolTipMsg); + } + else if (is_uuid_dragged) + { + handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE, + mCargoTypes[mCurItemIndex], + (void*)&mCargoIDs[mCurItemIndex], + &item_acceptance, + mToolTipMsg); + } if (handled) { // use sort order to determine priority of acceptance @@ -745,17 +781,25 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop, for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) { - LLInventoryObject* cargo = locateInventory(item, cat); + EAcceptance item_acceptance; + LLInventoryObject* cargo = locateInventory(item, cat); if (cargo) { - EAcceptance item_acceptance; handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE, mCargoTypes[mCurItemIndex], (void*)cargo, &item_acceptance, mToolTipMsg); } + else if (is_uuid_dragged) + { + handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE, + mCargoTypes[mCurItemIndex], + (void*)&mCargoIDs[mCurItemIndex], + &item_acceptance, + mToolTipMsg); + } } } @@ -767,6 +811,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); + 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 +924,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)) @@ -980,7 +1039,14 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj, } } // Add the texture item to the target object's inventory. - hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + if (LLAssetType::AT_TEXTURE == new_item->getType()) + { + hit_obj->updateTextureInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + } + else + { + hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + } // TODO: Check to see if adding the item was successful; if not, then // we should return false here. } @@ -995,7 +1061,14 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj, // *FIX: may want to make sure agent can paint hit_obj. // Add the texture item to the target object's inventory. - hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + if (LLAssetType::AT_TEXTURE == new_item->getType()) + { + hit_obj->updateTextureInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + } + else + { + hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + } // Force the object to update its refetch its inventory so it has this texture. hit_obj->fetchInventoryFromServer(); // TODO: Check to see if adding the item was successful; if not, then @@ -2468,7 +2541,13 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory( { item = NULL; cat = NULL; - if(mCargoIDs.empty()) return NULL; + + if (mCargoIDs.empty() + || (mSource == SOURCE_PEOPLE)) ///< There is no inventory item for people drag and drop. + { + return NULL; + } + if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)) { // The object should be in user inventory. @@ -2502,8 +2581,9 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory( } else if(mSource == SOURCE_VIEWER) { - item = (LLViewerInventoryItem*)gClipboard.getSourceObject(); + item = (LLViewerInventoryItem*)gToolBarView->getDragItem(); } + if(item) return item; if(cat) return cat; return NULL; diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 92f007a251..f17300a76a 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -67,7 +67,8 @@ public: SOURCE_WORLD, SOURCE_NOTECARD, SOURCE_LIBRARY, - SOURCE_VIEWER + SOURCE_VIEWER, + SOURCE_PEOPLE }; void beginDrag(EDragAndDropType type, @@ -87,6 +88,19 @@ public: boost::signals2::connection setEndDragCallback( const enddrag_signal_t::slot_type& cb ) { return mEndDragSignal.connect(cb); } + void setCargoCount(U32 count) { mCargoCount = count; } + void resetCargoCount() { mCargoCount = 0; } + U32 getCargoCount() const { return (mCargoCount > 0) ? mCargoCount : mCargoIDs.size(); } + + static S32 getOperationId() { return sOperationId; } + + // deal with permissions of object, etc. returns TRUE if drop can + // proceed, otherwise FALSE. + static BOOL handleDropTextureProtections(LLViewerObject* hit_obj, + LLInventoryItem* item, + LLToolDragAndDrop::ESource source, + const LLUUID& src_id); + protected: enum EDropTarget { @@ -115,6 +129,8 @@ protected: protected: + U32 mCargoCount; + S32 mDragStartX; S32 mDragStartY; @@ -125,6 +141,8 @@ protected: LLUUID mSourceID; LLUUID mObjectID; + static S32 sOperationId; + LLVector3d mLastCameraPos; LLVector3d mLastHitPos; @@ -209,13 +227,6 @@ protected: // inventory items to determine if a drop would be ok. static EAcceptance willObjectAcceptInventory(LLViewerObject* obj, LLInventoryItem* item); - // deal with permissions of object, etc. returns TRUE if drop can - // proceed, otherwise FALSE. - static BOOL handleDropTextureProtections(LLViewerObject* hit_obj, - LLInventoryItem* item, - LLToolDragAndDrop::ESource source, - const LLUUID& src_id); - public: // helper functions static BOOL isInventoryDropAcceptable(LLViewerObject* obj, LLInventoryItem* item) { return (ACCEPT_YES_COPY_SINGLE <= willObjectAcceptInventory(obj, item)); } diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index 319e2508e0..9907da0f0e 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -205,9 +205,9 @@ BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info) // Clicks on scripted or physical objects are temporary grabs, so // not "Build mode" - mHideBuildHighlight = script_touch || objectp->usePhysics(); + mHideBuildHighlight = script_touch || objectp->flagUsePhysics(); - if (!objectp->usePhysics()) + if (!objectp->flagUsePhysics()) { if (script_touch) { @@ -222,18 +222,24 @@ BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info) if (gAgentCamera.cameraMouselook()) { mMode = GRAB_LOCKED; + gViewerWindow->hideCursor(); + gViewerWindow->moveCursorToCenter(); } - else + else if (objectp->permMove() && !objectp->isPermanentEnforced()) { mMode = GRAB_ACTIVE_CENTER; + gViewerWindow->hideCursor(); + gViewerWindow->moveCursorToCenter(); + } + else + { + mMode = GRAB_LOCKED; } - gViewerWindow->hideCursor(); - gViewerWindow->moveCursorToCenter(); } } - else if( !objectp->permMove() ) + else if( objectp->flagCharacter() || !objectp->permMove() || objectp->isPermanentEnforced()) { // if mouse is over a physical object without move permission, show feedback if user tries to move it. mMode = GRAB_LOCKED; diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp index 6bc7c6de11..a135ba70f5 100644 --- a/indra/newview/lltoolmgr.cpp +++ b/indra/newview/lltoolmgr.cpp @@ -81,7 +81,7 @@ LLToolMgr::LLToolMgr() // Not a panel, register these callbacks globally. LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Active", boost::bind(&LLToolMgr::inEdit, this)); LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Enabled", boost::bind(&LLToolMgr::canEdit, this)); - LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Build.Toggle", boost::bind(&LLToolMgr::toggleBuildMode, this)); + LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Build.Toggle", boost::bind(&LLToolMgr::toggleBuildMode, this, _2)); gToolNull = new LLTool(LLStringUtil::null); // Does nothing setCurrentTool(gToolNull); @@ -91,6 +91,8 @@ LLToolMgr::LLToolMgr() // gLandToolset = new LLToolset(); gMouselookToolset = new LLToolset(); gFaceEditToolset = new LLToolset(); + gMouselookToolset->setShowFloaterTools(false); + gFaceEditToolset->setShowFloaterTools(false); } void LLToolMgr::initTools() @@ -245,8 +247,15 @@ bool LLToolMgr::canEdit() return LLViewerParcelMgr::getInstance()->allowAgentBuild(); } -void LLToolMgr::toggleBuildMode() +void LLToolMgr::toggleBuildMode(const LLSD& sdname) { + const std::string& param = sdname.asString(); + + if (param == "build" && !canEdit()) + { + return; + } + LLFloaterReg::toggleInstanceOrBringToFront("build"); bool build_visible = LLFloaterReg::instanceVisible("build"); diff --git a/indra/newview/lltoolmgr.h b/indra/newview/lltoolmgr.h index d489c4c829..e7d1c56c83 100644 --- a/indra/newview/lltoolmgr.h +++ b/indra/newview/lltoolmgr.h @@ -54,7 +54,7 @@ public: bool inEdit(); bool canEdit(); - void toggleBuildMode(); + void toggleBuildMode(const LLSD& sdname); /* Determines if we are in Build mode or not. */ bool inBuildMode(); @@ -89,7 +89,7 @@ protected: class LLToolset { public: - LLToolset() : mSelectedTool(NULL) {} + LLToolset() : mSelectedTool(NULL), mIsShowFloaterTools(true) {} LLTool* getSelectedTool() { return mSelectedTool; } @@ -105,10 +105,14 @@ public: BOOL isToolSelected( S32 index ); + void setShowFloaterTools(bool pShowFloaterTools) {mIsShowFloaterTools = pShowFloaterTools;}; + bool isShowFloaterTools() const {return mIsShowFloaterTools;}; + protected: LLTool* mSelectedTool; typedef std::vector<LLTool*> tool_list_t; tool_list_t mToolList; + bool mIsShowFloaterTools; }; // Globals diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index 718201e381..0d5daf129f 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -225,7 +225,8 @@ BOOL LLVisualParamHint::render() LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); - if (gAgentAvatarp->mDrawable.notNull()) + if (gAgentAvatarp->mDrawable.notNull() && + gAgentAvatarp->mDrawable->getFace(0)) { LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)gAgentAvatarp->mDrawable->getFace(0)->getPool(); LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index b0d9bd5d70..f24891baf6 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -125,9 +125,10 @@ BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask) mPick.mKeyMask = mask; // claim not handled so UI focus stays same - - handleRightClickPick(); - + if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) + { + handleRightClickPick(); + } return FALSE; } @@ -312,7 +313,7 @@ BOOL LLToolPie::handleLeftClickPick() // Switch to grab tool if physical or triggerable if (object && !object->isAvatar() && - ((object->usePhysics() || (parent && !parent->isAvatar() && parent->usePhysics())) || touchable) + ((object->flagUsePhysics() || (parent && !parent->isAvatar() && parent->flagUsePhysics())) || touchable) ) { gGrabTransientTool = this; @@ -596,8 +597,8 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; } - else if ((object && !object->isAvatar() && object->usePhysics()) - || (parent && !parent->isAvatar() && parent->usePhysics())) + else if ((object && !object->isAvatar() && object->flagUsePhysics()) + || (parent && !parent->isAvatar() && parent->flagUsePhysics())) { show_highlight = true; gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB); @@ -972,33 +973,16 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l || !existing_inspector->getVisible() || existing_inspector->getKey()["avatar_id"].asUUID() != hover_object->getID()) { - // IDEVO: try to get display name + username + // Try to get display name + username std::string final_name; - std::string full_name; - if (!gCacheName->getFullName(hover_object->getID(), full_name)) - { - LLNameValue* firstname = hover_object->getNVPair("FirstName"); - LLNameValue* lastname = hover_object->getNVPair("LastName"); - if (firstname && lastname) - { - full_name = LLCacheName::buildFullName( - firstname->getString(), lastname->getString()); - } - else - { - full_name = LLTrans::getString("TooltipPerson"); - } - } - LLAvatarName av_name; - if (LLAvatarNameCache::useDisplayNames() && - LLAvatarNameCache::get(hover_object->getID(), &av_name)) + if (LLAvatarNameCache::get(hover_object->getID(), &av_name)) { final_name = av_name.getCompleteName(); } else { - final_name = full_name; + final_name = LLTrans::getString("TooltipPerson");; } // *HACK: We may select this object, so pretend it was clicked diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp index bf1f8808a7..cbd16e873d 100644 --- a/indra/newview/lltracker.cpp +++ b/indra/newview/lltracker.cpp @@ -251,7 +251,7 @@ void LLTracker::render3D() instance()->mBeaconText->setDoFade(FALSE); } - F32 dist = gFloaterWorldMap->getDistanceToDestination(instance()->mTrackedPositionGlobal, 0.0f); + F32 dist = gFloaterWorldMap->getDistanceToDestination(instance()->getTrackedPositionGlobal(), 0.0f); if (dist < DESTINATION_REACHED_RADIUS) { instance()->stopTrackingAvatar(); diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index 7eb54271f4..f3d8de1904 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, @@ -156,10 +162,10 @@ void LLBingTranslationHandler::getTranslateURL( const std::string &text) const { url = std::string("http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=") - + getAPIKey() + "&text=" + LLURI::escape(text) + "&to=" + to_lang; + + getAPIKey() + "&text=" + LLURI::escape(text) + "&to=" + getAPILanguageCode(to_lang); if (!from_lang.empty()) { - url += "&from=" + from_lang; + url += "&from=" + getAPILanguageCode(from_lang); } } @@ -218,12 +224,24 @@ bool LLBingTranslationHandler::parseResponse( return true; } +// virtual +bool LLBingTranslationHandler::isConfigured() const +{ + return !getAPIKey().empty(); +} + // static std::string LLBingTranslationHandler::getAPIKey() { return gSavedSettings.getString("BingTranslateAPIKey"); } +// static +std::string LLBingTranslationHandler::getAPILanguageCode(const std::string& lang) +{ + return lang == "zh" ? "zh-CHT" : lang; // treat Chinese as Traditional Chinese +} + LLTranslate::TranslationReceiver::TranslationReceiver(const std::string& from_lang, const std::string& to_lang) : mFromLang(from_lang) , mToLang(to_lang) @@ -332,6 +350,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..db5ad9479c 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,8 +154,10 @@ public: std::string& translation, std::string& detected_lang, std::string& err_msg) const; + /*virtual*/ bool isConfigured() const; private: static std::string getAPIKey(); + static std::string getAPILanguageCode(const std::string& lang); }; /** @@ -255,8 +263,8 @@ public : EService mService; }; - typedef boost::intrusive_ptr<TranslationReceiver> TranslationReceiverPtr; - typedef boost::intrusive_ptr<KeyVerificationReceiver> KeyVerificationReceiverPtr; + typedef LLPointer<TranslationReceiver> TranslationReceiverPtr; + typedef LLPointer<KeyVerificationReceiver> KeyVerificationReceiverPtr; /** * Translate given text. @@ -275,8 +283,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/lluploaddialog.cpp b/indra/newview/lluploaddialog.cpp index df7c5be0d6..e59064c074 100644 --- a/indra/newview/lluploaddialog.cpp +++ b/indra/newview/lluploaddialog.cpp @@ -115,7 +115,7 @@ void LLUploadDialog::setMessage( const std::string& msg) token = strtok( NULL, "\n" ); } - S32 line_height = S32( font->getLineHeight() + 0.99f ); + S32 line_height = font->getLineHeight(); S32 dialog_width = max_msg_width + 2 * HPAD; S32 dialog_height = line_height * msg_lines.size() + 2 * VPAD; diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index f6d7ceeec3..00b15a5f26 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -167,9 +167,9 @@ bool LLURLDispatcherImpl::dispatchApp(const LLSLURL& slurl, // static bool LLURLDispatcherImpl::dispatchRegion(const LLSLURL& slurl, const std::string& nav_type, bool right_mouse) { - if(slurl.getType() != LLSLURL::LOCATION) + if(slurl.getType() != LLSLURL::LOCATION) { - return false; + return false; } // Before we're logged in, need to update the startup screen // to tell the user where they are going. @@ -205,18 +205,18 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const LLSLURL& { // we can't teleport cross grid at this point - if((!LLGridManager::getInstance()->isSystemGrid(slurl.getGrid()) || !LLGridManager::getInstance()->isSystemGrid()) && - (slurl.getGrid() != LLGridManager::getInstance()->getGrid())) + if( LLGridManager::getInstance()->getGrid(slurl.getGrid()) + != LLGridManager::getInstance()->getGrid()) { LLSD args; args["SLURL"] = slurl.getLocationString(); args["CURRENT_GRID"] = LLGridManager::getInstance()->getGridLabel(); - LLSD grid_info; - LLGridManager::getInstance()->getGridInfo(slurl.getGrid(), grid_info); + std::string grid_label = + LLGridManager::getInstance()->getGridLabel(slurl.getGrid()); - if(grid_info.has(GRID_LABEL_VALUE)) + if(!grid_label.empty()) { - args["GRID"] = grid_info[GRID_LABEL_VALUE].asString(); + args["GRID"] = grid_label; } else { diff --git a/indra/newview/llurllineeditorctrl.cpp b/indra/newview/llurllineeditorctrl.cpp index 56b5bbf942..cad5769042 100644 --- a/indra/newview/llurllineeditorctrl.cpp +++ b/indra/newview/llurllineeditorctrl.cpp @@ -89,5 +89,5 @@ void LLURLLineEditor::copyEscapedURLToClipboard() else // human-readable location text_to_copy = utf8str_to_wstring(unescaped_text); - gClipboard.copyFromString( text_to_copy ); + LLClipboard::instance().copyToClipboard(text_to_copy, 0, text_to_copy.size()); } diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index e621cf647e..4c59fd0371 100644 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -30,6 +30,7 @@ #include "llregionhandle.h" #include "stdtypes.h" +#include "llvoavatar.h" /* * Classes and utility functions for per-thread and per-region @@ -126,6 +127,8 @@ LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionSta mFPS.merge(src.mFPS); } + // Avatar stats - data all comes from main thread, so leave alone. + // Requests for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i) { @@ -133,6 +136,7 @@ LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionSta mRequests[i].mDequeued.merge(src.mRequests[i].mDequeued); mRequests[i].mResponse.merge(src.mRequests[i].mResponse); } + } @@ -156,7 +160,9 @@ LLViewerAssetStats::LLViewerAssetStats() LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src) : mRegionHandle(src.mRegionHandle), - mResetTimestamp(src.mResetTimestamp) + mResetTimestamp(src.mResetTimestamp), + mPhaseStats(src.mPhaseStats), + mAvatarRezStates(src.mAvatarRezStates) { const PerRegionContainer::const_iterator it_end(src.mRegionStats.end()); for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it) @@ -252,6 +258,17 @@ LLViewerAssetStats::recordFPS(F32 fps) mCurRegionStats->mFPS.record(fps); } +void +LLViewerAssetStats::recordAvatarStats() +{ + std::vector<S32> rez_counts; + LLVOAvatar::getNearbyRezzedStats(rez_counts); + mAvatarRezStates = rez_counts; + mPhaseStats.clear(); + mPhaseStats["cloud"] = LLViewerStats::PhaseMap::getPhaseStats("cloud"); + mPhaseStats["cloud-or-gray"] = LLViewerStats::PhaseMap::getPhaseStats("cloud-or-gray"); +} + LLSD LLViewerAssetStats::asLLSD(bool compact_output) { @@ -282,6 +299,11 @@ LLViewerAssetStats::asLLSD(bool compact_output) static const LLSD::String max_tag("max"); static const LLSD::String mean_tag("mean"); + // Avatar sub-tags + static const LLSD::String avatar_tag("avatar"); + static const LLSD::String avatar_nearby_tag("nearby"); + static const LLSD::String avatar_phase_stats_tag("phase_stats"); + const duration_t now = LLViewerAssetStatsFF::get_timestamp(); mCurRegionStats->accumulateTime(now); @@ -329,7 +351,6 @@ LLViewerAssetStats::asLLSD(bool compact_output) slot[max_tag] = LLSD(F64(stats.mFPS.getMax())); slot[mean_tag] = LLSD(F64(stats.mFPS.getMean())); } - U32 grid_x(0), grid_y(0); grid_from_region_handle(it->first, &grid_x, &grid_y); reg_stat["grid_x"] = LLSD::Integer(grid_x); @@ -341,6 +362,16 @@ LLViewerAssetStats::asLLSD(bool compact_output) LLSD ret = LLSD::emptyMap(); ret["regions"] = regions; ret["duration"] = LLSD::Real((now - mResetTimestamp) * 1.0e-6); + LLSD avatar_info; + avatar_info[avatar_nearby_tag] = LLSD::emptyArray(); + for (S32 rez_stat=0; rez_stat < mAvatarRezStates.size(); ++rez_stat) + { + std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat); + avatar_info[avatar_nearby_tag][rez_status_name] = mAvatarRezStates[rez_stat]; + } + avatar_info[avatar_phase_stats_tag]["cloud"] = mPhaseStats["cloud"].getData(); + avatar_info[avatar_phase_stats_tag]["cloud-or-gray"] = mPhaseStats["cloud-or-gray"].getData(); + ret[avatar_tag] = avatar_info; return ret; } @@ -439,6 +470,14 @@ record_fps_main(F32 fps) gViewerAssetStatsMain->recordFPS(fps); } +void +record_avatar_stats() +{ + if (! gViewerAssetStatsMain) + return; + + gViewerAssetStatsMain->recordAvatarStats(); +} // 'thread1' - should be for TextureFetch thread diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 73ec5974b2..8319752230 100644 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -36,6 +36,7 @@ #include "llviewerassetstorage.h" #include "llsimplestat.h" #include "llsd.h" +#include "llvoavatar.h" /** * @class LLViewerAssetStats @@ -181,6 +182,9 @@ public: // Frames-Per-Second Samples void recordFPS(F32 fps); + // Avatar-related statistics + void recordAvatarStats(); + // Merge a source instance into a destination instance. This is // conceptually an 'operator+=()' method: // - counts are added @@ -252,6 +256,10 @@ protected: // Time of last reset duration_t mResetTimestamp; + + // Nearby avatar stats + std::vector<S32> mAvatarRezStates; + LLViewerStats::phase_stats_t mPhaseStats; }; @@ -310,6 +318,7 @@ void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_t void record_fps_main(F32 fps); +void record_avatar_stats(); /** * Region context, event and duration loggers for Thread 1. diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp index a4b1c2155f..08ba5a5f25 100644 --- a/indra/newview/llviewerassettype.cpp +++ b/indra/newview/llviewerassettype.cpp @@ -83,6 +83,8 @@ LLViewerAssetDictionary::LLViewerAssetDictionary() addEntry(LLViewerAssetType::AT_WIDGET, new ViewerAssetEntry(DAD_WIDGET)); + addEntry(LLViewerAssetType::AT_PERSON, new ViewerAssetEntry(DAD_PERSON)); + addEntry(LLViewerAssetType::AT_NONE, new ViewerAssetEntry(DAD_NONE)); }; diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index f7fa5690d6..564bf7997a 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -30,6 +30,7 @@ #include "llagent.h" #include "llagentcamera.h" #include "llappviewer.h" +#include "lldeferredsounds.h" #include "llvieweraudio.h" #include "llviewercamera.h" #include "llviewercontrol.h" @@ -37,9 +38,271 @@ #include "llvoiceclient.h" #include "llviewermedia.h" #include "llprogressview.h" +#include "llcallbacklist.h" +#include "llstartup.h" +#include "llviewerparcelmgr.h" +#include "llparcel.h" +#include "llviewermessage.h" ///////////////////////////////////////////////////////// +LLViewerAudio::LLViewerAudio() : + mDone(true), + mFadeState(FADE_IDLE), + mFadeTime(), + mIdleListnerActive(false), + mForcedTeleportFade(false), + mWasPlaying(false) +{ + mTeleportFailedConnection = LLViewerParcelMgr::getInstance()-> + setTeleportFailedCallback(boost::bind(&LLViewerAudio::onTeleportFailed, this)); + mTeleportFinishedConnection = LLViewerParcelMgr::getInstance()-> + setTeleportFinishedCallback(boost::bind(&LLViewerAudio::onTeleportFinished, this, _1, _2)); + mTeleportStartedConnection = LLViewerMessage::getInstance()-> + setTeleportStartedCallback(boost::bind(&LLViewerAudio::onTeleportStarted, this)); +} + +LLViewerAudio::~LLViewerAudio() +{ + mTeleportFailedConnection.disconnect(); + mTeleportFinishedConnection.disconnect(); + mTeleportStartedConnection.disconnect(); +} + +void LLViewerAudio::registerIdleListener() +{ + if(mIdleListnerActive==false) + { + mIdleListnerActive = true; + doOnIdleRepeating(boost::bind(boost::bind(&LLViewerAudio::onIdleUpdate, this))); + } +} + +void LLViewerAudio::startInternetStreamWithAutoFade(std::string streamURI) +{ + // Old and new stream are identical + if (mNextStreamURI == streamURI) + { + return; + } + + // Record the URI we are going to be switching to + mNextStreamURI = streamURI; + + switch (mFadeState) + { + case FADE_IDLE: + // If a stream is playing fade it out first + if (!gAudiop->getInternetStreamURL().empty()) + { + // The order of these tests is important, state FADE_OUT will be processed below + mFadeState = FADE_OUT; + } + // Otherwise the new stream can be faded in + else + { + mFadeState = FADE_IN; + gAudiop->startInternetStream(mNextStreamURI); + startFading(); + registerIdleListener(); + break; + } + + case FADE_OUT: + startFading(); + registerIdleListener(); + break; + + case FADE_IN: + registerIdleListener(); + break; + + default: + llwarns << "Unknown fading state: " << mFadeState << llendl; + break; + } +} + +// A return of false from onIdleUpdate means it will be called again next idle update. +// A return of true means we have finished with it and the callback will be deleted. +bool LLViewerAudio::onIdleUpdate() +{ + bool fadeIsFinished = false; + + // There is a delay in the login sequence between when the parcel information has + // arrived and the music stream is started and when the audio system is called to set + // initial volume levels. This code extends the fade time so you hear a full fade in. + if ((LLStartUp::getStartupState() < STATE_STARTED)) + { + stream_fade_timer.reset(); + stream_fade_timer.setTimerExpirySec(mFadeTime); + } + + if (mDone) + { + // This should be a rare or never occurring state. + if (mFadeState == FADE_IDLE) + { + deregisterIdleListener(); + fadeIsFinished = true; // Stop calling onIdleUpdate + } + + // we have finished the current fade operation + if (mFadeState == FADE_OUT) + { + // Clear URI + gAudiop->startInternetStream(LLStringUtil::null); + gAudiop->stopInternetStream(); + + if (!mNextStreamURI.empty()) + { + mFadeState = FADE_IN; + gAudiop->startInternetStream(mNextStreamURI); + startFading(); + } + else + { + mFadeState = FADE_IDLE; + deregisterIdleListener(); + fadeIsFinished = true; // Stop calling onIdleUpdate + } + } + else if (mFadeState == FADE_IN) + { + if (mNextStreamURI != gAudiop->getInternetStreamURL()) + { + mFadeState = FADE_OUT; + startFading(); + } + else + { + mFadeState = FADE_IDLE; + deregisterIdleListener(); + fadeIsFinished = true; // Stop calling onIdleUpdate + } + } + } + + return fadeIsFinished; +} + +void LLViewerAudio::stopInternetStreamWithAutoFade() +{ + mFadeState = FADE_IDLE; + mNextStreamURI = LLStringUtil::null; + mDone = true; + + gAudiop->startInternetStream(LLStringUtil::null); + gAudiop->stopInternetStream(); +} + +void LLViewerAudio::startFading() +{ + const F32 AUDIO_MUSIC_FADE_IN_TIME = 3.0f; + const F32 AUDIO_MUSIC_FADE_OUT_TIME = 2.0f; + // This minimum fade time prevents divide by zero and negative times + const F32 AUDIO_MUSIC_MINIMUM_FADE_TIME = 0.01f; + + if(mDone) + { + // The fade state here should only be one of FADE_IN or FADE_OUT, but, in case it is not, + // rather than check for both states assume a fade in and check for the fade out case. + mFadeTime = AUDIO_MUSIC_FADE_IN_TIME; + if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT) + { + mFadeTime = AUDIO_MUSIC_FADE_OUT_TIME; + } + + // Prevent invalid fade time + mFadeTime = llmax(mFadeTime, AUDIO_MUSIC_MINIMUM_FADE_TIME); + + stream_fade_timer.reset(); + stream_fade_timer.setTimerExpirySec(mFadeTime); + mDone = false; + } +} + +F32 LLViewerAudio::getFadeVolume() +{ + F32 fade_volume = 1.0f; + + if (stream_fade_timer.hasExpired()) + { + mDone = true; + // If we have been fading out set volume to 0 until the next fade state occurs to prevent + // an audio transient. + if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT) + { + fade_volume = 0.0f; + } + } + + if (!mDone) + { + // Calculate how far we are into the fade time + fade_volume = stream_fade_timer.getElapsedTimeF32() / mFadeTime; + + if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT) + { + // If we are not fading in then we are fading out, so invert the fade + // direction; start loud and move towards zero volume. + fade_volume = 1.0f - fade_volume; + } + } + + return fade_volume; +} + +void LLViewerAudio::onTeleportStarted() +{ + if (!LLViewerAudio::getInstance()->getForcedTeleportFade()) + { + // Even though the music was turned off it was starting up (with autoplay disabled) occasionally + // after a failed teleport or after an intra-parcel teleport. Also, the music sometimes was not + // restarting after a successful intra-parcel teleport. Setting mWasPlaying fixes these issues. + LLViewerAudio::getInstance()->setWasPlaying(!gAudiop->getInternetStreamURL().empty()); + LLViewerAudio::getInstance()->setForcedTeleportFade(true); + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); + LLViewerAudio::getInstance()->setNextStreamURI(LLStringUtil::null); + } +} + +void LLViewerAudio::onTeleportFailed() +{ + // Calling audio_update_volume makes sure that the music stream is properly set to be restored to + // its previous value + audio_update_volume(false); + + if (gAudiop && mWasPlaying) + { + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (parcel) + { + mNextStreamURI = parcel->getMusicURL(); + llinfos << "Teleport failed -- setting music stream to " << mNextStreamURI << llendl; + } + } + mWasPlaying = false; +} + +void LLViewerAudio::onTeleportFinished(const LLVector3d& pos, const bool& local) +{ + // Calling audio_update_volume makes sure that the music stream is properly set to be restored to + // its previous value + audio_update_volume(false); + + if (gAudiop && local && mWasPlaying) + { + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (parcel) + { + mNextStreamURI = parcel->getMusicURL(); + llinfos << "Intraparcel teleport -- setting music stream to " << mNextStreamURI << llendl; + } + } + mWasPlaying = false; +} + void init_audio() { if (!gAudiop) @@ -126,6 +389,12 @@ void audio_update_volume(bool force_update) gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff")); gAudiop->setMuted(mute_audio || progress_view_visible); + //Play any deferred sounds when unmuted + if(!gAudiop->getMuted()) + { + LLDeferredSounds::instance().playdeferredSounds(); + } + if (force_update) { audio_update_wind(true); @@ -142,12 +411,19 @@ void audio_update_volume(bool force_update) // Streaming Music if (gAudiop) - { + { + if (!progress_view_visible && LLViewerAudio::getInstance()->getForcedTeleportFade()) + { + LLViewerAudio::getInstance()->setWasPlaying(!gAudiop->getInternetStreamURL().empty()); + LLViewerAudio::getInstance()->setForcedTeleportFade(false); + } + F32 music_volume = gSavedSettings.getF32("AudioLevelMusic"); BOOL music_muted = gSavedSettings.getBOOL("MuteMusic"); - music_volume = mute_volume * master_volume * music_volume; - gAudiop->setInternetStreamGain ( music_muted || progress_view_visible ? 0.f : music_volume ); - + F32 fade_volume = LLViewerAudio::getInstance()->getFadeVolume(); + + music_volume = mute_volume * master_volume * music_volume * fade_volume; + gAudiop->setInternetStreamGain (music_muted ? 0.f : music_volume); } // Streaming Media diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h index e5916285fb..8c302c6549 100644 --- a/indra/newview/llvieweraudio.h +++ b/indra/newview/llvieweraudio.h @@ -27,6 +27,9 @@ #ifndef LL_VIEWERAUDIO_H #define LL_VIEWERAUDIO_H +#include "llframetimer.h" +#include "llsingleton.h" + // comment out to turn off wind #define kAUDIO_ENABLE_WIND //#define kAUDIO_ENABLE_WATER 1 // comment out to turn off water @@ -38,4 +41,53 @@ void audio_update_volume(bool force_update = true); void audio_update_listener(); void audio_update_wind(bool force_update = true); +class LLViewerAudio : public LLSingleton<LLViewerAudio> +{ +public: + + enum EFadeState + { + FADE_IDLE, + FADE_IN, + FADE_OUT, + }; + + LLViewerAudio(); + virtual ~LLViewerAudio(); + + void startInternetStreamWithAutoFade(std::string streamURI); + void stopInternetStreamWithAutoFade(); + + bool onIdleUpdate(); + + EFadeState getFadeState() { return mFadeState; } + bool isDone() { return mDone; }; + F32 getFadeVolume(); + bool getForcedTeleportFade() { return mForcedTeleportFade; }; + void setForcedTeleportFade(bool fade) { mForcedTeleportFade = fade;} ; + void setNextStreamURI(std::string stream) { mNextStreamURI = stream; } ; + void setWasPlaying(bool playing) { mWasPlaying = playing;} ; + +private: + + bool mDone; + F32 mFadeTime; + std::string mNextStreamURI; + EFadeState mFadeState; + LLFrameTimer stream_fade_timer; + bool mIdleListnerActive; + bool mForcedTeleportFade; + bool mWasPlaying; + boost::signals2::connection mTeleportFailedConnection; + boost::signals2::connection mTeleportFinishedConnection; + boost::signals2::connection mTeleportStartedConnection; + + void registerIdleListener(); + void deregisterIdleListener() { mIdleListnerActive = false; }; + void startFading(); + void onTeleportFailed(); + void onTeleportFinished(const LLVector3d& pos, const bool& local); + void onTeleportStarted(); +}; + #endif //LL_VIEWER_H diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index cc3395115b..b857c7fe89 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -32,8 +32,8 @@ #include "llstat.h" #include "lltimer.h" #include "m4math.h" +#include "llcoord.h" -class LLCoordGL; class LLViewerObject; // This rotation matrix moves the default OpenGL reference frame @@ -51,9 +51,19 @@ const BOOL NOT_FOR_SELECTION = FALSE; extern template class LLViewerCamera* LLSingleton<class LLViewerCamera>::getInstance(); #endif +LL_ALIGN_PREFIX(16) class LLViewerCamera : public LLCamera, public LLSingleton<LLViewerCamera> { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } typedef enum { @@ -137,6 +147,7 @@ protected: S16 mZoomSubregion; public: -}; +} LL_ALIGN_POSTFIX(16); + #endif // LL_LLVIEWERCAMERA_H diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 73e4d11d7b..051f5f4485 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -71,8 +71,14 @@ #include "llpaneloutfitsinventory.h" #include "llpanellogin.h" #include "llpaneltopinfobar.h" +#include "llspellcheck.h" +#include "llslurl.h" +#include "llstartup.h" #include "llupdaterservice.h" +// Third party library includes +#include <boost/algorithm/string.hpp> + #ifdef TOGGLE_HACKED_GODLIKE_VIEWER BOOL gHackGodmode = FALSE; #endif @@ -87,7 +93,6 @@ std::string gLastRunVersion; extern BOOL gResizeScreenTexture; extern BOOL gDebugGL; -extern BOOL gAuditTexture; //////////////////////////////////////////////////////////////////////////// // Listeners @@ -181,6 +186,16 @@ static bool handleReleaseGLBufferChanged(const LLSD& newvalue) return true; } +static bool handleLUTBufferChanged(const LLSD& newvalue) +{ + if (gPipeline.isInit()) + { + gPipeline.releaseLUTBuffers(); + gPipeline.createLUTBuffers(); + } + return true; +} + static bool handleAnisotropicChanged(const LLSD& newvalue) { LLImageGL::sGlobalUseAnisotropic = newvalue.asBoolean(); @@ -316,7 +331,7 @@ static bool handleJoystickChanged(const LLSD& newvalue) static bool handleUseOcclusionChanged(const LLSD& newvalue) { - LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery + LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery && LLGLSLShader::sNoFixedFunction && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0; return true; } @@ -328,15 +343,6 @@ static bool handleUploadBakedTexOldChanged(const LLSD& newvalue) } -static bool handleNumpadControlChanged(const LLSD& newvalue) -{ - if (gKeyboard) - { - gKeyboard->setNumpadDistinct(static_cast<LLKeyboard::e_numpad_distinct>(newvalue.asInteger())); - } - return true; -} - static bool handleWLSkyDetailChanged(const LLSD&) { if (gSky.mVOWLSkyp.notNull()) @@ -401,12 +407,6 @@ static bool handleRenderUseImpostorsChanged(const LLSD& newvalue) return true; } -static bool handleAuditTextureChanged(const LLSD& newvalue) -{ - gAuditTexture = newvalue.asBoolean(); - return true; -} - static bool handleRenderDebugGLChanged(const LLSD& newvalue) { gDebugGL = newvalue.asBoolean() || gDebugSession; @@ -498,6 +498,39 @@ bool handleForceShowGrid(const LLSD& newvalue) return true; } +bool handleLoginLocationChanged() +{ + /* + * This connects the default preference setting to the state of the login + * panel if it is displayed; if you open the preferences panel before + * logging in, and change the default login location there, the login + * panel immediately changes to match your new preference. + */ + std::string new_login_location = gSavedSettings.getString("LoginLocation"); + LL_DEBUGS("AppInit")<<new_login_location<<LL_ENDL; + LLStartUp::setStartSLURL(LLSLURL(new_login_location)); + return true; +} + +bool handleSpellCheckChanged() +{ + if (gSavedSettings.getBOOL("SpellCheck")) + { + std::list<std::string> dict_list; + std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary"); + boost::split(dict_list, dict_setting, boost::is_any_of(std::string(","))); + if (!dict_list.empty()) + { + LLSpellChecker::setUseSpellCheck(dict_list.front()); + dict_list.pop_front(); + LLSpellChecker::instance().setSecondaryDictionaries(dict_list); + return true; + } + } + LLSpellChecker::setUseSpellCheck(LLStringUtil::null); + return true; +} + bool toggle_agent_pause(const LLSD& newvalue) { if ( newvalue.asBoolean() ) @@ -564,15 +597,14 @@ void settings_setup_listeners() gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); gSavedSettings.getControl("RenderDepthOfField")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); + gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2)); + gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2)); + gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2)); gSavedSettings.getControl("RenderAnisotropic")->getSignal()->connect(boost::bind(&handleAnisotropicChanged, _2)); gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); @@ -609,7 +641,6 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2)); gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2)); - gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _2)); gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2)); gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2)); gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2)); @@ -636,7 +667,6 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2)); - gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2)); gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); gSavedSettings.getControl("JoystickAxis2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); @@ -705,6 +735,9 @@ void settings_setup_listeners() gSavedSettings.getControl("UpdaterServiceSetting")->getSignal()->connect(boost::bind(&toggle_updater_service_active, _2)); gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2)); gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2)); + gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); + gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); + gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged)); } #if TEST_CACHED_CONTROL diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 3f0b5bf3fb..ffeea2f4df 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -79,6 +79,7 @@ #include "llpostprocess.h" extern LLPointer<LLViewerTexture> gStartTexture; +extern bool gShiftFrame; LLPointer<LLViewerTexture> gDisconnectedImagep = NULL; @@ -162,9 +163,11 @@ void display_startup() glClear(GL_DEPTH_BUFFER_BIT); } +static LLFastTimer::DeclareTimer FTM_UPDATE_CAMERA("Update Camera"); + void display_update_camera() { - LLMemType mt_uc(LLMemType::MTYPE_DISPLAY_UPDATE_CAMERA); + LLFastTimer t(FTM_UPDATE_CAMERA); // TODO: cut draw distance down if customizing avatar? // TODO: cut draw distance on per-parcel basis? @@ -214,23 +217,27 @@ static LLFastTimer::DeclareTimer FTM_UPDATE_SKY("Update Sky"); static LLFastTimer::DeclareTimer FTM_UPDATE_TEXTURES("Update Textures"); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE("Update Images"); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_CLASS("Class"); -static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Bump"); +static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Image Update Bump"); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List"); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_DELETE("Delete"); +static LLFastTimer::DeclareTimer FTM_RESIZE_WINDOW("Resize Window"); +static LLFastTimer::DeclareTimer FTM_HUD_UPDATE("HUD Update"); +static LLFastTimer::DeclareTimer FTM_DISPLAY_UPDATE_GEOM("Update Geom"); +static LLFastTimer::DeclareTimer FTM_TEXTURE_UNBIND("Texture Unbind"); +static LLFastTimer::DeclareTimer FTM_TELEPORT_DISPLAY("Teleport Display"); // Paint the display! void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { - LLMemType mt_render(LLMemType::MTYPE_RENDER); LLFastTimer t(FTM_RENDER); if (gWindowResized) { //skip render on frames where window has been resized + LLFastTimer t(FTM_RESIZE_WINDOW); gGL.flush(); glClear(GL_COLOR_BUFFER_BIT); gViewerWindow->getWindow()->swapBuffers(); LLPipeline::refreshCachedSettings(); - LLPipeline::refreshRenderDeferred(); gPipeline.resizeScreenTexture(); gResizeScreenTexture = FALSE; gWindowResized = FALSE; @@ -261,6 +268,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gPipeline.disableLights(); + //reset vertex buffers if needed + gPipeline.doResetVertexBuffers(); + stop_glerror(); // Don't draw if the window is hidden or minimized. @@ -360,6 +370,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (gTeleportDisplay) { + LLFastTimer t(FTM_TELEPORT_DISPLAY); LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport"); const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. @@ -381,15 +392,24 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) const std::string& message = gAgent.getTeleportMessage(); switch( gAgent.getTeleportState() ) { + case LLAgent::TELEPORT_PENDING: + gTeleportDisplayTimer.reset(); + gViewerWindow->setShowProgress(TRUE); + gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); + gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["pending"]); + gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["pending"]); + break; + case LLAgent::TELEPORT_START: // Transition to REQUESTED. Viewer has sent some kind // of TeleportRequest to the source simulator gTeleportDisplayTimer.reset(); gViewerWindow->setShowProgress(TRUE); - gViewerWindow->setProgressPercent(0); + gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["requesting"]); + gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["requesting"]); break; case LLAgent::TELEPORT_REQUESTED: @@ -414,6 +434,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLAgent::sTeleportProgressMessages["arriving"]); gTextureList.mForceResetTextureStats = TRUE; gAgentCamera.resetView(TRUE, TRUE); + break; case LLAgent::TELEPORT_ARRIVING: @@ -558,7 +579,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (!gDisconnected) { - LLMemType mt_du(LLMemType::MTYPE_DISPLAY_UPDATE); LLAppViewer::instance()->pingMainloopTimeout("Display:Update"); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { //don't draw hud objects in this frame @@ -579,14 +599,14 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) // *TODO: merge these two methods { - LLMemType mt_uh(LLMemType::MTYPE_DISPLAY_UPDATE_HUD); + LLFastTimer t(FTM_HUD_UPDATE); LLHUDManager::getInstance()->updateEffects(); LLHUDObject::updateAll(); stop_glerror(); } { - LLMemType mt_ug(LLMemType::MTYPE_DISPLAY_UPDATE_GEOM); + LLFastTimer t(FTM_DISPLAY_UPDATE_GEOM); const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time gPipeline.createObjects(max_geom_update_time); gPipeline.processPartitionQ(); @@ -595,6 +615,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) } gPipeline.updateGL(); + stop_glerror(); S32 water_clip = 0; @@ -617,17 +638,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) //Increment drawable frame counter LLDrawable::incrementVisible(); - LLPipeline::refreshCachedSettings(); - LLPipeline::refreshRenderDeferred(); - LLSpatialGroup::sNoDelete = TRUE; LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName(); - /*if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred) - { //force occlusion on for all render types if doing deferred render (tighter shadow frustum) - LLPipeline::sUseOcclusion = 3; - }*/ - S32 occlusion = LLPipeline::sUseOcclusion; if (gDepthDirty) { //depth buffer is invalid, don't overwrite occlusion state @@ -654,8 +667,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLAppViewer::instance()->pingMainloopTimeout("Display:Swap"); { - LLMemType mt_ds(LLMemType::MTYPE_DISPLAY_SWAP); - if (gResizeScreenTexture) { gResizeScreenTexture = FALSE; @@ -714,7 +725,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) //if (!for_snapshot) { - LLMemType mt_gw(LLMemType::MTYPE_DISPLAY_GEN_REFLECTION); LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery"); gPipeline.generateWaterReflection(*LLViewerCamera::getInstance()); gPipeline.generateHighlight(*LLViewerCamera::getInstance()); @@ -734,7 +744,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages"); { - LLMemType mt_iu(LLMemType::MTYPE_DISPLAY_IMAGE_UPDATE); LLFastTimer t(FTM_IMAGE_UPDATE); { @@ -756,13 +765,13 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gTextureList.updateImages(max_image_decode_time); } - { + /*{ LLFastTimer t(FTM_IMAGE_UPDATE_DELETE); //remove dead textures from GL LLImageGL::deleteDeadTextures(); stop_glerror(); + }*/ } - } LLGLState::checkStates(); LLGLState::checkClientArrays(); @@ -778,7 +787,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort"); { LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - LLMemType mt_ss(LLMemType::MTYPE_DISPLAY_STATE_SORT); gPipeline.stateSort(*LLViewerCamera::getInstance(), result); stop_glerror(); @@ -800,7 +808,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLPipeline::sUseOcclusion = occlusion; { - LLMemType mt_ds(LLMemType::MTYPE_DISPLAY_SKY); LLAppViewer::instance()->pingMainloopTimeout("Display:Sky"); LLFastTimer t(FTM_UPDATE_SKY); gSky.updateSky(); @@ -889,7 +896,28 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) && !gRestoreGL) { LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - LLMemType mt_rg(LLMemType::MTYPE_DISPLAY_RENDER_GEOM); + + if (gSavedSettings.getBOOL("RenderDepthPrePass") && LLGLSLShader::sNoFixedFunction) + { + gGL.setColorMask(false, false); + + U32 types[] = { + LLRenderPass::PASS_SIMPLE, + LLRenderPass::PASS_FULLBRIGHT, + LLRenderPass::PASS_SHINY + }; + + U32 num_types = LL_ARRAY_SIZE(types); + gOcclusionProgram.bind(); + for (U32 i = 0; i < num_types; i++) + { + gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); + } + + gOcclusionProgram.unbind(); + } + + gGL.setColorMask(true, false); if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { @@ -912,19 +940,22 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) stop_glerror(); } - for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++) - { //dummy cleanup of any currently bound textures - if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) - { - gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); - gGL.getTexUnit(i)->disable(); + { + LLFastTimer t(FTM_TEXTURE_UNBIND); + for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++) + { //dummy cleanup of any currently bound textures + if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) + { + gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); + gGL.getTexUnit(i)->disable(); + } } } + LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush"); if (to_texture) { - LLMemType mt_rf(LLMemType::MTYPE_DISPLAY_RENDER_FLUSH); if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { gPipeline.mDeferredScreen.flush(); @@ -985,11 +1016,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) display_stats(); LLAppViewer::instance()->pingMainloopTimeout("Display:Done"); + + gShiftFrame = false; } void render_hud_attachments() { - LLMemType mt_ra(LLMemType::MTYPE_DISPLAY_RENDER_ATTACHMENTS); gGL.matrixMode(LLRender::MM_PROJECTION); gGL.pushMatrix(); gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -1179,7 +1211,6 @@ static LLFastTimer::DeclareTimer FTM_SWAP("Swap"); void render_ui(F32 zoom_factor, int subfield) { - LLMemType mt_ru(LLMemType::MTYPE_DISPLAY_RENDER_UI); LLGLState::checkStates(); glh::matrix4f saved_view = glh_get_current_modelview(); diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp index 5741fab29a..6bd5631df6 100644 --- a/indra/newview/llviewerdisplayname.cpp +++ b/indra/newview/llviewerdisplayname.cpp @@ -53,6 +53,7 @@ namespace LLViewerDisplayName sNameChangedSignal.connect(cb); } + void doNothing() { } } class LLSetDisplayNameResponder : public LLHTTPClient::Responder @@ -97,7 +98,7 @@ void LLViewerDisplayName::set(const std::string& display_name, const set_name_sl // People API expects array of [ "old value", "new value" ] LLSD change_array = LLSD::emptyArray(); - change_array.append(av_name.mDisplayName); + change_array.append(av_name.getDisplayName()); change_array.append(display_name); llinfos << "Set name POST to " << cap_url << llendl; @@ -139,9 +140,9 @@ public: LLUUID agent_id = gAgent.getID(); // Flush stale data LLAvatarNameCache::erase( agent_id ); - // Queue request for new data - LLAvatarName ignored; - LLAvatarNameCache::get( agent_id, &ignored ); + // Queue request for new data: nothing to do on callback though... + // Note: no need to disconnect the callback as it never gets out of scope + LLAvatarNameCache::get(agent_id, boost::bind(&LLViewerDisplayName::doNothing)); // Kill name tag, as it is wrong LLVOAvatar::invalidateNameTag( agent_id ); } @@ -189,8 +190,8 @@ class LLDisplayNameUpdate : public LLHTTPNode LLSD args; args["OLD_NAME"] = old_display_name; - args["SLID"] = av_name.mUsername; - args["NEW_NAME"] = av_name.mDisplayName; + args["SLID"] = av_name.getUserName(); + args["NEW_NAME"] = av_name.getDisplayName(); LLNotificationsUtil::add("DisplayNameUpdate", args); if (agent_id == gAgent.getID()) { diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 273bf822bc..c6b28b9e5e 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -30,12 +30,10 @@ #include "llfloaterreg.h" #include "llviewerfloaterreg.h" - +#include "llfloaterautoreplacesettings.h" #include "llcompilequeue.h" -#include "llcallfloater.h" #include "llfasttimerview.h" #include "llfloaterabout.h" -#include "llfloateranimpreview.h" #include "llfloaterauction.h" #include "llfloateravatar.h" #include "llfloateravatarpicker.h" @@ -49,7 +47,11 @@ #include "llfloaterbuyland.h" #include "llfloaterbulkpermission.h" #include "llfloaterbump.h" +#include "llfloaterbvhpreview.h" #include "llfloatercamera.h" +#include "llfloaterchatvoicevolume.h" +#include "llfloaterconversationlog.h" +#include "llfloaterconversationpreview.h" #include "llfloaterdeleteenvpreset.h" #include "llfloaterdisplayname.h" #include "llfloatereditdaycycle.h" @@ -65,10 +67,11 @@ #include "llfloaterhardwaresettings.h" #include "llfloaterhelpbrowser.h" #include "llfloaterwebcontent.h" +#include "llfloaterwebprofile.h" #include "llfloatermediasettings.h" #include "llfloaterhud.h" #include "llfloaterimagepreview.h" -#include "llimfloater.h" +#include "llfloaterimsession.h" #include "llfloaterinspect.h" #include "llfloaterinventory.h" #include "llfloaterjoystick.h" @@ -77,11 +80,14 @@ #include "llfloaterlandholdings.h" #include "llfloatermap.h" #include "llfloatermemleak.h" -#include "llfloatermodelwizard.h" #include "llfloaternamedesc.h" #include "llfloaternotificationsconsole.h" #include "llfloaterobjectweights.h" #include "llfloateropenobject.h" +#include "llfloateroutbox.h" +#include "llfloaterpathfindingcharacters.h" +#include "llfloaterpathfindinglinksets.h" +#include "llfloaterpathfindingconsole.h" #include "llfloaterpay.h" #include "llfloaterperms.h" #include "llfloaterpostprocess.h" @@ -98,9 +104,11 @@ #include "llfloatersidepanelcontainer.h" #include "llfloatersnapshot.h" #include "llfloatersounddevices.h" +#include "llfloaterspellchecksettings.h" #include "llfloatertelehub.h" #include "llfloatertestinspectors.h" #include "llfloatertestlistview.h" +#include "llfloatertexturefetchdebugger.h" #include "llfloatertools.h" #include "llfloatertos.h" #include "llfloatertopobjects.h" @@ -108,17 +116,18 @@ #include "llfloatertranslationsettings.h" #include "llfloateruipreview.h" #include "llfloatervoiceeffect.h" +#include "llfloatervoicevolume.h" #include "llfloaterwhitelistentry.h" #include "llfloaterwindowsize.h" #include "llfloaterworldmap.h" -#include "llimfloatercontainer.h" +#include "llfloaterimcontainer.h" #include "llinspectavatar.h" #include "llinspectgroup.h" #include "llinspectobject.h" #include "llinspectremoteobject.h" #include "llinspecttoast.h" #include "llmoveview.h" -#include "llnearbychat.h" +#include "llfloaterimnearbychat.h" #include "llpanelblockedlist.h" #include "llpanelclassified.h" #include "llpreviewanim.h" @@ -131,7 +140,6 @@ #include "llscriptfloater.h" #include "llfloatermodelpreview.h" #include "llcommandhandler.h" -#include "llnearbychatbar.h" // *NOTE: Please add files in alphabetical order to keep merges easy. @@ -184,9 +192,10 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>); LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>); - LLFloaterReg::add("chat_bar", "floater_chat_bar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChatBar>); - + LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>); + LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater); LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>); + LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>); LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>); @@ -208,8 +217,8 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>); LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>); - LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>); - LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloaterContainer>); + LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterIMSession>); + LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterIMContainer>); LLFloaterReg::add("im_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMWellWindow>); LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>); LLFloaterReg::add("inventory", "floater_my_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>); @@ -218,6 +227,7 @@ void LLViewerFloaterReg::registerFloaters() LLInspectGroupUtil::registerFloater(); LLInspectObjectUtil::registerFloater(); LLInspectRemoteObjectUtil::registerFloater(); + LLFloaterVoiceVolumeUtil::registerFloater(); LLNotificationsUI::registerFloater(); LLFloaterDisplayNameUtil::registerFloater(); @@ -225,6 +235,11 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>); LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>); + + if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled")) + { + LLFloaterReg::add("tex_fetch_debugger", "floater_texture_fetch_debugger.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTextureFetchDebugger>); + } LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaSettings>); LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>); LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>); @@ -237,19 +252,27 @@ 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(); + LLFloaterReg::add("pathfinding_characters", "floater_pathfinding_characters.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingCharacters>); + LLFloaterReg::add("pathfinding_linksets", "floater_pathfinding_linksets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingLinksets>); + LLFloaterReg::add("pathfinding_console", "floater_pathfinding_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingConsole>); LLFloaterReg::add("people", "floater_people.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>); LLFloaterReg::add("places", "floater_places.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>); LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>); LLFloaterReg::add("prefs_proxy", "floater_preferences_proxy.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceProxy>); LLFloaterReg::add("prefs_hardware_settings", "floater_hardware_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHardwareSettings>); + LLFloaterReg::add("prefs_spellchecker_import", "floater_spellcheck_import.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerImport>); LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>); + LLFloaterReg::add("prefs_spellchecker", "floater_spellcheck.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerSettings>); + LLFloaterReg::add("prefs_autoreplace", "floater_autoreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAutoReplaceSettings>); LLFloaterReg::add("perm_prefs", "floater_perm_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerms>); LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>); LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>); LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview"); + LLFloaterReg::add("preview_conversation", "floater_conversation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationPreview>); LLFloaterReg::add("preview_gesture", "floater_preview_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewGesture>, "preview"); LLFloaterReg::add("preview_notecard", "floater_preview_notecard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewNotecard>, "preview"); LLFloaterReg::add("preview_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewLSL>, "preview"); @@ -285,23 +308,24 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>); LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>); LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); - LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create); + LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create); + LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create); LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create); LLFloaterUIPreviewUtil::registerFloater(); - LLFloaterReg::add("upload_anim", "floater_animation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAnimPreview>, "upload"); + LLFloaterReg::add("upload_anim_bvh", "floater_animation_bvh_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBvhPreview>, "upload"); + LLFloaterReg::add("upload_anim_anim", "floater_animation_anim_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>); LLFloaterReg::add("web_content", "floater_web_content.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create); LLFloaterReg::add("whitelist_entry", "floater_whitelist_entry.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWhiteListEntry>); - LLFloaterWindowSizeUtil::registerFloater(); + LLFloaterReg::add("window_size", "floater_window_size.xml", &LLFloaterReg::build<LLFloaterWindowSize>); LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWorldMap>); // *NOTE: Please keep these alphabetized for easier merges diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index 9101222393..a179b61cff 100644..100755 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -40,6 +40,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry const std::string &icon_name_open, // name of the folder icon const std::string &icon_name_closed, BOOL is_quiet, // folder doesn't need a UI update when changed + bool hide_if_empty, // folder not shown if empty const std::string &dictionary_name = empty_string // no reverse lookup needed on non-ensembles, so in most cases just leave this blank ) : @@ -47,7 +48,8 @@ struct ViewerFolderEntry : public LLDictionaryEntry mNewCategoryName(new_category_name), mIconNameOpen(icon_name_open), mIconNameClosed(icon_name_closed), - mIsQuiet(is_quiet) + mIsQuiet(is_quiet), + mHideIfEmpty(hide_if_empty) { mAllowedNames.clear(); } @@ -66,7 +68,8 @@ struct ViewerFolderEntry : public LLDictionaryEntry */ mIconNameOpen("Inv_FolderOpen"), mIconNameClosed("Inv_FolderClosed"), mNewCategoryName(new_category_name), - mIsQuiet(FALSE) + mIsQuiet(FALSE), + mHideIfEmpty(false) { const std::string delims (","); LLStringUtilBase<char>::getTokens(allowed_names, mAllowedNames, delims); @@ -91,6 +94,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry typedef std::vector<std::string> name_vec_t; name_vec_t mAllowedNames; BOOL mIsQuiet; + bool mHideIfEmpty; }; class LLViewerFolderDictionary : public LLSingleton<LLViewerFolderDictionary>, @@ -104,43 +108,43 @@ protected: LLViewerFolderDictionary::LLViewerFolderDictionary() { - // NEW CATEGORY NAME FOLDER OPEN FOLDER CLOSED QUIET? - // |-------------------------|-----------------------|----------------------|-----------| - addEntry(LLFolderType::FT_TEXTURE, new ViewerFolderEntry("Textures", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_SOUND, new ViewerFolderEntry("Sounds", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_CALLINGCARD, new ViewerFolderEntry("Calling Cards", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_LANDMARK, new ViewerFolderEntry("Landmarks", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_CLOTHING, new ViewerFolderEntry("Clothing", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_OBJECT, new ViewerFolderEntry("Objects", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_NOTECARD, new ViewerFolderEntry("Notecards", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_ROOT_INVENTORY, new ViewerFolderEntry("My Inventory", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_LSL_TEXT, new ViewerFolderEntry("Scripts", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_BODYPART, new ViewerFolderEntry("Body Parts", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_TRASH, new ViewerFolderEntry("Trash", "Inv_TrashOpen", "Inv_TrashClosed", TRUE)); - addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, new ViewerFolderEntry("Photo Album", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_LOST_AND_FOUND, new ViewerFolderEntry("Lost And Found", "Inv_LostOpen", "Inv_LostClosed", TRUE)); - addEntry(LLFolderType::FT_ANIMATION, new ViewerFolderEntry("Animations", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_GESTURE, new ViewerFolderEntry("Gestures", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_FAVORITE, new ViewerFolderEntry("Favorites", "Inv_SysOpen", "Inv_SysClosed", FALSE)); + // NEW CATEGORY NAME FOLDER OPEN FOLDER CLOSED QUIET? HIDE IF EMPTY? + // |-------------------------|-----------------------|----------------------|-----------|--------------| + addEntry(LLFolderType::FT_TEXTURE, new ViewerFolderEntry("Textures", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_SOUND, new ViewerFolderEntry("Sounds", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_CALLINGCARD, new ViewerFolderEntry("Calling Cards", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_LANDMARK, new ViewerFolderEntry("Landmarks", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_CLOTHING, new ViewerFolderEntry("Clothing", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_OBJECT, new ViewerFolderEntry("Objects", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_NOTECARD, new ViewerFolderEntry("Notecards", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_ROOT_INVENTORY, new ViewerFolderEntry("My Inventory", "Inv_SysOpen", "Inv_SysClosed", FALSE, false)); + addEntry(LLFolderType::FT_LSL_TEXT, new ViewerFolderEntry("Scripts", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_BODYPART, new ViewerFolderEntry("Body Parts", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_TRASH, new ViewerFolderEntry("Trash", "Inv_TrashOpen", "Inv_TrashClosed", TRUE, false)); + addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, new ViewerFolderEntry("Photo Album", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_LOST_AND_FOUND, new ViewerFolderEntry("Lost And Found", "Inv_LostOpen", "Inv_LostClosed", TRUE, true)); + addEntry(LLFolderType::FT_ANIMATION, new ViewerFolderEntry("Animations", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_GESTURE, new ViewerFolderEntry("Gestures", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_FAVORITE, new ViewerFolderEntry("Favorites", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); - addEntry(LLFolderType::FT_CURRENT_OUTFIT, new ViewerFolderEntry("Current Outfit", "Inv_SysOpen", "Inv_SysClosed", TRUE)); - addEntry(LLFolderType::FT_OUTFIT, new ViewerFolderEntry("New Outfit", "Inv_LookFolderOpen", "Inv_LookFolderClosed", TRUE)); - addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "Inv_SysOpen", "Inv_SysClosed", TRUE)); - addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "Inv_SysOpen", "Inv_SysClosed", FALSE)); + addEntry(LLFolderType::FT_CURRENT_OUTFIT, new ViewerFolderEntry("Current Outfit", "Inv_SysOpen", "Inv_SysClosed", TRUE, false)); + addEntry(LLFolderType::FT_OUTFIT, new ViewerFolderEntry("New Outfit", "Inv_LookFolderOpen", "Inv_LookFolderClosed", TRUE, true)); + addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "Inv_SysOpen", "Inv_SysClosed", TRUE, true)); + addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); - addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Outbox", "Inv_SysOpen", "Inv_SysClosed", FALSE)); + addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Outbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); - addEntry(LLFolderType::FT_BASIC_ROOT, new ViewerFolderEntry("Basic Root", "Inv_SysOpen", "Inv_SysClosed", FALSE)); + addEntry(LLFolderType::FT_BASIC_ROOT, new ViewerFolderEntry("Basic Root", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); - addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "Inv_FolderOpen", "Inv_FolderClosed", FALSE, "default")); + addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "Inv_FolderOpen", "Inv_FolderClosed", FALSE, false, "default")); #if SUPPORT_ENSEMBLES initEnsemblesFromFile(); #else for (U32 type = (U32)LLFolderType::FT_ENSEMBLE_START; type <= (U32)LLFolderType::FT_ENSEMBLE_END; ++type) { - addEntry((LLFolderType::EType)type, new ViewerFolderEntry("New Folder", "Inv_FolderOpen", "Inv_FolderClosed", FALSE)); + addEntry((LLFolderType::EType)type, new ViewerFolderEntry("New Folder", "Inv_FolderOpen", "Inv_FolderClosed", FALSE, false)); } #endif } @@ -259,6 +263,15 @@ BOOL LLViewerFolderType::lookupIsQuietType(LLFolderType::EType folder_type) return FALSE; } +bool LLViewerFolderType::lookupIsHiddenIfEmpty(LLFolderType::EType folder_type) +{ + const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type); + if (entry) + { + return entry->mHideIfEmpty; + } + return false; +} const std::string &LLViewerFolderType::lookupNewCategoryName(LLFolderType::EType folder_type) { diff --git a/indra/newview/llviewerfoldertype.h b/indra/newview/llviewerfoldertype.h index f5938de619..13d5a8fbbd 100644 --- a/indra/newview/llviewerfoldertype.h +++ b/indra/newview/llviewerfoldertype.h @@ -40,6 +40,7 @@ public: static const std::string& lookupIconName(EType folder_type, BOOL is_open = FALSE); // folder icon name static BOOL lookupIsQuietType(EType folder_type); // folder doesn't require UI update when changes have occured + static bool lookupIsHiddenIfEmpty(EType folder_type); // folder is not displayed if empty static const std::string& lookupNewCategoryName(EType folder_type); // default name when creating new category static LLFolderType::EType lookupTypeFromNewCategoryName(const std::string& name); // default name when creating new category diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp index a32a78cbf9..3f35a5001d 100644 --- a/indra/newview/llviewergesture.cpp +++ b/indra/newview/llviewergesture.cpp @@ -33,6 +33,7 @@ #include "llviewerinventory.h" #include "sound_ids.h" // for testing +#include "llfloaterreg.h" #include "llkeyboard.h" // for key shortcuts for testing #include "llinventorymodel.h" #include "llvoavatar.h" @@ -40,7 +41,7 @@ #include "llviewermessage.h" // send_guid_sound_trigger #include "llviewernetwork.h" #include "llagent.h" -#include "llnearbychatbar.h" +#include "llfloaterimnearbychat.h" // Globals LLViewerGestureList gGestureList; @@ -130,7 +131,8 @@ void LLViewerGesture::doTrigger( BOOL send_chat ) { // Don't play nodding animation, since that might not blend // with the gesture animation. - LLNearbyChatBar::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE); + (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))-> + sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE); } } diff --git a/indra/newview/llviewerhelp.cpp b/indra/newview/llviewerhelp.cpp index a8a918f259..04c2e27c9d 100644 --- a/indra/newview/llviewerhelp.cpp +++ b/indra/newview/llviewerhelp.cpp @@ -71,12 +71,6 @@ LLHelpHandler gHelpHandler; std::string LLViewerHelp::getURL(const std::string &topic) { - // allow overriding the help server with a local help file - if( gSavedSettings.getBOOL("HelpUseLocal") ) - { - return "__local"; - } - // if the help topic is empty, use the default topic std::string help_topic = topic; if (help_topic.empty()) diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 163581ea7f..a187318eb7 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -342,8 +342,8 @@ void LLViewerInventoryItem::cloneViewerItem(LLPointer<LLViewerInventoryItem>& ne void LLViewerInventoryItem::removeFromServer() { - llinfos << "Removing inventory item " << mUUID << " from server." - << llendl; + lldebugs << "Removing inventory item " << mUUID << " from server." + << llendl; LLInventoryModel::LLCategoryUpdate up(mParentUUID, -1); gInventory.accountForUpdate(up); @@ -436,11 +436,6 @@ void LLViewerInventoryItem::fetchFromServer(void) const gAgent.sendReliableMessage(); } } - else - { - // *FIX: this can be removed after a bit. - llwarns << "request to fetch complete item" << llendl; - } } // virtual @@ -1035,12 +1030,7 @@ void CreateGestureCallback::fire(const LLUUID& inv_item) gFloaterView->adjustToFitScreen(preview, FALSE); } -void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id) -{ - if (mTargetLandmarkId.isNull()) return; - gInventory.rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId); -} LLInventoryCallbackManager gInventoryCallbacks; @@ -1313,7 +1303,7 @@ const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not) // ! REFACTOR ! Really need to refactor this so that it's not a bunch of if-then statements... -void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid) +void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid) { std::string type_name = userdata.asString(); @@ -1337,7 +1327,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons LLUUID category = gInventory.createNewCategory(parent_id, preferred_type, LLStringUtil::null); gInventory.notifyObservers(); - root->setSelectionByID(category, TRUE); + panel->setSelectionByID(category, TRUE); } else if ("lsl" == type_name) { @@ -1380,7 +1370,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons llwarns << "Can't create unrecognized type " << type_name << llendl; } } - root->setNeedsAutoRename(TRUE); + panel->getRootFolder()->setNeedsAutoRename(TRUE); } LLAssetType::EType LLViewerInventoryItem::getType() const @@ -1454,331 +1444,6 @@ const std::string& LLViewerInventoryItem::getName() const return LLInventoryItem::getName(); } -/** - * Class to store sorting order of favorites landmarks in a local file. EXT-3985. - * It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix. - * Data are stored in user home directory. - */ -class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage> - , public LLDestroyClass<LLFavoritesOrderStorage> -{ -public: - /** - * Sets sort index for specified with LLUUID favorite landmark - */ - void setSortIndex(const LLUUID& inv_item_id, S32 sort_index); - - /** - * Gets sort index for specified with LLUUID favorite landmark - */ - S32 getSortIndex(const LLUUID& inv_item_id); - void removeSortIndex(const LLUUID& inv_item_id); - - void getSLURL(const LLUUID& asset_id); - - /** - * Implementation of LLDestroyClass. Calls cleanup() instance method. - * - * It is important this callback is called before gInventory is cleaned. - * For now it is called from LLAppViewer::cleanup() -> LLAppViewer::disconnectViewer(), - * Inventory is cleaned later from LLAppViewer::cleanup() after LLAppViewer::disconnectViewer() is called. - * @see cleanup() - */ - static void destroyClass(); - - const static S32 NO_INDEX; -private: - friend class LLSingleton<LLFavoritesOrderStorage>; - LLFavoritesOrderStorage() : mIsDirty(false) { load(); } - ~LLFavoritesOrderStorage() { save(); } - - /** - * Removes sort indexes for items which are not in Favorites bar for now. - */ - void cleanup(); - - const static std::string SORTING_DATA_FILE_NAME; - - void load(); - void save(); - - void saveFavoritesSLURLs(); - - // Remove record of current user's favorites from file on disk. - void removeFavoritesRecordOfUser(); - - void onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark); - void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl); - - typedef std::map<LLUUID, S32> sort_index_map_t; - sort_index_map_t mSortIndexes; - - typedef std::map<LLUUID, std::string> slurls_map_t; - slurls_map_t mSLURLs; - - bool mIsDirty; - - struct IsNotInFavorites - { - IsNotInFavorites(const LLInventoryModel::item_array_t& items) - : mFavoriteItems(items) - { - - } - - /** - * Returns true if specified item is not found among inventory items - */ - bool operator()(const sort_index_map_t::value_type& id_index_pair) const - { - LLPointer<LLViewerInventoryItem> item = gInventory.getItem(id_index_pair.first); - if (item.isNull()) return true; - - LLInventoryModel::item_array_t::const_iterator found_it = - std::find(mFavoriteItems.begin(), mFavoriteItems.end(), item); - - return found_it == mFavoriteItems.end(); - } - private: - LLInventoryModel::item_array_t mFavoriteItems; - }; - -}; - -const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml"; -const S32 LLFavoritesOrderStorage::NO_INDEX = -1; - -void LLFavoritesOrderStorage::setSortIndex(const LLUUID& inv_item_id, S32 sort_index) -{ - mSortIndexes[inv_item_id] = sort_index; - mIsDirty = true; -} - -S32 LLFavoritesOrderStorage::getSortIndex(const LLUUID& inv_item_id) -{ - sort_index_map_t::const_iterator it = mSortIndexes.find(inv_item_id); - if (it != mSortIndexes.end()) - { - return it->second; - } - return NO_INDEX; -} - -void LLFavoritesOrderStorage::removeSortIndex(const LLUUID& inv_item_id) -{ - mSortIndexes.erase(inv_item_id); - mIsDirty = true; -} - -void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id) -{ - slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id); - if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached - - LLLandmark* lm = gLandmarkList.getAsset(asset_id, - boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1)); - if (lm) - { - onLandmarkLoaded(asset_id, lm); - } -} - -// static -void LLFavoritesOrderStorage::destroyClass() -{ - LLFavoritesOrderStorage::instance().cleanup(); - if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin")) - { - LLFavoritesOrderStorage::instance().saveFavoritesSLURLs(); - } - else - { - LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser(); - } -} - -void LLFavoritesOrderStorage::load() -{ - // load per-resident sorting information - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME); - - LLSD settings_llsd; - llifstream file; - file.open(filename); - if (file.is_open()) - { - LLSDSerialize::fromXML(settings_llsd, file); - } - - for (LLSD::map_const_iterator iter = settings_llsd.beginMap(); - iter != settings_llsd.endMap(); ++iter) - { - mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger())); - } -} - -void LLFavoritesOrderStorage::saveFavoritesSLURLs() -{ - // Do not change the file if we are not logged in yet. - if (!LLLoginInstance::getInstance()->authSuccess()) return; - - std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""); - if (user_dir.empty()) return; - - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); - llifstream in_file; - in_file.open(filename); - LLSD fav_llsd; - if (in_file.is_open()) - { - LLSDSerialize::fromXML(fav_llsd, in_file); - } - - const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH); - - LLSD user_llsd; - for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++) - { - LLSD value; - value["name"] = (*it)->getName(); - value["asset_id"] = (*it)->getAssetUUID(); - - slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]); - if (slurl_iter != mSLURLs.end()) - { - value["slurl"] = slurl_iter->second; - user_llsd[(*it)->getSortField()] = value; - } - } - - LLAvatarName av_name; - LLAvatarNameCache::get( gAgentID, &av_name ); - fav_llsd[av_name.getLegacyName()] = user_llsd; - - llofstream file; - file.open(filename); - LLSDSerialize::toPrettyXML(fav_llsd, file); -} - -void LLFavoritesOrderStorage::removeFavoritesRecordOfUser() -{ - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); - LLSD fav_llsd; - llifstream file; - file.open(filename); - if (!file.is_open()) return; - LLSDSerialize::fromXML(fav_llsd, file); - - LLAvatarName av_name; - LLAvatarNameCache::get( gAgentID, &av_name ); - if (fav_llsd.has(av_name.getLegacyName())) - { - fav_llsd.erase(av_name.getLegacyName()); - } - - llofstream out_file; - out_file.open(filename); - LLSDSerialize::toPrettyXML(fav_llsd, out_file); - -} - -void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark) -{ - if (!landmark) return; - - LLVector3d pos_global; - if (!landmark->getGlobalPos(pos_global)) - { - // If global position was unknown on first getGlobalPos() call - // it should be set for the subsequent calls. - landmark->getGlobalPos(pos_global); - } - - if (!pos_global.isExactlyZero()) - { - LLLandmarkActions::getSLURLfromPosGlobal(pos_global, - boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1)); - } -} - -void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl) -{ - mSLURLs[asset_id] = slurl; -} - -void LLFavoritesOrderStorage::save() -{ - // nothing to save if clean - if (!mIsDirty) return; - - // If we quit from the login screen we will not have an SL account - // name. Don't try to save, otherwise we'll dump a file in - // C:\Program Files\SecondLife\ or similar. JC - std::string user_dir = gDirUtilp->getLindenUserDir(); - if (!user_dir.empty()) - { - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME); - LLSD settings_llsd; - - for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter) - { - settings_llsd[iter->first.asString()] = iter->second; - } - - llofstream file; - file.open(filename); - LLSDSerialize::toPrettyXML(settings_llsd, file); - } -} - -void LLFavoritesOrderStorage::cleanup() -{ - // nothing to clean - if (!mIsDirty) return; - - const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH); - - IsNotInFavorites is_not_in_fav(items); - - sort_index_map_t aTempMap; - //copy unremoved values from mSortIndexes to aTempMap - std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(), - inserter(aTempMap, aTempMap.begin()), - is_not_in_fav); - - //Swap the contents of mSortIndexes and aTempMap - mSortIndexes.swap(aTempMap); -} - - -S32 LLViewerInventoryItem::getSortField() const -{ - return LLFavoritesOrderStorage::instance().getSortIndex(mUUID); -} - -void LLViewerInventoryItem::setSortField(S32 sortField) -{ - LLFavoritesOrderStorage::instance().setSortIndex(mUUID, sortField); - getSLURL(); -} - -void LLViewerInventoryItem::getSLURL() -{ - LLFavoritesOrderStorage::instance().getSLURL(mAssetUUID); -} - -const LLPermissions& LLViewerInventoryItem::getPermissions() const -{ - // Use the actual permissions of the symlink, not its parent. - return LLInventoryItem::getPermissions(); -} - const LLUUID& LLViewerInventoryItem::getCreatorUUID() const { if (const LLViewerInventoryItem *linked_item = getLinkedItem()) @@ -1849,17 +1514,6 @@ LLWearableType::EType LLViewerInventoryItem::getWearableType() const return LLWearableType::EType(getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK); } - -time_t LLViewerInventoryItem::getCreationDate() const -{ - return LLInventoryItem::getCreationDate(); -} - -U32 LLViewerInventoryItem::getCRC32() const -{ - return LLInventoryItem::getCRC32(); -} - // *TODO: mantipov: should be removed with LMSortPrefix patch in llinventorymodel.cpp, EXT-3985 static char getSeparator() { return '@'; } BOOL LLViewerInventoryItem::extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName) diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 7822ef4da6..3cf03c3bc5 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -34,7 +34,7 @@ #include <boost/signals2.hpp> // boost::signals2::trackable -class LLFolderView; +class LLInventoryPanel; class LLFolderBridge; class LLViewerInventoryCategory; @@ -60,10 +60,6 @@ public: virtual const LLUUID& getAssetUUID() const; virtual const LLUUID& getProtectedAssetUUID() const; // returns LLUUID::null if current agent does not have permission to expose this asset's UUID to the user virtual const std::string& getName() const; - virtual S32 getSortField() const; - virtual void setSortField(S32 sortField); - virtual void getSLURL(); //Caches SLURL for landmark. //*TODO: Find a better way to do it and remove this method from here. - virtual const LLPermissions& getPermissions() const; virtual const bool getIsFullPerm() const; // 'fullperm' in the popular sense: modify-ok & copy-ok & transfer-ok, no special god rules applied virtual const LLUUID& getCreatorUUID() const; virtual const std::string& getDescription() const; @@ -72,8 +68,11 @@ public: virtual bool isWearableType() const; virtual LLWearableType::EType getWearableType() const; virtual U32 getFlags() const; - virtual time_t getCreationDate() const; - virtual U32 getCRC32() const; // really more of a checksum. + + using LLInventoryItem::getPermissions; + using LLInventoryItem::getCreationDate; + using LLInventoryItem::setCreationDate; + using LLInventoryItem::getCRC32; static BOOL extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName); @@ -285,18 +284,6 @@ public: void fire(const LLUUID& inv_item); }; -class AddFavoriteLandmarkCallback : public LLInventoryCallback -{ -public: - AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {} - void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; } - -private: - void fire(const LLUUID& inv_item); - - LLUUID mTargetLandmarkId; -}; - // misc functions //void inventory_reliable_callback(void**, S32 status); @@ -372,7 +359,7 @@ void copy_inventory_from_notecard(const LLUUID& destination_id, U32 callback_id = 0); -void menu_create_inventory_item(LLFolderView* root, +void menu_create_inventory_item(LLInventoryPanel* root, LLFolderBridge* bridge, const LLSD& userdata, const LLUUID& default_parent_uuid = LLUUID::null); diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index 4e14824e69..3a04bbed4f 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -127,7 +127,11 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object) { for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++) { - object->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER); + LLFace *face = object->mDrawable->getFace(face_num); + if (face) + { + face->setState(LLFace::HUD_RENDER); + } } } @@ -146,7 +150,11 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object) { for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++) { - childp->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER); + LLFace * face = childp->mDrawable->getFace(face_num); + if (face) + { + face->setState(LLFace::HUD_RENDER); + } } } } @@ -254,7 +262,11 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object) { for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++) { - object->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER); + LLFace * face = object->mDrawable->getFace(face_num); + if (face) + { + face->clearState(LLFace::HUD_RENDER); + } } } } @@ -272,7 +284,11 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object) { for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++) { - childp->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER); + LLFace * face = childp->mDrawable->getFace(face_num); + if (face) + { + face->clearState(LLFace::HUD_RENDER); + } } } } diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 76f4e18c27..5d1aa870a3 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -63,7 +63,6 @@ extern PFNGLWEIGHTFVARBPROC glWeightfvARB; extern PFNGLVERTEXBLENDARBPROC glVertexBlendARB; #endif -static LLPointer<LLVertexBuffer> sRenderBuffer = NULL; static const U32 sRenderMask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; @@ -577,7 +576,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { old_mode = mTexture->getAddressMode(); } - gGL.getTexUnit(diffuse_channel)->bind(mTexture.get()); gGL.getTexUnit(diffuse_channel)->bind(mTexture); gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); } @@ -731,8 +729,10 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w F32* vw = (F32*) vertex_weightsp.get(); F32* cw = (F32*) clothing_weightsp.get(); - LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), num_verts*2*sizeof(F32)); - LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), num_verts*sizeof(F32)); + S32 tc_size = (num_verts*2*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), tc_size); + S32 vw_size = (num_verts*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), vw_size); LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32)); } diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index 0191f0cae8..dd5dae1dc1 100644 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -61,6 +61,7 @@ public: //----------------------------------------------------------------------------- class LLViewerJointMesh : public LLViewerJoint { + friend class LLVOAvatar; protected: LLColor4 mColor; // color value // LLColor4 mSpecular; // specular color (always white for now) diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 1aa9fd8a45..4ecdc31e21 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -27,11 +27,12 @@ #include "llviewerprecompiledheaders.h" #include "llappviewer.h" +#include "llfloaterreg.h" #include "llviewerkeyboard.h" #include "llmath.h" #include "llagent.h" #include "llagentcamera.h" -#include "llnearbychatbar.h" +#include "llfloaterimnearbychat.h" #include "llviewercontrol.h" #include "llfocusmgr.h" #include "llmorphview.h" @@ -534,7 +535,7 @@ void stop_moving( EKeystate s ) void start_chat( EKeystate s ) { // start chat - LLNearbyChatBar::startChat(NULL); + LLFloaterIMNearbyChat::startChat(NULL); } void start_gesture( EKeystate s ) @@ -543,15 +544,15 @@ void start_gesture( EKeystate s ) if (KEYSTATE_UP == s && ! (focus_ctrlp && focus_ctrlp->acceptsTextInput())) { - if (LLNearbyChatBar::getInstance()->getCurrentChat().empty()) + if ((LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->getCurrentChat().empty()) { // No existing chat in chat editor, insert '/' - LLNearbyChatBar::startChat("/"); + LLFloaterIMNearbyChat::startChat("/"); } else { // Don't overwrite existing text in chat editor - LLNearbyChatBar::startChat(NULL); + LLFloaterIMNearbyChat::startChat(NULL); } } } diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 98f4ce58fe..2df028de69 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -26,48 +26,50 @@ #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" #include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows. @@ -314,9 +316,13 @@ public: /* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content) { LL_WARNS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL; - LL_WARNS("MediaAuth") << content << LL_ENDL; + + LLSD stripped_content = content; + stripped_content.erase("set-cookie"); + LL_WARNS("MediaAuth") << stripped_content << LL_ENDL; std::string cookie = content["set-cookie"].asString(); + LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL; LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, mHost); @@ -385,7 +391,6 @@ class LLViewerMediaMuteListObserver : public LLMuteListObserver static LLViewerMediaMuteListObserver sViewerMediaMuteListObserver; static bool sViewerMediaMuteListObserverInitialized = false; -static bool sInWorldMediaDisabled = false; ////////////////////////////////////////////////////////////////////////////////////////// @@ -652,20 +657,6 @@ void LLViewerMedia::muteListChanged() ////////////////////////////////////////////////////////////////////////////////////////// // static -void LLViewerMedia::setInWorldMediaDisabled(bool disabled) -{ - sInWorldMediaDisabled = disabled; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// static -bool LLViewerMedia::getInWorldMediaDisabled() -{ - return sInWorldMediaDisabled; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// static bool LLViewerMedia::isInterestingEnough(const LLVOVolume *object, const F64 &object_interest) { bool result = false; @@ -986,7 +977,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) { if(LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio()) { - gAudiop->stopInternetStream(); + LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); } } pimpl->setPriority(new_priority); @@ -1090,13 +1081,24 @@ void LLViewerMedia::setAllMediaEnabled(bool val) gAudiop && LLViewerMedia::hasParcelAudio()) { - gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); + if (LLAudioEngine::AUDIO_PAUSED == gAudiop->isInternetStreamPlaying()) + { + // 'false' means unpause + gAudiop->pauseInternetStream(false); + } + else + { + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL()); + } } } else { // This actually unloads the impl, as opposed to "stop"ping the media LLViewerParcelMedia::stop(); - if (gAudiop) gAudiop->stopInternetStream(); + if (gAudiop) + { + LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); + } } } @@ -1186,12 +1188,9 @@ void LLViewerMedia::clearAllCookies() LLDirIterator dir_iter(base_dir, "*_*"); while (dir_iter.next(filename)) { - target = base_dir; - target += filename; - target += gDirUtilp->getDirDelimiter(); - target += "browser_profile"; - target += gDirUtilp->getDirDelimiter(); - target += "cookies"; + target = gDirUtilp->add(base_dir, filename); + gDirUtilp->append(target, "browser_profile"); + gDirUtilp->append(target, "cookies"); lldebugs << "target = " << target << llendl; if(LLFile::isfile(target)) { @@ -1199,10 +1198,8 @@ void LLViewerMedia::clearAllCookies() } // Other accounts may have new-style cookie files too -- delete them as well - target = base_dir; - target += filename; - target += gDirUtilp->getDirDelimiter(); - target += PLUGIN_COOKIE_FILE_NAME; + target = gDirUtilp->add(base_dir, filename); + gDirUtilp->append(target, PLUGIN_COOKIE_FILE_NAME); lldebugs << "target = " << target << llendl; if(LLFile::isfile(target)) { @@ -1387,75 +1384,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(); @@ -1510,9 +1443,6 @@ void LLViewerMedia::setOpenIDCookie() LLHTTPClient::get(profile_url, new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()), headers); - - // FUI: No longer perform the user_status query - //doOnetimeEarlyHTTPRequests(); } } @@ -1622,7 +1552,6 @@ LLPluginClassMedia* LLViewerMedia::getSpareBrowserMediaSource() bool LLViewerMedia::hasInWorldMedia() { - if (sInWorldMediaDisabled) return false; impl_list::iterator iter = sViewerMediaImplList.begin(); impl_list::iterator end = sViewerMediaImplList.end(); // This should be quick, because there should be very few non-in-world-media impls @@ -1886,7 +1815,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ if(plugin_basename.empty()) { - LL_WARNS("Media") << "Couldn't find plugin for media type " << media_type << LL_ENDL; + LL_WARNS_ONCE("Media") << "Couldn't find plugin for media type " << media_type << LL_ENDL; } else { @@ -1912,11 +1841,11 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ llstat s; if(LLFile::stat(launcher_name, &s)) { - LL_WARNS("Media") << "Couldn't find launcher at " << launcher_name << LL_ENDL; + LL_WARNS_ONCE("Media") << "Couldn't find launcher at " << launcher_name << LL_ENDL; } else if(LLFile::stat(plugin_name, &s)) { - LL_WARNS("Media") << "Couldn't find plugin at " << plugin_name << LL_ENDL; + LL_WARNS_ONCE("Media") << "Couldn't find plugin at " << plugin_name << LL_ENDL; } else { @@ -1955,7 +1884,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 initialization failed for mime type: " << media_type << LL_ENDL; LLSD args; args["MIME_TYPE"] = media_type; LLNotificationsUtil::add("NoPlugin", args); @@ -3161,15 +3090,6 @@ bool LLViewerMediaImpl::isForcedUnloaded() const return true; } - if(sInWorldMediaDisabled) - { - // When inworld media is disabled, all instances that aren't marked as "used in UI" will not be loaded. - if(!mUsedInUI) - { - return true; - } - } - // If this media's class is not supposed to be shown, unload if (!shouldShowBasedOnClass()) { @@ -3837,12 +3757,22 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const // If it is attached to an avatar and the pref is off, we shouldn't show it if (attached_to_another_avatar) - return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING); - + { + static LLCachedControl<bool> show_media_on_others(gSavedSettings, LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING); + return show_media_on_others; + } if (inside_parcel) - return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING); + { + static LLCachedControl<bool> show_media_within_parcel(gSavedSettings, LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING); + + return show_media_within_parcel; + } else - return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING); + { + static LLCachedControl<bool> show_media_outside_parcel(gSavedSettings, LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING); + + return show_media_outside_parcel; + } } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 15dcda59cf..fff5b3fc08 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -112,9 +112,6 @@ public: static F32 getVolume(); static void muteListChanged(); - static void setInWorldMediaDisabled(bool disabled); - static bool getInWorldMediaDisabled(); - static bool isInterestingEnough(const LLVOVolume* object, const F64 &object_interest); // Returns the priority-sorted list of all media impls. diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 4069ac1a69..66db0ac8f3 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -25,6 +25,11 @@ */ #include "llviewerprecompiledheaders.h" + +#ifdef INCLUDE_VLD +#include "vld.h" +#endif + #include "llviewermenu.h" // linden library includes @@ -54,7 +59,10 @@ #include "llbuycurrencyhtml.h" #include "llfloatergodtools.h" #include "llfloaterinventory.h" +#include "llfloaterimcontainer.h" #include "llfloaterland.h" +#include "llfloaterpathfindingcharacters.h" +#include "llfloaterpathfindinglinksets.h" #include "llfloaterpay.h" #include "llfloaterreporter.h" #include "llfloatersearch.h" @@ -76,12 +84,13 @@ #include "llinventoryfunctions.h" #include "llpanellogin.h" #include "llpanelblockedlist.h" -#include "llmenucommands.h" +#include "llmenuoptionpathfindingrebakenavmesh.h" #include "llmoveview.h" #include "llparcel.h" #include "llrootview.h" #include "llsceneview.h" #include "llselectmgr.h" +#include "llspellcheckmenuhandler.h" #include "llstatusbar.h" #include "lltextureview.h" #include "lltoolcomp.h" @@ -89,6 +98,7 @@ #include "lltoolpie.h" #include "lltoolselectland.h" #include "lltrans.h" +#include "llviewerdisplay.h" //for gWindowResized #include "llviewergenericmessage.h" #include "llviewerhelp.h" #include "llviewermenufile.h" // init_menu_file() @@ -98,6 +108,7 @@ #include "llviewerparcelmgr.h" #include "llviewerstats.h" #include "llvoavatarself.h" +#include "llvoicevivox.h" #include "llworldmap.h" #include "pipeline.h" #include "llviewerjoystick.h" @@ -111,6 +122,7 @@ #include "lleconomy.h" #include "lltoolgrab.h" #include "llwindow.h" +#include "llpathfindingmanager.h" #include "boost/unordered_map.hpp" using namespace LLVOAvatarDefines; @@ -156,7 +168,6 @@ LLContextMenu *gMenuAttachmentSelf = NULL; LLContextMenu *gMenuAttachmentOther = NULL; LLContextMenu *gMenuLand = NULL; -const std::string SAVE_INTO_INVENTORY("Save Object Back to My Inventory"); const std::string SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents"); LLMenuGL* gAttachSubMenu = NULL; @@ -169,9 +180,6 @@ LLContextMenu* gDetachPieMenu = NULL; LLContextMenu* gDetachScreenPieMenu = NULL; LLContextMenu* gDetachBodyPartPieMenus[8]; -LLMenuItemCallGL* gAFKMenu = NULL; -LLMenuItemCallGL* gBusyMenu = NULL; - // // Local prototypes @@ -198,10 +206,9 @@ void near_sit_object(); BOOL is_selection_buy_not_take(); S32 selection_price(); BOOL enable_take(); -void handle_take(); void handle_object_show_inspector(); void handle_avatar_show_inspector(); -bool confirm_take(const LLSD& notification, const LLSD& response); +bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection_handle); void handle_buy_object(LLSaleInfo sale_info); void handle_buy_contents(LLSaleInfo sale_info); @@ -215,7 +222,7 @@ void near_sit_down_point(BOOL success, void *); void velocity_interpolate( void* ); - +void handle_visual_leak_detector_toggle(void*); void handle_rebake_textures(void*); BOOL check_admin_override(void*); void handle_admin_override_toggle(void*); @@ -295,7 +302,6 @@ BOOL enable_buy_land(void*); void handle_test_male(void *); void handle_test_female(void *); -void handle_toggle_pg(void*); void handle_dump_attachments(void *); void handle_dump_avatar_local_textures(void*); void handle_debug_avatar_textures(void*); @@ -303,7 +309,6 @@ void handle_grab_baked_texture(void*); BOOL enable_grab_baked_texture(void*); void handle_dump_region_object_cache(void*); -BOOL enable_save_into_inventory(void*); BOOL enable_save_into_task_inventory(void*); BOOL enable_detach(const LLSD& = LLSD()); @@ -334,7 +339,8 @@ LLMenuParcelObserver::~LLMenuParcelObserver() void LLMenuParcelObserver::changed() { - gMenuHolder->childSetEnabled("Land Buy Pass", LLPanelLandGeneral::enableBuyPass(NULL)); + LLParcel *parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(); + gMenuHolder->childSetEnabled("Land Buy Pass", LLPanelLandGeneral::enableBuyPass(NULL) && !(parcel->getOwnerID()== gAgent.getID())); BOOL buyable = enable_buy_land(NULL); gMenuHolder->childSetEnabled("Land Buy", buyable); @@ -463,8 +469,6 @@ void init_menus() gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", upload_cost); gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", upload_cost); - gAFKMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Away", TRUE); - gBusyMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Busy", TRUE); gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE); gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE); @@ -512,14 +516,6 @@ class LLAdvancedToggleConsole : public view_listener_t { toggle_visibility( (void*)static_cast<LLUICtrl*>(gDebugView->mDebugConsolep)); } - else if (gTextureSizeView && "texture size" == console_type) - { - toggle_visibility( (void*)gTextureSizeView ); - } - else if (gTextureCategoryView && "texture category" == console_type) - { - toggle_visibility( (void*)gTextureCategoryView ); - } else if ("fast timers" == console_type) { LLFloaterReg::toggleInstance("fast_timers"); @@ -552,14 +548,6 @@ class LLAdvancedCheckConsole : public view_listener_t { new_value = get_visibility( (void*)((LLView*)gDebugView->mDebugConsolep) ); } - else if (gTextureSizeView && "texture size" == console_type) - { - new_value = get_visibility( (void*)gTextureSizeView ); - } - else if (gTextureCategoryView && "texture category" == console_type) - { - new_value = get_visibility( (void*)gTextureCategoryView ); - } else if ("fast timers" == console_type) { new_value = LLFloaterReg::instanceVisible("fast_timers"); @@ -862,6 +850,73 @@ class LLAdvancedCheckFeature : public view_listener_t } }; +class LLAdvancedCheckDisplayTextureDensity : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + std::string mode = userdata.asString(); + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) + { + return mode == "none"; + } + if (mode == "current") + { + return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_CURRENT; + } + else if (mode == "desired") + { + return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_DESIRED; + } + else if (mode == "full") + { + return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_FULL; + } + return false; + } +}; + +class LLAdvancedSetDisplayTextureDensity : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + std::string mode = userdata.asString(); + if (mode == "none") + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == TRUE) + { + gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + } + LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF; + } + else if (mode == "current") + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) + { + gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + } + LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_CURRENT; + } + else if (mode == "desired") + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) + { + gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + } + gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY, true); + LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_DESIRED; + } + else if (mode == "full") + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) + { + gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + } + LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_FULL; + } + return true; + } +}; + ////////////////// // INFO DISPLAY // @@ -948,6 +1003,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; @@ -972,6 +1031,10 @@ U32 info_display_from_string(std::string info_display) { return LLPipeline::RENDER_DEBUG_WIND_VECTORS; } + else if ("texel density" == info_display) + { + return LLPipeline::RENDER_DEBUG_TEXEL_DENSITY; + } else { return 0; @@ -1110,6 +1173,7 @@ class LLAdvancedToggleWireframe : public view_listener_t bool handleEvent(const LLSD& userdata) { gUseWireframe = !(gUseWireframe); + gWindowResized = TRUE; LLPipeline::updateRenderDeferred(); gPipeline.resetVertexBuffers(); return true; @@ -1249,22 +1313,6 @@ class LLAdvancedPrintAgentInfo : public view_listener_t } }; - - -//////////////////////////////// -// PRINT TEXTURE MEMORY STATS // -//////////////////////////////// - - -class LLAdvancedPrintTextureMemoryStats : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - output_statistics(NULL); - return true; - } -}; - ////////////////// // DEBUG CLICKS // ////////////////// @@ -1578,32 +1626,63 @@ class LLAdvancedTestFemale : public view_listener_t } }; +class LLAdvancedForceParamsToDefault : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLAgent::clearVisualParams(NULL); + return true; + } +}; -/////////////// -// TOGGLE PG // -/////////////// +////////////////////////// +// ANIMATION SPEED // +////////////////////////// +// Utility function to set all AV time factors to the same global value +static void set_all_animation_time_factors(F32 time_factor) +{ + LLMotionController::setCurrentTimeFactor(time_factor); + for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + (*iter)->setAnimTimeFactor(time_factor); + } +} -class LLAdvancedTogglePG : public view_listener_t +class LLAdvancedAnimTenFaster : public view_listener_t { bool handleEvent(const LLSD& userdata) { - handle_toggle_pg(NULL); + //llinfos << "LLAdvancedAnimTenFaster" << llendl; + F32 time_factor = LLMotionController::getCurrentTimeFactor(); + time_factor = llmin(time_factor + 0.1f, 2.f); // Upper limit is 200% speed + set_all_animation_time_factors(time_factor); return true; } }; - -class LLAdvancedForceParamsToDefault : public view_listener_t +class LLAdvancedAnimTenSlower : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLAgent::clearVisualParams(NULL); + //llinfos << "LLAdvancedAnimTenSlower" << llendl; + F32 time_factor = LLMotionController::getCurrentTimeFactor(); + time_factor = llmax(time_factor - 0.1f, 0.1f); // Lower limit is at 10% of normal speed + set_all_animation_time_factors(time_factor); return true; } }; +class LLAdvancedAnimResetAll : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + set_all_animation_time_factors(1.f); + return true; + } +}; ////////////////////////// @@ -1974,7 +2053,6 @@ class LLAdvancedCompressImage : public view_listener_t }; - ///////////////////////// // SHOW DEBUG SETTINGS // ///////////////////////// @@ -2015,6 +2093,15 @@ class LLAdvancedToggleViewAdminOptions : public view_listener_t } }; +class LLAdvancedToggleVisualLeakDetector : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + handle_visual_leak_detector_toggle(NULL); + return true; + } +}; + class LLAdvancedCheckViewAdminOptions : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -2204,6 +2291,38 @@ 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; + } +}; + +class LLDevelopTextureFetchDebugger : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + return gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"); + } +}; + ////////////////// // ADMIN MENU // ////////////////// @@ -2694,6 +2813,16 @@ bool enable_object_build() return !enable_object_edit(); } +bool enable_object_select_in_pathfinding_linksets() +{ + return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetEditableLinksets(); +} + +bool enable_object_select_in_pathfinding_characters() +{ + return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetViewableCharacters(); +} + class LLSelfRemoveAllAttachments : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -2763,8 +2892,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());; } } @@ -3102,7 +3254,7 @@ void handle_avatar_eject(const LLSD& avatar_id) bool my_profile_visible() { - LLFloater* floaterp = LLFloaterReg::findInstance("profile", LLSD().with("id", gAgent.getID())); + LLFloater* floaterp = LLAvatarActions::getProfileFloater(gAgentID); return floaterp && floaterp->isInVisibleChain(); } @@ -3140,15 +3292,6 @@ bool enable_freeze_eject(const LLSD& avatar_id) return new_value; } - -void login_done(S32 which, void *user) -{ - llinfos << "Login done " << which << llendl; - - LLPanelLogin::closePanel(); -} - - bool callback_leave_group(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -3192,7 +3335,7 @@ void append_aggregate(std::string& string, const LLAggregatePermissions& ag_perm bool enable_buy_object() { // In order to buy, there must only be 1 purchaseable object in - // the selection manger. + // the selection manager. if(LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() != 1) return false; LLViewerObject* obj = NULL; LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); @@ -3340,6 +3483,20 @@ bool enable_sitdown_self() return isAgentAvatarValid() && !gAgentAvatarp->isSitting() && !gAgent.getFlying(); } +class LLCheckPanelPeopleTab : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + std::string panel_name = userdata.asString(); + + LLPanel *panel = LLFloaterSidePanelContainer::getPanel("people", panel_name); + if(panel && panel->isInVisibleChain()) + { + return true; + } + return false; + } +}; // Toggle one of "People" panel tabs in side tray. class LLTogglePanelPeopleTab : public view_listener_t { @@ -3352,7 +3509,8 @@ class LLTogglePanelPeopleTab : public view_listener_t if ( panel_name == "friends_panel" || panel_name == "groups_panel" - || panel_name == "nearby_panel") + || panel_name == "nearby_panel" + || panel_name == "blocked_panel") { return togglePeoplePanel(panel_name, param); } @@ -3394,6 +3552,35 @@ void handle_admin_override_toggle(void*) show_debug_menus(); } +void handle_visual_leak_detector_toggle(void*) +{ + static bool vld_enabled = false; + + if ( vld_enabled ) + { +#ifdef INCLUDE_VLD + // only works for debug builds (hard coded into vld.h) +#ifdef _DEBUG + // start with Visual Leak Detector turned off + VLDDisable(); +#endif // _DEBUG +#endif // INCLUDE_VLD + vld_enabled = false; + } + else + { +#ifdef INCLUDE_VLD + // only works for debug builds (hard coded into vld.h) + #ifdef _DEBUG + // start with Visual Leak Detector turned off + VLDEnable(); + #endif // _DEBUG +#endif // INCLUDE_VLD + + vld_enabled = true; + }; +} + void handle_god_mode(void*) { gAgent.requestEnterGodMode(); @@ -3759,25 +3946,27 @@ class LLViewToggleUI : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLNotification::Params params("ConfirmHideUI"); - params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2)); - LLSD substitutions; + if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) + { + LLNotification::Params params("ConfirmHideUI"); + params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2)); + LLSD substitutions; #if LL_DARWIN - substitutions["SHORTCUT"] = "Cmd+Shift+U"; + substitutions["SHORTCUT"] = "Cmd+Shift+U"; #else - substitutions["SHORTCUT"] = "Ctrl+Shift+U"; + substitutions["SHORTCUT"] = "Ctrl+Shift+U"; #endif - params.substitutions = substitutions; - if (gViewerWindow->getUIVisibility()) - { - // hiding, so show notification - LLNotifications::instance().add(params); - } - else - { - LLNotifications::instance().forceResponse(params, 0); + params.substitutions = substitutions; + if (!gSavedSettings.getBOOL("HideUIControls")) + { + // hiding, so show notification + LLNotifications::instance().add(params); + } + else + { + LLNotifications::instance().forceResponse(params, 0); + } } - return true; } @@ -3787,7 +3976,9 @@ class LLViewToggleUI : public view_listener_t if (option == 0) // OK { - gViewerWindow->setUIVisibility(!gViewerWindow->getUIVisibility()); + gViewerWindow->setUIVisibility(gSavedSettings.getBOOL("HideUIControls")); + LLPanelStandStopFlying::getInstance()->setVisible(gSavedSettings.getBOOL("HideUIControls")); + gSavedSettings.setBOOL("HideUIControls",!gSavedSettings.getBOOL("HideUIControls")); } } }; @@ -4041,8 +4232,9 @@ static bool get_derezzable_objects( { case DRD_TAKE_INTO_AGENT_INVENTORY: case DRD_TRASH: - if( (node->mPermissions->allowTransferTo(gAgent.getID()) && object->permModify()) - || (node->allowOperationOnNode(PERM_OWNER, GP_OBJECT_MANIPULATE)) ) + if (!object->isPermanentEnforced() && + ((node->mPermissions->allowTransferTo(gAgent.getID()) && object->permModify()) + || (node->allowOperationOnNode(PERM_OWNER, GP_OBJECT_MANIPULATE)))) { can_derez_current = TRUE; } @@ -4355,7 +4547,10 @@ void handle_take() LLNotification::Params params("ConfirmObjectTakeLock"); params.payload(payload); - params.functor.function(confirm_take); + // MAINT-290 + // Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez. + // Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened + params.functor.function(boost::bind(confirm_take, _1, _2, LLSelectMgr::instance().getSelection())); if(locked_but_takeable_object || !you_own_everything) @@ -4408,7 +4603,7 @@ void handle_avatar_show_inspector() -bool confirm_take(const LLSD& notification, const LLSD& response) +bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection_handle) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if(enable_take() && (option == 0)) @@ -4449,9 +4644,10 @@ BOOL enable_take() return TRUE; } # endif - if((node->mPermissions->allowTransferTo(gAgent.getID()) + if(!object->isPermanentEnforced() && + ((node->mPermissions->allowTransferTo(gAgent.getID()) && object->permModify()) - || (node->mPermissions->getOwner() == gAgent.getID())) + || (node->mPermissions->getOwner() == gAgent.getID()))) { return TRUE; } @@ -4677,29 +4873,64 @@ BOOL sitting_on_selection() return (gAgentAvatarp->isSitting() && gAgentAvatarp->getRoot() == root_object); } -class LLToolsSaveToInventory : public view_listener_t +class LLToolsSaveToObjectInventory : public view_listener_t { bool handleEvent(const LLSD& userdata) { - if(enable_save_into_inventory(NULL)) + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); + if(node && (node->mValid) && (!node->mFromTaskID.isNull())) { - derez_objects(DRD_SAVE_INTO_AGENT_INVENTORY, LLUUID::null); + // *TODO: check to see if the fromtaskid object exists. + derez_objects(DRD_SAVE_INTO_TASK_INVENTORY, node->mFromTaskID); } return true; } }; -class LLToolsSaveToObjectInventory : public view_listener_t +class LLToolsEnablePathfinding : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); - if(node && (node->mValid) && (!node->mFromTaskID.isNull())) + return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion(); + } +}; + +class LLToolsEnablePathfindingView : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLPathfindingManager::getInstance()->isPathfindingViewEnabled(); + } +}; + +class LLToolsDoPathfindingRebakeRegion : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + bool hasPathfinding = (LLPathfindingManager::getInstance() != NULL); + + if (hasPathfinding) { - // *TODO: check to see if the fromtaskid object exists. - derez_objects(DRD_SAVE_INTO_TASK_INVENTORY, node->mFromTaskID); + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh(); } - return true; + + return hasPathfinding; + } +}; + +class LLToolsEnablePathfindingRebakeRegion : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + bool returnValue = false; + + if (LLPathfindingManager::getInstance() != NULL) + { + LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance(); + returnValue = (rebakeInstance->canRebakeRegion() && + (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available)); + } + return returnValue; } }; @@ -4961,6 +5192,84 @@ class LLEditDelete : public view_listener_t } }; +void handle_spellcheck_replace_with_suggestion(const LLUICtrl* ctrl, const LLSD& param) +{ + const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent()); + LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL; + if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) ) + { + return; + } + + U32 index = 0; + if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) ) + { + return; + } + + spellcheck_handler->replaceWithSuggestion(index); +} + +bool visible_spellcheck_suggestion(LLUICtrl* ctrl, const LLSD& param) +{ + LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(ctrl); + const LLContextMenu* menu = (item) ? dynamic_cast<const LLContextMenu*>(item->getParent()) : NULL; + const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL; + if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) ) + { + return false; + } + + U32 index = 0; + if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) ) + { + return false; + } + + item->setLabel(spellcheck_handler->getSuggestion(index)); + return true; +} + +void handle_spellcheck_add_to_dictionary(const LLUICtrl* ctrl) +{ + const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent()); + LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL; + if ( (spellcheck_handler) && (spellcheck_handler->canAddToDictionary()) ) + { + spellcheck_handler->addToDictionary(); + } +} + +bool enable_spellcheck_add_to_dictionary(const LLUICtrl* ctrl) +{ + const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent()); + const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL; + return (spellcheck_handler) && (spellcheck_handler->canAddToDictionary()); +} + +void handle_spellcheck_add_to_ignore(const LLUICtrl* ctrl) +{ + const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent()); + LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL; + if ( (spellcheck_handler) && (spellcheck_handler->canAddToIgnore()) ) + { + spellcheck_handler->addToIgnore(); + } +} + +bool enable_spellcheck_add_to_ignore(const LLUICtrl* ctrl) +{ + const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent()); + const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL; + return (spellcheck_handler) && (spellcheck_handler->canAddToIgnore()); +} + +bool enable_object_return() +{ + return (!LLSelectMgr::getInstance()->getSelection()->isEmpty() && + (gAgent.isGodlike() || can_derez(DRD_RETURN_TO_OWNER))); +} + bool enable_object_delete() { bool new_value = @@ -4976,6 +5285,49 @@ bool enable_object_delete() return new_value; } +class LLObjectsReturnPackage +{ +public: + LLObjectsReturnPackage() : mObjectSelection(), mReturnableObjects(), mError(), mFirstRegion(NULL) {}; + ~LLObjectsReturnPackage() + { + mObjectSelection.clear(); + mReturnableObjects.clear(); + mError.clear(); + mFirstRegion = NULL; + }; + + LLObjectSelectionHandle mObjectSelection; + LLDynamicArray<LLViewerObjectPtr> mReturnableObjects; + std::string mError; + LLViewerRegion *mFirstRegion; +}; + +static void return_objects(LLObjectsReturnPackage *objectsReturnPackage, const LLSD& notification, const LLSD& response) +{ + if (LLNotificationsUtil::getSelectedOption(notification, response) == 0) + { + // Ignore category ID for this derez destination. + derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, objectsReturnPackage->mFirstRegion, objectsReturnPackage->mError, &objectsReturnPackage->mReturnableObjects); + } + + delete objectsReturnPackage; +} + +void handle_object_return() +{ + if (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) + { + LLObjectsReturnPackage *objectsReturnPackage = new LLObjectsReturnPackage(); + objectsReturnPackage->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); + + // Save selected objects, so that we still know what to return after the confirmation dialog resets selection. + get_derezzable_objects(DRD_RETURN_TO_OWNER, objectsReturnPackage->mError, objectsReturnPackage->mFirstRegion, &objectsReturnPackage->mReturnableObjects); + + LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&return_objects, objectsReturnPackage, _1, _2)); + } +} + void handle_object_delete() { @@ -5205,8 +5557,6 @@ void toggle_debug_menus(void*) // gExportDialog = LLUploadDialog::modalUploadDialog("Exporting selected objects..."); // } // - - class LLWorldSetHomeLocation : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -5280,18 +5630,18 @@ class LLWorldSetAway : public view_listener_t } }; -class LLWorldSetBusy : public view_listener_t +class LLWorldSetDoNotDisturb : public view_listener_t { bool handleEvent(const LLSD& userdata) { - if (gAgent.getBusy()) + if (gAgent.isDoNotDisturb()) { - gAgent.clearBusy(); + gAgent.setDoNotDisturb(false); } else { - gAgent.setBusy(); - LLNotificationsUtil::add("BusyModeSet"); + gAgent.setDoNotDisturb(true); + LLNotificationsUtil::add("DoNotDisturbModeSet"); } return true; } @@ -5453,7 +5803,7 @@ bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjec S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (option == 0) { - gAgent.clearBusy(); + gAgent.setDoNotDisturb(false); } LLViewerObject* objectp = selection->getPrimaryObject(); @@ -5486,12 +5836,12 @@ bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjec void handle_give_money_dialog() { - LLNotification::Params params("BusyModePay"); + LLNotification::Params params("DoNotDisturbModePay"); params.functor.function(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstance()->getSelection())); - if (gAgent.getBusy()) + if (gAgent.isDoNotDisturb()) { - // warn users of being in busy mode during a transaction + // warn users of being in do not disturb mode during a transaction LLNotifications::instance().add(params); } else @@ -6329,6 +6679,7 @@ BOOL object_selected_and_point_valid() (selection->getFirstRootObject()->getPCode() == LL_PCODE_VOLUME) && selection->getFirstRootObject()->permYouOwner() && selection->getFirstRootObject()->flagObjectMove() && + !selection->getFirstRootObject()->flagObjectPermanent() && !((LLViewerObject*)selection->getFirstRootObject()->getRoot())->isAvatar() && (selection->getFirstRootObject()->getNVPair("AssetContainer") == NULL); } @@ -6463,31 +6814,37 @@ class LLToolsSelectedScriptAction : public view_listener_t std::string action = userdata.asString(); bool mono = false; std::string msg, name; + std::string title; if (action == "compile mono") { name = "compile_queue"; mono = true; msg = "Recompile"; + title = LLTrans::getString("CompileQueueTitle"); } if (action == "compile lsl") { name = "compile_queue"; msg = "Recompile"; + title = LLTrans::getString("CompileQueueTitle"); } else if (action == "reset") { name = "reset_queue"; msg = "Reset"; + title = LLTrans::getString("ResetQueueTitle"); } else if (action == "start") { name = "start_queue"; msg = "SetRunning"; + title = LLTrans::getString("RunQueueTitle"); } else if (action == "stop") { name = "stop_queue"; msg = "SetRunningNot"; + title = LLTrans::getString("NotRunQueueTitle"); } LLUUID id; id.generate(); @@ -6496,6 +6853,7 @@ class LLToolsSelectedScriptAction : public view_listener_t { queue->setMono(mono); queue_actions(queue, msg); + queue->setTitle(title); } else { @@ -6570,15 +6928,6 @@ void handle_test_female(void*) //gGestureList.requestResetFromServer( FALSE ); } -void handle_toggle_pg(void*) -{ - gAgent.setTeen( !gAgent.isTeen() ); - - LLFloaterWorldMap::reloadIcons(NULL); - - llinfos << "PG status set to " << (S32)gAgent.isTeen() << llendl; -} - void handle_dump_attachments(void*) { if(!isAgentAvatarValid()) return; @@ -6806,50 +7155,6 @@ bool LLHasAsset::operator()(LLInventoryCategory* cat, return FALSE; } -BOOL enable_save_into_inventory(void*) -{ - // *TODO: clean this up - // find the last root - LLSelectNode* last_node = NULL; - for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin(); - iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++) - { - last_node = *iter; - } - -#ifdef HACKED_GODLIKE_VIEWER - return TRUE; -#else -# ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (!LLGridManager::getInstance()->isInProductionGrid() - && gAgent.isGodlike()) - { - return TRUE; - } -# endif - // check all pre-req's for save into inventory. - if(last_node && last_node->mValid && !last_node->mItemID.isNull() - && (last_node->mPermissions->getOwner() == gAgent.getID()) - && (gInventory.getItem(last_node->mItemID) != NULL)) - { - LLViewerObject* obj = last_node->getObject(); - if( obj && !obj->isAttachment() ) - { - return TRUE; - } - } -#endif - return FALSE; -} - -class LLToolsEnableSaveToInventory : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - bool new_value = enable_save_into_inventory(NULL); - return new_value; - } -}; BOOL enable_save_into_task_inventory(void*) { @@ -7231,12 +7536,7 @@ class LLToolsUseSelectionForGrid : public view_listener_t } func; LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func); LLSelectMgr::getInstance()->setGridMode(GRID_MODE_REF_OBJECT); - - LLFloaterBuildOptions* build_options_floater = LLFloaterReg::getTypedInstance<LLFloaterBuildOptions>("build_options"); - if (build_options_floater && build_options_floater->getVisible()) - { - build_options_floater->setGridMode(GRID_MODE_REF_OBJECT); - } + LLFloaterTools::setGridMode((S32)GRID_MODE_REF_OBJECT); return true; } }; @@ -7313,6 +7613,20 @@ void handle_web_content_test(const LLSD& param) LLWeb::loadURLInternal(url); } +void handle_show_url(const LLSD& param) +{ + std::string url = param.asString(); + if(gSavedSettings.getBOOL("UseExternalBrowser")) + { + LLWeb::loadURLExternal(url); + } + else + { + LLWeb::loadURLInternal(url); + } + +} + void handle_buy_currency_test(void*) { std::string url = @@ -7566,6 +7880,22 @@ class LLViewCheckRenderType : public view_listener_t } }; +class LLViewStatusAway : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + return (gAgent.isInitialized() && gAgent.getAFK()); + } +}; + +class LLViewStatusDoNotDisturb : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + return (gAgent.isInitialized() && gAgent.isDoNotDisturb()); + } +}; + class LLViewShowHUDAttachments : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -7790,31 +8120,9 @@ class LLWorldPostProcess : public view_listener_t } }; -class LLWorldToggleMovementControls : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFloaterReg::toggleInstanceOrBringToFront("moveview"); - return true; - } -}; - -class LLWorldToggleCameraControls : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFloaterReg::toggleInstanceOrBringToFront("camera"); - return true; - } -}; - void handle_flush_name_caches() { - // Toggle display names on and off to flush - bool use_display_names = LLAvatarNameCache::useDisplayNames(); - LLAvatarNameCache::setUseDisplayNames(!use_display_names); - LLAvatarNameCache::setUseDisplayNames(use_display_names); - + LLAvatarNameCache::cleanupClass(); if (gCacheName) gCacheName->clear(); } @@ -7839,6 +8147,11 @@ public: } }; +void handle_voice_morphing_subscribe() +{ + LLWeb::loadURLExternal(LLTrans::getString("voice_morphing_url")); +} + class LLToggleUIHints : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -7928,6 +8241,19 @@ void initialize_edit_menu() } +void initialize_spellcheck_menu() +{ + LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar(); + LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar(); + + commit.add("SpellCheck.ReplaceWithSuggestion", boost::bind(&handle_spellcheck_replace_with_suggestion, _1, _2)); + enable.add("SpellCheck.VisibleSuggestion", boost::bind(&visible_spellcheck_suggestion, _1, _2)); + commit.add("SpellCheck.AddToDictionary", boost::bind(&handle_spellcheck_add_to_dictionary, _1)); + enable.add("SpellCheck.EnableAddToDictionary", boost::bind(&enable_spellcheck_add_to_dictionary, _1)); + commit.add("SpellCheck.AddToIgnore", boost::bind(&handle_spellcheck_add_to_ignore, _1)); + enable.add("SpellCheck.EnableAddToIgnore", boost::bind(&enable_spellcheck_add_to_ignore, _1)); +} + void initialize_menus() { // A parameterized event handler used as ctrl-8/9/0 zoom controls below. @@ -7959,10 +8285,16 @@ void initialize_menus() commit.add("Inventory.NewWindow", boost::bind(&LLFloaterInventory::showAgentInventory)); + enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed)); // Agent commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying)); enable.add("Agent.enableFlying", boost::bind(&LLAgent::enableFlying)); + commit.add("Agent.PressMicrophone", boost::bind(&LLAgent::pressMicrophone, _2)); + commit.add("Agent.ReleaseMicrophone", boost::bind(&LLAgent::releaseMicrophone, _2)); + commit.add("Agent.ToggleMicrophone", boost::bind(&LLAgent::toggleMicrophone, _2)); + enable.add("Agent.IsMicrophoneOn", boost::bind(&LLAgent::isMicrophoneOn, _2)); + enable.add("Agent.IsActionAllowed", boost::bind(&LLAgent::isActionAllowed, _2)); // File menu init_menu_file(); @@ -7999,20 +8331,29 @@ void initialize_menus() view_listener_t::addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips"); view_listener_t::addMenu(new LLViewCheckHighlightTransparent(), "View.CheckHighlightTransparent"); view_listener_t::addMenu(new LLViewCheckRenderType(), "View.CheckRenderType"); + view_listener_t::addMenu(new LLViewStatusAway(), "View.Status.CheckAway"); + view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb"); view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments"); - + // Me > Movement view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying"); - + + // Communicate > Voice morphing > Subscribe... + commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe)); + LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance(); + enable.add("Communicate.VoiceMorphing.NoVoiceMorphing.Check" + , boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing")); + commit.add("Communicate.VoiceMorphing.NoVoiceMorphing.Click" + , boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, voice_clientp, "NoVoiceMorphing")); + // World menu - commit.add("World.Chat", boost::bind(&handle_chat, (void*)NULL)); view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun"); view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark"); view_listener_t::addMenu(new LLWorldPlaceProfile(), "World.PlaceProfile"); view_listener_t::addMenu(new LLWorldSetHomeLocation(), "World.SetHomeLocation"); view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome"); view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway"); - view_listener_t::addMenu(new LLWorldSetBusy(), "World.SetBusy"); + view_listener_t::addMenu(new LLWorldSetDoNotDisturb(), "World.SetDoNotDisturb"); view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark"); view_listener_t::addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation"); @@ -8026,9 +8367,6 @@ void initialize_menus() view_listener_t::addMenu(new LLWorldEnableEnvPreset(), "World.EnableEnvPreset"); view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess"); - view_listener_t::addMenu(new LLWorldToggleMovementControls(), "World.Toggle.MovementControls"); - view_listener_t::addMenu(new LLWorldToggleCameraControls(), "World.Toggle.CameraControls"); - // Tools menu view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool"); view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects"); @@ -8048,7 +8386,6 @@ void initialize_menus() commit.add("Tools.LookAtSelection", boost::bind(&handle_look_at_selection, _2)); commit.add("Tools.BuyOrTake", boost::bind(&handle_buy_or_take)); commit.add("Tools.TakeCopy", boost::bind(&handle_take_copy)); - view_listener_t::addMenu(new LLToolsSaveToInventory(), "Tools.SaveToInventory"); view_listener_t::addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory"); view_listener_t::addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction"); @@ -8060,9 +8397,13 @@ void initialize_menus() enable.add("Tools.EnableTakeCopy", boost::bind(&enable_object_take_copy)); enable.add("Tools.VisibleBuyObject", boost::bind(&tools_visible_buy_object)); enable.add("Tools.VisibleTakeObject", boost::bind(&tools_visible_take_object)); - view_listener_t::addMenu(new LLToolsEnableSaveToInventory(), "Tools.EnableSaveToInventory"); view_listener_t::addMenu(new LLToolsEnableSaveToObjectInventory(), "Tools.EnableSaveToObjectInventory"); + view_listener_t::addMenu(new LLToolsEnablePathfinding(), "Tools.EnablePathfinding"); + view_listener_t::addMenu(new LLToolsEnablePathfindingView(), "Tools.EnablePathfindingView"); + view_listener_t::addMenu(new LLToolsDoPathfindingRebakeRegion(), "Tools.DoPathfindingRebakeRegion"); + view_listener_t::addMenu(new LLToolsEnablePathfindingRebakeRegion(), "Tools.EnablePathfindingRebakeRegion"); + // Help menu // most items use the ShowFloater method view_listener_t::addMenu(new LLToggleHowTo(), "Help.ToggleHowTo"); @@ -8087,6 +8428,10 @@ void initialize_menus() //// Advanced > Render > Features view_listener_t::addMenu(new LLAdvancedToggleFeature(), "Advanced.ToggleFeature"); view_listener_t::addMenu(new LLAdvancedCheckFeature(), "Advanced.CheckFeature"); + + view_listener_t::addMenu(new LLAdvancedCheckDisplayTextureDensity(), "Advanced.CheckDisplayTextureDensity"); + view_listener_t::addMenu(new LLAdvancedSetDisplayTextureDensity(), "Advanced.SetDisplayTextureDensity"); + // Advanced > Render > Info Displays view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay"); view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay"); @@ -8124,6 +8469,7 @@ void initialize_menus() // Advanced > UI commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test, _2)); // sigh! this one opens the MEDIA browser commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2)); // this one opens the Web Content floater + commit.add("Advanced.ShowURL", boost::bind(&handle_show_url, _2)); view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest"); view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr"); view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory"); @@ -8131,7 +8477,6 @@ void initialize_menus() commit.add("Advanced.DumpFocusHolder", boost::bind(&handle_dump_focus) ); view_listener_t::addMenu(new LLAdvancedPrintSelectedObjectInfo(), "Advanced.PrintSelectedObjectInfo"); view_listener_t::addMenu(new LLAdvancedPrintAgentInfo(), "Advanced.PrintAgentInfo"); - view_listener_t::addMenu(new LLAdvancedPrintTextureMemoryStats(), "Advanced.PrintTextureMemoryStats"); view_listener_t::addMenu(new LLAdvancedToggleDebugClicks(), "Advanced.ToggleDebugClicks"); view_listener_t::addMenu(new LLAdvancedCheckDebugClicks(), "Advanced.CheckDebugClicks"); view_listener_t::addMenu(new LLAdvancedCheckDebugViews(), "Advanced.CheckDebugViews"); @@ -8162,8 +8507,12 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale"); view_listener_t::addMenu(new LLAdvancedTestFemale(), "Advanced.TestFemale"); - view_listener_t::addMenu(new LLAdvancedTogglePG(), "Advanced.TogglePG"); + // Advanced > Character > Animation Speed + view_listener_t::addMenu(new LLAdvancedAnimTenFaster(), "Advanced.AnimTenFaster"); + view_listener_t::addMenu(new LLAdvancedAnimTenSlower(), "Advanced.AnimTenSlower"); + view_listener_t::addMenu(new LLAdvancedAnimResetAll(), "Advanced.AnimResetAll"); + // Advanced > Character (toplevel) view_listener_t::addMenu(new LLAdvancedForceParamsToDefault(), "Advanced.ForceParamsToDefault"); view_listener_t::addMenu(new LLAdvancedReloadVertexShader(), "Advanced.ReloadVertexShader"); @@ -8210,9 +8559,17 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions"); view_listener_t::addMenu(new LLAdvancedToggleViewAdminOptions(), "Advanced.ToggleViewAdminOptions"); view_listener_t::addMenu(new LLAdvancedCheckViewAdminOptions(), "Advanced.CheckViewAdminOptions"); + view_listener_t::addMenu(new LLAdvancedToggleVisualLeakDetector(), "Advanced.ToggleVisualLeakDetector"); + 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"); + + //Develop (Texture Fetch Debug Console) + view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger"); // Admin >Object view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy"); @@ -8243,6 +8600,7 @@ void initialize_menus() // we don't use boost::bind directly to delay side tray construction view_listener_t::addMenu( new LLTogglePanelPeopleTab(), "SideTray.PanelPeopleTab"); + view_listener_t::addMenu( new LLCheckPanelPeopleTab(), "SideTray.CheckPanelPeopleTab"); // Avatar pie menu view_listener_t::addMenu(new LLObjectMute(), "Avatar.Mute"); @@ -8299,6 +8657,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")); @@ -8340,6 +8699,10 @@ void initialize_menus() enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar)); enable.add("EnableEdit", boost::bind(&enable_object_edit)); enable.add("VisibleBuild", boost::bind(&enable_object_build)); + commit.add("Pathfinding.Linksets.Select", boost::bind(&LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects)); + enable.add("EnableSelectInPathfindingLinksets", boost::bind(&enable_object_select_in_pathfinding_linksets)); + commit.add("Pathfinding.Characters.Select", boost::bind(&LLFloaterPathfindingCharacters::openCharactersWithSelectedObjects)); + enable.add("EnableSelectInPathfindingCharacters", boost::bind(&enable_object_select_in_pathfinding_characters)); view_listener_t::addMenu(new LLFloaterVisible(), "FloaterVisible"); view_listener_t::addMenu(new LLShowSidetrayPanel(), "ShowSidetrayPanel"); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 87cb4efbc4..01534503f3 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -27,7 +27,7 @@ #ifndef LL_LLVIEWERMENU_H #define LL_LLVIEWERMENU_H -#include "llmenugl.h" +#include "../llui/llmenugl.h" #include "llsafehandle.h" class LLMessageSystem; @@ -39,6 +39,7 @@ class LLObjectSelection; class LLSelectNode; void initialize_edit_menu(); +void initialize_spellcheck_menu(); void init_menus(); void cleanup_menus(); @@ -48,7 +49,6 @@ void show_context_menu( S32 x, S32 y, MASK mask ); void show_build_mode_context_menu(S32 x, S32 y, MASK mask); void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y); void show_topinfobar_context_menu(LLView* ctrl, S32 x, S32 y); -BOOL enable_save_into_inventory(void*); void handle_reset_view(); void handle_cut(void*); void handle_copy(void*); @@ -93,11 +93,20 @@ void handle_object_touch(); bool enable_object_open(); void handle_object_open(); +bool visible_take_object(); +bool tools_visible_take_object(); +bool enable_object_take_copy(); +bool enable_object_return(); +bool enable_object_delete(); + // Buy either contents or object itself void handle_buy(); +void handle_take(); void handle_take_copy(); void handle_look_at_selection(const LLSD& param); void handle_zoom_to_object(LLUUID object_id); +void handle_object_return(); +void handle_object_delete(); void handle_buy_land(); @@ -149,8 +158,6 @@ protected: LLSafeHandle<LLObjectSelection> mObjectSelection; }; -extern const std::string SAVE_INTO_INVENTORY; - extern LLMenuBarGL* gMenuBarView; //extern LLView* gMenuBarHolder; extern LLMenuGL* gEditMenu; @@ -177,8 +184,6 @@ extern LLContextMenu* gDetachPieMenu; extern LLContextMenu* gAttachBodyPartPieMenus[8]; extern LLContextMenu* gDetachBodyPartPieMenus[8]; -extern LLMenuItemCallGL* gAFKMenu; -extern LLMenuItemCallGL* gBusyMenu; extern LLMenuItemCallGL* gMutePieMenu; extern LLMenuItemCallGL* gMuteObjectPieMenu; extern LLMenuItemCallGL* gBuyPassPieMenu; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 7e830e14bf..be78603e2d 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -34,6 +34,7 @@ #include "llfilepicker.h" #include "llfloaterreg.h" #include "llbuycurrencyhtml.h" +#include "llfloatermap.h" #include "llfloatermodelpreview.h" #include "llfloatersnapshot.h" #include "llimage.h" @@ -183,7 +184,7 @@ void LLFilePickerThread::clearDead() #if LL_WINDOWS static std::string SOUND_EXTENSIONS = "wav"; static std::string IMAGE_EXTENSIONS = "tga bmp jpg jpeg png"; -static std::string ANIM_EXTENSIONS = "bvh"; +static std::string ANIM_EXTENSIONS = "bvh anim"; #ifdef _CORY_TESTING static std::string GEOMETRY_EXTENSIONS = "slg"; #endif @@ -385,7 +386,14 @@ class LLFileUploadAnim : public view_listener_t const std::string filename = upload_pick((void*)LLFilePicker::FFLOAD_ANIM); if (!filename.empty()) { - LLFloaterReg::showInstance("upload_anim", LLSD(filename)); + if (filename.rfind(".anim") != std::string::npos) + { + LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename)); + } + else + { + LLFloaterReg::showInstance("upload_anim_bvh", LLSD(filename)); + } } return true; } @@ -468,7 +476,7 @@ class LLFileEnableCloseWindow : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = NULL != LLFloater::getClosableFloaterFromFocus(); + bool new_value = NULL != gFloaterView->getFrontmostClosableFloater(); return new_value; } }; @@ -477,8 +485,7 @@ class LLFileCloseWindow : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLFloater::closeFocusedFloater(); - + LLFloater::closeFrontmostFloater(); return true; } }; @@ -487,7 +494,7 @@ class LLFileEnableCloseAllWindows : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool open_children = gFloaterView->allChildrenClosed(); + bool open_children = gFloaterView->allChildrenClosed() && !LLFloaterSnapshot::getInstance()->isInVisibleChain(); return !open_children; } }; @@ -498,7 +505,7 @@ class LLFileCloseAllWindows : public view_listener_t { bool app_quitting = false; gFloaterView->closeAllChildren(app_quitting); - + LLFloaterSnapshot::getInstance()->closeFloater(app_quitting); return true; } }; @@ -527,8 +534,22 @@ class LLFileTakeSnapshotToDisk : public view_listener_t FALSE)) { gViewerWindow->playSnapshotAnimAndSound(); - - LLPointer<LLImageFormatted> formatted = new LLImagePNG; + LLPointer<LLImageFormatted> formatted; + LLFloaterSnapshot::ESnapshotFormat fmt = (LLFloaterSnapshot::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat"); + switch (fmt) + { + case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG: + formatted = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality")); + break; + default: + llwarns << "Unknown local snapshot format: " << fmt << llendl; + case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG: + formatted = new LLImagePNG; + break; + case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP: + formatted = new LLImageBMP; + break; + } formatted->enableOverSize() ; formatted->encode(raw, 0); formatted->disableOverSize() ; @@ -785,6 +806,11 @@ LLUUID upload_new_resource( upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args); return LLUUID(); } + else if (exten == "anim") + { + asset_type = LLAssetType::AT_ANIMATION; + filename = src_filename; + } else { // Unknown extension @@ -949,11 +975,12 @@ void upload_done_callback( args["REASON"] = std::string(LLAssetStorage::getErrorString(result)); LLNotificationsUtil::add("CannotUploadReason", args); } + + delete data; + data = NULL; } LLUploadDialog::modalUploadFinished(); - delete data; - data = NULL; // *NOTE: This is a pretty big hack. What this does is check the // file picker if there are any more pending uploads. If so, diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index dca5cdd06d..2340436a01 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -42,6 +42,7 @@ #include "llinventorydefines.h" #include "lllslconstants.h" #include "llregionhandle.h" +#include "llsd.h" #include "llsdserialize.h" #include "llteleportflags.h" #include "lltransactionflags.h" @@ -64,10 +65,11 @@ #include "llfloatersnapshot.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" +#include "llimview.h" #include "llinventoryfunctions.h" #include "llinventoryobserver.h" #include "llinventorypanel.h" -#include "llnearbychat.h" +#include "llfloaterimnearbychat.h" #include "llnotifications.h" #include "llnotificationsutil.h" #include "llpanelgrouplandmoney.h" @@ -107,6 +109,7 @@ #include "llagentui.h" #include "llpanelblockedlist.h" #include "llpanelplaceprofile.h" +#include "llviewerregion.h" #include <boost/algorithm/string/split.hpp> // #include <boost/regex.hpp> @@ -118,6 +121,8 @@ #pragma warning (disable:4702) #endif +extern void on_new_message(const LLSD& msg); + // // Constants // @@ -132,9 +137,11 @@ static const U32 LLREQUEST_PERMISSION_THROTTLE_LIMIT = 5; // requests static const F32 LLREQUEST_PERMISSION_THROTTLE_INTERVAL = 10.0f; // seconds extern BOOL gDebugClicks; +extern bool gShiftFrame; // function prototypes bool check_offer_throttle(const std::string& from_name, bool check_only); +bool check_asset_previewable(const LLAssetType::EType asset_type); static void process_money_balance_reply_extended(LLMessageSystem* msg); //inventory offer throttle globals @@ -155,7 +162,8 @@ const std::string SCRIPT_QUESTIONS[SCRIPT_PERMISSION_EOF] = "AddAndRemoveJoints", "ChangePermissions", "TrackYourCamera", - "ControlYourCamera" + "ControlYourCamera", + "TeleportYourAgent" }; const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] = @@ -170,7 +178,8 @@ const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] = FALSE, // AddAndRemoveJoints FALSE, // ChangePermissions FALSE, // TrackYourCamera, - FALSE // ControlYourCamera + FALSE, // ControlYourCamera + FALSE // TeleportYourAgent }; bool friendship_offer_callback(const LLSD& notification, const LLSD& response) @@ -178,78 +187,82 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response) S32 option = LLNotificationsUtil::getSelectedOption(notification, response); LLMessageSystem* msg = gMessageSystem; const LLSD& payload = notification["payload"]; - - // add friend to recent people list - LLRecentPeople::instance().add(payload["from_id"]); - - switch(option) - { - case 0: - { - // accept - LLAvatarTracker::formFriendship(payload["from_id"]); - - const LLUUID fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD); - - // This will also trigger an onlinenotification if the user is online - msg->newMessageFast(_PREHASH_AcceptFriendship); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_TransactionBlock); - msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]); - msg->nextBlockFast(_PREHASH_FolderData); - msg->addUUIDFast(_PREHASH_FolderID, fid); - msg->sendReliable(LLHost(payload["sender"].asString())); - - LLSD payload = notification["payload"]; - payload["SUPPRESS_TOAST"] = true; - LLNotificationsUtil::add("FriendshipAcceptedByMe", - notification["substitutions"], payload); - break; - } - case 1: // Decline - { - LLSD payload = notification["payload"]; - payload["SUPPRESS_TOAST"] = true; - LLNotificationsUtil::add("FriendshipDeclinedByMe", - notification["substitutions"], payload); - } - // fall-through - case 2: // Send IM - decline and start IM session - { - // decline - // We no longer notify other viewers, but we DO still send - // the rejection to the simulator to delete the pending userop. - msg->newMessageFast(_PREHASH_DeclineFriendship); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_TransactionBlock); - msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]); - msg->sendReliable(LLHost(payload["sender"].asString())); - - // start IM session - if(2 == option) - { - LLAvatarActions::startIM(payload["from_id"].asUUID()); - } - } - default: - // close button probably, possibly timed out - break; - } + LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID()); + + // this will be skipped if the user offering friendship is blocked + if (notification_ptr) + { + // add friend to recent people list + LLRecentPeople::instance().add(payload["from_id"]); + + switch(option) + { + case 0: + { + // accept + LLAvatarTracker::formFriendship(payload["from_id"]); + + const LLUUID fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD); + + // This will also trigger an onlinenotification if the user is online + msg->newMessageFast(_PREHASH_AcceptFriendship); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_TransactionBlock); + msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]); + msg->nextBlockFast(_PREHASH_FolderData); + msg->addUUIDFast(_PREHASH_FolderID, fid); + msg->sendReliable(LLHost(payload["sender"].asString())); + + LLSD payload = notification["payload"]; + LLNotificationsUtil::add("FriendshipAcceptedByMe", + notification["substitutions"], payload); + break; + } + case 1: // Decline + { + LLSD payload = notification["payload"]; + LLNotificationsUtil::add("FriendshipDeclinedByMe", + notification["substitutions"], payload); + } + // fall-through + case 2: // Send IM - decline and start IM session + { + // decline + // We no longer notify other viewers, but we DO still send + // the rejection to the simulator to delete the pending userop. + msg->newMessageFast(_PREHASH_DeclineFriendship); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_TransactionBlock); + msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]); + msg->sendReliable(LLHost(payload["sender"].asString())); + + // start IM session + if(2 == option) + { + LLAvatarActions::startIM(payload["from_id"].asUUID()); + } + } + default: + // close button probably, possibly timed out + break; + } + + LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm())); + modified_form->setElementEnabled("Accept", false); + modified_form->setElementEnabled("Decline", false); + notification_ptr->updateForm(modified_form); + notification_ptr->repost(); + } return false; } static LLNotificationFunctorRegistration friendship_offer_callback_reg("OfferFriendship", friendship_offer_callback); static LLNotificationFunctorRegistration friendship_offer_callback_reg_nm("OfferFriendshipNoMessage", friendship_offer_callback); -//const char BUSY_AUTO_RESPONSE[] = "The Resident you messaged is in 'busy mode' which means they have " -// "requested not to be disturbed. Your message will still be shown in their IM " -// "panel for later viewing."; - -// // Functions // @@ -720,7 +733,7 @@ static void highlight_inventory_objects_in_panel(const std::vector<LLUUID>& item LLFolderView* fv = inventory_panel->getRootFolder(); if (fv) { - LLFolderViewItem* fv_item = fv->getItemByID(item_id); + LLFolderViewItem* fv_item = inventory_panel->getItemByID(item_id); if (fv_item) { LLFolderViewItem* fv_folder = fv_item->getParentFolder(); @@ -808,7 +821,13 @@ private: mSelectedItems.clear(); if (LLInventoryPanel::getActiveInventoryPanel()) { - mSelectedItems = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList(); + std::set<LLFolderViewItem*> selection = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList(); + for (std::set<LLFolderViewItem*>::iterator it = selection.begin(), end_it = selection.end(); + it != end_it; + ++it) + { + mSelectedItems.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID()); + } } mSelectedItems.erase(mMoveIntoFolderID); } @@ -843,7 +862,15 @@ private: } // get selected items (without destination folder) - selected_items_t selected_items = active_panel->getRootFolder()->getSelectionList(); + selected_items_t selected_items; + + std::set<LLFolderViewItem*> selection = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList(); + for (std::set<LLFolderViewItem*>::iterator it = selection.begin(), end_it = selection.end(); + it != end_it; + ++it) + { + selected_items.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID()); + } selected_items.erase(mMoveIntoFolderID); // compare stored & current sets of selected items @@ -1064,7 +1091,9 @@ public: // If we now try to remove the inventory item, it will cause a nested // notifyObservers() call, which won't work. // So defer moving the item to trash until viewer gets idle (in a moment). - LLAppViewer::instance()->addOnIdleCallback(boost::bind(&LLInventoryModel::removeItem, &gInventory, mObjectID)); + // Use removeObject() rather than removeItem() because at this level, + // the object could be either an item or a folder. + LLAppViewer::instance()->addOnIdleCallback(boost::bind(&LLInventoryModel::removeObject, &gInventory, mObjectID)); gInventory.removeObserver(this); delete this; } @@ -1148,6 +1177,17 @@ bool check_offer_throttle(const std::string& from_name, bool check_only) } } +// Return "true" if we have a preview method for that asset type, "false" otherwise +bool check_asset_previewable(const LLAssetType::EType asset_type) +{ + return (asset_type == LLAssetType::AT_NOTECARD) || + (asset_type == LLAssetType::AT_LANDMARK) || + (asset_type == LLAssetType::AT_TEXTURE) || + (asset_type == LLAssetType::AT_ANIMATION) || + (asset_type == LLAssetType::AT_SCRIPT) || + (asset_type == LLAssetType::AT_SOUND); +} + void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_name) { for (uuid_vec_t::const_iterator obj_iter = objects.begin(); @@ -1171,7 +1211,7 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam // Either an inventory item or a category. const LLInventoryItem* item = dynamic_cast<const LLInventoryItem*>(obj); - if (item) + if (item && check_asset_previewable(asset_type)) { //////////////////////////////////////////////////////////////////////////////// // Special handling for various types. @@ -1246,6 +1286,7 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam LLFloaterReg::showInstance("preview_sound", LLSD(obj_id), take_focus); break; default: + LL_DEBUGS("Messaging") << "No preview method for previewable asset type : " << LLAssetType::lookupHumanReadable(asset_type) << LL_ENDL; break; } } @@ -1324,6 +1365,8 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id, gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(blocked_id)); } +std::string LLOfferInfo::mResponderType = "offer_info"; + LLOfferInfo::LLOfferInfo() : LLNotificationResponderInterface() , mFromGroup(FALSE) @@ -1369,6 +1412,7 @@ LLOfferInfo::LLOfferInfo(const LLOfferInfo& info) LLSD LLOfferInfo::asLLSD() { LLSD sd; + sd["responder_type"] = mResponderType; sd["im_type"] = mIM; sd["from_id"] = mFromID; sd["from_group"] = mFromGroup; @@ -1458,16 +1502,15 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& itemp = (LLViewerInventoryItem*)gInventory.getItem(mObjectID); } + LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID()); + // For muting, we need to add the mute, then decline the offer. // This must be done here because: // * callback may be called immediately, // * adding the mute sends a message, // * we can't build two messages at once. - if (2 == button) // Block + if (IOR_MUTE == button) // Block { - LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID()); - - llassert(notification_ptr != NULL); if (notification_ptr != NULL) { gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3)); @@ -1480,8 +1523,8 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& // TODO: when task inventory offers can also be handled the new way, migrate the code that sets these strings here: from_string = chatHistory_string = mFromName; - bool busy = gAgent.getBusy(); - + LLNotificationFormPtr modified_form(notification_ptr ? new LLNotificationForm(*notification_ptr->getForm()) : new LLNotificationForm()); + switch(button) { case IOR_SHOW: @@ -1525,6 +1568,11 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL; break; } + + if (modified_form != NULL) + { + modified_form->setElementEnabled("Show", false); + } break; // end switch (mIM) @@ -1537,9 +1585,14 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& args["MESSAGE"] = log_message; LLNotificationsUtil::add("SystemMessageTip", args); } + break; case IOR_MUTE: + if (modified_form != NULL) + { + modified_form->setElementEnabled("Mute", false); + } // MUTE falls through to decline case IOR_DECLINE: { @@ -1569,12 +1622,13 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& { opener = discard_agent_offer; } - - - if (busy && (!mFromGroup && !mFromObject)) + + if (modified_form != NULL) { - busy_message(gMessageSystem, mFromID); + modified_form->setElementEnabled("Show", false); + modified_form->setElementEnabled("Discard", false); } + break; } default: @@ -1594,6 +1648,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& { delete this; } + return false; } @@ -1684,7 +1739,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const from_string = chatHistory_string = mFromName; } - bool busy = gAgent.getBusy(); + bool is_do_not_disturb = gAgent.isDoNotDisturb(); switch(button) { @@ -1757,9 +1812,9 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const LLNotificationsUtil::add("SystemMessageTip", args); } - if (busy && (!mFromGroup && !mFromObject)) + if (is_do_not_disturb && (!mFromGroup && !mFromObject)) { - busy_message(msg,mFromID); + send_do_not_disturb_message(msg,mFromID); } break; } @@ -1911,6 +1966,7 @@ void inventory_offer_handler(LLOfferInfo* info) p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info)); info->mPersist = true; p.name = "UserGiveItem"; + p.offer_from_agent = true; // Prefetch the item into your local inventory. LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID); @@ -1927,6 +1983,11 @@ void inventory_offer_handler(LLOfferInfo* info) // In viewer 2 we're now auto receiving inventory offers and messaging as such (not sending reject messages). info->send_auto_receive_response(); + if (gAgent.isDoNotDisturb()) + { + send_do_not_disturb_message(gMessageSystem, info->mFromID); + } + // Inform user that there is a script floater via toast system { payload["give_inventory_notification"] = TRUE; @@ -1971,10 +2032,62 @@ bool lure_callback(const LLSD& notification, const LLSD& response) lure_id); break; } + + LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID()); + + if (notification_ptr) + { + LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm())); + modified_form->setElementEnabled("Teleport", false); + modified_form->setElementEnabled("Cancel", false); + notification_ptr->updateForm(modified_form); + notification_ptr->repost(); + } + return false; } static LLNotificationFunctorRegistration lure_callback_reg("TeleportOffered", lure_callback); +bool mature_lure_callback(const LLSD& notification, const LLSD& response) +{ + S32 option = 0; + if (response.isInteger()) + { + option = response.asInteger(); + } + else + { + option = LLNotificationsUtil::getSelectedOption(notification, response); + } + + LLUUID from_id = notification["payload"]["from_id"].asUUID(); + LLUUID lure_id = notification["payload"]["lure_id"].asUUID(); + BOOL godlike = notification["payload"]["godlike"].asBoolean(); + U8 region_access = static_cast<U8>(notification["payload"]["region_maturity"].asInteger()); + + switch(option) + { + case 0: + { + // accept + gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(region_access)); + gAgent.setMaturityRatingChangeDuringTeleport(region_access); + gAgent.teleportViaLure(lure_id, godlike); + } + break; + case 1: + default: + // decline + send_simple_im(from_id, + LLStringUtil::null, + IM_LURE_DECLINED, + lure_id); + break; + } + return false; +} +static LLNotificationFunctorRegistration mature_lure_callback_reg("TeleportOffered_MaturityExceeded", mature_lure_callback); + bool goto_url_callback(const LLSD& notification, const LLSD& response) { std::string url = notification["payload"]["url"].asString(); @@ -2092,7 +2205,7 @@ static std::string clean_name_from_im(const std::string& name, EInstantMessage t case IM_SESSION_SEND: case IM_SESSION_LEAVE: //IM_FROM_TASK - case IM_BUSY_AUTO_RESPONSE: + case IM_DO_NOT_DISTURB_AUTO_RESPONSE: case IM_CONSOLE_AND_CHAT_HISTORY: case IM_LURE_USER: case IM_LURE_ACCEPTED: @@ -2133,16 +2246,7 @@ static std::string clean_name_from_task_im(const std::string& msg, // Don't try to clean up group names if (!from_group) { - if (LLAvatarNameCache::useDisplayNames()) - { - // ...just convert to username - final += LLCacheName::buildUsername(name); - } - else - { - // ...strip out legacy "Resident" name - final += LLCacheName::cleanFullName(name); - } + final += LLCacheName::buildUsername(name); } final += match[3].str(); return final; @@ -2150,13 +2254,13 @@ static std::string clean_name_from_task_im(const std::string& msg, return msg; } -void notification_display_name_callback(const LLUUID& id, +static void notification_display_name_callback(const LLUUID& id, const LLAvatarName& av_name, const std::string& name, LLSD& substitutions, const LLSD& payload) { - substitutions["NAME"] = av_name.mDisplayName; + substitutions["NAME"] = av_name.getDisplayName(); LLNotificationsUtil::add(name, substitutions, payload); } @@ -2174,7 +2278,7 @@ protected: }; // Callback for name resolution of a god/estate message -void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message) +static void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message) { LLSD args; args["NAME"] = av_name.getCompleteName(); @@ -2184,12 +2288,11 @@ void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string m // Treat like a system message and put in chat history. chat.mText = av_name.getCompleteName() + ": " + message; - LLNearbyChat* nearby_chat = LLNearbyChat::getInstance(); - if(nearby_chat) + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + if (nearby_chat) { nearby_chat->addMessage(chat); } - } void process_improved_im(LLMessageSystem *msg, void **user_data) @@ -2235,19 +2338,22 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { name = LLTrans::getString("Unnamed"); } + + // Preserve the unaltered name for use in group notice mute checking. + std::string original_name = name; + // IDEVO convert new-style "Resident" names for display name = clean_name_from_im(name, dialog); - BOOL is_busy = gAgent.getBusy(); + BOOL is_do_not_disturb = gAgent.isDoNotDisturb(); BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat) // object IMs contain sender object id in session_id (STORM-1209) || dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id); - BOOL is_linden = LLMuteList::getInstance()->isLinden(name); BOOL is_owned_by_me = FALSE; BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true; BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly"); - chat.mMuted = is_muted && !is_linden; + chat.mMuted = is_muted; chat.mFromID = from_id; chat.mFromName = name; chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT; @@ -2265,7 +2371,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) LLNotification::Params params; switch(dialog) - { + { case IM_CONSOLE_AND_CHAT_HISTORY: args["MESSAGE"] = message; payload["from_id"] = from_id; @@ -2285,29 +2391,18 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // do nothing -- don't distract newbies in // Prelude with global IMs } - else if (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM) + else if (offline == IM_ONLINE + && is_do_not_disturb + && from_id.notNull() //not a system message + && to_id.notNull()) //not global message { - // return a standard "busy" message, but only do it to online IM + // return a standard "do not disturb" message, but only do it to online IM // (i.e. not other auto responses and not store-and-forward IM) if (!gIMMgr->hasSession(session_id)) { // if there is not a panel for this conversation (i.e. it is a new IM conversation // initiated by the other party) then... - std::string my_name; - LLAgentUI::buildFullname(my_name); - std::string response = gSavedPerAccountSettings.getString("BusyModeResponse"); - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - from_id, - my_name, - response, - IM_ONLINE, - IM_BUSY_AUTO_RESPONSE, - session_id); - gAgent.sendReliableMessage(); + send_do_not_disturb_message(msg, from_id, session_id); } // now store incoming IM in chat history @@ -2322,6 +2417,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) from_id, name, buffer, + IM_OFFLINE == offline, LLStringUtil::null, dialog, parent_estate_id, @@ -2358,15 +2454,23 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) bool mute_im = is_muted; if(accept_im_from_only_friend&&!is_friend) { + if (!gIMMgr->isNonFriendSessionNotified(session_id)) + { + std::string message = LLTrans::getString("IM_unblock_only_groups_friends"); + gIMMgr->addMessage(session_id, from_id, name, message, IM_OFFLINE == offline); + gIMMgr->addNotifiedNonFriendSessionID(session_id); + } + mute_im = true; } - if (!mute_im || is_linden) + if (!mute_im) { gIMMgr->addMessage( session_id, from_id, name, buffer, + IM_OFFLINE == offline, LLStringUtil::null, dialog, parent_estate_id, @@ -2441,6 +2545,26 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) break; } + // The group notice packet does not have an AgentID. Obtain one from the name cache. + // If last name is "Resident" strip it out so the cache name lookup works. + U32 index = original_name.find(" Resident"); + if (index != std::string::npos) + { + original_name = original_name.substr(0, index); + } + std::string legacy_name = gCacheName->buildLegacyName(original_name); + LLUUID agent_id; + gCacheName->getUUID(legacy_name, agent_id); + + if (agent_id.isNull()) + { + LL_WARNS("Messaging") << "buildLegacyName returned null while processing " << original_name << LL_ENDL; + } + else if (LLMuteList::getInstance()->isMuted(agent_id)) + { + break; + } + notice_bin_bucket = (struct notice_bucket_full_t*) &binary_bucket[0]; U8 has_inventory = notice_bin_bucket->header.has_inventory; U8 asset_type = notice_bin_bucket->header.asset_type; @@ -2491,7 +2615,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) payload["sender_name"] = name; payload["group_id"] = group_id; payload["inventory_name"] = item_name; - payload["inventory_offer"] = info ? info->asLLSD() : LLSD(); + if(info && info->asLLSD()) + { + payload["inventory_offer"] = info->asLLSD(); + } LLSD args; args["SUBJECT"] = subj; @@ -2513,11 +2640,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) break; case IM_GROUP_INVITATION: { - //if (!is_linden && (is_busy || is_muted)) - if ((is_busy || is_muted)) + if (is_do_not_disturb || is_muted) { - LLMessageSystem *msg = gMessageSystem; - busy_message(msg,from_id); + send_do_not_disturb_message(msg, from_id); } else { @@ -2600,7 +2725,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) info->mFromName = name; info->mDesc = message; info->mHost = msg->getSender(); - //if (((is_busy && !is_owned_by_me) || is_muted)) + //if (((is_do_not_disturb && !is_owned_by_me) || is_muted)) if (is_muted) { // Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331) @@ -2611,9 +2736,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // Same as closing window info->forceResponse(IOR_DECLINE); } - else if (is_busy && dialog != IM_TASK_INVENTORY_OFFERED) // busy mode must not affect interaction with objects (STORM-565) + // old logic: busy mode must not affect interaction with objects (STORM-565) + // new logic: inventory offers from in-world objects should be auto-declined (CHUI-519) + else if (is_do_not_disturb && dialog == IM_TASK_INVENTORY_OFFERED) { - // Until throttling is implemented, busy mode should reject inventory instead of silently + // Until throttling is implemented, do not disturb mode should reject inventory instead of silently // accepting it. SEE SL-39554 info->forceResponse(IOR_DECLINE); } @@ -2658,7 +2785,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_SESSION_SEND: { - if (!is_linden && is_busy) + if (is_do_not_disturb) { return; } @@ -2687,6 +2814,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) from_id, name, buffer, + IM_OFFLINE == offline, ll_safe_string((char*)binary_bucket), IM_SESSION_INVITE, parent_estate_id, @@ -2698,7 +2826,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_FROM_TASK: { - if (is_busy && !is_owned_by_me) + if (is_do_not_disturb && !is_owned_by_me) { return; } @@ -2722,7 +2850,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) chat.mSourceType = CHAT_SOURCE_OBJECT; - if(SYSTEM_FROM == name) + // To conclude that the source type of message is CHAT_SOURCE_SYSTEM it's not + // enough to check only from name (i.e. fromName = "Second Life"). For example + // source type of messages from objects called "Second Life" should not be CHAT_SOURCE_SYSTEM. + bool chat_from_system = (SYSTEM_FROM == name) && region_id.isNull() && position.isNull(); + if(chat_from_system) { // System's UUID is NULL (fixes EXT-4766) chat.mFromID = LLUUID::null; @@ -2746,13 +2878,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // Note: lie to Nearby Chat, pretending that this is NOT an IM, because // IMs from obejcts don't open IM sessions. - LLNearbyChat* nearby_chat = LLNearbyChat::getInstance(); - if(SYSTEM_FROM != name && nearby_chat) + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + if(!chat_from_system && nearby_chat) { chat.mOwnerID = from_id; LLSD args; args["slurl"] = location; - args["type"] = LLNotificationsUI::NT_NEARBYCHAT; // Look for IRC-style emotes here so object name formatting is correct std::string prefix = message.substr(0, 4); @@ -2766,7 +2897,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) //Object IMs send with from name: 'Second Life' need to be displayed also in notification toasts (EXT-1590) - if (SYSTEM_FROM != name) break; + if (!chat_from_system) break; LLSD substitutions; substitutions["NAME"] = name; @@ -2792,7 +2923,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } break; case IM_FROM_TASK_AS_ALERT: - if (is_busy && !is_owned_by_me) + if (is_do_not_disturb && !is_owned_by_me) { return; } @@ -2803,17 +2934,15 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) LLNotificationsUtil::add("ObjectMessage", args); } break; - case IM_BUSY_AUTO_RESPONSE: + case IM_DO_NOT_DISTURB_AUTO_RESPONSE: if (is_muted) { - LL_DEBUGS("Messaging") << "Ignoring busy response from " << from_id << LL_ENDL; + LL_DEBUGS("Messaging") << "Ignoring do-not-disturb response from " << from_id << LL_ENDL; return; } else { - // TODO: after LLTrans hits release, get "busy response" into translatable file - buffer = llformat("%s (%s): %s", name.c_str(), "busy response", message.c_str()); - gIMMgr->addMessage(session_id, from_id, name, buffer); + gIMMgr->addMessage(session_id, from_id, name, message); } break; @@ -2823,23 +2952,62 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { return; } - else if (is_busy) + else if (is_do_not_disturb) { - busy_message(msg,from_id); + send_do_not_disturb_message(msg, from_id); } else { LLVector3 pos, look_at; U64 region_handle(0); - U8 region_access(0); + U8 region_access(SIM_ACCESS_MIN); std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size); std::string region_access_str = LLStringUtil::null; std::string region_access_icn = LLStringUtil::null; + std::string region_access_lc = LLStringUtil::null; + + bool canUserAccessDstRegion = true; + bool doesUserRequireMaturityIncrease = false; if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access)) { region_access_str = LLViewerRegion::accessToString(region_access); region_access_icn = LLViewerRegion::getAccessIcon(region_access); + region_access_lc = region_access_str; + LLStringUtil::toLower(region_access_lc); + + if (!gAgent.isGodlike()) + { + switch (region_access) + { + case SIM_ACCESS_MIN : + case SIM_ACCESS_PG : + break; + case SIM_ACCESS_MATURE : + if (gAgent.isTeen()) + { + canUserAccessDstRegion = false; + } + else if (gAgent.prefersPG()) + { + doesUserRequireMaturityIncrease = true; + } + break; + case SIM_ACCESS_ADULT : + if (!gAgent.isAdult()) + { + canUserAccessDstRegion = false; + } + else if (!gAgent.prefersAdult()) + { + doesUserRequireMaturityIncrease = true; + } + break; + default : + llassert(0); + break; + } + } } LLSD args; @@ -2848,29 +3016,131 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) args["MESSAGE"] = message; args["MATURITY_STR"] = region_access_str; args["MATURITY_ICON"] = region_access_icn; + args["REGION_CONTENT_MATURITY"] = region_access_lc; LLSD payload; payload["from_id"] = from_id; payload["lure_id"] = session_id; payload["godlike"] = FALSE; + payload["region_maturity"] = region_access; + if (!canUserAccessDstRegion) + { + LLNotification::Params params("TeleportOffered_MaturityBlocked"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); + send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id); + send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id); + } + else if (doesUserRequireMaturityIncrease) + { + LLNotification::Params params("TeleportOffered_MaturityExceeded"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); + } + else + { LLNotification::Params params("TeleportOffered"); params.substitutions = args; params.payload = payload; LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); } + + } } break; case IM_GODLIKE_LURE_USER: { + LLVector3 pos, look_at; + U64 region_handle(0); + U8 region_access(SIM_ACCESS_MIN); + std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size); + std::string region_access_str = LLStringUtil::null; + std::string region_access_icn = LLStringUtil::null; + std::string region_access_lc = LLStringUtil::null; + + bool canUserAccessDstRegion = true; + bool doesUserRequireMaturityIncrease = false; + + if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access)) + { + region_access_str = LLViewerRegion::accessToString(region_access); + region_access_icn = LLViewerRegion::getAccessIcon(region_access); + region_access_lc = region_access_str; + LLStringUtil::toLower(region_access_lc); + + if (!gAgent.isGodlike()) + { + switch (region_access) + { + case SIM_ACCESS_MIN : + case SIM_ACCESS_PG : + break; + case SIM_ACCESS_MATURE : + if (gAgent.isTeen()) + { + canUserAccessDstRegion = false; + } + else if (gAgent.prefersPG()) + { + doesUserRequireMaturityIncrease = true; + } + break; + case SIM_ACCESS_ADULT : + if (!gAgent.isAdult()) + { + canUserAccessDstRegion = false; + } + else if (!gAgent.prefersAdult()) + { + doesUserRequireMaturityIncrease = true; + } + break; + default : + llassert(0); + break; + } + } + } + + LLSD args; + // *TODO: Translate -> [FIRST] [LAST] (maybe) + args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString(); + args["MESSAGE"] = message; + args["MATURITY_STR"] = region_access_str; + args["MATURITY_ICON"] = region_access_icn; + args["REGION_CONTENT_MATURITY"] = region_access_lc; LLSD payload; payload["from_id"] = from_id; payload["lure_id"] = session_id; payload["godlike"] = TRUE; + payload["region_maturity"] = region_access; + + if (!canUserAccessDstRegion) + { + LLNotification::Params params("TeleportOffered_MaturityBlocked"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); + send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id); + send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id); + } + else if (doesUserRequireMaturityIncrease) + { + LLNotification::Params params("TeleportOffered_MaturityExceeded"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); + } + else + { // do not show a message box, because you're about to be // teleported. LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0); } + } break; case IM_GOTO_URL: @@ -2905,17 +3175,16 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) payload["online"] = (offline == IM_ONLINE); payload["sender"] = msg->getSender().getIPandPort(); - if (is_busy) - { - busy_message(msg, from_id); - LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1); - } - else if (is_muted) + if (is_muted) { LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1); } else { + if (is_do_not_disturb) + { + send_do_not_disturb_message(msg, from_id); + } args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString(); if(message.empty()) { @@ -2948,12 +3217,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) args["NAME"] = name; LLSD payload; payload["from_id"] = from_id; - LLAvatarNameCache::get(from_id, boost::bind(¬ification_display_name_callback, - _1, - _2, - "FriendshipAccepted", - args, - payload)); + LLAvatarNameCache::get(from_id, boost::bind(¬ification_display_name_callback,_1,_2,"FriendshipAccepted",args,payload)); } break; @@ -2971,15 +3235,15 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } } -void busy_message (LLMessageSystem* msg, LLUUID from_id) +void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id) { - if (gAgent.getBusy()) + if (gAgent.isDoNotDisturb()) { std::string my_name; LLAgentUI::buildFullname(my_name); - std::string response = gSavedPerAccountSettings.getString("BusyModeResponse"); + std::string response = gSavedPerAccountSettings.getString("DoNotDisturbModeResponse"); pack_instant_message( - gMessageSystem, + msg, gAgent.getID(), FALSE, gAgent.getSessionID(), @@ -2987,7 +3251,8 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id) my_name, response, IM_ONLINE, - IM_BUSY_AUTO_RESPONSE); + IM_DO_NOT_DISTURB_AUTO_RESPONSE, + session_id); gAgent.sendReliableMessage(); } } @@ -3022,7 +3287,7 @@ bool callingcard_offer_callback(const LLSD& notification, const LLSD& response) msg->nextBlockFast(_PREHASH_TransactionBlock); msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID()); msg->sendReliable(LLHost(notification["payload"]["sender"].asString())); - busy_message(msg, notification["payload"]["source_id"].asUUID()); + send_do_not_disturb_message(msg, notification["payload"]["source_id"].asUUID()); break; default: // close button probably, possibly timed out @@ -3064,7 +3329,7 @@ void process_offer_callingcard(LLMessageSystem* msg, void**) if(!source_name.empty()) { - if (gAgent.getBusy() + if (gAgent.isDoNotDisturb() || LLMuteList::getInstance()->isMuted(source_id, source_name, LLMute::flagTextChat)) { // automatically decline offer @@ -3104,9 +3369,9 @@ public : { } - static boost::intrusive_ptr<ChatTranslationReceiver> build(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, const LLChat &chat, const LLSD &toast_args) + static ChatTranslationReceiver* build(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, const LLChat &chat, const LLSD &toast_args) { - return boost::intrusive_ptr<ChatTranslationReceiver>(new ChatTranslationReceiver(from_lang, to_lang, mesg, chat, toast_args)); + return new ChatTranslationReceiver(from_lang, to_lang, mesg, chat, toast_args); } protected: @@ -3181,7 +3446,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) LLAvatarName av_name; if (LLAvatarNameCache::get(from_id, &av_name)) { - chat.mFromName = av_name.mDisplayName; + chat.mFromName = av_name.getDisplayName(); } else { @@ -3193,7 +3458,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) chat.mFromName = from_name; } - BOOL is_busy = gAgent.getBusy(); + BOOL is_do_not_disturb = gAgent.isDoNotDisturb(); BOOL is_muted = FALSE; BOOL is_linden = FALSE; @@ -3227,7 +3492,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) // record last audible utterance if (is_audible - && (is_linden || (!is_muted && !is_busy))) + && (is_linden || (!is_muted && !is_do_not_disturb))) { if (chat.mChatType != CHAT_TYPE_START && chat.mChatType != CHAT_TYPE_STOP) @@ -3322,7 +3587,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE); ((LLVOAvatar*)chatter)->stopTyping(); - if (!is_muted && !is_busy) + if (!is_muted && !is_do_not_disturb) { visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles"); std::string formated_msg = ""; @@ -3355,7 +3620,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) // pass owner_id to chat so that we can display the remote // object inspect for an object that is chatting with you LLSD args; - args["type"] = LLNotificationsUI::NT_NEARBYCHAT; chat.mOwnerID = owner_id; if (gSavedSettings.getBOOL("TranslateChat") && chat.mSourceType != CHAT_SOURCE_SYSTEM) @@ -3374,6 +3638,11 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) { LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args); } + + LLSD msg_notify = LLSD(LLSD::emptyMap()); + msg_notify["session_id"] = LLUUID(); + msg_notify["from_id"] = chat.mFromID; + on_new_message(msg_notify); } } @@ -3393,6 +3662,9 @@ void process_teleport_start(LLMessageSystem *msg, void**) LL_DEBUGS("Messaging") << "Got TeleportStart with TeleportFlags=" << teleport_flags << ". gTeleportDisplay: " << gTeleportDisplay << ", gAgent.mTeleportState: " << gAgent.getTeleportState() << LL_ENDL; + // *NOTE: The server sends two StartTeleport packets when you are teleporting to a LM + LLViewerMessage::getInstance()->mTeleportStartedSignal(); + if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL) { gViewerWindow->setProgressCancelButtonVisible(FALSE); @@ -3412,11 +3684,17 @@ void process_teleport_start(LLMessageSystem *msg, void**) make_ui_sound("UISndTeleportOut"); LL_INFOS("Messaging") << "Teleport initiated by remote TeleportStart message with TeleportFlags: " << teleport_flags << LL_ENDL; + // Don't call LLFirstUse::useTeleport here because this could be // due to being killed, which would send you home, not to a Telehub } } +boost::signals2::connection LLViewerMessage::setTeleportStartedCallback(teleport_started_callback_t cb) +{ + return mTeleportStartedSignal.connect(cb); +} + void process_teleport_progress(LLMessageSystem* msg, void**) { LLUUID agent_id; @@ -3638,6 +3916,9 @@ void process_teleport_finish(LLMessageSystem* msg, void**) gCacheName->setUpstream(sim); */ + // Make sure we're standing + gAgent.standUp(); + // now, use the circuit info to tell simulator about us! LL_INFOS("Messaging") << "process_teleport_finish() Enabling " << sim_host << " with code " << msg->mOurCircuitCode << LL_ENDL; @@ -3683,6 +3964,7 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**) void process_agent_movement_complete(LLMessageSystem* msg, void**) { + gShiftFrame = true; gAgentMovementCompleted = true; LLUUID agent_id; @@ -3848,14 +4130,14 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) gAgent.setFlying(gAgent.canFly()); } - // force simulator to recognize busy state - if (gAgent.getBusy()) + // force simulator to recognize do not disturb state + if (gAgent.isDoNotDisturb()) { - gAgent.setBusy(); + gAgent.setDoNotDisturb(true); } else { - gAgent.clearBusy(); + gAgent.setDoNotDisturb(false); } if (isAgentAvatarValid()) @@ -4013,6 +4295,8 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) head_rot_chg = dot(last_head_rot, head_rotation); + //static S32 msg_number = 0; // Used for diagnostic log messages + if (force_send || (cam_center_chg.magVec() > TRANSLATE_THRESHOLD) || (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) || @@ -4021,19 +4305,20 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) control_flag_change != 0 || flag_change != 0) { -/* + /* Diagnotics to show why we send the AgentUpdate message. Also un-commment the msg_number code above and below this block + msg_number += 1; if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) { //LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL; - LL_INFOS("Messaging") << "head_rot_chg = " << head_rot_chg << LL_ENDL; + LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", head_rot_chg " << head_rot_chg << LL_ENDL; } if (cam_rot_chg.magVec() > ROTATION_THRESHOLD) { - LL_INFOS("Messaging") << "cam rot " << cam_rot_chg.magVec() << LL_ENDL; + LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam rot " << cam_rot_chg.magVec() << LL_ENDL; } if (cam_center_chg.magVec() > TRANSLATE_THRESHOLD) { - LL_INFOS("Messaging") << "cam center " << cam_center_chg.magVec() << LL_ENDL; + LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam center " << cam_center_chg.magVec() << LL_ENDL; } // if (drag_delta_chg.magVec() > TRANSLATE_THRESHOLD) // { @@ -4041,7 +4326,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) // } if (control_flag_change) { - LL_INFOS("Messaging") << "dcf = " << control_flag_change << LL_ENDL; + LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", dcf = " << control_flag_change << LL_ENDL; } */ @@ -4078,6 +4363,26 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) if (duplicate_count < DUP_MSGS && !gDisconnected) { + /* More diagnostics to count AgentUpdate messages + static S32 update_sec = 0; + static S32 update_count = 0; + static S32 max_update_count = 0; + S32 cur_sec = lltrunc( LLTimer::getTotalSeconds() ); + update_count += 1; + if (cur_sec != update_sec) + { + if (update_sec != 0) + { + update_sec = cur_sec; + //msg_number = 0; + max_update_count = llmax(max_update_count, update_count); + llinfos << "Sent " << update_count << " AgentUpdate messages per second, max is " << max_update_count << llendl; + } + update_sec = cur_sec; + update_count = 0; + } + */ + LLFastTimer t(FTM_AGENT_UPDATE_SEND); // Build the message msg->newMessageFast(_PREHASH_AgentUpdate); @@ -4148,7 +4453,6 @@ extern U32 gObjectBits; void process_object_update(LLMessageSystem *mesgsys, void **user_data) { - LLMemType mt(LLMemType::MTYPE_OBJECT); // Update the data counters if (mesgsys->getReceiveCompressedSize()) { @@ -4165,7 +4469,6 @@ void process_object_update(LLMessageSystem *mesgsys, void **user_data) void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data) { - LLMemType mt(LLMemType::MTYPE_OBJECT); // Update the data counters if (mesgsys->getReceiveCompressedSize()) { @@ -4182,7 +4485,6 @@ void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data) { - LLMemType mt(LLMemType::MTYPE_OBJECT); // Update the data counters if (mesgsys->getReceiveCompressedSize()) { @@ -4200,7 +4502,6 @@ void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data) void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_data) { - LLMemType mt(LLMemType::MTYPE_OBJECT); if (mesgsys->getReceiveCompressedSize()) { gObjectBits += mesgsys->getReceiveCompressedSize() * 8; @@ -4213,7 +4514,7 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_ gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED); } -static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects"); +static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Kill Objects"); void process_kill_object(LLMessageSystem *mesgsys, void **user_data) @@ -4246,8 +4547,6 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data) LL_DEBUGS("Messaging") << "Kill message for local " << local_id << LL_ENDL; } - LLSelectMgr::getInstance()->removeObjectFromSelections(id); - // ...don't kill the avatar if (!(id == gAgentID)) { @@ -4270,6 +4569,12 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data) gObjectList.mNumUnknownKills++; } } + + // We should remove the object from selection after it is marked dead by gObjectList to make LLToolGrab, + // which is using the object, release the mouse capture correctly when the object dies. + // See LLToolGrab::handleHoverActive() and LLToolGrab::handleHoverNonPhysical(). + LLSelectMgr::getInstance()->removeObjectFromSelections(id); + } } @@ -4579,6 +4884,18 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data) case LL_SIM_STAT_IOPUMPTIME: LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value); break; + case LL_SIM_STAT_PCTSCRIPTSRUN: + LLViewerStats::getInstance()->mSimPctScriptsRun.addValue(stat_value); + break; + case LL_SIM_STAT_SIMAISTEPTIMEMS: + LLViewerStats::getInstance()->mSimSimAIStepMsec.addValue(stat_value); + break; + case LL_SIM_STAT_SKIPPEDAISILSTEPS_PS: + LLViewerStats::getInstance()->mSimSimSkippedSilhouetteSteps.addValue(stat_value); + break; + case LL_SIM_STAT_PCTSTEPPEDCHARACTERS: + LLViewerStats::getInstance()->mSimSimPctSteppedCharacters.addValue(stat_value); + break; default: // Used to be a commented out warning. LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL; @@ -4688,7 +5005,7 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data) LLViewerObject* object = gObjectList.findObject(object_id); if (object) { - object->mFlags |= FLAGS_ANIM_SOURCE; + object->setFlagsWithoutUpdate(FLAGS_ANIM_SOURCE, TRUE); BOOL anim_found = FALSE; LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.find(object_id); @@ -4835,7 +5152,7 @@ void process_set_follow_cam_properties(LLMessageSystem *mesgsys, void **user_dat LLViewerObject* objectp = gObjectList.findObject(source_id); if (objectp) { - objectp->mFlags |= FLAGS_CAMERA_SOURCE; + objectp->setFlagsWithoutUpdate(FLAGS_CAMERA_SOURCE, TRUE); } S32 num_objects = mesgsys->getNumberOfBlocks("CameraProperty"); @@ -5203,6 +5520,7 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) BOOL is_dest_group = FALSE; S32 amount = 0; std::string item_description; + BOOL success = FALSE; msg->getS32("TransactionInfo", "TransactionType", transaction_type); msg->getUUID("TransactionInfo", "SourceID", source_id); @@ -5211,6 +5529,7 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) msg->getBOOL("TransactionInfo", "IsDestGroup", is_dest_group); msg->getS32("TransactionInfo", "Amount", amount); msg->getString("TransactionInfo", "ItemDescription", item_description); + msg->getBOOL("MoneyData", "TransactionSuccess", success); LL_INFOS("Money") << "MoneyBalanceReply source " << source_id << " dest " << dest_id << " type " << transaction_type @@ -5272,28 +5591,32 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) { if (dest_id.notNull()) { - message = LLTrans::getString("you_paid_ldollars", args); + message = success ? LLTrans::getString("you_paid_ldollars", args) : + LLTrans::getString("you_paid_failure_ldollars", args); } else { // transaction fee to the system, eg, to create a group - message = LLTrans::getString("you_paid_ldollars_no_name", args); + message = success ? LLTrans::getString("you_paid_ldollars_no_name", args) : + LLTrans::getString("you_paid_failure_ldollars_no_name", args); } } else { if (dest_id.notNull()) { - message = LLTrans::getString("you_paid_ldollars_no_reason", args); + message = success ? LLTrans::getString("you_paid_ldollars_no_reason", args) : + LLTrans::getString("you_paid_failure_ldollars_no_reason", args); } else { // no target, no reason, you just paid money - message = LLTrans::getString("you_paid_ldollars_no_info", args); + message = success ? LLTrans::getString("you_paid_ldollars_no_info", args) : + LLTrans::getString("you_paid_failure_ldollars_no_info", args); } } final_args["MESSAGE"] = message; - notification = "PaymentSent"; + notification = success ? "PaymentSent" : "PaymentFailure"; } else { // ...someone paid you @@ -5324,31 +5647,41 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) _1, _2, _3, notification, final_args, payload)); } - else { - LLAvatarNameCache::get(name_id, - boost::bind(&money_balance_avatar_notify, - _1, _2, - notification, final_args, payload)); + else + { + LLAvatarNameCache::get(name_id, boost::bind(&money_balance_avatar_notify, _1, _2, notification, final_args, payload)); } } +bool handle_prompt_for_maturity_level_change_callback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + // set the preference to the maturity of the region we're calling + U8 preferredMaturity = static_cast<U8>(notification["payload"]["_region_access"].asInteger()); + gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity)); + } -bool handle_special_notification_callback(const LLSD& notification, const LLSD& response) + return false; +} + +bool handle_prompt_for_maturity_level_change_and_reteleport_callback(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (0 == option) { // set the preference to the maturity of the region we're calling - int preferredMaturity = notification["payload"]["_region_access"].asInteger(); - gSavedSettings.setU32("PreferredMaturity", preferredMaturity); - gAgent.sendMaturityPreferenceToServer(preferredMaturity); - - // notify user that the maturity preference has been changed - LLSD args; - args["RATING"] = LLViewerRegion::accessToString(preferredMaturity); - LLNotificationsUtil::add("PreferredMaturityChanged", args); + U8 preferredMaturity = static_cast<U8>(notification["payload"]["_region_access"].asInteger()); + gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity)); + gAgent.setMaturityRatingChangeDuringTeleport(preferredMaturity); + gAgent.restartFailedTeleportRequest(); + } + else + { + gAgent.clearTeleportRequest(); } return false; @@ -5357,39 +5690,148 @@ bool handle_special_notification_callback(const LLSD& notification, const LLSD& // some of the server notifications need special handling. This is where we do that. bool handle_special_notification(std::string notificationID, LLSD& llsdBlock) { - int regionAccess = llsdBlock["_region_access"].asInteger(); - llsdBlock["REGIONMATURITY"] = LLViewerRegion::accessToString(regionAccess); + U8 regionAccess = static_cast<U8>(llsdBlock["_region_access"].asInteger()); + std::string regionMaturity = LLViewerRegion::accessToString(regionAccess); + LLStringUtil::toLower(regionMaturity); + llsdBlock["REGIONMATURITY"] = regionMaturity; - // we're going to throw the LLSD in there in case anyone ever wants to use it - LLNotificationsUtil::add(notificationID+"_Notify", llsdBlock); + bool returnValue = false; + LLNotificationPtr maturityLevelNotification; + std::string notifySuffix = "_Notify"; + if (regionAccess == SIM_ACCESS_MATURE) + { + if (gAgent.isTeen()) + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; + } + else if (gAgent.prefersPG()) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock); + returnValue = true; + } + } + else if (regionAccess == SIM_ACCESS_ADULT) + { + if (!gAgent.isAdult()) + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; + } + else if (gAgent.prefersPG() || gAgent.prefersMature()) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock); + returnValue = true; + } + } + + if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored()) + { + // Given a simple notification if no maturityLevelNotification is set or it is ignore + LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock); + } + + return returnValue; +} + +// some of the server notifications need special handling. This is where we do that. +bool handle_teleport_access_blocked(LLSD& llsdBlock) +{ + std::string notificationID("TeleportEntryAccessBlocked"); + U8 regionAccess = static_cast<U8>(llsdBlock["_region_access"].asInteger()); + std::string regionMaturity = LLViewerRegion::accessToString(regionAccess); + LLStringUtil::toLower(regionMaturity); + llsdBlock["REGIONMATURITY"] = regionMaturity; + bool returnValue = false; + LLNotificationPtr maturityLevelNotification; + std::string notifySuffix = "_Notify"; if (regionAccess == SIM_ACCESS_MATURE) { if (gAgent.isTeen()) { - LLNotificationsUtil::add(notificationID+"_KB", llsdBlock); - return true; + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; } else if (gAgent.prefersPG()) { - LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback); - return true; + if (gAgent.hasRestartableFailedTeleportRequest()) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback); + returnValue = true; + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; } } else if (regionAccess == SIM_ACCESS_ADULT) { if (!gAgent.isAdult()) { - LLNotificationsUtil::add(notificationID+"_KB", llsdBlock); - return true; + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; } else if (gAgent.prefersPG() || gAgent.prefersMature()) { - LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback); - return true; + if (gAgent.hasRestartableFailedTeleportRequest()) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback); + returnValue = true; + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } } + + if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored()) + { + // Given a simple notification if no maturityLevelNotification is set or it is ignore + LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock); } - return false; + + return returnValue; } bool attempt_standard_notification(LLMessageSystem* msgsystem) @@ -5433,16 +5875,20 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem) RegionEntryAccessBlocked RegionEntryAccessBlocked_Notify + RegionEntryAccessBlocked_NotifyAdultsOnly RegionEntryAccessBlocked_Change - RegionEntryAccessBlocked_KB + RegionEntryAccessBlocked_AdultsOnlyContent + RegionEntryAccessBlocked_ChangeAndReTeleport LandClaimAccessBlocked LandClaimAccessBlocked_Notify + LandClaimAccessBlocked_NotifyAdultsOnly LandClaimAccessBlocked_Change - LandClaimAccessBlocked_KB + LandClaimAccessBlocked_AdultsOnlyContent LandBuyAccessBlocked LandBuyAccessBlocked_Notify + LandBuyAccessBlocked_NotifyAdultsOnly LandBuyAccessBlocked_Change - LandBuyAccessBlocked_KB + LandBuyAccessBlocked_AdultsOnlyContent -----------------------------------------------------------------------*/ if (handle_special_notification(notificationID, llsdBlock)) @@ -5494,6 +5940,30 @@ void process_alert_message(LLMessageSystem *msgsystem, void **user_data) } } +bool handle_not_age_verified_alert(const std::string &pAlertName) +{ + LLNotificationPtr notification = LLNotificationsUtil::add(pAlertName); + if ((notification == NULL) || notification->isIgnored()) + { + LLNotificationsUtil::add(pAlertName + "_Notify"); + } + + return true; +} + +bool handle_special_alerts(const std::string &pAlertName) +{ + bool isHandled = false; + + if (LLStringUtil::compareStrings(pAlertName, "NotAgeVerified") == 0) + { + + isHandled = handle_not_age_verified_alert(pAlertName); + } + + return isHandled; +} + void process_alert_core(const std::string& message, BOOL modal) { // HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml @@ -5517,8 +5987,11 @@ void process_alert_core(const std::string& message, BOOL modal) // Allow the server to spawn a named alert so that server alerts can be // translated out of English. std::string alert_name(message.substr(ALERT_PREFIX.length())); + if (!handle_special_alerts(alert_name)) + { LLNotificationsUtil::add(alert_name); } + } else if (message.find(NOTIFY_PREFIX) == 0) { // Allow the server to spawn a named notification so that server notifications can be @@ -5783,6 +6256,16 @@ bool script_question_cb(const LLSD& notification, const LLSD& response) S32 orig = notification["payload"]["questions"].asInteger(); S32 new_questions = orig; + if (response["Details"]) + { + // respawn notification... + LLNotificationsUtil::add(notification["name"], notification["substitutions"], notification["payload"]); + + // ...with description on top + LLNotificationsUtil::add("DebitPermissionDetails"); + return false; + } + // check whether permissions were granted or denied BOOL allowed = TRUE; // the "yes/accept" button is the first button in the template, making it button 0 @@ -5840,14 +6323,6 @@ bool script_question_cb(const LLSD& notification, const LLSD& response) gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(item_id)); } - if (response["Details"]) - { - // respawn notification... - LLNotificationsUtil::add(notification["name"], notification["substitutions"], notification["payload"]); - - // ...with description on top - LLNotificationsUtil::add("DebitPermissionDetails"); - } return false; } static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb); @@ -5917,16 +6392,21 @@ void process_script_question(LLMessageSystem *msg, void **user_data) args["OBJECTNAME"] = object_name; args["NAME"] = LLCacheName::cleanFullName(owner_name); + BOOL has_not_only_debit = questions ^ LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_DEBIT]; // check the received permission flags against each permission for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++) { if (questions & LSCRIPTRunTimePermissionBits[i]) { count++; - script_question += " " + LLTrans::getString(SCRIPT_QUESTIONS[i]) + "\n"; // check whether permission question should cause special caution dialog caution |= (SCRIPT_QUESTION_IS_CAUTION[i]); + + if (("ScriptTakeMoney" == SCRIPT_QUESTIONS[i]) && has_not_only_debit) + continue; + + script_question += " " + LLTrans::getString(SCRIPT_QUESTIONS[i]) + "\n"; } } args["QUESTIONS"] = script_question; @@ -5942,6 +6422,10 @@ void process_script_question(LLMessageSystem *msg, void **user_data) // check whether cautions are even enabled or not if (gSavedSettings.getBOOL("PermissionsCautionEnabled")) { + if (caution) + { + args["FOOTERTEXT"] = (count > 1) ? LLTrans::getString("AdditionalPermissionsRequestHeader") + "\n\n" + script_question : ""; + } // display the caution permissions prompt LLNotificationsUtil::add(caution ? "ScriptQuestionCaution" : "ScriptQuestion", args, payload); } @@ -6092,6 +6576,9 @@ void process_teleport_failed(LLMessageSystem *msg, void**) std::string big_reason; LLSD args; + // Let the interested parties know that teleport failed. + LLViewerParcelMgr::getInstance()->onTeleportFailed(); + // if we have additional alert data if (msg->has(_PREHASH_AlertInfo) && msg->getSizeFast(_PREHASH_AlertInfo, _PREHASH_Message) > 0) { @@ -6121,7 +6608,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**) else { // change notification name in this special case - if (handle_special_notification("RegionEntryAccessBlocked", llsd_block)) + if (handle_teleport_access_blocked(llsd_block)) { if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE ) { @@ -6150,9 +6637,6 @@ void process_teleport_failed(LLMessageSystem *msg, void**) LLNotificationsUtil::add("CouldNotTeleportReason", args); - // Let the interested parties know that teleport failed. - LLViewerParcelMgr::getInstance()->onTeleportFailed(); - if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE ) { gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); @@ -6341,7 +6825,6 @@ bool handle_lure_callback(const LLSD& notification, const LLSD& response) //*TODO please rewrite all keys to the same case, lower or upper payload["from_id"] = target_id; - payload["SUPPRESS_TOAST"] = true; LLNotificationsUtil::add("TeleportOfferSent", args, payload); // Add the recepient to the recent people list. @@ -6462,7 +6945,7 @@ void process_user_info_reply(LLMessageSystem* msg, void**) std::string dir_visibility; msg->getString( "UserData", "DirectoryVisibility", dir_visibility); - LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, email); + LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email); LLFloaterSnapshot::setAgentEmail(email); } @@ -6790,12 +7273,14 @@ void process_covenant_reply(LLMessageSystem* msg, void**) LLPanelEstateCovenant::updateEstateName(estate_name); LLPanelLandCovenant::updateEstateName(estate_name); + LLPanelEstateInfo::updateEstateName(estate_name); LLFloaterBuyLand::updateEstateName(estate_name); std::string owner_name = LLSLURL("agent", estate_owner_id, "inspect").getSLURLString(); LLPanelEstateCovenant::updateEstateOwnerName(owner_name); LLPanelLandCovenant::updateEstateOwnerName(owner_name); + LLPanelEstateInfo::updateEstateOwnerName(owner_name); LLFloaterBuyLand::updateEstateOwnerName(owner_name); LLPanelPlaceProfile* panel = LLFloaterSidePanelContainer::getPanel<LLPanelPlaceProfile>("places", "panel_place_profile"); diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index d8acd99953..3237f3fbdd 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -35,6 +35,10 @@ #include "message.h" #include "stdenums.h" #include "llnotifications.h" +#include "llextendedstatus.h" + +#include <boost/function.hpp> +#include <boost/signals2.hpp> // // Forward declarations @@ -63,7 +67,6 @@ enum InventoryOfferResponse BOOL can_afford_transaction(S32 cost); void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group = FALSE, S32 trx_type = TRANS_GIFT, const std::string& desc = LLStringUtil::null); -void busy_message (LLMessageSystem* msg, LLUUID from_id); void process_logout_reply(LLMessageSystem* msg, void**); void process_layer_data(LLMessageSystem *mesgsys, void **user_data); @@ -149,6 +152,8 @@ void send_group_notice(const LLUUID& group_id, const std::string& message, const LLInventoryItem* item); +void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id = LLUUID::null); + void handle_lure(const LLUUID& invitee); void handle_lure(const uuid_vec_t& ids); @@ -204,6 +209,15 @@ bool highlight_offered_object(const LLUUID& obj_id); void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder_uuid); void set_dad_inbox_object(const LLUUID& object_id); +class LLViewerMessage : public LLSingleton<LLViewerMessage> +{ +public: + typedef boost::function<void()> teleport_started_callback_t; + typedef boost::signals2::signal<void()> teleport_started_signal_t; + boost::signals2::connection setTeleportStartedCallback(teleport_started_callback_t cb); + + teleport_started_signal_t mTeleportStartedSignal; +}; class LLOfferInfo : public LLNotificationResponderInterface { @@ -215,6 +229,7 @@ public: void forceResponse(InventoryOfferResponse response); + static std::string mResponderType; EInstantMessage mIM; LLUUID mFromID; BOOL mFromGroup; @@ -252,5 +267,3 @@ private: void process_feature_disabled_message(LLMessageSystem* msg, void**); #endif - - diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index ef5c65eb87..97f4c3e5fe 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llviewernetwork.cpp * @author James Cook, Richard Nelson * @brief Networking constants and globals for viewer. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,13 +34,39 @@ #include "lltrans.h" #include "llweb.h" - -const char* DEFAULT_LOGIN_PAGE = "http://viewer-login.agni.lindenlab.com/"; -const char* SYSTEM_GRID_SLURL_BASE = "secondlife://%s/secondlife/"; -const char* MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/"; -const char* SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app"; +/// key used to store the grid, and the name attribute in the grid data +const std::string GRID_VALUE = "keyname"; +/// the value displayed in the grid selector menu, and other human-oriented text +const std::string GRID_LABEL_VALUE = "label"; +/// the value used on the --grid command line argument +const std::string GRID_ID_VALUE = "grid_login_id"; +/// the url for the login cgi script +const std::string GRID_LOGIN_URI_VALUE = "login_uri"; +/// +const std::string GRID_HELPER_URI_VALUE = "helper_uri"; +/// the splash page url +const std::string GRID_LOGIN_PAGE_VALUE = "login_page"; +/// internal data on system grids +const std::string GRID_IS_SYSTEM_GRID_VALUE = "system_grid"; +/// whether this is single or double names +const std::string GRID_LOGIN_IDENTIFIER_TYPES = "login_identifier_types"; + +// defines slurl formats associated with various grids. +// we need to continue to support existing forms, as slurls +// are shared between viewers that may not understand newer +// forms. +const std::string GRID_SLURL_BASE = "slurl_base"; +const std::string GRID_APP_SLURL_BASE = "app_slurl_base"; + +const std::string DEFAULT_LOGIN_PAGE = "http://viewer-login.agni.lindenlab.com/"; + +const std::string MAIN_GRID_LOGIN_URI = "https://login.agni.lindenlab.com/cgi-bin/login.cgi"; + +const std::string MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/"; +const std::string SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app"; +const char* SYSTEM_GRID_SLURL_BASE = "secondlife://%s/secondlife/"; const char* DEFAULT_SLURL_BASE = "https://%s/region/"; const char* DEFAULT_APP_SLURL_BASE = "x-grid-location-info://%s/app"; @@ -54,14 +80,17 @@ LLGridManager::LLGridManager() // an attacker. Don't want someone snagging a password. std::string grid_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "grids.xml"); + LL_DEBUGS("GridManager")<<LL_ENDL; + initialize(grid_file); - + } LLGridManager::LLGridManager(const std::string& grid_file) { // initialize with an explicity grid file for testing. + LL_DEBUGS("GridManager")<<LL_ENDL; initialize(grid_file); } @@ -74,183 +103,83 @@ LLGridManager::LLGridManager(const std::string& grid_file) // // LLGridManager::initialze - initialize the list of known grids based // on the fixed list of linden grids (fixed for security reasons) -// the grids.xml file -// and the command line. +// and the grids.xml file void LLGridManager::initialize(const std::string& grid_file) { // default grid list. // Don't move to a modifiable file for security reasons, mGrid.clear() ; + // set to undefined mGridList = LLSD(); mGridFile = grid_file; // as we don't want an attacker to override our grid list // to point the default grid to an invalid grid - addSystemGrid("None", "", "", "", DEFAULT_LOGIN_PAGE); - - - - addSystemGrid("Agni", - MAINGRID, - "https://login.agni.lindenlab.com/cgi-bin/login.cgi", - "https://secondlife.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Aditi", - "util.aditi.lindenlab.com", - "https://login.aditi.lindenlab.com/cgi-bin/login.cgi", + addSystemGrid("Second Life Main Grid (Agni)", + MAINGRID, + MAIN_GRID_LOGIN_URI, + "https://secondlife.com/helpers/", + DEFAULT_LOGIN_PAGE, + "Agni"); + addSystemGrid("Second Life Beta Test Grid (Aditi)", + "util.aditi.lindenlab.com", + "https://login.aditi.lindenlab.com/cgi-bin/login.cgi", "http://aditi-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Aruna", - "util.aruna.lindenlab.com", - "https://login.aruna.lindenlab.com/cgi-bin/login.cgi", - "http://aruna-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Bharati", - "util.bharati.lindenlab.com", - "https://login.bharati.lindenlab.com/cgi-bin/login.cgi", - "http://bharati-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Chandra", - "util.chandra.lindenlab.com", - "https://login.chandra.lindenlab.com/cgi-bin/login.cgi", - "http://chandra-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Damballah", - "util.damballah.lindenlab.com", - "https://login.damballah.lindenlab.com/cgi-bin/login.cgi", - "http://damballah-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Danu", - "util.danu.lindenlab.com", - "https://login.danu.lindenlab.com/cgi-bin/login.cgi", - "http://danu-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Durga", - "util.durga.lindenlab.com", - "https://login.durga.lindenlab.com/cgi-bin/login.cgi", - "http://durga-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Ganga", - "util.ganga.lindenlab.com", - "https://login.ganga.lindenlab.com/cgi-bin/login.cgi", - "http://ganga-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Mitra", - "util.mitra.lindenlab.com", - "https://login.mitra.lindenlab.com/cgi-bin/login.cgi", - "http://mitra-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Mohini", - "util.mohini.lindenlab.com", - "https://login.mohini.lindenlab.com/cgi-bin/login.cgi", - "http://mohini-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Nandi", - "util.nandi.lindenlab.com", - "https://login.nandi.lindenlab.com/cgi-bin/login.cgi", - "http://nandi-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Parvati", - "util.parvati.lindenlab.com", - "https://login.parvati.lindenlab.com/cgi-bin/login.cgi", - "http://parvati-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Radha", - "util.radha.lindenlab.com", - "https://login.radha.lindenlab.com/cgi-bin/login.cgi", - "http://radha-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Ravi", - "util.ravi.lindenlab.com", - "https://login.ravi.lindenlab.com/cgi-bin/login.cgi", - "http://ravi-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Siva", - "util.siva.lindenlab.com", - "https://login.siva.lindenlab.com/cgi-bin/login.cgi", - "http://siva-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Shakti", - "util.shakti.lindenlab.com", - "https://login.shakti.lindenlab.com/cgi-bin/login.cgi", - "http://shakti-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Soma", - "util.soma.lindenlab.com", - "https://login.soma.lindenlab.com/cgi-bin/login.cgi", - "http://soma-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Uma", - "util.uma.lindenlab.com", - "https://login.uma.lindenlab.com/cgi-bin/login.cgi", - "http://uma-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Vaak", - "util.vaak.lindenlab.com", - "https://login.vaak.lindenlab.com/cgi-bin/login.cgi", - "http://vaak-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Yami", - "util.yami.lindenlab.com", - "https://login.yami.lindenlab.com/cgi-bin/login.cgi", - "http://yami-secondlife.webdev.lindenlab.com/helpers/", - DEFAULT_LOGIN_PAGE); - addSystemGrid("Local (Linden)", - "localhost", - "https://login.dmz.lindenlab.com/cgi-bin/login.cgi", - "", - DEFAULT_LOGIN_PAGE); - - + DEFAULT_LOGIN_PAGE, + "Aditi"); + LLSD other_grids; llifstream llsd_xml; if (!grid_file.empty()) { + LL_INFOS("GridManager")<<"Grid configuration file '"<<grid_file<<"'"<<LL_ENDL; llsd_xml.open( grid_file.c_str(), std::ios::in | std::ios::binary ); // parse through the gridfile, inserting grids into the list unless - // they overwrite a linden grid. - if( llsd_xml.is_open()) + // they overwrite an existing grid. + if( llsd_xml.is_open()) { LLSDSerialize::fromXMLDocument( other_grids, llsd_xml ); if(other_grids.isMap()) { - for(LLSD::map_iterator grid_itr = other_grids.beginMap(); + for(LLSD::map_iterator grid_itr = other_grids.beginMap(); grid_itr != other_grids.endMap(); ++grid_itr) { LLSD::String key_name = grid_itr->first; LLSD grid = grid_itr->second; - // TODO: Make sure gridfile specified label is not - // a system grid label - LL_DEBUGS("GridManager") << "reading: " << key_name << LL_ENDL; - if (mGridList.has(key_name) && - mGridList[key_name].has(GRID_IS_SYSTEM_GRID_VALUE)) + + std::string existingGrid = getGrid(grid); + if (mGridList.has(key_name) || !existingGrid.empty()) { - LL_DEBUGS("GridManager") << "Cannot override grid " << key_name << " as it's a system grid" << LL_ENDL; - // If the system grid does exist in the grids file, and it's marked as a favorite, set it as a favorite. - if(grid_itr->second.has(GRID_IS_FAVORITE_VALUE) && grid_itr->second[GRID_IS_FAVORITE_VALUE].asBoolean() ) - { - mGridList[key_name][GRID_IS_FAVORITE_VALUE] = TRUE; - } + LL_WARNS("GridManager") << "Cannot override existing grid '" << key_name << "'; ignoring definition from '"<<grid_file<<"'" << LL_ENDL; + } + else if ( addGrid(grid) ) + { + LL_INFOS("GridManager") << "added grid '"<<key_name<<"'"<<LL_ENDL; } else { - try - { - addGrid(grid); - LL_DEBUGS("GridManager") << "Added grid: " << key_name << LL_ENDL; - } - catch (...) - { - } + LL_WARNS("GridManager") << "failed to add invalid grid '"<<key_name<<"'"<<LL_ENDL; } } llsd_xml.close(); - } - } + } + else + { + LL_WARNS("GridManager")<<"Failed to parse grid configuration '"<<grid_file<<"'"<<LL_ENDL; + } + } + else + { + LL_WARNS("GridManager")<<"Failed to open grid configuration '"<<grid_file<<"'"<<LL_ENDL; + } + } + else + { + LL_DEBUGS("GridManager")<<"no grid file specified"<<LL_ENDL; } - + // load a grid from the command line. // if the actual grid name is specified from the command line, // set it as the 'selected' grid. @@ -259,50 +188,38 @@ void LLGridManager::initialize(const std::string& grid_file) { // try to find the grid assuming the command line parameter is // the case-insensitive 'label' of the grid. ie 'Agni' - mGrid = getGridByLabel(cmd_line_grid); + mGrid = getGrid(cmd_line_grid); if(mGrid.empty()) { - // if we couldn't find it, assume the - // requested grid is the actual grid 'name' or index, - // which would be the dns name of the grid (for non - // linden hosted grids) - // If the grid isn't there, that's ok, as it will be - // automatically added later. - mGrid = cmd_line_grid; + LL_WARNS("GridManager")<<"Unknown grid '"<<cmd_line_grid<<"'"<<LL_ENDL; + } + else + { + LL_INFOS("GridManager")<<"Command line specified '"<<cmd_line_grid<<"': "<<mGrid<<LL_ENDL; } - } else { // if a grid was not passed in via the command line, grab it from the CurrentGrid setting. // if there's no current grid, that's ok as it'll be either set by the value passed // in via the login uri if that's specified, or will default to maingrid - mGrid = gSavedSettings.getString("CurrentGrid"); + std::string last_grid = gSavedSettings.getString("CurrentGrid"); + if ( ! getGrid(last_grid).empty() ) + { + LL_INFOS("GridManager")<<"Using last grid: "<<last_grid<<LL_ENDL; + mGrid = last_grid; + } + else + { + LL_INFOS("GridManager")<<"Last grid '"<<last_grid<<"' not configured"<<LL_ENDL; + } } - + if(mGrid.empty()) { // no grid was specified so default to maingrid - LL_DEBUGS("GridManager") << "Setting grid to MAINGRID as no grid has been specified " << LL_ENDL; + LL_INFOS("GridManager") << "Default grid to "<<MAINGRID<< LL_ENDL; mGrid = MAINGRID; - - } - - // generate a 'grid list' entry for any command line parameter overrides - // or setting overides that we'll add to the grid list or override - // any grid list entries with. - LLSD grid = LLSD::emptyMap(); - - if(mGridList.has(mGrid)) - { - grid = mGridList[mGrid]; - } - else - { - grid[GRID_VALUE] = mGrid; - // add the grid with the additional values, or update the - // existing grid if it exists with the given values - addGrid(grid); } LLControlVariablePtr grid_control = gSavedSettings.getControl("CurrentGrid"); @@ -314,115 +231,105 @@ void LLGridManager::initialize(const std::string& grid_file) // since above only triggers on changes, trigger the callback manually to initialize state updateIsInProductionGrid(); - LL_DEBUGS("GridManager") << "Selected grid is " << mGrid << LL_ENDL; setGridChoice(mGrid); - if(mGridList[mGrid][GRID_LOGIN_URI_VALUE].isArray()) - { - llinfos << "is array" << llendl; - } } LLGridManager::~LLGridManager() { - saveFavorites(); } -void LLGridManager::getGridInfo(const std::string &grid, LLSD& grid_info) -{ - - grid_info = mGridList[grid]; - - // override any grid data with the command line info. - - LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI"); - if (cmd_line_login_uri.isString()) - { - grid_info[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray(); - grid_info[GRID_LOGIN_URI_VALUE].append(cmd_line_login_uri); - } - - // override the helper uri if it was passed in - std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI"); - if(!cmd_line_helper_uri.empty()) - { - grid_info[GRID_HELPER_URI_VALUE] = cmd_line_helper_uri; - } - - // override the login page if it was passed in - std::string cmd_line_login_page = gSavedSettings.getString("LoginPage"); - if(!cmd_line_login_page.empty()) - { - grid_info[GRID_LOGIN_PAGE_VALUE] = cmd_line_login_page; - } -} - - // // LLGridManager::addGrid - add a grid to the grid list, populating the needed values // if they're not populated yet. // -void LLGridManager::addGrid(LLSD& grid_data) +bool LLGridManager::addGrid(LLSD& grid_data) { + bool added = false; if (grid_data.isMap() && grid_data.has(GRID_VALUE)) { - std::string grid = utf8str_tolower(grid_data[GRID_VALUE]); + std::string grid = utf8str_tolower(grid_data[GRID_VALUE].asString()); - // grid should be in the form of a dns address - if (!grid.empty() && - grid.find_first_not_of("abcdefghijklmnopqrstuvwxyz1234567890-_. ") != std::string::npos) - { - printf("grid name: %s", grid.c_str()); - throw LLInvalidGridName(grid); - } - - // populate the other values if they don't exist - if (!grid_data.has(GRID_LABEL_VALUE)) - { - grid_data[GRID_LABEL_VALUE] = grid; - } - if (!grid_data.has(GRID_ID_VALUE)) - { - grid_data[GRID_ID_VALUE] = grid; - } - - // if the grid data doesn't include any of the URIs, then - // generate them from the grid, which should be a dns address - if (!grid_data.has(GRID_LOGIN_URI_VALUE)) + if ( getGrid(grid_data[GRID_VALUE]).empty() && getGrid(grid).empty() ) { - grid_data[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray(); - grid_data[GRID_LOGIN_URI_VALUE].append(std::string("https://") + - grid + "/cgi-bin/login.cgi"); - } - // Populate to the default values - if (!grid_data.has(GRID_LOGIN_PAGE_VALUE)) - { - grid_data[GRID_LOGIN_PAGE_VALUE] = std::string("http://") + grid + "/app/login/"; - } - if (!grid_data.has(GRID_HELPER_URI_VALUE)) - { - grid_data[GRID_HELPER_URI_VALUE] = std::string("https://") + grid + "/helpers/"; + std::string grid_id = grid_data.has(GRID_ID_VALUE) ? grid_data[GRID_ID_VALUE].asString() : ""; + if ( getGrid(grid_id).empty() ) + { + // populate the other values if they don't exist + if (!grid_data.has(GRID_LABEL_VALUE)) + { + grid_data[GRID_LABEL_VALUE] = grid; + } + if (!grid_data.has(GRID_ID_VALUE)) + { + grid_data[GRID_ID_VALUE] = grid; + } + + // if the grid data doesn't include any of the URIs, then + // generate them from the grid, which should be a dns address + if (!grid_data.has(GRID_LOGIN_URI_VALUE)) + { + grid_data[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray(); + grid_data[GRID_LOGIN_URI_VALUE].append(std::string("https://") + + grid + "/cgi-bin/login.cgi"); + } + // Populate to the default values + if (!grid_data.has(GRID_LOGIN_PAGE_VALUE)) + { + grid_data[GRID_LOGIN_PAGE_VALUE] = std::string("http://") + grid + "/app/login/"; + } + if (!grid_data.has(GRID_HELPER_URI_VALUE)) + { + grid_data[GRID_HELPER_URI_VALUE] = std::string("https://") + grid + "/helpers/"; + } + + if (!grid_data.has(GRID_LOGIN_IDENTIFIER_TYPES)) + { + // non system grids and grids that haven't already been configured with values + // get both types of credentials. + grid_data[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray(); + grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT); + grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_ACCOUNT); + } + + LL_DEBUGS("GridManager") <<grid<<"\n" + <<" id: "<<grid_data[GRID_ID_VALUE].asString()<<"\n" + <<" label: "<<grid_data[GRID_LABEL_VALUE].asString()<<"\n" + <<" login page: "<<grid_data[GRID_LOGIN_PAGE_VALUE].asString()<<"\n" + <<" helper page: "<<grid_data[GRID_HELPER_URI_VALUE].asString()<<"\n"; + /* still in LL_DEBUGS */ + for (LLSD::array_const_iterator login_uris = grid_data[GRID_LOGIN_URI_VALUE].beginArray(); + login_uris != grid_data[GRID_LOGIN_URI_VALUE].endArray(); + login_uris++) + { + LL_CONT << " login uri: "<<login_uris->asString()<<"\n"; + } + LL_CONT << LL_ENDL; + mGridList[grid] = grid_data; + added = true; + } + else + { + LL_WARNS("GridManager")<<"duplicate grid id'"<<grid_id<<"' ignored"<<LL_ENDL; + } } - - if (!grid_data.has(GRID_LOGIN_IDENTIFIER_TYPES)) + else { - // non system grids and grids that haven't already been configured with values - // get both types of credentials. - grid_data[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray(); - grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT); - grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_ACCOUNT); + LL_WARNS("GridManager")<<"duplicate grid name '"<<grid<<"' ignored"<<LL_ENDL; } - - LL_DEBUGS("GridManager") << "ADDING: " << grid << LL_ENDL; - mGridList[grid] = grid_data; } + else + { + LL_WARNS("GridManager")<<"invalid grid definition ignored"<<LL_ENDL; + } + return added; } // // LLGridManager::addSystemGrid - helper for adding a system grid. -void LLGridManager::addSystemGrid(const std::string& label, - const std::string& name, - const std::string& login, +void LLGridManager::addSystemGrid(const std::string& label, + const std::string& name, + const std::string& login_uri, const std::string& helper, const std::string& login_page, const std::string& login_id) @@ -432,12 +339,12 @@ void LLGridManager::addSystemGrid(const std::string& label, grid[GRID_LABEL_VALUE] = label; grid[GRID_HELPER_URI_VALUE] = helper; grid[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray(); - grid[GRID_LOGIN_URI_VALUE].append(login); + grid[GRID_LOGIN_URI_VALUE].append(login_uri); grid[GRID_LOGIN_PAGE_VALUE] = login_page; - grid[GRID_IS_SYSTEM_GRID_VALUE] = TRUE; + grid[GRID_IS_SYSTEM_GRID_VALUE] = true; grid[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray(); grid[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT); - + grid[GRID_APP_SLURL_BASE] = SYSTEM_GRID_APP_SLURL_BASE; if (login_id.empty()) { @@ -447,124 +354,187 @@ void LLGridManager::addSystemGrid(const std::string& label, { grid[GRID_ID_VALUE] = login_id; } - - // only add the system grids beyond agni to the visible list - // if we're building a debug version. + if (name == std::string(MAINGRID)) { - grid[GRID_SLURL_BASE] = MAIN_GRID_SLURL_BASE; - grid[GRID_IS_FAVORITE_VALUE] = TRUE; + grid[GRID_SLURL_BASE] = MAIN_GRID_SLURL_BASE; } else { - grid[GRID_SLURL_BASE] = llformat(SYSTEM_GRID_SLURL_BASE, label.c_str()); + grid[GRID_SLURL_BASE] = llformat(SYSTEM_GRID_SLURL_BASE, grid[GRID_ID_VALUE].asString().c_str()); } + addGrid(grid); } // return a list of grid name -> grid label mappings for UI purposes -std::map<std::string, std::string> LLGridManager::getKnownGrids(bool favorite_only) +std::map<std::string, std::string> LLGridManager::getKnownGrids() { std::map<std::string, std::string> result; for(LLSD::map_iterator grid_iter = mGridList.beginMap(); grid_iter != mGridList.endMap(); - grid_iter++) + grid_iter++) { - if(!favorite_only || grid_iter->second.has(GRID_IS_FAVORITE_VALUE)) - { - result[grid_iter->first] = grid_iter->second[GRID_LABEL_VALUE].asString(); - } + result[grid_iter->first] = grid_iter->second[GRID_LABEL_VALUE].asString(); } return result; } - void LLGridManager::setGridChoice(const std::string& grid) { // Set the grid choice based on a string. - // The string can be: - // - a grid label from the gGridInfo table - // - a hostname - // - an ip address - - // loop through. We could do just a hash lookup but we also want to match - // on label - std::string grid_name = grid; - if(!mGridList.has(grid_name)) + LL_DEBUGS("GridManager")<<"requested "<<grid<<LL_ENDL; + std::string grid_name = getGrid(grid); // resolved either the name or the id to the name + + if(!grid_name.empty()) { - // case insensitive - grid_name = getGridByLabel(grid); + LL_INFOS("GridManager")<<"setting "<<grid_name<<LL_ENDL; + mGrid = grid_name; + gSavedSettings.setString("CurrentGrid", grid_name); + + updateIsInProductionGrid(); } - - if(grid_name.empty()) + else { // the grid was not in the list of grids. - LLSD grid_data = LLSD::emptyMap(); - grid_data[GRID_VALUE] = grid; - addGrid(grid_data); + LL_WARNS("GridManager")<<"unknown grid "<<grid<<LL_ENDL; } - mGrid = grid; - gSavedSettings.setString("CurrentGrid", grid); - - updateIsInProductionGrid(); } -std::string LLGridManager::getGridByLabel( const std::string &grid_label, bool case_sensitive) +std::string LLGridManager::getGrid( const std::string &grid ) { - for(LLSD::map_iterator grid_iter = mGridList.beginMap(); - grid_iter != mGridList.endMap(); - grid_iter++) + std::string grid_name; + + if (mGridList.has(grid)) + { + // the grid was the long name, so we're good, return it + grid_name = grid; + } + else { - if (grid_iter->second.has(GRID_LABEL_VALUE)) + // search the grid list for a grid with a matching id + for(LLSD::map_iterator grid_iter = mGridList.beginMap(); + grid_name.empty() && grid_iter != mGridList.endMap(); + grid_iter++) { - if (0 == (case_sensitive?LLStringUtil::compareStrings(grid_label, grid_iter->second[GRID_LABEL_VALUE].asString()): - LLStringUtil::compareInsensitive(grid_label, grid_iter->second[GRID_LABEL_VALUE].asString()))) + if (grid_iter->second.has(GRID_ID_VALUE)) { - return grid_iter->first; + if (0 == (LLStringUtil::compareInsensitive(grid, + grid_iter->second[GRID_ID_VALUE].asString()))) + { + // found a matching label, return this name + grid_name = grid_iter->first; + } } } } - return std::string(); + return grid_name; } -void LLGridManager::getLoginURIs(std::vector<std::string>& uris) +std::string LLGridManager::getGridLabel(const std::string& grid) +{ + std::string grid_label; + std::string grid_name = getGrid(grid); + if (!grid.empty()) + { + grid_label = mGridList[grid_name][GRID_LABEL_VALUE].asString(); + } + else + { + LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL; + } + LL_DEBUGS("GridManager")<<"returning "<<grid_label<<LL_ENDL; + return grid_label; +} + +std::string LLGridManager::getGridId(const std::string& grid) +{ + std::string grid_id; + std::string grid_name = getGrid(grid); + if (!grid.empty()) + { + grid_id = mGridList[grid_name][GRID_ID_VALUE].asString(); + } + else + { + LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL; + } + LL_DEBUGS("GridManager")<<"returning "<<grid_id<<LL_ENDL; + return grid_id; +} + +void LLGridManager::getLoginURIs(const std::string& grid, std::vector<std::string>& uris) { uris.clear(); - LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI"); - if (cmd_line_login_uri.isString()) - { - uris.push_back(cmd_line_login_uri); - return; + std::string grid_name = getGrid(grid); + if (!grid_name.empty()) + { + for (LLSD::array_iterator llsd_uri = mGridList[grid_name][GRID_LOGIN_URI_VALUE].beginArray(); + llsd_uri != mGridList[grid_name][GRID_LOGIN_URI_VALUE].endArray(); + llsd_uri++) + { + uris.push_back(llsd_uri->asString()); + } } - for (LLSD::array_iterator llsd_uri = mGridList[mGrid][GRID_LOGIN_URI_VALUE].beginArray(); - llsd_uri != mGridList[mGrid][GRID_LOGIN_URI_VALUE].endArray(); - llsd_uri++) + else { - uris.push_back(llsd_uri->asString()); + LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL; } } -std::string LLGridManager::getHelperURI() +void LLGridManager::getLoginURIs(std::vector<std::string>& uris) { - std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI"); - if(!cmd_line_helper_uri.empty()) + getLoginURIs(mGrid, uris); +} + +std::string LLGridManager::getHelperURI(const std::string& grid) +{ + std::string helper_uri; + std::string grid_name = getGrid(grid); + if (!grid_name.empty()) { - return cmd_line_helper_uri; + helper_uri = mGridList[grid_name][GRID_HELPER_URI_VALUE].asString(); } - return mGridList[mGrid][GRID_HELPER_URI_VALUE]; + else + { + LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL; + } + + LL_DEBUGS("GridManager")<<"returning "<<helper_uri<<LL_ENDL; + return helper_uri; } -std::string LLGridManager::getLoginPage() +std::string LLGridManager::getLoginPage(const std::string& grid) { - // override the login page if it was passed in - std::string cmd_line_login_page = gSavedSettings.getString("LoginPage"); - if(!cmd_line_login_page.empty()) + std::string grid_login_page; + std::string grid_name = getGrid(grid); + if (!grid_name.empty()) + { + grid_login_page = mGridList[grid_name][GRID_LOGIN_PAGE_VALUE].asString(); + } + else { - return cmd_line_login_page; - } - - return mGridList[mGrid][GRID_LOGIN_PAGE_VALUE]; + LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL; + } + return grid_login_page; +} + +std::string LLGridManager::getLoginPage() +{ + std::string login_page = mGridList[mGrid][GRID_LOGIN_PAGE_VALUE].asString(); + LL_DEBUGS("GridManager")<<"returning "<<login_page<<LL_ENDL; + return login_page; +} + +void LLGridManager::getLoginIdentifierTypes(LLSD& idTypes) +{ + idTypes = mGridList[mGrid][GRID_LOGIN_IDENTIFIER_TYPES]; +} + +std::string LLGridManager::getGridLoginID() +{ + return mGridList[mGrid][GRID_ID_VALUE]; } void LLGridManager::updateIsInProductionGrid() @@ -578,13 +548,19 @@ void LLGridManager::updateIsInProductionGrid() if (uris.empty()) { mIsInProductionGrid = true; - return; } - LLStringUtil::toLower(uris[0]); - if((uris[0].find("agni") != std::string::npos)) + else { - mIsInProductionGrid = true; - return; + for ( std::vector<std::string>::iterator uri_it = uris.begin(); + ! mIsInProductionGrid && uri_it != uris.end(); + uri_it++ + ) + { + if( MAIN_GRID_LOGIN_URI == *uri_it ) + { + mIsInProductionGrid = true; + } + } } } @@ -593,50 +569,53 @@ bool LLGridManager::isInProductionGrid() return mIsInProductionGrid; } -void LLGridManager::saveFavorites() +bool LLGridManager::isSystemGrid(const std::string& grid) { - // filter out just those marked as favorites - LLSD output_grid_list = LLSD::emptyMap(); - for(LLSD::map_iterator grid_iter = mGridList.beginMap(); - grid_iter != mGridList.endMap(); - grid_iter++) - { - if(grid_iter->second.has(GRID_IS_FAVORITE_VALUE)) - { - output_grid_list[grid_iter->first] = grid_iter->second; - } - } - llofstream llsd_xml; - llsd_xml.open( mGridFile.c_str(), std::ios::out | std::ios::binary); - LLSDSerialize::toPrettyXML(output_grid_list, llsd_xml); - llsd_xml.close(); -} + std::string grid_name = getGrid(grid); + return ( !grid_name.empty() + && mGridList.has(grid) + && mGridList[grid].has(GRID_IS_SYSTEM_GRID_VALUE) + && mGridList[grid][GRID_IS_SYSTEM_GRID_VALUE].asBoolean() + ); +} // build a slurl for the given region within the selected grid std::string LLGridManager::getSLURLBase(const std::string& grid) { - std::string grid_base; - if(mGridList.has(grid) && mGridList[grid].has(GRID_SLURL_BASE)) + std::string grid_base = ""; + std::string grid_name = getGrid(grid); + if( ! grid_name.empty() && mGridList.has(grid_name) ) { - return mGridList[grid][GRID_SLURL_BASE].asString(); - } - else - { - return llformat(DEFAULT_SLURL_BASE, grid.c_str()); + if (mGridList[grid_name].has(GRID_SLURL_BASE)) + { + grid_base = mGridList[grid_name][GRID_SLURL_BASE].asString(); + } + else + { + grid_base = llformat(DEFAULT_SLURL_BASE, grid_name.c_str()); + } } + LL_DEBUGS("GridManager")<<"returning '"<<grid_base<<"'"<<LL_ENDL; + return grid_base; } // build a slurl for the given region within the selected grid std::string LLGridManager::getAppSLURLBase(const std::string& grid) { - std::string grid_base; - if(mGridList.has(grid) && mGridList[grid].has(GRID_APP_SLURL_BASE)) - { - return mGridList[grid][GRID_APP_SLURL_BASE].asString(); - } - else + std::string grid_base = ""; + std::string grid_name = getGrid(grid); + if(!grid_name.empty() && mGridList.has(grid)) { - return llformat(DEFAULT_APP_SLURL_BASE, grid.c_str()); + if (mGridList[grid].has(GRID_APP_SLURL_BASE)) + { + grid_base = mGridList[grid][GRID_APP_SLURL_BASE].asString(); + } + else + { + grid_base = llformat(DEFAULT_APP_SLURL_BASE, grid_name.c_str()); + } } + LL_DEBUGS("GridManager")<<"returning '"<<grid_base<<"'"<<LL_ENDL; + return grid_base; } diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h index 15e25b4952..3f56103b2e 100644 --- a/indra/newview/llviewernetwork.h +++ b/indra/newview/llviewernetwork.h @@ -27,113 +27,181 @@ #ifndef LL_LLVIEWERNETWORK_H #define LL_LLVIEWERNETWORK_H - -extern const char* DEFAULT_LOGIN_PAGE; - -#define GRID_VALUE "name" -#define GRID_LABEL_VALUE "label" -#define GRID_ID_VALUE "grid_login_id" -#define GRID_LOGIN_URI_VALUE "login_uri" -#define GRID_HELPER_URI_VALUE "helper_uri" -#define GRID_LOGIN_PAGE_VALUE "login_page" -#define GRID_IS_SYSTEM_GRID_VALUE "system_grid" -#define GRID_IS_FAVORITE_VALUE "favorite" + +// @TODO this really should be private, but is used in llslurl #define MAINGRID "util.agni.lindenlab.com" -#define GRID_LOGIN_IDENTIFIER_TYPES "login_identifier_types" -// defines slurl formats associated with various grids. -// we need to continue to support existing forms, as slurls -// are shared between viewers that may not understand newer -// forms. -#define GRID_SLURL_BASE "slurl_base" -#define GRID_APP_SLURL_BASE "app_slurl_base" +/// Exception thrown when a grid is not valid class LLInvalidGridName { public: LLInvalidGridName(std::string grid) : mGrid(grid) { } + std::string name() { return mGrid; } protected: std::string mGrid; }; - /** - * @brief A class to manage the grids available to the viewer - * including persistance. This class also maintains the currently - * selected grid. - * + * @brief A singleton class to manage the grids available to the viewer. + * + * This class maintains several properties for each known grid, and provides + * interfaces for obtaining each of these properties given a specified + * grid. Grids are specified by either of two identifiers, each of which + * must be unique among all known grids: + * - grid name : DNS name for the grid + * - grid id : a short form (conventionally a single word) + * + * This class maintains the currently selected grid, and provides short + * form accessors for each of the properties of the selected grid. **/ class LLGridManager : public LLSingleton<LLGridManager> { -public: - - // when the grid manager is instantiated, the default grids are automatically - // loaded, and the grids favorites list is loaded from the xml file. + public: + /* ================================================================ + * @name Initialization and Configuration + * @{ + */ + /// Instantiate the grid manager, load default grids, selects the default grid LLGridManager(const std::string& grid_file); LLGridManager(); ~LLGridManager(); + /// add grids from an external grids file void initialize(const std::string& grid_file); - // grid list management - - // add a grid to the list of grids - void addGrid(LLSD& grid_info); - - // retrieve a map of grid-name <-> label - // by default only return the user visible grids - std::map<std::string, std::string> getKnownGrids(bool favorites_only=FALSE); - void getGridInfo(const std::string& grid, LLSD &grid_info); + //@} - // current grid management + /* ================================================================ + * @name Grid Identifiers + * @{ + * The id is a short form (typically one word) grid name, + * It should be used in URL path elements or parameters + * + * Each grid also has a "label", intented to be a user friendly + * descriptive form (it is used in the login panel grid menu, for example). + */ + /// Return the name of a grid, given either its name or its id + std::string getGrid( const std::string &grid ); - // select a given grid as the current grid. If the grid - // is not a known grid, then it's assumed to be a dns name for the - // grid, and the various URIs will be automatically generated. - void setGridChoice(const std::string& grid); + /// Get the id (short form selector) for a given grid + std::string getGridId(const std::string& grid); + + /// Get the id (short form selector) for the selected grid + std::string getGridId() { return getGridId(mGrid); } + + /// Get the user-friendly long form descriptor for a given grid + std::string getGridLabel(const std::string& grid); + /// Get the user-friendly long form descriptor for the selected grid + std::string getGridLabel() { return getGridLabel(mGrid); } + + /// Retrieve a map of grid-name -> label + std::map<std::string, std::string> getKnownGrids(); + + //@} + + /* ================================================================ + * @name Login related properties + * @{ + */ + + /** + * Get the login uris for the specified grid. + * The login uri for a grid is the target of the authentication request. + * A grid may have multple login uris, so they are returned as a vector. + */ + void getLoginURIs(const std::string& grid, std::vector<std::string>& uris); - std::string getGridLabel() { return mGridList[mGrid][GRID_LABEL_VALUE]; } - std::string getGrid() const { return mGrid; } + /// Get the login uris for the selected grid void getLoginURIs(std::vector<std::string>& uris); - std::string getHelperURI(); - std::string getLoginPage(); - std::string getGridLoginID() { return mGridList[mGrid][GRID_ID_VALUE]; } - std::string getLoginPage(const std::string& grid) { return mGridList[grid][GRID_LOGIN_PAGE_VALUE]; } - void getLoginIdentifierTypes(LLSD& idTypes) { idTypes = mGridList[mGrid][GRID_LOGIN_IDENTIFIER_TYPES]; } - // build a slurl for the given region within the selected grid + /// Get the URI for webdev help functions for the specified grid + std::string getHelperURI(const std::string& grid); + + /// Get the URI for webdev help functions for the selected grid + std::string getHelperURI() { return getHelperURI(mGrid); } + + /// Get the url of the splash page to be displayed prior to login + std::string getLoginPage(const std::string& grid_name); + + /// Get the URI for the login splash page for the selected grid + std::string getLoginPage(); + + /// Get the id to be used as a short name in url path components or parameters + std::string getGridLoginID(); + + /// Get an array of the login types supported by the grid + void getLoginIdentifierTypes(LLSD& idTypes); + /**< the types are "agent" and "avatar"; + * one means single-name (someone Resident) accounts and other first/last name accounts + * I am not sure which is which + */ + + //@} + + /* ================================================================ + * @name URL Construction Properties + * @{ + */ + + /// Return the slurl prefix (everything up to but not including the region) for a given grid std::string getSLURLBase(const std::string& grid); + + /// Return the slurl prefix (everything up to but not including the region) for the selected grid std::string getSLURLBase() { return getSLURLBase(mGrid); } + /// Return the application URL prefix for the given grid std::string getAppSLURLBase(const std::string& grid); + + /// Return the application URL prefix for the selected grid std::string getAppSLURLBase() { return getAppSLURLBase(mGrid); } - - void getGridInfo(LLSD &grid_info) { getGridInfo(mGrid, grid_info); } - - std::string getGridByLabel( const std::string &grid_label, bool case_sensitive = false); - - bool isSystemGrid(const std::string& grid) - { - return mGridList.has(grid) && - mGridList[grid].has(GRID_IS_SYSTEM_GRID_VALUE) && - mGridList[grid][GRID_IS_SYSTEM_GRID_VALUE].asBoolean(); - } + + //@} + + /* ================================================================ + * @name Selecting the current grid + * @{ + * At initialization, the current grid is set by the first of: + * -# The value supplied by the --grid command line option (setting CmdLineGridChoice); + * Note that a default for this may be set at build time. + * -# The grid used most recently (setting CurrentGrid) + * -# The main grid (Agni) + */ + + /// Select a given grid as the current grid. + void setGridChoice(const std::string& grid); + + /// Returns the name of the currently selected grid + std::string getGrid() const { return mGrid; } + + //@} + + /// Is the given grid one of the hard-coded default grids (Agni or Aditi) + bool isSystemGrid(const std::string& grid); + + /// Is the selected grid one of the hard-coded default grids (Agni or Aditi) bool isSystemGrid() { return isSystemGrid(mGrid); } - // Mark this grid as a favorite that should be persisited on 'save' - // this is currently used to persist a grid after a successful login - void setFavorite() { mGridList[mGrid][GRID_IS_FAVORITE_VALUE] = TRUE; } - + + /// Is the selected grid a production grid? bool isInProductionGrid(); - void saveFavorites(); - void clearFavorites(); + /** + * yes, that's not a very helpful description. + * I don't really know why that is different from isSystemGrid() + * In practice, the implementation is that it + * @returns true if the login uri for the grid is the uri for MAINGRID + */ -protected: + private: + + /// Add a grid to the list of grids + bool addGrid(LLSD& grid_info); + ///< @returns true if successfully added void updateIsInProductionGrid(); - // helper function for adding the predefined grids + // helper function for adding the hard coded grids void addSystemGrid(const std::string& label, const std::string& name, const std::string& login, diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index b8772971aa..b1a60197a2 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -143,7 +143,10 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco } else { - gAgentAvatarp->updateRegion(regionp); + if (isAgentAvatarValid()) + { + gAgentAvatarp->updateRegion(regionp); + } } res = gAgentAvatarp; } @@ -196,6 +199,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mID(id), mLocalID(0), mTotalCRC(0), + mListIndex(-1), mTEImages(NULL), mGLName(0), mbCanSelect(TRUE), @@ -232,7 +236,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mNumFaces(0), mTimeDilation(1.f), mRotTime(0.f), - mJointInfo(NULL), + mAngularVelocityRot(), + mPreviousRotation(), mState(0), mMedia(NULL), mClickAction(0), @@ -262,6 +267,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe { mPositionAgent = mRegionp->getOriginAgent(); } + resetRot(); LLViewerObject::sNumObjects++; } @@ -277,12 +283,6 @@ LLViewerObject::~LLViewerObject() mInventory = NULL; } - if (mJointInfo) - { - delete mJointInfo; - mJointInfo = NULL; - } - if (mPartSourcep) { mPartSourcep->setDead(); @@ -333,9 +333,6 @@ void LLViewerObject::markDead() if (getParent()) { ((LLViewerObject *)getParent())->removeChild(this); - // go ahead and delete any jointinfo's that we find - delete mJointInfo; - mJointInfo = NULL; } // Mark itself as dead @@ -429,7 +426,9 @@ void LLViewerObject::dump() const llinfos << "PositionAgent: " << getPositionAgent() << llendl; llinfos << "PositionGlobal: " << getPositionGlobal() << llendl; llinfos << "Velocity: " << getVelocity() << llendl; - if (mDrawable.notNull() && mDrawable->getNumFaces()) + if (mDrawable.notNull() && + mDrawable->getNumFaces() && + mDrawable->getFace(0)) { LLFacePool *poolp = mDrawable->getFace(0)->getPool(); if (poolp) @@ -443,7 +442,7 @@ void LLViewerObject::dump() const /* llinfos << "Velocity: " << getVelocity() << llendl; llinfos << "AnyOwner: " << permAnyOwner() << " YouOwner: " << permYouOwner() << " Edit: " << mPermEdit << llendl; - llinfos << "UsePhysics: " << usePhysics() << " CanSelect " << mbCanSelect << " UserSelected " << mUserSelected << llendl; + llinfos << "UsePhysics: " << flagUsePhysics() << " CanSelect " << mbCanSelect << " UserSelected " << mUserSelected << llendl; llinfos << "AppAngle: " << mAppAngle << llendl; llinfos << "PixelArea: " << mPixelArea << llendl; @@ -736,7 +735,7 @@ void LLViewerObject::addThisAndNonJointChildren(std::vector<LLViewerObject*>& ob iter != mChildList.end(); iter++) { LLViewerObject* child = *iter; - if ( (!child->isAvatar()) && (!child->isJointChild())) + if ( (!child->isAvatar())) { child->addThisAndNonJointChildren(objects); } @@ -787,6 +786,12 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp) LLDrawable* old_parent = mDrawable->mParent; mDrawable->mParent = parentp; + if (parentp && mDrawable->isActive()) + { + parentp->makeActive(); + parentp->setState(LLDrawable::ACTIVE_CHILD); + } + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); if( (old_parent != parentp && old_parent) || (parentp && parentp->isActive())) @@ -871,9 +876,15 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, const EObjectUpdateType update_type, LLDataPacker *dp) { - LLMemType mt(LLMemType::MTYPE_OBJECT); U32 retval = 0x0; + // If region is removed from the list it is also deleted. + if (!LLWorld::instance().isRegionListed(mRegionp)) + { + llwarns << "Updating object in an invalid region" << llendl; + return retval; + } + // Coordinates of objects on simulators are region-local. U64 region_handle; mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); @@ -1220,12 +1231,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, coloru.mV[3] = 255 - coloru.mV[3]; mText->setColor(LLColor4(coloru)); mText->setString(temp_string); - - if (mDrawable.notNull()) - { - setChanged(MOVED | SILHOUETTE); - gPipeline.markMoved(mDrawable, FALSE); // undamped - } + + setChanged(MOVED | SILHOUETTE); } else if (mText.notNull()) { @@ -1282,26 +1289,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, } } - U8 joint_type = 0; - mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_JointType, joint_type, block_num); - if (joint_type) - { - // create new joint info - if (!mJointInfo) - { - mJointInfo = new LLVOJointInfo; - } - mJointInfo->mJointType = (EHavokJointType) joint_type; - mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointPivot, mJointInfo->mPivot, block_num); - mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointAxisOrAnchor, mJointInfo->mAxisOrAnchor, block_num); - } - else if (mJointInfo) - { - // this joint info is no longer needed - delete mJointInfo; - mJointInfo = NULL; - } - break; } @@ -1419,9 +1406,10 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, #else val = (U16 *) &data[count]; #endif - setAngularVelocity( U16_to_F32(val[VX], -size, size), + new_angv.set(U16_to_F32(val[VX], -size, size), U16_to_F32(val[VY], -size, size), U16_to_F32(val[VZ], -size, size)); + setAngularVelocity(new_angv); break; case 16: @@ -1445,9 +1433,10 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f); new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f); - setAngularVelocity( U8_to_F32(data[13], -size, size), + new_angv.set(U8_to_F32(data[13], -size, size), U8_to_F32(data[14], -size, size), U8_to_F32(data[15], -size, size) ); + setAngularVelocity(new_angv); break; } @@ -1519,9 +1508,10 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, dp->unpackU16(val[VX], "AccX"); dp->unpackU16(val[VY], "AccY"); dp->unpackU16(val[VZ], "AccZ"); - setAngularVelocity( U16_to_F32(val[VX], -64.f, 64.f), + new_angv.set(U16_to_F32(val[VX], -64.f, 64.f), U16_to_F32(val[VY], -64.f, 64.f), U16_to_F32(val[VZ], -64.f, 64.f)); + setAngularVelocity(new_angv); } break; case OUT_FULL_COMPRESSED: @@ -1565,8 +1555,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, if (value & 0x80) { - dp->unpackVector3(vec, "Omega"); - setAngularVelocity(vec); + dp->unpackVector3(new_angv, "Omega"); + setAngularVelocity(new_angv); } if (value & 0x20) @@ -1949,14 +1939,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, cur_parentp->removeChild(this); - if (mJointInfo && !parent_id) - { - // since this object is no longer parent-relative - // we make sure we delete any joint info - delete mJointInfo; - mJointInfo = NULL; - } - setChanged(MOVED | SILHOUETTE); if (mDrawable.notNull()) @@ -2055,21 +2037,33 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, } } - if (new_rot != mLastRot - || new_angv != old_angv) + if ((new_rot != getRotation()) + || (new_angv != old_angv)) { - if (new_rot != mLastRot) + if (new_rot != mPreviousRotation) { - mLastRot = new_rot; - setRotation(new_rot); + resetRot(); } - + else if (new_angv != old_angv) + { + if (flagUsePhysics()) + { + resetRot(); + } + else + { + resetRotTime(); + } + } + + // Remember the last rotation value + mPreviousRotation = new_rot; + + // Set the rotation of the object followed by adjusting for the accumulated angular velocity (llSetTargetOmega) + setRotation(new_rot * mAngularVelocityRot); setChanged(ROTATED | SILHOUETTE); - - resetRot(); } - if ( gShowObjectUpdates ) { LLColor4 color; @@ -2084,9 +2078,15 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, gPipeline.addDebugBlip(getPositionAgent(), color); } - if ((0.0f == vel_mag_sq) && - (0.0f == accel_mag_sq) && - (0.0f == getAngularVelocity().magVecSquared())) + const F32 MAG_CUTOFF = F_APPROXIMATELY_ZERO; + + llassert(vel_mag_sq >= 0.f); + llassert(accel_mag_sq >= 0.f); + llassert(getAngularVelocity().magVecSquared() >= 0.f); + + if ((MAG_CUTOFF >= vel_mag_sq) && + (MAG_CUTOFF >= accel_mag_sq) && + (MAG_CUTOFF >= getAngularVelocity().magVecSquared())) { mStatic = TRUE; // This object doesn't move! } @@ -2157,17 +2157,13 @@ BOOL LLViewerObject::isActive() const -BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - static LLFastTimer::DeclareTimer ftm("Viewer Object"); - LLFastTimer t(ftm); + //static LLFastTimer::DeclareTimer ftm("Viewer Object"); + //LLFastTimer t(ftm); - if (mDead) + if (!mDead) { - // It's dead. Don't update it. - return TRUE; - } - // CRO - don't velocity interp linked objects! // Leviathan - but DO velocity interp joints if (!mStatic && sVelocityInterpolate && !isSelected()) @@ -2176,88 +2172,12 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) F32 dt_raw = (F32)(time - mLastInterpUpdateSecs); F32 dt = mTimeDilation * dt_raw; - if (!mJointInfo) - { applyAngularVelocity(dt); - } - LLViewerObject *parentp = (LLViewerObject *) getParent(); - if (mJointInfo) - { - if (parentp) - { - // do parent-relative stuff - LLVector3 ang_vel = getAngularVelocity(); - F32 omega = ang_vel.magVecSquared(); - F32 angle = 0.0f; - LLQuaternion dQ; - if (omega > 0.00001f) + if (isAttachment()) { - omega = sqrt(omega); - angle = omega * dt; - dQ.setQuat(angle, ang_vel); - } - LLVector3 pos = getPosition(); - - if (HJT_HINGE == mJointInfo->mJointType) - { - // hinge = uniform circular motion - LLVector3 parent_pivot = getVelocity(); - LLVector3 parent_axis = getAcceleration(); - - angle = dt * (ang_vel * mJointInfo->mAxisOrAnchor); // AxisOrAnchor = axis - dQ.setQuat(angle, mJointInfo->mAxisOrAnchor); // AxisOrAnchor = axis - LLVector3 pivot_offset = pos - mJointInfo->mPivot; // pos in pivot-frame - pivot_offset = pivot_offset * dQ; // new rotated pivot-frame pos - pos = mJointInfo->mPivot + pivot_offset; // parent-frame - LLViewerObject::setPosition(pos); - LLQuaternion Q_PC = getRotation(); - setRotation(Q_PC * dQ); mLastInterpUpdateSecs = time; - } - else if (HJT_POINT == mJointInfo->mJointType) - // || HJT_LPOINT == mJointInfo->mJointType) - { - // point-to-point = spin about axis and uniform circular motion - // of axis about the pivot point - // - // NOTE: this interpolation scheme is not quite good enough to - // reduce the bandwidth -- needs a gravitational correction. - // Similarly for hinges with axes that deviate from vertical. - - LLQuaternion Q_PC = getRotation(); - Q_PC = Q_PC * dQ; - setRotation(Q_PC); - - LLVector3 pivot_to_child = - mJointInfo->mAxisOrAnchor; // AxisOrAnchor = anchor - pos = mJointInfo->mPivot + pivot_to_child * Q_PC; - LLViewerObject::setPosition(pos); - mLastInterpUpdateSecs = time; - } - /* else if (HJT_WHEEL == mJointInfo->mJointInfo) - { - // wheel = uniform rotation about axis, with linear - // velocity interpolation (if any) - LLVector3 parent_axis = getAcceleration(); // HACK -- accel stores the parent-axis (parent-frame) - - LLQuaternion Q_PC = getRotation(); - - angle = dt * (parent_axis * ang_vel); - dQ.setQuat(angle, parent_axis); - - Q_PC = Q_PC * dQ; - setRotation(Q_PC); - - pos = getPosition() + dt * getVelocity(); - LLViewerObject::setPosition(pos); - mLastInterpUpdateSecs = time; - }*/ - } - } - else if (isAttachment()) - { - mLastInterpUpdateSecs = time; - return TRUE; + return; } else { // Move object based on it's velocity and rotation @@ -2266,8 +2186,7 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } updateDrawable(FALSE); - - return TRUE; + } } @@ -2379,10 +2298,11 @@ void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt) { // This will put the object underground, but we can't tell if it will stop // at ground level or not min_height = LLWorld::getInstance()->getMinAllowedZ(this, new_pos_global); + // Cap maximum height + new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]); } new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]); - new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]); // Check to see if it's going off the region LLVector3 temp(new_pos); @@ -2426,8 +2346,6 @@ void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt) BOOL LLViewerObject::setData(const U8 *datap, const U32 data_size) { - LLMemType mt(LLMemType::MTYPE_OBJECT); - delete [] mData; if (datap) @@ -2469,8 +2387,6 @@ void LLViewerObject::doUpdateInventory( U8 key, bool is_new) { - LLMemType mt(LLMemType::MTYPE_OBJECT); - LLViewerInventoryItem* old_item = NULL; if(TASK_INVENTORY_ITEM_KEY == key) { @@ -2554,8 +2470,6 @@ void LLViewerObject::saveScript( BOOL active, bool is_new) { - LLMemType mt(LLMemType::MTYPE_OBJECT); - /* * XXXPAM Investigate not making this copy. Seems unecessary, but I'm unsure about the * interaction with doUpdateInventory() called below. @@ -2631,8 +2545,6 @@ void LLViewerObject::dirtyInventory() void LLViewerObject::registerInventoryListener(LLVOInventoryListener* listener, void* user_data) { - LLMemType mt(LLMemType::MTYPE_OBJECT); - LLInventoryCallbackInfo* info = new LLInventoryCallbackInfo; info->mListener = listener; info->mInventoryData = user_data; @@ -2730,8 +2642,6 @@ S32 LLFilenameAndTask::sCount = 0; // static void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data) { - LLMemType mt(LLMemType::MTYPE_OBJECT); - LLUUID task_id; msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id); LLViewerObject* object = gObjectList.findObject(task_id); @@ -2788,6 +2698,23 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS (object = gObjectList.findObject(ft->mTaskID))) { object->loadTaskInvFile(ft->mFilename); + + LLInventoryObject::object_list_t::iterator it = object->mInventory->begin(); + LLInventoryObject::object_list_t::iterator end = object->mInventory->end(); + std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs; + + for (; it != end && pending_lst.size(); ++it) + { + LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get()); + if(item && item->getType() != LLAssetType::AT_CATEGORY) + { + std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID()); + if (id_it != pending_lst.end()) + { + pending_lst.erase(id_it); + } + } + } } else { @@ -2801,8 +2728,6 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS void LLViewerObject::loadTaskInvFile(const std::string& filename) { - LLMemType mt(LLMemType::MTYPE_OBJECT); - std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename); llifstream ifs(filename_and_local_path); if(ifs.good()) @@ -2894,13 +2819,38 @@ void LLViewerObject::removeInventory(const LLUUID& item_id) ++mInventorySerialNum; } +bool LLViewerObject::isTextureInInventory(LLViewerInventoryItem* item) +{ + bool result = false; + + if (item && LLAssetType::AT_TEXTURE == item->getType()) + { + std::list<LLUUID>::iterator begin = mPendingInventoryItemsIDs.begin(); + std::list<LLUUID>::iterator end = mPendingInventoryItemsIDs.end(); + + bool is_fetching = std::find(begin, end, item->getAssetUUID()) != end; + bool is_fetched = getInventoryItemByAsset(item->getAssetUUID()) != NULL; + + result = is_fetched || is_fetching; + } + + return result; +} + +void LLViewerObject::updateTextureInventory(LLViewerInventoryItem* item, U8 key, bool is_new) +{ + if (item && !isTextureInInventory(item)) + { + mPendingInventoryItemsIDs.push_back(item->getAssetUUID()); + updateInventory(item, key, is_new); + } +} + void LLViewerObject::updateInventory( LLViewerInventoryItem* item, U8 key, bool is_new) { - LLMemType mt(LLMemType::MTYPE_OBJECT); - // This slices the object into what we're concerned about on the // viewer. The simulator will take the permissions and transfer // ownership. @@ -3475,7 +3425,8 @@ LLNameValue *LLViewerObject::getNVPair(const std::string& name) const void LLViewerObject::updatePositionCaches() const { - if(mRegionp) + // If region is removed from the list it is also deleted. + if(mRegionp && LLWorld::instance().isRegionListed(mRegionp)) { if (!isRoot()) { @@ -3492,7 +3443,8 @@ void LLViewerObject::updatePositionCaches() const const LLVector3d LLViewerObject::getPositionGlobal() const { - if(mRegionp) + // If region is removed from the list it is also deleted. + if(mRegionp && LLWorld::instance().isRegionListed(mRegionp)) { LLVector3d position_global = mRegionp->getPosGlobalFromRegion(getPositionRegion()); @@ -3511,7 +3463,8 @@ const LLVector3d LLViewerObject::getPositionGlobal() const const LLVector3 &LLViewerObject::getPositionAgent() const { - if (mRegionp) + // If region is removed from the list it is also deleted. + if(mRegionp && LLWorld::instance().isRegionListed(mRegionp)) { if (mDrawable.notNull() && (!mDrawable->isRoot() && getParent())) { @@ -3809,15 +3762,6 @@ void LLViewerObject::setPositionEdit(const LLVector3 &pos_edit, BOOL damped) ((LLViewerObject *)getParent())->setPositionEdit(pos_edit - position_offset); updateDrawable(damped); } - else if (isJointChild()) - { - // compute new parent-relative position - LLViewerObject *parent = (LLViewerObject *) getParent(); - LLQuaternion inv_parent_rot = parent->getRotation(); - inv_parent_rot.transQuat(); - LLVector3 pos_parent = (pos_edit - parent->getPositionRegion()) * inv_parent_rot; - LLViewerObject::setPosition(pos_parent, damped); - } else { LLViewerObject::setPosition(pos_edit, damped); @@ -3831,8 +3775,7 @@ LLViewerObject* LLViewerObject::getRootEdit() const { const LLViewerObject* root = this; while (root->mParent - && !(root->mJointInfo - || ((LLViewerObject*)root->mParent)->isAvatar()) ) + && !((LLViewerObject*)root->mParent)->isAvatar()) { root = (LLViewerObject*)root->mParent; } @@ -3916,8 +3859,6 @@ std::string LLViewerObject::getMediaURL() const void LLViewerObject::setMediaURL(const std::string& media_url) { - LLMemType mt(LLMemType::MTYPE_OBJECT); - if (!mMedia) { mMedia = new LLViewerObjectMedia; @@ -3967,8 +3908,6 @@ BOOL LLViewerObject::setMaterial(const U8 material) void LLViewerObject::setNumTEs(const U8 num_tes) { - LLMemType mt(LLMemType::MTYPE_OBJECT); - U32 i; if (num_tes != getNumTEs()) { @@ -4025,38 +3964,6 @@ void LLViewerObject::sendMaterialUpdate() const } -// formerly send_object_rotation -void LLViewerObject::sendRotationUpdate() const -{ - LLViewerRegion* regionp = getRegion(); - if(!regionp) return; - gMessageSystem->newMessageFast(_PREHASH_ObjectRotation); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID); - gMessageSystem->addQuatFast(_PREHASH_Rotation, getRotationEdit()); - //llinfos << "Sent rotation " << getRotationEdit() << llendl; - gMessageSystem->sendReliable( regionp->getHost() ); -} - -/* Obsolete, we use MultipleObjectUpdate instead -//// formerly send_object_position_global -//void LLViewerObject::sendPositionUpdate() const -//{ -// gMessageSystem->newMessageFast(_PREHASH_ObjectPosition); -// gMessageSystem->nextBlockFast(_PREHASH_AgentData); -// gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); -// gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -// gMessageSystem->nextBlockFast(_PREHASH_ObjectData); -// gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID ); -// gMessageSystem->addVector3Fast(_PREHASH_Position, getPositionRegion()); -// LLViewerRegion* regionp = getRegion(); -// gMessageSystem->sendReliable(regionp->getHost()); -//} -*/ - //formerly send_object_shape(LLViewerObject *object) void LLViewerObject::sendShapeUpdate() { @@ -4145,7 +4052,7 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos return retval; } - +//virtual void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image) { if(index < 0 || index >= getNumTEs()) @@ -4464,7 +4371,11 @@ U32 LLViewerObject::getNumVertices() const num_faces = mDrawable->getNumFaces(); for (i = 0; i < num_faces; i++) { - num_vertices += mDrawable->getFace(i)->getGeomCount(); + LLFace * facep = mDrawable->getFace(i); + if (facep) + { + num_vertices += facep->getGeomCount(); + } } } return num_vertices; @@ -4479,7 +4390,11 @@ U32 LLViewerObject::getNumIndices() const num_faces = mDrawable->getNumFaces(); for (i = 0; i < num_faces; i++) { - num_indices += mDrawable->getFace(i)->getIndicesCount(); + LLFace * facep = mDrawable->getFace(i); + if (facep) + { + num_indices += facep->getIndicesCount(); + } } } return num_indices; @@ -4565,19 +4480,11 @@ void LLViewerObject::clearIcon() LLViewerObject* LLViewerObject::getSubParent() { - if (isJointChild()) - { - return this; - } return (LLViewerObject*) getParent(); } const LLViewerObject* LLViewerObject::getSubParent() const { - if (isJointChild()) - { - return this; - } return (const LLViewerObject*) getParent(); } @@ -4756,9 +4663,11 @@ void LLViewerObject::deleteParticleSource() // virtual void LLViewerObject::updateDrawable(BOOL force_damped) { - if (mDrawable.notNull() && - !mDrawable->isState(LLDrawable::ON_MOVE_LIST) && - isChanged(MOVED)) + if (!isChanged(MOVED)) + { //most common case, having an empty if case here makes for better branch prediction + } + else if (mDrawable.notNull() && + !mDrawable->isState(LLDrawable::ON_MOVE_LIST)) { BOOL damped_motion = !isChanged(SHIFTED) && // not shifted between regions this frame and... @@ -5123,7 +5032,7 @@ BOOL LLViewerObject::permAnyOwner() const { if (isRootEdit()) { - return ((mFlags & FLAGS_OBJECT_ANY_OWNER) != 0); + return flagObjectAnyOwner(); } else { @@ -5145,7 +5054,7 @@ BOOL LLViewerObject::permYouOwner() const return TRUE; } # endif - return ((mFlags & FLAGS_OBJECT_YOU_OWNER) != 0); + return flagObjectYouOwner(); #endif } else @@ -5159,7 +5068,7 @@ BOOL LLViewerObject::permGroupOwner() const { if (isRootEdit()) { - return ((mFlags & FLAGS_OBJECT_GROUP_OWNED) != 0); + return flagObjectGroupOwned(); } else { @@ -5182,7 +5091,7 @@ BOOL LLViewerObject::permOwnerModify() const return TRUE; } # endif - return ((mFlags & FLAGS_OBJECT_OWNER_MODIFY) != 0); + return flagObjectOwnerModify(); #endif } else @@ -5206,7 +5115,7 @@ BOOL LLViewerObject::permModify() const return TRUE; } # endif - return ((mFlags & FLAGS_OBJECT_MODIFY) != 0); + return flagObjectModify(); #endif } else @@ -5230,7 +5139,7 @@ BOOL LLViewerObject::permCopy() const return TRUE; } # endif - return ((mFlags & FLAGS_OBJECT_COPY) != 0); + return flagObjectCopy(); #endif } else @@ -5254,7 +5163,7 @@ BOOL LLViewerObject::permMove() const return TRUE; } # endif - return ((mFlags & FLAGS_OBJECT_MOVE) != 0); + return flagObjectMove(); #endif } else @@ -5278,7 +5187,7 @@ BOOL LLViewerObject::permTransfer() const return TRUE; } # endif - return ((mFlags & FLAGS_OBJECT_TRANSFER) != 0); + return flagObjectTransfer(); #endif } else @@ -5321,21 +5230,19 @@ void LLViewerObject::markForUpdate(BOOL priority) } } +bool LLViewerObject::isPermanentEnforced() const +{ + return flagObjectPermanent() && (mRegionp != gAgent.getRegion()) && !gAgent.isGodlike(); +} + bool LLViewerObject::getIncludeInSearch() const { - return ((mFlags & FLAGS_INCLUDE_IN_SEARCH) != 0); + return flagIncludeInSearch(); } void LLViewerObject::setIncludeInSearch(bool include_in_search) { - if (include_in_search) - { - mFlags |= FLAGS_INCLUDE_IN_SEARCH; - } - else - { - mFlags &= ~FLAGS_INCLUDE_IN_SEARCH; - } + setFlags(FLAGS_INCLUDE_IN_SEARCH, include_in_search); } void LLViewerObject::setRegion(LLViewerRegion *regionp) @@ -5374,8 +5281,8 @@ void LLViewerObject::updateRegion(LLViewerRegion *regionp) bool LLViewerObject::specialHoverCursor() const { - return (mFlags & FLAGS_USE_PHYSICS) - || (mFlags & FLAGS_HANDLE_TOUCH) + return flagUsePhysics() + || flagHandleTouch() || (mClickAction != 0); } @@ -5388,10 +5295,15 @@ void LLViewerObject::updateFlags(BOOL physics_changed) gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, getLocalID() ); - gMessageSystem->addBOOLFast(_PREHASH_UsePhysics, usePhysics() ); + gMessageSystem->addBOOLFast(_PREHASH_UsePhysics, flagUsePhysics() ); gMessageSystem->addBOOL("IsTemporary", flagTemporaryOnRez() ); gMessageSystem->addBOOL("IsPhantom", flagPhantom() ); - gMessageSystem->addBOOL("CastsShadows", flagCastShadows() ); + + // stinson 02/28/2012 : This CastsShadows BOOL is no longer used in either the viewer or the simulator + // The simulator code does not even unpack this value when the message is received. + // This could be potentially hijacked in the future for another use should the urgent need arise. + gMessageSystem->addBOOL("CastsShadows", FALSE ); + if (physics_changed) { gMessageSystem->nextBlock("ExtraPhysics"); @@ -5406,6 +5318,19 @@ void LLViewerObject::updateFlags(BOOL physics_changed) BOOL LLViewerObject::setFlags(U32 flags, BOOL state) { + BOOL setit = setFlagsWithoutUpdate(flags, state); + + // BUG: Sometimes viewer physics and simulator physics get + // out of sync. To fix this, always send update to simulator. +// if (setit) + { + updateFlags(); + } + return setit; +} + +BOOL LLViewerObject::setFlagsWithoutUpdate(U32 flags, BOOL state) +{ BOOL setit = FALSE; if (state) { @@ -5423,22 +5348,18 @@ BOOL LLViewerObject::setFlags(U32 flags, BOOL state) setit = TRUE; } } - - // BUG: Sometimes viewer physics and simulator physics get - // out of sync. To fix this, always send update to simulator. -// if (setit) - { - updateFlags(); - } return setit; } void LLViewerObject::setPhysicsShapeType(U8 type) { mPhysicsShapeUnknown = false; + if (type != mPhysicsShapeType) + { mPhysicsShapeType = type; mCostStale = true; } +} void LLViewerObject::setPhysicsGravity(F32 gravity) { @@ -5464,7 +5385,6 @@ U8 LLViewerObject::getPhysicsShapeType() const { if (mPhysicsShapeUnknown) { - mPhysicsShapeUnknown = false; gObjectList.updatePhysicsFlags(this); } @@ -5486,18 +5406,31 @@ void LLViewerObject::applyAngularVelocity(F32 dt) ang_vel *= 1.f/omega; + // calculate the delta increment based on the object's angular velocity dQ.setQuat(angle, ang_vel); + + // accumulate the angular velocity rotations to re-apply in the case of an object update + mAngularVelocityRot *= dQ; + // Just apply the delta increment to the current rotation setRotation(getRotation()*dQ); setChanged(MOVED | SILHOUETTE); } } -void LLViewerObject::resetRot() +void LLViewerObject::resetRotTime() { mRotTime = 0.0f; } +void LLViewerObject::resetRot() +{ + resetRotTime(); + + // Reset the accumulated angular velocity rotation + mAngularVelocityRot.loadIdentity(); +} + U32 LLViewerObject::getPartitionType() const { return LLViewerRegion::PARTITION_NONE; @@ -5520,11 +5453,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/llviewerobject.h b/indra/newview/llviewerobject.h index c8152e1539..97cf0a4850 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -34,7 +34,6 @@ #include "llhudicon.h" #include "llinventory.h" #include "llrefcount.h" -#include "llmemtype.h" #include "llprimitive.h" #include "lluuid.h" #include "llvoinventorylistener.h" @@ -88,18 +87,6 @@ typedef void (*inventory_callback)(LLViewerObject*, S32 serial_num, void*); -// a small struct for keeping track of joints -struct LLVOJointInfo -{ - EHavokJointType mJointType; - LLVector3 mPivot; // parent-frame - // whether the below an axis or anchor (and thus its frame) - // depends on the joint type: - // HINGE ==> axis=parent-frame - // P2P ==> anchor=child-frame - LLVector3 mAxisOrAnchor; -}; - // for exporting textured materials from SL struct LLMaterialExportInfo { @@ -140,7 +127,6 @@ public: typedef const child_list_t const_child_list_t; LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global = FALSE); - MEM_TYPE_NEW(LLMemType::MTYPE_OBJECT); virtual void markDead(); // Mark this object as dead, and clean up its references BOOL isDead() const {return mDead;} @@ -157,7 +143,7 @@ public: LLNameValue* getNVPair(const std::string& name) const; // null if no name value pair by that name // Object create and update functions - virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); // Types of media we can associate enum { MEDIA_NONE = 0, MEDIA_SET = 1 }; @@ -188,8 +174,6 @@ public: virtual void updateRadius() {}; virtual F32 getVObjRadius() const; // default implemenation is mDrawable->getRadius() - BOOL isJointChild() const { return mJointInfo ? TRUE : FALSE; } - EHavokJointType getJointType() const { return mJointInfo ? mJointInfo->mJointType : HJT_INVALID; } // for jointed and other parent-relative hacks LLViewerObject* getSubParent(); const LLViewerObject* getSubParent() const; @@ -212,6 +196,9 @@ public: virtual BOOL updateLOD(); virtual BOOL setDrawableParent(LLDrawable* parentp); F32 getRotTime() { return mRotTime; } +private: + void resetRotTime(); +public: void resetRot(); void applyAngularVelocity(F32 dt); @@ -224,11 +211,13 @@ public: LLViewerRegion* getRegion() const { return mRegionp; } BOOL isSelected() const { return mUserSelected; } - virtual void setSelected(BOOL sel) { mUserSelected = sel; mRotTime = 0.f;} + virtual void setSelected(BOOL sel) { mUserSelected = sel; resetRot();} const LLUUID &getID() const { return mID; } U32 getLocalID() const { return mLocalID; } U32 getCRC() const { return mTotalCRC; } + S32 getListIndex() const { return mListIndex; } + void setListIndex(S32 idx) { mListIndex = idx; } virtual BOOL isFlexible() const { return FALSE; } virtual BOOL isSculpted() const { return FALSE; } @@ -308,7 +297,6 @@ public: inline void setRotation(const F32 x, const F32 y, const F32 z, BOOL damped = FALSE); inline void setRotation(const LLQuaternion& quat, BOOL damped = FALSE); - void sendRotationUpdate() const; /*virtual*/ void setNumTEs(const U8 num_tes); /*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry); @@ -332,7 +320,7 @@ public: /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); /*virtual*/ BOOL setMaterial(const U8 material); virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive - void changeTEImage(S32 index, LLViewerTexture* new_image) ; + virtual void changeTEImage(S32 index, LLViewerTexture* new_image) ; LLViewerTexture *getTEImage(const U8 te) const; void fitFaceTexture(const U8 face); @@ -432,12 +420,15 @@ public: // manager until we have better iterators. void updateInventory(LLViewerInventoryItem* item, U8 key, bool is_new); void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging. + void updateTextureInventory(LLViewerInventoryItem* item, U8 key, bool is_new); LLInventoryObject* getInventoryObject(const LLUUID& item_id); void getInventoryContents(LLInventoryObject::object_list_t& objects); LLInventoryObject* getInventoryRoot(); LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id); S16 getInventorySerial() const { return mInventorySerialNum; } + bool isTextureInInventory(LLViewerInventoryItem* item); + // These functions does viewer-side only object inventory modifications void updateViewerInventoryAsset( const LLViewerInventoryItem* item, @@ -468,26 +459,37 @@ public: BOOL permCopy() const; BOOL permMove() const; BOOL permTransfer() const; - inline BOOL usePhysics() const { return ((mFlags & FLAGS_USE_PHYSICS) != 0); } + inline BOOL flagUsePhysics() const { return ((mFlags & FLAGS_USE_PHYSICS) != 0); } + inline BOOL flagObjectAnyOwner() const { return ((mFlags & FLAGS_OBJECT_ANY_OWNER) != 0); } + inline BOOL flagObjectYouOwner() const { return ((mFlags & FLAGS_OBJECT_YOU_OWNER) != 0); } + inline BOOL flagObjectGroupOwned() const { return ((mFlags & FLAGS_OBJECT_GROUP_OWNED) != 0); } + inline BOOL flagObjectOwnerModify() const { return ((mFlags & FLAGS_OBJECT_OWNER_MODIFY) != 0); } + inline BOOL flagObjectModify() const { return ((mFlags & FLAGS_OBJECT_MODIFY) != 0); } + inline BOOL flagObjectCopy() const { return ((mFlags & FLAGS_OBJECT_COPY) != 0); } + inline BOOL flagObjectMove() const { return ((mFlags & FLAGS_OBJECT_MOVE) != 0); } + inline BOOL flagObjectTransfer() const { return ((mFlags & FLAGS_OBJECT_TRANSFER) != 0); } + inline BOOL flagObjectPermanent() const { return ((mFlags & FLAGS_AFFECTS_NAVMESH) != 0); } + inline BOOL flagCharacter() const { return ((mFlags & FLAGS_CHARACTER) != 0); } + inline BOOL flagVolumeDetect() const { return ((mFlags & FLAGS_VOLUME_DETECT) != 0); } + inline BOOL flagIncludeInSearch() const { return ((mFlags & FLAGS_INCLUDE_IN_SEARCH) != 0); } inline BOOL flagScripted() const { return ((mFlags & FLAGS_SCRIPTED) != 0); } inline BOOL flagHandleTouch() const { return ((mFlags & FLAGS_HANDLE_TOUCH) != 0); } inline BOOL flagTakesMoney() const { return ((mFlags & FLAGS_TAKES_MONEY) != 0); } inline BOOL flagPhantom() const { return ((mFlags & FLAGS_PHANTOM) != 0); } inline BOOL flagInventoryEmpty() const { return ((mFlags & FLAGS_INVENTORY_EMPTY) != 0); } - inline BOOL flagCastShadows() const { return ((mFlags & FLAGS_CAST_SHADOWS) != 0); } inline BOOL flagAllowInventoryAdd() const { return ((mFlags & FLAGS_ALLOW_INVENTORY_DROP) != 0); } - inline BOOL flagTemporary() const { return ((mFlags & FLAGS_TEMPORARY) != 0); } inline BOOL flagTemporaryOnRez() const { return ((mFlags & FLAGS_TEMPORARY_ON_REZ) != 0); } inline BOOL flagAnimSource() const { return ((mFlags & FLAGS_ANIM_SOURCE) != 0); } inline BOOL flagCameraSource() const { return ((mFlags & FLAGS_CAMERA_SOURCE) != 0); } inline BOOL flagCameraDecoupled() const { return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); } - inline BOOL flagObjectMove() const { return ((mFlags & FLAGS_OBJECT_MOVE) != 0); } U8 getPhysicsShapeType() const; inline F32 getPhysicsGravity() const { return mPhysicsGravity; } inline F32 getPhysicsFriction() const { return mPhysicsFriction; } inline F32 getPhysicsDensity() const { return mPhysicsDensity; } inline F32 getPhysicsRestitution() const { return mPhysicsRestitution; } + + bool isPermanentEnforced() const; bool getIncludeInSearch() const; void setIncludeInSearch(bool include_in_search); @@ -504,6 +506,7 @@ public: void updateFlags(BOOL physics_changed = FALSE); BOOL setFlags(U32 flag, BOOL state); + BOOL setFlagsWithoutUpdate(U32 flag, BOOL state); void setPhysicsShapeType(U8 type); void setPhysicsGravity(F32 gravity); void setPhysicsFriction(F32 friction); @@ -589,15 +592,20 @@ public: // Last total CRC received from sim, used for caching U32 mTotalCRC; + // index into LLViewerObjectList::mActiveObjects or -1 if not in list + S32 mListIndex; + LLPointer<LLViewerTexture> *mTEImages; // Selection, picking and rendering variables U32 mGLName; // GL "name" used by selection code BOOL mbCanSelect; // true if user can select this object by clicking +private: // Grabbed from UPDATE_FLAGS U32 mFlags; +public: // Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties U8 mPhysicsShapeType; F32 mPhysicsGravity; @@ -684,6 +692,10 @@ protected: F32 mAppAngle; // Apparent visual arc in degrees F32 mPixelArea; // Apparent area in pixels + // IDs of of all items in the object's content which are added to the object's content, + // but not updated on the server yet. After item was updated, its ID will be removed from this list. + std::list<LLUUID> mPendingInventoryItemsIDs; + // This is the object's inventory from the viewer's perspective. LLInventoryObject::object_list_t* mInventory; class LLInventoryCallbackInfo @@ -710,9 +722,9 @@ protected: F32 mTimeDilation; // Time dilation sent with the object. F32 mRotTime; // Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega) - LLQuaternion mLastRot; // last rotation received from the simulator + LLQuaternion mAngularVelocityRot; // accumulated rotation from the angular velocity computations + LLQuaternion mPreviousRotation; - LLVOJointInfo* mJointInfo; U8 mState; // legacy LLViewerObjectMedia* mMedia; // NULL if no media associated U8 mClickAction; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 6912faa9ec..4049e31472 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -49,6 +49,8 @@ #include "llstring.h" #include "llhudnametag.h" #include "lldrawable.h" +#include "llflexibleobject.h" +#include "llviewertextureanim.h" #include "xform.h" #include "llsky.h" #include "llviewercamera.h" @@ -78,11 +80,9 @@ extern F32 gMinObjectDistance; extern BOOL gAnimateTextures; -void dialog_refresh_all(); +#define MAX_CONCURRENT_PHYSICS_REQUESTS 256 -#define CULL_VIS -//#define ORPHAN_SPAM -//#define IGNORE_DEAD +void dialog_refresh_all(); // Global lists of objects - should go away soon. LLViewerObjectList gObjectList; @@ -91,8 +91,9 @@ extern LLPipeline gPipeline; // Statics for object lookup tables. U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check. -std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex; +std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex; std::map<U64, LLUUID> LLViewerObjectList::sIndexAndLocalIDToUUID; +LLStat LLViewerObjectList::sCacheHitRate("object_cache_hits", 128); LLViewerObjectList::LLViewerObjectList() { @@ -229,7 +230,6 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, LLDataPacker* dpp, BOOL just_created) { - LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE_CORE); LLMessageSystem* msg = gMessageSystem; // ignore returned flags @@ -282,7 +282,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, const EObjectUpdateType update_type, bool cached, bool compressed) { - LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE); LLFastTimer t(FTM_PROCESS_OBJECTS); LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); @@ -333,6 +332,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, U64 region_handle; mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle); if (!regionp) @@ -344,16 +344,14 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, U8 compressed_dpbuffer[2048]; LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048); LLDataPacker *cached_dpp = NULL; - -#if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(regionp); -#endif + LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); for (i = 0; i < num_objects; i++) { // timer is unused? LLTimer update_timer; BOOL justCreated = FALSE; + S32 msg_size = 0; if (cached) { @@ -361,6 +359,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, U32 crc; mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i); mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i); + msg_size += sizeof(U32) * 2; // Lookup data packer and add this id to cache miss lists if necessary. U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE; @@ -376,18 +375,14 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, else { // Cache Miss. - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->recordCacheMissEvent(id, update_type, cache_miss_type); - #endif + recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size); continue; // no data packer, skip this object } } else if (compressed) { - U8 compbuffer[2048]; S32 uncompressed_length = 2048; - S32 compressed_length; compressed_dp.reset(); U32 flags = 0; @@ -396,24 +391,9 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i); } - // I don't think we ever use this flag from the server. DK 2010/12/09 - if (flags & FLAGS_ZLIB_COMPRESSED) - { - //llinfos << "TEST: flags & FLAGS_ZLIB_COMPRESSED" << llendl; - compressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data); - mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compbuffer, 0, i); - uncompressed_length = 2048; - uncompress(compressed_dpbuffer, (unsigned long *)&uncompressed_length, - compbuffer, compressed_length); - compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length); - } - else - { - uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data); - mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i); - compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length); - } - + uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data); + mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i); + compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length); if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only? { @@ -438,6 +418,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, else if (update_type != OUT_FULL) // !compressed, !OUT_FULL ==> OUT_FULL_CACHED only? { mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i); + msg_size += sizeof(U32); + getUUIDFromLocal(fullid, local_id, gMessageSystem->getSenderIP(), @@ -452,6 +434,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, { mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i); mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i); + msg_size += sizeof(LLUUID); + msg_size += sizeof(U32); // llinfos << "Full Update, obj " << local_id << ", global ID" << fullid << "from " << mesgsys->getSender() << llendl; } objectp = findObject(fullid); @@ -497,9 +481,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, if (update_type == OUT_TERSE_IMPROVED) { // llinfos << "terse update for an unknown object (compressed):" << fullid << llendl; - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); - #endif + recorder.objectUpdateFailure(local_id, update_type, msg_size); continue; } } @@ -511,22 +493,20 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, if (update_type != OUT_FULL) { //llinfos << "terse update for an unknown object:" << fullid << llendl; - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); - #endif + recorder.objectUpdateFailure(local_id, update_type, msg_size); continue; } mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_PCode, pcode, i); + msg_size += sizeof(U8); + } #ifdef IGNORE_DEAD if (mDeadObjects.find(fullid) != mDeadObjects.end()) { mNumDeadObjectUpdates++; //llinfos << "update for a dead object:" << fullid << llendl; - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); - #endif + recorder.objectUpdateFailure(local_id, update_type, msg_size); continue; } #endif @@ -535,13 +515,13 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, if (!objectp) { llinfos << "createObject failure for object: " << fullid << llendl; - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); - #endif + recorder.objectUpdateFailure(local_id, update_type, msg_size); continue; } justCreated = TRUE; mNumNewObjects++; + sCacheHitRate.addValue(cached ? 100.f : 0.f); + } @@ -561,12 +541,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only? { bCached = true; - #if LL_RECORD_VIEWER_STATS LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); - LLViewerStatsRecorder::instance()->recordCacheFullUpdate(local_id, update_type, result, objectp); - #else - objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); - #endif + recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size); } } else if (cached) // Cache hit only? @@ -582,16 +558,12 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } processUpdateCore(objectp, user_data, i, update_type, NULL, justCreated); } - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->recordObjectUpdateEvent(local_id, update_type, objectp); - #endif + recorder.objectUpdateEvent(local_id, update_type, objectp, msg_size); objectp->setLastUpdateType(update_type); objectp->setLastUpdateCached(bCached); } -#if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->endObjectUpdateEvents(); -#endif + recorder.log(0.2f); LLVOAvatar::cullAvatarsByPixelArea(); } @@ -880,8 +852,6 @@ private: void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) { - LLMemType mt(LLMemType::MTYPE_OBJECT); - // Update globals LLViewerObject::setVelocityInterpolate( gSavedSettings.getBOOL("VelocityInterpolate") ); LLViewerObject::setPingInterpolate( gSavedSettings.getBOOL("PingInterpolate") ); @@ -923,28 +893,35 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) const F64 frame_time = LLFrameTimer::getElapsedSeconds(); - std::vector<LLViewerObject*> kill_list; - S32 num_active_objects = 0; LLViewerObject *objectp = NULL; // Make a copy of the list in case something in idleUpdate() messes with it - std::vector<LLViewerObject*> idle_list; + static std::vector<LLViewerObject*> idle_list; + + U32 idle_count = 0; static LLFastTimer::DeclareTimer idle_copy("Idle Copy"); { LLFastTimer t(idle_copy); - idle_list.reserve( mActiveObjects.size() ); - for (std::set<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin(); + for (std::vector<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin(); active_iter != mActiveObjects.end(); active_iter++) { objectp = *active_iter; if (objectp) { + if (idle_count >= idle_list.size()) + { idle_list.push_back( objectp ); } else + { + idle_list[idle_count] = objectp; + } + ++idle_count; + } + else { // There shouldn't be any NULL pointers in the list, but they have caused // crashes before. This may be idleUpdate() messing with the list. llwarns << "LLViewerObjectList::update has a NULL objectp" << llendl; @@ -952,10 +929,13 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) } } + std::vector<LLViewerObject*>::iterator idle_end = idle_list.begin()+idle_count; + if (gSavedSettings.getBOOL("FreezeTime")) { + for (std::vector<LLViewerObject*>::iterator iter = idle_list.begin(); - iter != idle_list.end(); iter++) + iter != idle_end; iter++) { objectp = *iter; if (objectp->isAvatar()) @@ -967,26 +947,22 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) else { for (std::vector<LLViewerObject*>::iterator idle_iter = idle_list.begin(); - idle_iter != idle_list.end(); idle_iter++) + idle_iter != idle_end; idle_iter++) { objectp = *idle_iter; - if (!objectp->idleUpdate(agent, world, frame_time)) - { - // If Idle Update returns false, kill object! - kill_list.push_back(objectp); + llassert(objectp->isActive()); + objectp->idleUpdate(agent, world, frame_time); + } - else - { - num_active_objects++; + + //update flexible objects + LLVolumeImplFlexible::updateClass(); + + //update animated textures + LLViewerTextureAnim::updateClass(); } - } - for (std::vector<LLViewerObject*>::iterator kill_iter = kill_list.begin(); - kill_iter != kill_list.end(); kill_iter++) - { - objectp = *kill_iter; - killObject(objectp); - } - } + + fetchObjectCosts(); fetchPhysicsFlags(); @@ -1054,7 +1030,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) */ LLViewerStats::getInstance()->mNumObjectsStat.addValue((S32) mObjects.size()); - LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(num_active_objects); + LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(idle_count); LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled); LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled); } @@ -1075,8 +1051,6 @@ void LLViewerObjectList::fetchObjectCosts() LLSD id_list; U32 object_index = 0; - U32 count = 0; - for ( std::set<LLUUID>::iterator iter = mStaleObjectCost.begin(); iter != mStaleObjectCost.end(); @@ -1093,7 +1067,7 @@ void LLViewerObjectList::fetchObjectCosts() mStaleObjectCost.erase(iter++); - if (count++ >= 450) + if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS) { break; } @@ -1138,7 +1112,7 @@ void LLViewerObjectList::fetchPhysicsFlags() for ( std::set<LLUUID>::iterator iter = mStalePhysicsFlags.begin(); iter != mStalePhysicsFlags.end(); - ++iter) + ) { // Check to see if a request for this object // has already been made. @@ -1148,12 +1122,14 @@ void LLViewerObjectList::fetchPhysicsFlags() mPendingPhysicsFlags.insert(*iter); id_list[object_index++] = *iter; } - } - // id_list should now contain all - // requests in mStalePhysicsFlags before, so clear - // it now - mStalePhysicsFlags.clear(); + mStalePhysicsFlags.erase(iter++); + + if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS) + { + break; + } + } if ( id_list.size() > 0 ) { @@ -1187,7 +1163,6 @@ void LLViewerObjectList::clearDebugText() void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) { - LLMemType mt(LLMemType::MTYPE_OBJECT); if (mDeadObjects.find(objectp->mID) != mDeadObjects.end()) { llinfos << "Object " << objectp->mID << " already on dead list!" << llendl; @@ -1215,7 +1190,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) { //llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list in cleanupReferences." << llendl; objectp->setOnActiveList(FALSE); - mActiveObjects.erase(objectp); + removeFromActiveList(objectp); } if (objectp->isOnMap()) @@ -1392,9 +1367,29 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer) mNumDeadObjects = 0; } +void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp) +{ + S32 idx = objectp->getListIndex(); + if (idx != -1) + { //remove by moving last element to this object's position + llassert(mActiveObjects[idx] == objectp); + + objectp->setListIndex(-1); + + S32 last_index = mActiveObjects.size()-1; + + if (idx != last_index) + { + mActiveObjects[idx] = mActiveObjects[last_index]; + mActiveObjects[idx]->setListIndex(idx); + } + + mActiveObjects.pop_back(); + } +} + void LLViewerObjectList::updateActive(LLViewerObject *objectp) { - LLMemType mt(LLMemType::MTYPE_OBJECT); if (objectp->isDead()) { return; // We don't update dead objects! @@ -1406,16 +1401,38 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp) if (active) { //llinfos << "Adding " << objectp->mID << " " << objectp->getPCodeString() << " to active list." << llendl; - mActiveObjects.insert(objectp); + S32 idx = objectp->getListIndex(); + if (idx <= -1) + { + mActiveObjects.push_back(objectp); + objectp->setListIndex(mActiveObjects.size()-1); objectp->setOnActiveList(TRUE); } else { + llassert(idx < mActiveObjects.size()); + llassert(mActiveObjects[idx] == objectp); + + if (idx >= mActiveObjects.size() || + mActiveObjects[idx] != objectp) + { + llwarns << "Invalid object list index detected!" << llendl; + } + } + } + else + { //llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list." << llendl; - mActiveObjects.erase(objectp); + removeFromActiveList(objectp); objectp->setOnActiveList(FALSE); } } + + //post condition: if object is active, it must be on the active list + llassert(!active || std::find(mActiveObjects.begin(), mActiveObjects.end(), objectp) != mActiveObjects.end()); + + //post condition: if object is not active, it must not be on the active list + llassert(active || std::find(mActiveObjects.begin(), mActiveObjects.end(), objectp) == mActiveObjects.end()); } void LLViewerObjectList::updateObjectCost(LLViewerObject* object) @@ -1486,6 +1503,10 @@ void LLViewerObjectList::onPhysicsFlagsFetchFailure(const LLUUID& object_id) mPendingPhysicsFlags.erase(object_id); } +static LLFastTimer::DeclareTimer FTM_SHIFT_OBJECTS("Shift Objects"); +static LLFastTimer::DeclareTimer FTM_PIPELINE_SHIFT("Pipeline Shift"); +static LLFastTimer::DeclareTimer FTM_REGION_SHIFT("Region Shift"); + void LLViewerObjectList::shiftObjects(const LLVector3 &offset) { // This is called when we shift our origin when we cross region boundaries... @@ -1497,6 +1518,8 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) return; } + LLFastTimer t(FTM_SHIFT_OBJECTS); + LLViewerObject *objectp; for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { @@ -1513,9 +1536,16 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) } } + { + LLFastTimer t(FTM_PIPELINE_SHIFT); gPipeline.shiftObjects(offset); + } + + { + LLFastTimer t(FTM_REGION_SHIFT); LLWorld::getInstance()->shiftRegions(offset); } +} void LLViewerObjectList::repartitionObjects() { @@ -1718,7 +1748,10 @@ void LLViewerObjectList::generatePickList(LLCamera &camera) LLViewerObject* last_objectp = NULL; for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++) { - LLViewerObject* objectp = drawablep->getFace(face_num)->getViewerObject(); + LLFace * facep = drawablep->getFace(face_num); + if (!facep) continue; + + LLViewerObject* objectp = facep->getViewerObject(); if (objectp && objectp != last_objectp) { @@ -1838,7 +1871,6 @@ void LLViewerObjectList::resetObjectBeacons() LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp) { - LLMemType mt(LLMemType::MTYPE_OBJECT); LLUUID fullid; fullid.generate(); @@ -1859,13 +1891,9 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi } -static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object"); - LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id, const LLHost &sender) { - LLMemType mt(LLMemType::MTYPE_OBJECT); - LLFastTimer t(FTM_CREATE_OBJECT); LLUUID fullid; if (uuid == LLUUID::null) @@ -1929,7 +1957,6 @@ S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip, U32 port) { - LLMemType mt(LLMemType::MTYPE_OBJECT); #ifdef ORPHAN_SPAM llinfos << "Orphaning object " << childp->getID() << " with parent " << parent_id << llendl; #endif diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index c5f2a2c1ee..449a4633ff 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -118,7 +118,9 @@ public: void dirtyAllObjectInventory(); + void removeFromActiveList(LLViewerObject* objectp); void updateActive(LLViewerObject *objectp); + void updateAvatarVisibility(); // Selection related stuff @@ -127,6 +129,7 @@ public: LLViewerObject *getSelectedObject(const U32 object_id); inline S32 getNumObjects() { return (S32) mObjects.size(); } + inline S32 getNumActiveObjects() { return (S32) mActiveObjects.size(); } void addToMap(LLViewerObject *objectp); void removeFromMap(LLViewerObject *objectp); @@ -192,10 +195,12 @@ protected: std::vector<OrphanInfo> mOrphanChildren; // UUID's of orphaned objects S32 mNumOrphans; + static LLStat sCacheHitRate; + typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t; vobj_list_t mObjects; - std::set<LLPointer<LLViewerObject> > mActiveObjects; + std::vector<LLPointer<LLViewerObject> > mActiveObjects; vobj_list_t mMapObjects; diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index d6002e7320..77e382b8c7 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -67,6 +67,7 @@ #include "llworld.h" #include "roles_constants.h" #include "llweb.h" +#include "llvieweraudio.h" const F32 PARCEL_COLLISION_DRAW_SECS = 1.f; @@ -81,7 +82,6 @@ LLPointer<LLViewerTexture> sBlockedImage; LLPointer<LLViewerTexture> sPassImage; // Local functions -void optionally_start_music(const std::string& music_url); void callback_start_music(S32 option, void* data); void optionally_prepare_video(const LLParcel *parcelp); void callback_prepare_video(S32 option, void* data); @@ -545,9 +545,6 @@ LLParcelSelectionHandle LLViewerParcelMgr::selectLand(const LLVector3d &corner1, mRequestResult = PARCEL_RESULT_NO_DATA; - // clear the list of segments to prevent flashing - resetSegments(mHighlightSegments); - mFloatingParcelSelection->setParcel(mCurrentParcel); mCurrentParcelSelection->setParcel(NULL); mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel); @@ -1457,6 +1454,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use S32 other_clean_time = 0; + LLViewerParcelMgr& parcel_mgr = LLViewerParcelMgr::instance(); + msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RequestResult, request_result ); msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id ); @@ -1472,31 +1471,31 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use if (sequence_id == SELECTED_PARCEL_SEQ_ID) { // ...selected parcels report this sequence id - LLViewerParcelMgr::getInstance()->mRequestResult = PARCEL_RESULT_SUCCESS; - parcel = LLViewerParcelMgr::getInstance()->mCurrentParcel; + parcel_mgr.mRequestResult = PARCEL_RESULT_SUCCESS; + parcel = parcel_mgr.mCurrentParcel; } else if (sequence_id == HOVERED_PARCEL_SEQ_ID) { - LLViewerParcelMgr::getInstance()->mHoverRequestResult = PARCEL_RESULT_SUCCESS; - parcel = LLViewerParcelMgr::getInstance()->mHoverParcel; + parcel_mgr.mHoverRequestResult = PARCEL_RESULT_SUCCESS; + parcel = parcel_mgr.mHoverParcel; } else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID || sequence_id == COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID || sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID) { - LLViewerParcelMgr::getInstance()->mHoverRequestResult = PARCEL_RESULT_SUCCESS; - parcel = LLViewerParcelMgr::getInstance()->mCollisionParcel; + parcel_mgr.mHoverRequestResult = PARCEL_RESULT_SUCCESS; + parcel = parcel_mgr.mCollisionParcel; } - else if (sequence_id == 0 || sequence_id > LLViewerParcelMgr::getInstance()->mAgentParcelSequenceID) + else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID) { // new agent parcel - LLViewerParcelMgr::getInstance()->mAgentParcelSequenceID = sequence_id; - parcel = LLViewerParcelMgr::getInstance()->mAgentParcel; + parcel_mgr.mAgentParcelSequenceID = sequence_id; + parcel = parcel_mgr.mAgentParcel; } else { llinfos << "out of order agent parcel sequence id " << sequence_id - << " last good " << LLViewerParcelMgr::getInstance()->mAgentParcelSequenceID + << " last good " << parcel_mgr.mAgentParcelSequenceID << llendl; return; } @@ -1567,15 +1566,15 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use parcel->setRegionDenyAgeUnverifiedOverride(region_deny_age_unverified_override); parcel->unpackMessage(msg); - if (parcel == LLViewerParcelMgr::getInstance()->mAgentParcel) + if (parcel == parcel_mgr.mAgentParcel) { - S32 bitmap_size = LLViewerParcelMgr::getInstance()->mParcelsPerEdge - * LLViewerParcelMgr::getInstance()->mParcelsPerEdge + S32 bitmap_size = parcel_mgr.mParcelsPerEdge + * parcel_mgr.mParcelsPerEdge / 8; U8* bitmap = new U8[ bitmap_size ]; msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size); - LLViewerParcelMgr::getInstance()->writeAgentParcelFromBitmap(bitmap); + parcel_mgr.writeAgentParcelFromBitmap(bitmap); delete[] bitmap; // Let interesting parties know about agent parcel change. @@ -1586,7 +1585,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use if (instance->mTeleportInProgress) { instance->mTeleportInProgress = FALSE; - instance->mTeleportFinishedSignal(gAgent.getPositionGlobal()); + instance->mTeleportFinishedSignal(gAgent.getPositionGlobal(), false); } } } @@ -1595,11 +1594,11 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use if (sequence_id == SELECTED_PARCEL_SEQ_ID) { // Update selected counts - LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mSelectedSelfCount = self_count; - LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mSelectedOtherCount = other_count; - LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mSelectedPublicCount = public_count; + parcel_mgr.mCurrentParcelSelection->mSelectedSelfCount = self_count; + parcel_mgr.mCurrentParcelSelection->mSelectedOtherCount = other_count; + parcel_mgr.mCurrentParcelSelection->mSelectedPublicCount = public_count; - LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mSelectedMultipleOwners = + parcel_mgr.mCurrentParcelSelection->mSelectedMultipleOwners = (request_result == PARCEL_RESULT_MULTIPLE); // Select the whole parcel @@ -1610,67 +1609,64 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use { // don't muck with the westsouth and eastnorth. // just highlight it - LLVector3 west_south = region->getPosRegionFromGlobal(LLViewerParcelMgr::getInstance()->mWestSouth); - LLVector3 east_north = region->getPosRegionFromGlobal(LLViewerParcelMgr::getInstance()->mEastNorth); + LLVector3 west_south = region->getPosRegionFromGlobal(parcel_mgr.mWestSouth); + LLVector3 east_north = region->getPosRegionFromGlobal(parcel_mgr.mEastNorth); - LLViewerParcelMgr::getInstance()->resetSegments(LLViewerParcelMgr::getInstance()->mHighlightSegments); - LLViewerParcelMgr::getInstance()->writeHighlightSegments( + parcel_mgr.resetSegments(parcel_mgr.mHighlightSegments); + parcel_mgr.writeHighlightSegments( west_south.mV[VX], west_south.mV[VY], east_north.mV[VX], east_north.mV[VY] ); - LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mWholeParcelSelected = FALSE; + parcel_mgr.mCurrentParcelSelection->mWholeParcelSelected = FALSE; } else if (0 == local_id) { // this is public land, just highlight the selection - LLViewerParcelMgr::getInstance()->mWestSouth = region->getPosGlobalFromRegion( aabb_min ); - LLViewerParcelMgr::getInstance()->mEastNorth = region->getPosGlobalFromRegion( aabb_max ); + parcel_mgr.mWestSouth = region->getPosGlobalFromRegion( aabb_min ); + parcel_mgr.mEastNorth = region->getPosGlobalFromRegion( aabb_max ); - LLViewerParcelMgr::getInstance()->resetSegments(LLViewerParcelMgr::getInstance()->mHighlightSegments); - LLViewerParcelMgr::getInstance()->writeHighlightSegments( + parcel_mgr.resetSegments(parcel_mgr.mHighlightSegments); + parcel_mgr.writeHighlightSegments( aabb_min.mV[VX], aabb_min.mV[VY], aabb_max.mV[VX], aabb_max.mV[VY] ); - LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mWholeParcelSelected = TRUE; + parcel_mgr.mCurrentParcelSelection->mWholeParcelSelected = TRUE; } else { - LLViewerParcelMgr::getInstance()->mWestSouth = region->getPosGlobalFromRegion( aabb_min ); - LLViewerParcelMgr::getInstance()->mEastNorth = region->getPosGlobalFromRegion( aabb_max ); + parcel_mgr.mWestSouth = region->getPosGlobalFromRegion( aabb_min ); + parcel_mgr.mEastNorth = region->getPosGlobalFromRegion( aabb_max ); // Owned land, highlight the boundaries - S32 bitmap_size = LLViewerParcelMgr::getInstance()->mParcelsPerEdge - * LLViewerParcelMgr::getInstance()->mParcelsPerEdge + S32 bitmap_size = parcel_mgr.mParcelsPerEdge + * parcel_mgr.mParcelsPerEdge / 8; U8* bitmap = new U8[ bitmap_size ]; msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size); - LLViewerParcelMgr::getInstance()->resetSegments(LLViewerParcelMgr::getInstance()->mHighlightSegments); - LLViewerParcelMgr::getInstance()->writeSegmentsFromBitmap( bitmap, LLViewerParcelMgr::getInstance()->mHighlightSegments ); + parcel_mgr.resetSegments(parcel_mgr.mHighlightSegments); + parcel_mgr.writeSegmentsFromBitmap( bitmap, parcel_mgr.mHighlightSegments ); delete[] bitmap; bitmap = NULL; - LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mWholeParcelSelected = TRUE; + parcel_mgr.mCurrentParcelSelection->mWholeParcelSelected = TRUE; } // Request access list information for this land - LLViewerParcelMgr::getInstance()->sendParcelAccessListRequest(AL_ACCESS | AL_BAN); - - // Request the media url filter list for this land - LLViewerParcelMgr::getInstance()->requestParcelMediaURLFilter(); + parcel_mgr.sendParcelAccessListRequest(AL_ACCESS | AL_BAN); // Request dwell for this land, if it's not public land. - LLViewerParcelMgr::getInstance()->mSelectedDwell = DWELL_NAN; + parcel_mgr.mSelectedDwell = DWELL_NAN; if (0 != local_id) { - LLViewerParcelMgr::getInstance()->sendParcelDwellRequest(); + parcel_mgr.sendParcelDwellRequest(); } - LLViewerParcelMgr::getInstance()->mSelected = TRUE; - LLViewerParcelMgr::getInstance()->notifyObservers(); + parcel_mgr.mSelected = TRUE; + parcel_mgr.notifyObservers(); } } else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID || @@ -1678,32 +1674,32 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID) { // We're about to collide with this parcel - LLViewerParcelMgr::getInstance()->mRenderCollision = TRUE; - LLViewerParcelMgr::getInstance()->mCollisionTimer.reset(); + parcel_mgr.mRenderCollision = TRUE; + parcel_mgr.mCollisionTimer.reset(); // Differentiate this parcel if we are banned from it. if (sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID) { - LLViewerParcelMgr::getInstance()->mCollisionBanned = BA_BANNED; + parcel_mgr.mCollisionBanned = BA_BANNED; } else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID) { - LLViewerParcelMgr::getInstance()->mCollisionBanned = BA_NOT_IN_GROUP; + parcel_mgr.mCollisionBanned = BA_NOT_IN_GROUP; } else { - LLViewerParcelMgr::getInstance()->mCollisionBanned = BA_NOT_ON_LIST; + parcel_mgr.mCollisionBanned = BA_NOT_ON_LIST; } - S32 bitmap_size = LLViewerParcelMgr::getInstance()->mParcelsPerEdge - * LLViewerParcelMgr::getInstance()->mParcelsPerEdge + S32 bitmap_size = parcel_mgr.mParcelsPerEdge + * parcel_mgr.mParcelsPerEdge / 8; U8* bitmap = new U8[ bitmap_size ]; msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size); - LLViewerParcelMgr::getInstance()->resetSegments(LLViewerParcelMgr::getInstance()->mCollisionSegments); - LLViewerParcelMgr::getInstance()->writeSegmentsFromBitmap( bitmap, LLViewerParcelMgr::getInstance()->mCollisionSegments ); + parcel_mgr.resetSegments(parcel_mgr.mCollisionSegments); + parcel_mgr.writeSegmentsFromBitmap( bitmap, parcel_mgr.mCollisionSegments ); delete[] bitmap; bitmap = NULL; @@ -1714,18 +1710,21 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use LLViewerRegion *region = LLWorld::getInstance()->getRegion( msg->getSender() ); if (region) { - LLViewerParcelMgr::getInstance()->mHoverWestSouth = region->getPosGlobalFromRegion( aabb_min ); - LLViewerParcelMgr::getInstance()->mHoverEastNorth = region->getPosGlobalFromRegion( aabb_max ); + parcel_mgr.mHoverWestSouth = region->getPosGlobalFromRegion( aabb_min ); + parcel_mgr.mHoverEastNorth = region->getPosGlobalFromRegion( aabb_max ); } else { - LLViewerParcelMgr::getInstance()->mHoverWestSouth.clearVec(); - LLViewerParcelMgr::getInstance()->mHoverEastNorth.clearVec(); + parcel_mgr.mHoverWestSouth.clearVec(); + parcel_mgr.mHoverEastNorth.clearVec(); } } else { - // look for music. + // Check for video + LLViewerParcelMedia::update(parcel); + + // Then check for music if (gAudiop) { if (parcel) @@ -1736,56 +1735,44 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use std::string music_url = music_url_raw; LLStringUtil::trim(music_url); - // On entering a new parcel, stop the last stream if the - // new parcel has a different music url. (Empty URL counts - // as different.) - const std::string& stream_url = gAudiop->getInternetStreamURL(); - - if (music_url.empty() || music_url != stream_url) + // If there is a new music URL and it's valid, play it. + if (music_url.size() > 12) { - // URL is different from one currently playing. - gAudiop->stopInternetStream(); - - // If there is a new music URL and it's valid, play it. - if (music_url.size() > 12) + if (music_url.substr(0,7) == "http://") { - if (music_url.substr(0,7) == "http://") - { - optionally_start_music(music_url); - } - else - { - llinfos << "Stopping parcel music (invalid audio stream URL)" << llendl; - // clears the URL - gAudiop->startInternetStream(LLStringUtil::null); - } + optionally_start_music(music_url); } - else if (!gAudiop->getInternetStreamURL().empty()) + else { - llinfos << "Stopping parcel music (parcel stream URL is empty)" << llendl; - gAudiop->startInternetStream(LLStringUtil::null); + llinfos << "Stopping parcel music (invalid audio stream URL)" << llendl; + // clears the URL + // null value causes fade out + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); } } + else if (!gAudiop->getInternetStreamURL().empty()) + { + llinfos << "Stopping parcel music (parcel stream URL is empty)" << llendl; + // null value causes fade out + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); + } } else { // Public land has no music - gAudiop->stopInternetStream(); + LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); } }//if gAudiop - - // now check for video - LLViewerParcelMedia::update( parcel ); }; } -void optionally_start_music(const std::string& music_url) +void LLViewerParcelMgr::optionally_start_music(const std::string& music_url) { if (gSavedSettings.getBOOL("AudioStreamingMusic")) { // only play music when you enter a new parcel if the UI control for this // was not *explicitly* stopped by the user. (part of SL-4878) - LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel();; + LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel(); if ((nearby_media_panel && nearby_media_panel->getParcelAudioAutoStart()) || // or they have expressed no opinion in the UI, but have autoplay on... @@ -1794,7 +1781,11 @@ void optionally_start_music(const std::string& music_url) gSavedSettings.getBOOL("MediaTentativeAutoPlay"))) { llinfos << "Starting parcel music " << music_url << llendl; - gAudiop->startInternetStream(music_url); + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(music_url); + } + else + { + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); } } } @@ -1995,67 +1986,6 @@ void LLViewerParcelMgr::sendParcelAccessListUpdate(U32 which) } } -class LLParcelMediaURLFilterResponder : public LLHTTPClient::Responder -{ - virtual void result(const LLSD& content) - { - LLViewerParcelMgr::getInstance()->receiveParcelMediaURLFilter(content); - } -}; - -void LLViewerParcelMgr::requestParcelMediaURLFilter() -{ - if (!mSelected) - { - return; - } - - LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); - if (!region) - { - return; - } - - LLParcel* parcel = mCurrentParcel; - if (!parcel) - { - llwarns << "no parcel" << llendl; - return; - } - - LLSD body; - body["local-id"] = parcel->getLocalID(); - body["list"] = parcel->getMediaURLFilterList(); - - std::string url = region->getCapability("ParcelMediaURLFilterList"); - if (!url.empty()) - { - LLHTTPClient::post(url, body, new LLParcelMediaURLFilterResponder); - } - else - { - llwarns << "can't get ParcelMediaURLFilterList cap" << llendl; - } -} - - -void LLViewerParcelMgr::receiveParcelMediaURLFilter(const LLSD &content) -{ - if (content.has("list")) - { - LLParcel* parcel = LLViewerParcelMgr::getInstance()->mCurrentParcel; - if (!parcel) return; - - if (content["local-id"].asInteger() == parcel->getLocalID()) - { - parcel->setMediaURLFilterList(content["list"]); - - LLViewerParcelMgr::getInstance()->notifyObservers(); - } - } -} - - void LLViewerParcelMgr::deedLandToGroup() { std::string group_name; @@ -2561,7 +2491,7 @@ void LLViewerParcelMgr::onTeleportFinished(bool local, const LLVector3d& new_pos { // Local teleport. We already have the agent parcel data. // Emit the signal immediately. - getInstance()->mTeleportFinishedSignal(new_pos); + getInstance()->mTeleportFinishedSignal(new_pos, local); } else { diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index cac8d8391c..6183b7e90e 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -78,8 +78,8 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr> { public: - typedef boost::function<void (const LLVector3d&)> teleport_finished_callback_t; - typedef boost::signals2::signal<void (const LLVector3d&)> teleport_finished_signal_t; + typedef boost::function<void (const LLVector3d&, const bool& local)> teleport_finished_callback_t; + typedef boost::signals2::signal<void (const LLVector3d&, const bool&)> teleport_finished_signal_t; typedef boost::function<void()> parcel_changed_callback_t; typedef boost::signals2::signal<void()> parcel_changed_signal_t; @@ -223,11 +223,6 @@ public: // Takes an Access List flag, like AL_ACCESS or AL_BAN void sendParcelAccessListRequest(U32 flags); - // asks for the parcel's media url filter list - void requestParcelMediaURLFilter(); - // receive the response - void receiveParcelMediaURLFilter(const LLSD &content); - // Dwell is not part of the usual parcel update information because the // simulator doesn't actually know the per-parcel dwell. Ack! We have // to get it out of the database. @@ -275,6 +270,8 @@ public: // *NOTE: Taken out 2005-03-21. Phoenix. //void makeLandmarkAtSelection(); + static void optionally_start_music(const std::string& music_url); + static void processParcelOverlay(LLMessageSystem *msg, void **user_data); static void processParcelProperties(LLMessageSystem *msg, void **user_data); static void processParcelAccessListReply(LLMessageSystem *msg, void **user); diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index a0cf2fc803..a1c12c5cd6 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -828,7 +828,6 @@ void LLViewerParcelOverlay::updateGL() void LLViewerParcelOverlay::idleUpdate(bool force_update) { - LLMemType mt_iup(LLMemType::MTYPE_IDLE_UPDATE_PARCEL_OVERLAY); if (gGLManager.mIsDisabled) { return; diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 6b3e04348a..6bd9f66b9c 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -79,7 +79,6 @@ LLViewerPart::LLViewerPart() : mVPCallback(NULL), mImagep(NULL) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mPartSourcep = NULL; ++LLViewerPartSim::sParticleCount2 ; @@ -87,7 +86,6 @@ LLViewerPart::LLViewerPart() : LLViewerPart::~LLViewerPart() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mPartSourcep = NULL; --LLViewerPartSim::sParticleCount2 ; @@ -95,7 +93,6 @@ LLViewerPart::~LLViewerPart() void LLViewerPart::init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture *imagep, LLVPCallback cb) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mPartID = LLViewerPart::sNextPartID; LLViewerPart::sNextPartID++; mFlags = 0x00f; @@ -120,7 +117,6 @@ void LLViewerPart::init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture * LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 box_side, bool hud) : mHud(hud) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mVOPartGroupp = NULL; mUniformParticles = TRUE; @@ -177,7 +173,6 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo LLViewerPartGroup::~LLViewerPartGroup() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); cleanup(); S32 count = (S32) mParticles.size(); @@ -192,7 +187,6 @@ LLViewerPartGroup::~LLViewerPartGroup() void LLViewerPartGroup::cleanup() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); if (mVOPartGroupp) { if (!mVOPartGroupp->isDead()) @@ -205,7 +199,6 @@ void LLViewerPartGroup::cleanup() BOOL LLViewerPartGroup::posInGroup(const LLVector3 &pos, const F32 desired_size) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); if ((pos.mV[VX] < mMinObjPos.mV[VX]) || (pos.mV[VY] < mMinObjPos.mV[VY]) || (pos.mV[VZ] < mMinObjPos.mV[VZ])) @@ -233,8 +226,6 @@ BOOL LLViewerPartGroup::posInGroup(const LLVector3 &pos, const F32 desired_size) BOOL LLViewerPartGroup::addPart(LLViewerPart* part, F32 desired_size) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); - if (part->mFlags & LLPartData::LL_PART_HUD && !mHud) { return FALSE; @@ -261,7 +252,6 @@ BOOL LLViewerPartGroup::addPart(LLViewerPart* part, F32 desired_size) void LLViewerPartGroup::updateParticles(const F32 lastdt) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); F32 dt; LLVector3 gravity(0.f, 0.f, GRAVITY); @@ -429,7 +419,6 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt) void LLViewerPartGroup::shift(const LLVector3 &offset) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mCenterAgent += offset; mMinObjPos += offset; mMaxObjPos += offset; @@ -442,8 +431,6 @@ void LLViewerPartGroup::shift(const LLVector3 &offset) void LLViewerPartGroup::removeParticlesByID(const U32 source_id) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); - for (S32 i = 0; i < (S32)mParticles.size(); i++) { if(mParticles[i]->mPartSourcep->getID() == source_id) @@ -475,8 +462,7 @@ void LLViewerPartSim::checkParticleCount(U32 size) LLViewerPartSim::LLViewerPartSim() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); - sMaxParticleCount = gSavedSettings.getS32("RenderMaxPartCount"); + sMaxParticleCount = llmin(gSavedSettings.getS32("RenderMaxPartCount"), LL_MAX_PARTICLE_COUNT); static U32 id_seed = 0; mID = ++id_seed; } @@ -484,7 +470,6 @@ LLViewerPartSim::LLViewerPartSim() void LLViewerPartSim::destroyClass() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); S32 i; S32 count; @@ -500,9 +485,9 @@ void LLViewerPartSim::destroyClass() mViewerPartSources.clear(); } +//static BOOL LLViewerPartSim::shouldAddPart() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount) { @@ -525,7 +510,6 @@ BOOL LLViewerPartSim::shouldAddPart() void LLViewerPartSim::addPart(LLViewerPart* part) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); if (sParticleCount < MAX_PART_COUNT) { put(part); @@ -541,7 +525,6 @@ void LLViewerPartSim::addPart(LLViewerPart* part) LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million LLViewerPartGroup *return_group = NULL ; if (part->mPosAgent.magVecSquared() > MAX_MAG || !part->mPosAgent.isFinite()) @@ -599,7 +582,6 @@ LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part) LLViewerPartGroup *LLViewerPartSim::createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size, bool hud) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); //find a box that has a center position divisible by PART_SIM_BOX_SIDE that encompasses //pos_agent LLViewerPartGroup *groupp = new LLViewerPartGroup(pos_agent, desired_size, hud); @@ -632,8 +614,6 @@ static LLFastTimer::DeclareTimer FTM_SIMULATE_PARTICLES("Simulate Particles"); void LLViewerPartSim::updateSimulation() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); - static LLFrameTimer update_timer; const F32 dt = llmin(update_timer.getElapsedTimeAndResetF32(), 0.1f); @@ -800,7 +780,6 @@ void LLViewerPartSim::updatePartBurstRate() void LLViewerPartSim::addPartSource(LLPointer<LLViewerPartSource> sourcep) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); if (!sourcep) { llwarns << "Null part source!" << llendl; @@ -817,7 +796,6 @@ void LLViewerPartSim::removeLastCreatedSource() void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); for (group_list_t::iterator i = mViewerPartGroups.begin(); i != mViewerPartGroups.end(); ) { group_list_t::iterator iter = i++; @@ -832,7 +810,6 @@ void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp) void LLViewerPartSim::clearParticlesByID(const U32 system_id) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); for (group_list_t::iterator g = mViewerPartGroups.begin(); g != mViewerPartGroups.end(); ++g) { (*g)->removeParticlesByID(system_id); @@ -850,7 +827,6 @@ void LLViewerPartSim::clearParticlesByID(const U32 system_id) void LLViewerPartSim::clearParticlesByOwnerID(const LLUUID& task_id) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); for (source_list_t::iterator iter = mViewerPartSources.begin(); iter != mViewerPartSources.end(); ++iter) { if ((*iter)->getOwnerUUID() == task_id) diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h index 3e20f999c0..c91fcf0691 100644 --- a/indra/newview/llviewerpartsim.h +++ b/indra/newview/llviewerpartsim.h @@ -39,6 +39,8 @@ class LLViewerRegion; class LLViewerTexture; class LLVOPartGroup; +#define LL_MAX_PARTICLE_COUNT 8192 + typedef void (*LLVPCallback)(LLViewerPart &part, const F32 dt); /////////////////// @@ -140,7 +142,7 @@ public: void cleanupRegion(LLViewerRegion *regionp); - BOOL shouldAddPart(); // Just decides whether this particle should be added or not (for particle count capping) + static BOOL shouldAddPart(); // Just decides whether this particle should be added or not (for particle count capping) F32 maxRate() // Return maximum particle generation rate { if (sParticleCount >= MAX_PART_COUNT) diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index 4af92e79ff..b311f659fb 100644 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -90,7 +90,6 @@ void LLViewerPartSource::setStart() LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp) : LLViewerPartSource(LL_PART_SOURCE_SCRIPT) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); llassert(source_objp); mSourceObjectp = source_objp; mPosAgent = mSourceObjectp->getPositionAgent(); @@ -102,7 +101,6 @@ LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp) void LLViewerPartSourceScript::setDead() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mIsDead = TRUE; mSourceObjectp = NULL; mTargetObjectp = NULL; @@ -113,7 +111,6 @@ void LLViewerPartSourceScript::update(const F32 dt) if( mIsSuspended ) return; - LLMemType mt(LLMemType::MTYPE_PARTICLES); F32 old_update_time = mLastUpdateTime; mLastUpdateTime += dt; @@ -394,7 +391,6 @@ void LLViewerPartSourceScript::update(const F32 dt) // static LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, const S32 block_num) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); if (!pssp) { if (LLPartSysData::isNullPS(block_num)) @@ -436,7 +432,6 @@ LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewer LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); if (!pssp) { LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp); @@ -470,8 +465,6 @@ LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewer /* static */ LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); - LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp); new_pssp->mPartSysData = particle_parameters; @@ -487,13 +480,11 @@ LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::createPSS(LLViewer void LLViewerPartSourceScript::setImage(LLViewerTexture *imagep) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mImagep = imagep; } void LLViewerPartSourceScript::setTargetObject(LLViewerObject *objp) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mTargetObjectp = objp; } @@ -509,7 +500,6 @@ LLViewerPartSourceSpiral::LLViewerPartSourceSpiral(const LLVector3 &pos) : void LLViewerPartSourceSpiral::setDead() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mIsDead = TRUE; mSourceObjectp = NULL; } @@ -517,7 +507,6 @@ void LLViewerPartSourceSpiral::setDead() void LLViewerPartSourceSpiral::updatePart(LLViewerPart &part, const F32 dt) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); F32 frac = part.mLastUpdateTime/part.mMaxAge; LLVector3 center_pos; @@ -542,7 +531,6 @@ void LLViewerPartSourceSpiral::updatePart(LLViewerPart &part, const F32 dt) void LLViewerPartSourceSpiral::update(const F32 dt) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); if (!mImagep) { mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); @@ -588,7 +576,6 @@ void LLViewerPartSourceSpiral::update(const F32 dt) void LLViewerPartSourceSpiral::setSourceObject(LLViewerObject *objp) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mSourceObjectp = objp; } @@ -612,7 +599,6 @@ LLViewerPartSourceBeam::~LLViewerPartSourceBeam() void LLViewerPartSourceBeam::setDead() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mIsDead = TRUE; mSourceObjectp = NULL; mTargetObjectp = NULL; @@ -626,7 +612,6 @@ void LLViewerPartSourceBeam::setColor(const LLColor4 &color) void LLViewerPartSourceBeam::updatePart(LLViewerPart &part, const F32 dt) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); F32 frac = part.mLastUpdateTime/part.mMaxAge; LLViewerPartSource *ps = (LLViewerPartSource*)part.mPartSourcep; @@ -671,7 +656,6 @@ void LLViewerPartSourceBeam::updatePart(LLViewerPart &part, const F32 dt) void LLViewerPartSourceBeam::update(const F32 dt) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); const F32 RATE = 0.025f; mLastUpdateTime += dt; @@ -743,13 +727,11 @@ void LLViewerPartSourceBeam::update(const F32 dt) void LLViewerPartSourceBeam::setSourceObject(LLViewerObject* objp) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mSourceObjectp = objp; } void LLViewerPartSourceBeam::setTargetObject(LLViewerObject* objp) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mTargetObjectp = objp; } @@ -764,7 +746,6 @@ LLViewerPartSourceChat::LLViewerPartSourceChat(const LLVector3 &pos) : void LLViewerPartSourceChat::setDead() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mIsDead = TRUE; mSourceObjectp = NULL; } @@ -772,7 +753,6 @@ void LLViewerPartSourceChat::setDead() void LLViewerPartSourceChat::updatePart(LLViewerPart &part, const F32 dt) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); F32 frac = part.mLastUpdateTime/part.mMaxAge; LLVector3 center_pos; @@ -797,7 +777,6 @@ void LLViewerPartSourceChat::updatePart(LLViewerPart &part, const F32 dt) void LLViewerPartSourceChat::update(const F32 dt) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); if (!mImagep) { mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); @@ -853,7 +832,6 @@ void LLViewerPartSourceChat::update(const F32 dt) void LLViewerPartSourceChat::setSourceObject(LLViewerObject *objp) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mSourceObjectp = objp; } diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index 12f6a0dd1c..0316f79973 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -57,8 +57,8 @@ #include "lldeleteutils.h" #include "imageids.h" #include "indra_constants.h" -//#include "linden_common.h" -//#include "llpreprocessor.h" +#include "llinitparam.h" + #include "llallocator.h" #include "llapp.h" #include "llcriticaldamp.h" @@ -75,10 +75,8 @@ #include "llprocessor.h" #include "llrefcount.h" #include "llsafehandle.h" -//#include "llsecondlifeurls.h" #include "llsd.h" #include "llsingleton.h" -#include "llstat.h" #include "llstl.h" #include "llstrider.h" #include "llstring.h" @@ -86,11 +84,8 @@ #include "llthread.h" #include "lltimer.h" #include "lluuidhashmap.h" -//#include "processor.h" #include "stdenums.h" #include "stdtypes.h" -//#include "string_table.h" -//#include "timer.h" #include "timing.h" #include "u64.h" @@ -124,4 +119,5 @@ // Library includes from llmessage project #include "llcachename.h" + #endif diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index ed943964f9..e4234a538d 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -255,10 +255,9 @@ public: } } - static boost::intrusive_ptr<BaseCapabilitiesComplete> build( U64 region_handle, S32 id ) + static BaseCapabilitiesComplete* build( U64 region_handle, S32 id ) { - return boost::intrusive_ptr<BaseCapabilitiesComplete>( - new BaseCapabilitiesComplete(region_handle, id) ); + return new BaseCapabilitiesComplete(region_handle, id); } private: @@ -655,6 +654,31 @@ std::string LLViewerRegion::accessToShortString(U8 sim_access) } // static +U8 LLViewerRegion::shortStringToAccess(const std::string &sim_access) +{ + U8 accessValue; + + if (LLStringUtil::compareStrings(sim_access, "PG") == 0) + { + accessValue = SIM_ACCESS_PG; + } + else if (LLStringUtil::compareStrings(sim_access, "M") == 0) + { + accessValue = SIM_ACCESS_MATURE; + } + else if (LLStringUtil::compareStrings(sim_access, "A") == 0) + { + accessValue = SIM_ACCESS_ADULT; + } + else + { + accessValue = SIM_ACCESS_MIN; + } + + return accessValue; +} + +// static void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**) { // send it to 'observers' @@ -695,7 +719,6 @@ void LLViewerRegion::dirtyHeights() BOOL LLViewerRegion::idleUpdate(F32 max_update_time) { - LLMemType mt_ivr(LLMemType::MTYPE_IDLE_UPDATE_VIEWER_REGION); // did_update returns TRUE if we did at least one significant update BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time); @@ -1151,6 +1174,7 @@ void LLViewerRegion::getInfo(LLSD& info) void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features) { sim_features = mSimulatorFeatures; + } void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) @@ -1317,11 +1341,8 @@ void LLViewerRegion::requestCacheMisses() mCacheDirty = TRUE ; // llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl; - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(this); - LLViewerStatsRecorder::instance()->recordRequestCacheMissesEvent(full_count + crc_count); - LLViewerStatsRecorder::instance()->endObjectUpdateEvents(); - #endif + LLViewerStatsRecorder::instance().requestCacheMissesEvent(full_count + crc_count); + LLViewerStatsRecorder::instance().log(0.2f); } void LLViewerRegion::dumpCache() @@ -1461,7 +1482,8 @@ void LLViewerRegion::unpackRegionHandshake() // all of our terrain stuff, by if (compp->getParamsReady()) { - getLand().dirtyAllPatches(); + //this line creates frame stalls on region crossing and removing it appears to have no effect + //getLand().dirtyAllPatches(); } else { @@ -1489,16 +1511,17 @@ void LLViewerRegion::unpackRegionHandshake() void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) { + capabilityNames.append("AgentState"); capabilityNames.append("AttachmentResources"); capabilityNames.append("AvatarPickerSearch"); + capabilityNames.append("CharacterProperties"); capabilityNames.append("ChatSessionRequest"); capabilityNames.append("CopyInventoryFromNotecard"); + capabilityNames.append("CreateInventoryCategory"); capabilityNames.append("DispatchRegionInfo"); + capabilityNames.append("EnvironmentSettings"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); - capabilityNames.append("EnvironmentSettings"); - capabilityNames.append("ObjectMedia"); - capabilityNames.append("ObjectMediaNavigate"); if (gSavedSettings.getBOOL("UseHTTPInventory")) { @@ -1509,46 +1532,50 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) } capabilityNames.append("GetDisplayNames"); - capabilityNames.append("GetTexture"); capabilityNames.append("GetMesh"); capabilityNames.append("GetObjectCost"); capabilityNames.append("GetObjectPhysicsData"); + capabilityNames.append("GetTexture"); + capabilityNames.append("GroupMemberData"); capabilityNames.append("GroupProposalBallot"); capabilityNames.append("HomeLocation"); capabilityNames.append("LandResources"); capabilityNames.append("MapLayer"); capabilityNames.append("MapLayerGod"); capabilityNames.append("MeshUploadFlag"); + capabilityNames.append("NavMeshGenerationStatus"); capabilityNames.append("NewFileAgentInventory"); + capabilityNames.append("ObjectMedia"); + capabilityNames.append("ObjectMediaNavigate"); + capabilityNames.append("ObjectNavMeshProperties"); capabilityNames.append("ParcelPropertiesUpdate"); - capabilityNames.append("ParcelMediaURLFilterList"); - capabilityNames.append("ParcelNavigateMedia"); capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProductInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); capabilityNames.append("RemoteParcelRequest"); capabilityNames.append("RequestTextureDownload"); capabilityNames.append("ResourceCostSelected"); + capabilityNames.append("RetrieveNavMeshSrc"); capabilityNames.append("SearchStatRequest"); capabilityNames.append("SearchStatTracking"); capabilityNames.append("SendPostcard"); capabilityNames.append("SendUserReport"); capabilityNames.append("SendUserReportWithScreenshot"); capabilityNames.append("ServerReleaseNotes"); - capabilityNames.append("SimConsole"); - capabilityNames.append("SimulatorFeatures"); capabilityNames.append("SetDisplayName"); capabilityNames.append("SimConsoleAsync"); + capabilityNames.append("SimulatorFeatures"); capabilityNames.append("StartGroupProposal"); + capabilityNames.append("TerrainNavMeshProperties"); capabilityNames.append("TextureStats"); capabilityNames.append("UntrustedSimulatorMessage"); capabilityNames.append("UpdateAgentInformation"); capabilityNames.append("UpdateAgentLanguage"); capabilityNames.append("UpdateGestureAgentInventory"); - capabilityNames.append("UpdateNotecardAgentInventory"); - capabilityNames.append("UpdateScriptAgent"); capabilityNames.append("UpdateGestureTaskInventory"); + capabilityNames.append("UpdateNotecardAgentInventory"); capabilityNames.append("UpdateNotecardTaskInventory"); + capabilityNames.append("UpdateScriptAgent"); capabilityNames.append("UpdateScriptTask"); capabilityNames.append("UploadBakedTexture"); capabilityNames.append("ViewerMetrics"); @@ -1793,7 +1820,10 @@ void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& unique { mImpl->mLandp->getNeighboringRegions( uniqueRegions ); } - +void LLViewerRegion::getNeighboringRegionsStatus( std::vector<S32>& regions ) +{ + mImpl->mLandp->getNeighboringRegionsStatus( regions ); +} void LLViewerRegion::showReleaseNotes() { std::string url = this->getCapability("ServerReleaseNotes"); @@ -1826,4 +1856,9 @@ bool LLViewerRegion::meshRezEnabled() const mSimulatorFeatures["MeshRezEnabled"].asBoolean()); } +bool LLViewerRegion::dynamicPathfindingEnabled() const +{ + return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") && + mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean()); +} diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index c483c6ef52..c9fffaf30e 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -202,6 +202,7 @@ public: // Returns "M", "PG", "A" etc. static std::string accessToShortString(U8 sim_access); + static U8 shortStringToAccess(const std::string &sim_access); // Return access icon name static std::string getAccessIcon(U8 sim_access); @@ -285,6 +286,9 @@ public: void getSimulatorFeatures(LLSD& info); void setSimulatorFeatures(const LLSD& info); + + bool dynamicPathfindingEnabled() const; + typedef enum { CACHE_MISS_TYPE_FULL = 0, @@ -325,6 +329,7 @@ public: bool objectsCrossParcel(const std::vector<LLBBox>& boxes) const; void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ); + void getNeighboringRegionsStatus( std::vector<S32>& regions ); public: struct CompareDistance diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 18ae83e3b6..ba9818946c 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -63,8 +63,16 @@ bool LLViewerShaderMgr::sSkipReload = false; LLVector4 gShinyOrigin; +//transform shaders +LLGLSLShader gTransformPositionProgram; +LLGLSLShader gTransformTexCoordProgram; +LLGLSLShader gTransformNormalProgram; +LLGLSLShader gTransformColorProgram; +LLGLSLShader gTransformBinormalProgram; + //utility shaders LLGLSLShader gOcclusionProgram; +LLGLSLShader gOcclusionCubeProgram; LLGLSLShader gCustomAlphaProgram; LLGLSLShader gGlowCombineProgram; LLGLSLShader gSplatTextureRectProgram; @@ -72,6 +80,7 @@ LLGLSLShader gGlowCombineFXAAProgram; LLGLSLShader gTwoTextureAddProgram; LLGLSLShader gOneTextureNoColorProgram; LLGLSLShader gDebugProgram; +LLGLSLShader gClipProgram; LLGLSLShader gAlphaMaskProgram; //object shaders @@ -134,6 +143,8 @@ LLGLSLShader gUnderWaterProgram; //interface shaders LLGLSLShader gHighlightProgram; +LLGLSLShader gPathfindingProgram; +LLGLSLShader gPathfindingNoNormalsProgram; //avatar shader handles LLGLSLShader gAvatarProgram; @@ -178,6 +189,7 @@ LLGLSLShader gDeferredSunProgram; LLGLSLShader gDeferredBlurLightProgram; LLGLSLShader gDeferredSoftenProgram; LLGLSLShader gDeferredShadowProgram; +LLGLSLShader gDeferredShadowCubeProgram; LLGLSLShader gDeferredShadowAlphaMaskProgram; LLGLSLShader gDeferredAvatarShadowProgram; LLGLSLShader gDeferredAttachmentShadowProgram; @@ -363,6 +375,12 @@ void LLViewerShaderMgr::setShaders() //NEVER use more than 16 texture channels (work around for prevalent driver bug) LLGLSLShader::sIndexedTextureChannels = llmin(LLGLSLShader::sIndexedTextureChannels, 16); + if (gGLManager.mGLSLVersionMajor < 1 || + (gGLManager.mGLSLVersionMajor == 1 && gGLManager.mGLSLVersionMinor <= 20)) + { //NEVER use indexed texture rendering when GLSL version is 1.20 or earlier + LLGLSLShader::sIndexedTextureChannels = 1; + } + reentrance = true; if (LLRender::sGLCoreProfile) @@ -407,6 +425,8 @@ void LLViewerShaderMgr::setShaders() // Shaders LL_INFOS("ShaderLoading") << "\n~~~~~~~~~~~~~~~~~~\n Loading Shaders:\n~~~~~~~~~~~~~~~~~~" << LL_ENDL; + LL_INFOS("ShaderLoading") << llformat("Using GLSL %d.%d", gGLManager.mGLSLVersionMajor, gGLManager.mGLSLVersionMinor) << llendl; + for (S32 i = 0; i < SHADER_COUNT; i++) { mVertexShaderLevel[i] = 0; @@ -416,6 +436,7 @@ void LLViewerShaderMgr::setShaders() LLGLSLShader::sNoFixedFunction = false; LLVertexBuffer::unbind(); if (LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") + && (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10) && gSavedSettings.getBOOL("VertexShaderEnable")) { //using shaders, disable fixed function @@ -428,7 +449,8 @@ void LLViewerShaderMgr::setShaders() S32 wl_class = 2; S32 water_class = 2; S32 deferred_class = 0; - + S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0; + if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && gSavedSettings.getBOOL("RenderDeferred") && gSavedSettings.getBOOL("RenderAvatarVP") && @@ -466,6 +488,7 @@ void LLViewerShaderMgr::setShaders() gSky.mVOSkyp->forceSkyUpdate(); } + // Load lighting shaders mVertexShaderLevel[SHADER_LIGHTING] = light_class; mVertexShaderLevel[SHADER_INTERFACE] = light_class; @@ -475,6 +498,7 @@ void LLViewerShaderMgr::setShaders() mVertexShaderLevel[SHADER_EFFECT] = effect_class; mVertexShaderLevel[SHADER_WINDLIGHT] = wl_class; mVertexShaderLevel[SHADER_DEFERRED] = deferred_class; + mVertexShaderLevel[SHADER_TRANSFORM] = transform_class; BOOL loaded = loadBasicShaders(); @@ -484,65 +508,110 @@ void LLViewerShaderMgr::setShaders() gPipeline.mVertexShadersLoaded = 1; // Load all shaders to set max levels - loadShadersEnvironment(); - loadShadersWater(); - loadShadersWindLight(); - loadShadersEffects(); - loadShadersInterface(); - - // Load max avatar shaders to set the max level - mVertexShaderLevel[SHADER_AVATAR] = 3; - mMaxAvatarShaderLevel = 3; - - if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject()) - { //hardware skinning is enabled and rigged attachment shaders loaded correctly - BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth"); - S32 avatar_class = 1; - - // cloth is a class3 shader - if(avatar_cloth) - { - avatar_class = 3; - } + loaded = loadShadersEnvironment(); - // Set the actual level - mVertexShaderLevel[SHADER_AVATAR] = avatar_class; - loadShadersAvatar(); - if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class) - { - if (mVertexShaderLevel[SHADER_AVATAR] == 0) + if (loaded) + { + loaded = loadShadersWater(); + } + + if (loaded) + { + loaded = loadShadersWindLight(); + } + + if (loaded) + { + loaded = loadShadersEffects(); + } + + if (loaded) + { + loaded = loadShadersInterface(); + } + + if (loaded) + + { + loaded = loadTransformShaders(); + } + + if (loaded) + { + // Load max avatar shaders to set the max level + mVertexShaderLevel[SHADER_AVATAR] = 3; + mMaxAvatarShaderLevel = 3; + + if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject()) + { //hardware skinning is enabled and rigged attachment shaders loaded correctly + BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth"); + S32 avatar_class = 1; + + // cloth is a class3 shader + if(avatar_cloth) { - gSavedSettings.setBOOL("RenderAvatarVP", FALSE); + avatar_class = 3; } - if(llmax(mVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3) + + // Set the actual level + mVertexShaderLevel[SHADER_AVATAR] = avatar_class; + loadShadersAvatar(); + if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class) { - avatar_cloth = true; + if (mVertexShaderLevel[SHADER_AVATAR] == 0) + { + gSavedSettings.setBOOL("RenderAvatarVP", FALSE); + } + if(llmax(mVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3) + { + avatar_cloth = true; + } + else + { + avatar_cloth = false; + } + gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth); } - else + } + else + { //hardware skinning not possible, neither is deferred rendering + mVertexShaderLevel[SHADER_AVATAR] = 0; + mVertexShaderLevel[SHADER_DEFERRED] = 0; + + if (gSavedSettings.getBOOL("RenderAvatarVP")) { - avatar_cloth = false; + gSavedSettings.setBOOL("RenderDeferred", FALSE); + gSavedSettings.setBOOL("RenderAvatarCloth", FALSE); + gSavedSettings.setBOOL("RenderAvatarVP", FALSE); } - gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth); + + loadShadersAvatar(); // unloads + + loaded = loadShadersObject(); } } - else - { //hardware skinning not possible, neither is deferred rendering - mVertexShaderLevel[SHADER_AVATAR] = 0; - mVertexShaderLevel[SHADER_DEFERRED] = 0; - - if (gSavedSettings.getBOOL("RenderAvatarVP")) - { - gSavedSettings.setBOOL("RenderDeferred", FALSE); - gSavedSettings.setBOOL("RenderAvatarCloth", FALSE); - gSavedSettings.setBOOL("RenderAvatarVP", FALSE); + + if (!loaded) + { //some shader absolutely could not load, try to fall back to a simpler setting + if (gSavedSettings.getBOOL("WindLightUseAtmosShaders")) + { //disable windlight and try again + gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE); + reentrance = false; + setShaders(); + return; } - loadShadersAvatar(); // unloads - loadShadersObject(); - } + if (gSavedSettings.getBOOL("VertexShaderEnable")) + { //disable shaders outright and try again + gSavedSettings.setBOOL("VertexShaderEnable", FALSE); + reentrance = false; + setShaders(); + return; + } + } - if (!loadShadersDeferred()) - { + if (loaded && !loadShadersDeferred()) + { //everything else succeeded but deferred failed, disable deferred and try again gSavedSettings.setBOOL("RenderDeferred", FALSE); reentrance = false; setShaders(); @@ -591,9 +660,13 @@ void LLViewerShaderMgr::setShaders() void LLViewerShaderMgr::unloadShaders() { gOcclusionProgram.unload(); + gOcclusionCubeProgram.unload(); gDebugProgram.unload(); + gClipProgram.unload(); gAlphaMaskProgram.unload(); gUIProgram.unload(); + gPathfindingProgram.unload(); + gPathfindingNoNormalsProgram.unload(); gCustomAlphaProgram.unload(); gGlowCombineProgram.unload(); gSplatTextureRectProgram.unload(); @@ -683,6 +756,12 @@ void LLViewerShaderMgr::unloadShaders() gDeferredSkinnedBumpProgram.unload(); gDeferredSkinnedAlphaProgram.unload(); + gTransformPositionProgram.unload(); + gTransformTexCoordProgram.unload(); + gTransformNormalProgram.unload(); + gTransformColorProgram.unload(); + gTransformBinormalProgram.unload(); + mVertexShaderLevel[SHADER_LIGHTING] = 0; mVertexShaderLevel[SHADER_OBJECT] = 0; mVertexShaderLevel[SHADER_AVATAR] = 0; @@ -691,6 +770,7 @@ void LLViewerShaderMgr::unloadShaders() mVertexShaderLevel[SHADER_INTERFACE] = 0; mVertexShaderLevel[SHADER_EFFECT] = 0; mVertexShaderLevel[SHADER_WINDLIGHT] = 0; + mVertexShaderLevel[SHADER_TRANSFORM] = 0; gPipeline.mVertexShadersLoaded = 0; } @@ -730,7 +810,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders() vector< pair<string, S32> > shaders; shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterV.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterV.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); shaders.push_back( make_pair( "lighting/lightFuncV.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) ); @@ -741,7 +821,10 @@ BOOL LLViewerShaderMgr::loadBasicShaders() shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) ); shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) ); - shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) ); + if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30) + { + shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) ); + } shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) ); // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now. @@ -758,11 +841,11 @@ BOOL LLViewerShaderMgr::loadBasicShaders() // (in order of shader function call depth for reference purposes, deepest level first) shaders.clear(); - S32 ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1); + S32 ch = 1; - if (gGLManager.mGLVersion < 3.1f) - { //force to 1 texture index channel for old drivers - ch = 1; + if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) + { //use indexed texture rendering for GLSL >= 1.30 + ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1); } std::vector<S32> index_channels; @@ -816,7 +899,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment() if (mVertexShaderLevel[SHADER_ENVIRONMENT] == 0) { gTerrainProgram.unload(); - return FALSE; + return TRUE; } if (success) @@ -856,7 +939,7 @@ BOOL LLViewerShaderMgr::loadShadersWater() gWaterProgram.unload(); gUnderWaterProgram.unload(); gTerrainWaterProgram.unload(); - return FALSE; + return TRUE; } if (success) @@ -941,7 +1024,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects() gGlowExtractProgram.unload(); gPostColorFilterProgram.unload(); gPostNightVisionProgram.unload(); - return FALSE; + return TRUE; } if (success) @@ -1001,6 +1084,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredBlurLightProgram.unload(); gDeferredSoftenProgram.unload(); gDeferredShadowProgram.unload(); + gDeferredShadowCubeProgram.unload(); gDeferredShadowAlphaMaskProgram.unload(); gDeferredAvatarShadowProgram.unload(); gDeferredAttachmentShadowProgram.unload(); @@ -1102,18 +1186,25 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader"; + gDeferredSkinnedAlphaProgram.mFeatures.atmosphericHelpers = true; gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true; - gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = true; gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true; gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true; gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true; + gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = false; + gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false; + gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true; gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true; gDeferredSkinnedAlphaProgram.mShaderFiles.clear(); gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL); + + // Hack to include uniforms for lighting without linking in lighting file + gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true; } if (success) @@ -1181,7 +1272,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader"; gDeferredSpotLightProgram.mShaderFiles.clear(); gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredSpotLightProgram.createShader(NULL, NULL); } @@ -1190,7 +1281,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader"; gDeferredMultiSpotLightProgram.mShaderFiles.clear(); - gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL); @@ -1199,6 +1290,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { std::string fragment; + std::string vertex = "deferred/sunLightV.glsl"; if (gSavedSettings.getBOOL("RenderDeferredSSAO")) { @@ -1207,11 +1299,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() else { fragment = "deferred/sunLightF.glsl"; + if (mVertexShaderLevel[SHADER_DEFERRED] == 1) + { //no shadows, no SSAO, no frag coord + vertex = "deferred/sunLightNoFragCoordV.glsl"; + } } gDeferredSunProgram.mName = "Deferred Sun Shader"; gDeferredSunProgram.mShaderFiles.clear(); - gDeferredSunProgram.mShaderFiles.push_back(make_pair("deferred/sunLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER_ARB)); gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gDeferredSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredSunProgram.createShader(NULL, NULL); @@ -1230,11 +1326,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredAlphaProgram.mName = "Deferred Alpha Shader"; - gDeferredAlphaProgram.mFeatures.calculatesLighting = true; + gDeferredAlphaProgram.mFeatures.atmosphericHelpers = true; + gDeferredAlphaProgram.mFeatures.calculatesLighting = false; gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true; gDeferredAlphaProgram.mFeatures.hasGamma = true; gDeferredAlphaProgram.mFeatures.hasAtmospherics = true; - gDeferredAlphaProgram.mFeatures.hasLighting = true; + gDeferredAlphaProgram.mFeatures.hasLighting = false; + gDeferredAlphaProgram.mFeatures.isAlphaLighting = true; gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels if (mVertexShaderLevel[SHADER_DEFERRED] < 1) { @@ -1249,7 +1347,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredAlphaProgram.createShader(NULL, NULL); + + // Hack + gDeferredAlphaProgram.mFeatures.calculatesLighting = true; + gDeferredAlphaProgram.mFeatures.hasLighting = true; } if (success) @@ -1337,7 +1440,18 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader"; + gDeferredShadowCubeProgram.mShaderFiles.clear(); + gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredShadowCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredShadowCubeProgram.createShader(NULL, NULL); + } + + if (success) + { gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader"; + gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; gDeferredShadowAlphaMaskProgram.mShaderFiles.clear(); gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1391,18 +1505,24 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredAvatarAlphaProgram.mName = "Avatar Alpha Shader"; + gDeferredAvatarAlphaProgram.mFeatures.atmosphericHelpers = true; gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true; - gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true; + gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false; gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true; gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true; gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true; - gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; + gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false; + gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true; gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true; gDeferredAvatarAlphaProgram.mShaderFiles.clear(); - gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaNoColorV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedNoColorF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredAvatarAlphaProgram.createShader(NULL, &mAvatarUniforms); + + gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true; + gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; } if (success) @@ -1419,7 +1539,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredPostProgram.mName = "Deferred Post Shader"; gDeferredPostProgram.mShaderFiles.clear(); - gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredPostProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredPostProgram.createShader(NULL, NULL); @@ -1429,7 +1549,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredCoFProgram.mName = "Deferred CoF Shader"; gDeferredCoFProgram.mShaderFiles.clear(); - gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredCoFProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredCoFProgram.createShader(NULL, NULL); @@ -1439,7 +1559,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredDoFCombineProgram.mName = "Deferred DoFCombine Shader"; gDeferredDoFCombineProgram.mShaderFiles.clear(); - gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredDoFCombineProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredDoFCombineProgram.createShader(NULL, NULL); @@ -1449,7 +1569,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredPostNoDoFProgram.mName = "Deferred Post Shader"; gDeferredPostNoDoFProgram.mShaderFiles.clear(); - gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredPostNoDoFProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredPostNoDoFProgram.createShader(NULL, NULL); @@ -1905,18 +2025,19 @@ BOOL LLViewerShaderMgr::loadShadersObject() if (success) { gObjectPreviewProgram.mName = "Simple Shader"; - gObjectPreviewProgram.mFeatures.calculatesLighting = true; - gObjectPreviewProgram.mFeatures.calculatesAtmospherics = true; - gObjectPreviewProgram.mFeatures.hasGamma = true; - gObjectPreviewProgram.mFeatures.hasAtmospherics = true; - gObjectPreviewProgram.mFeatures.hasLighting = true; + gObjectPreviewProgram.mFeatures.calculatesLighting = false; + gObjectPreviewProgram.mFeatures.calculatesAtmospherics = false; + gObjectPreviewProgram.mFeatures.hasGamma = false; + gObjectPreviewProgram.mFeatures.hasAtmospherics = false; + gObjectPreviewProgram.mFeatures.hasLighting = false; gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0; gObjectPreviewProgram.mFeatures.disableTextureIndex = true; gObjectPreviewProgram.mShaderFiles.clear(); gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER_ARB)); gObjectPreviewProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; success = gObjectPreviewProgram.createShader(NULL, NULL); + gObjectPreviewProgram.mFeatures.hasLighting = true; } if (success) @@ -2372,7 +2493,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() gAvatarWaterProgram.unload(); gAvatarEyeballProgram.unload(); gAvatarPickProgram.unload(); - return FALSE; + return TRUE; } if (success) @@ -2466,7 +2587,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface() if (mVertexShaderLevel[SHADER_INTERFACE] == 0) { gHighlightProgram.unload(); - return FALSE; + return TRUE; } if (success) @@ -2491,6 +2612,26 @@ BOOL LLViewerShaderMgr::loadShadersInterface() if (success) { + gPathfindingProgram.mName = "Pathfinding Shader"; + gPathfindingProgram.mShaderFiles.clear(); + gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER_ARB)); + gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB)); + gPathfindingProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; + success = gPathfindingProgram.createShader(NULL, NULL); + } + + if (success) + { + gPathfindingNoNormalsProgram.mName = "PathfindingNoNormals Shader"; + gPathfindingNoNormalsProgram.mShaderFiles.clear(); + gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER_ARB)); + gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB)); + gPathfindingNoNormalsProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; + success = gPathfindingNoNormalsProgram.createShader(NULL, NULL); + } + + if (success) + { gCustomAlphaProgram.mName = "Custom Alpha Shader"; gCustomAlphaProgram.mShaderFiles.clear(); gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2609,6 +2750,16 @@ BOOL LLViewerShaderMgr::loadShadersInterface() if (success) { + gOcclusionCubeProgram.mName = "Occlusion Cube Shader"; + gOcclusionCubeProgram.mShaderFiles.clear(); + gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER_ARB)); + gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB)); + gOcclusionCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; + success = gOcclusionCubeProgram.createShader(NULL, NULL); + } + + if (success) + { gDebugProgram.mName = "Debug Shader"; gDebugProgram.mShaderFiles.clear(); gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2619,6 +2770,16 @@ BOOL LLViewerShaderMgr::loadShadersInterface() if (success) { + gClipProgram.mName = "Clip Shader"; + gClipProgram.mShaderFiles.clear(); + gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER_ARB)); + gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER_ARB)); + gClipProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; + success = gClipProgram.createShader(NULL, NULL); + } + + if (success) + { gAlphaMaskProgram.mName = "Alpha Mask Shader"; gAlphaMaskProgram.mShaderFiles.clear(); gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2644,7 +2805,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() { gWLSkyProgram.unload(); gWLCloudProgram.unload(); - return FALSE; + return TRUE; } if (success) @@ -2674,6 +2835,95 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() return success; } +BOOL LLViewerShaderMgr::loadTransformShaders() +{ + BOOL success = TRUE; + + if (mVertexShaderLevel[SHADER_TRANSFORM] < 1) + { + gTransformPositionProgram.unload(); + gTransformTexCoordProgram.unload(); + gTransformNormalProgram.unload(); + gTransformColorProgram.unload(); + gTransformBinormalProgram.unload(); + return TRUE; + } + + if (success) + { + gTransformPositionProgram.mName = "Position Transform Shader"; + gTransformPositionProgram.mShaderFiles.clear(); + gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER_ARB)); + gTransformPositionProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; + + const char* varyings[] = { + "position_out", + "texture_index_out", + }; + + success = gTransformPositionProgram.createShader(NULL, NULL, 2, varyings); + } + + if (success) + { + gTransformTexCoordProgram.mName = "TexCoord Transform Shader"; + gTransformTexCoordProgram.mShaderFiles.clear(); + gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER_ARB)); + gTransformTexCoordProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; + + const char* varyings[] = { + "texcoord_out", + }; + + success = gTransformTexCoordProgram.createShader(NULL, NULL, 1, varyings); + } + + if (success) + { + gTransformNormalProgram.mName = "Normal Transform Shader"; + gTransformNormalProgram.mShaderFiles.clear(); + gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER_ARB)); + gTransformNormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; + + const char* varyings[] = { + "normal_out", + }; + + success = gTransformNormalProgram.createShader(NULL, NULL, 1, varyings); + } + + if (success) + { + gTransformColorProgram.mName = "Color Transform Shader"; + gTransformColorProgram.mShaderFiles.clear(); + gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER_ARB)); + gTransformColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; + + const char* varyings[] = { + "color_out", + }; + + success = gTransformColorProgram.createShader(NULL, NULL, 1, varyings); + } + + if (success) + { + gTransformBinormalProgram.mName = "Binormal Transform Shader"; + gTransformBinormalProgram.mShaderFiles.clear(); + gTransformBinormalProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB)); + gTransformBinormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; + + const char* varyings[] = { + "binormal_out", + }; + + success = gTransformBinormalProgram.createShader(NULL, NULL, 1, varyings); + } + + + return success; +} + std::string LLViewerShaderMgr::getShaderDirPrefix(void) { return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 95eb551bf1..d6dd645e8c 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -54,6 +54,7 @@ public: BOOL loadShadersWater(); BOOL loadShadersInterface(); BOOL loadShadersWindLight(); + BOOL loadTransformShaders(); std::vector<S32> mVertexShaderLevel; S32 mMaxAvatarShaderLevel; @@ -69,6 +70,7 @@ public: SHADER_WINDLIGHT, SHADER_WATER, SHADER_DEFERRED, + SHADER_TRANSFORM, SHADER_COUNT }; @@ -209,13 +211,24 @@ inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShade extern LLVector4 gShinyOrigin; +//transform shaders +extern LLGLSLShader gTransformPositionProgram; +extern LLGLSLShader gTransformTexCoordProgram; +extern LLGLSLShader gTransformNormalProgram; +extern LLGLSLShader gTransformColorProgram; +extern LLGLSLShader gTransformBinormalProgram; + + + //utility shaders extern LLGLSLShader gOcclusionProgram; +extern LLGLSLShader gOcclusionCubeProgram; extern LLGLSLShader gCustomAlphaProgram; extern LLGLSLShader gGlowCombineProgram; extern LLGLSLShader gSplatTextureRectProgram; extern LLGLSLShader gGlowCombineFXAAProgram; extern LLGLSLShader gDebugProgram; +extern LLGLSLShader gClipProgram; extern LLGLSLShader gAlphaMaskProgram; //output tex0[tc0] + tex1[tc1] @@ -288,6 +301,8 @@ extern LLGLSLShader gGlowExtractProgram; //interface shaders extern LLGLSLShader gHighlightProgram; +extern LLGLSLShader gPathfindingProgram; +extern LLGLSLShader gPathfindingNoNormalsProgram; // avatar shader handles extern LLGLSLShader gAvatarProgram; @@ -328,6 +343,7 @@ extern LLGLSLShader gDeferredBlurLightProgram; extern LLGLSLShader gDeferredAvatarProgram; extern LLGLSLShader gDeferredSoftenProgram; extern LLGLSLShader gDeferredShadowProgram; +extern LLGLSLShader gDeferredShadowCubeProgram; extern LLGLSLShader gDeferredShadowAlphaMaskProgram; extern LLGLSLShader gDeferredPostProgram; extern LLGLSLShader gDeferredCoFProgram; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index c88122f22c..35839ae459 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -233,6 +233,9 @@ LLViewerStats::LLViewerStats() : mSimSimPhysicsStepMsec("simsimphysicsstepmsec"), mSimSimPhysicsShapeUpdateMsec("simsimphysicsshapeupdatemsec"), mSimSimPhysicsOtherMsec("simsimphysicsothermsec"), + mSimSimAIStepMsec("simsimaistepmsec"), + mSimSimSkippedSilhouetteSteps("simsimskippedsilhouettesteps"), + mSimSimPctSteppedCharacters("simsimpctsteppedcharacters"), mSimAgentMsec("simagentmsec"), mSimImagesMsec("simimagesmsec"), mSimScriptMsec("simscriptmsec"), @@ -244,6 +247,7 @@ LLViewerStats::LLViewerStats() : mSimObjects("simobjects"), mSimActiveObjects("simactiveobjects"), mSimActiveScripts("simactivescripts"), + mSimPctScriptsRun("simpctscriptsrun"), mSimInPPS("siminpps"), mSimOutPPS("simoutpps"), mSimPendingDownloads("simpendingdownloads"), @@ -286,19 +290,19 @@ LLViewerStats::~LLViewerStats() void LLViewerStats::resetStats() { - LLViewerStats::getInstance()->mKBitStat.reset(); - LLViewerStats::getInstance()->mLayersKBitStat.reset(); - LLViewerStats::getInstance()->mObjectKBitStat.reset(); - LLViewerStats::getInstance()->mTextureKBitStat.reset(); - LLViewerStats::getInstance()->mVFSPendingOperations.reset(); - LLViewerStats::getInstance()->mAssetKBitStat.reset(); - LLViewerStats::getInstance()->mPacketsInStat.reset(); - LLViewerStats::getInstance()->mPacketsLostStat.reset(); - LLViewerStats::getInstance()->mPacketsOutStat.reset(); - LLViewerStats::getInstance()->mFPSStat.reset(); - LLViewerStats::getInstance()->mTexturePacketsStat.reset(); - - LLViewerStats::getInstance()->mAgentPositionSnaps.reset(); + LLViewerStats& stats = LLViewerStats::instance(); + stats.mKBitStat.reset(); + stats.mLayersKBitStat.reset(); + stats.mObjectKBitStat.reset(); + stats.mTextureKBitStat.reset(); + stats.mVFSPendingOperations.reset(); + stats.mAssetKBitStat.reset(); + stats.mPacketsInStat.reset(); + stats.mPacketsLostStat.reset(); + stats.mPacketsOutStat.reset(); + stats.mFPSStat.reset(); + stats.mTexturePacketsStat.reset(); + stats.mAgentPositionSnaps.reset(); } @@ -323,55 +327,55 @@ void LLViewerStats::updateFrameStats(const F64 time_diff) { if (mPacketsLostPercentStat.getCurrent() > 5.0) { - incStat(LLViewerStats::ST_LOSS_05_SECONDS, time_diff); + incStat(ST_LOSS_05_SECONDS, time_diff); } if (mSimFPS.getCurrent() < 20.f && mSimFPS.getCurrent() > 0.f) { - incStat(LLViewerStats::ST_SIM_FPS_20_SECONDS, time_diff); + incStat(ST_SIM_FPS_20_SECONDS, time_diff); } if (mSimPhysicsFPS.getCurrent() < 20.f && mSimPhysicsFPS.getCurrent() > 0.f) { - incStat(LLViewerStats::ST_PHYS_FPS_20_SECONDS, time_diff); + incStat(ST_PHYS_FPS_20_SECONDS, time_diff); } if (time_diff >= 0.5) { - incStat(LLViewerStats::ST_FPS_2_SECONDS, time_diff); + incStat(ST_FPS_2_SECONDS, time_diff); } if (time_diff >= 0.125) { - incStat(LLViewerStats::ST_FPS_8_SECONDS, time_diff); + incStat(ST_FPS_8_SECONDS, time_diff); } if (time_diff >= 0.1) { - incStat(LLViewerStats::ST_FPS_10_SECONDS, time_diff); + incStat(ST_FPS_10_SECONDS, time_diff); } if (gFrameCount && mLastTimeDiff > 0.0) { // new "stutter" meter - setStat(LLViewerStats::ST_FPS_DROP_50_RATIO, - (getStat(LLViewerStats::ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) + + setStat(ST_FPS_DROP_50_RATIO, + (getStat(ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) + (time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount); // old stats that were never really used - setStat(LLViewerStats::ST_FRAMETIME_JITTER, - (getStat(LLViewerStats::ST_FRAMETIME_JITTER) * (gFrameCount - 1) + + setStat(ST_FRAMETIME_JITTER, + (getStat(ST_FRAMETIME_JITTER) * (gFrameCount - 1) + fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount); F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount; - setStat(LLViewerStats::ST_FRAMETIME_SLEW, - (getStat(LLViewerStats::ST_FRAMETIME_SLEW) * (gFrameCount - 1) + + setStat(ST_FRAMETIME_SLEW, + (getStat(ST_FRAMETIME_SLEW) * (gFrameCount - 1) + fabs(average_frametime - time_diff) / average_frametime) / gFrameCount); F32 max_bandwidth = gViewerThrottle.getMaxBandwidth(); F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth; - setStat(LLViewerStats::ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f); + setStat(ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f); - setStat(LLViewerStats::ST_MAX_BANDWIDTH, max_bandwidth / 1024.f); + setStat(ST_MAX_BANDWIDTH, max_bandwidth / 1024.f); } @@ -399,155 +403,8 @@ void LLViewerStats::addToMessage(LLSD &body) const << "; Count = " << mAgentPositionSnaps.getCount() << llendl; } -// static -// const std::string LLViewerStats::statTypeToText(EStatType type) -// { -// if (type >= 0 && type < ST_COUNT) -// { -// return STAT_INFO[type].mName; -// } -// else -// { -// return "Unknown statistic"; -// } -// } - // *NOTE:Mani The following methods used to exist in viewer.cpp // Moving them here, but not merging them into LLViewerStats yet. -void reset_statistics() -{ - if (LLSurface::sTextureUpdateTime) - { - LLSurface::sTexelsUpdated = 0; - LLSurface::sTextureUpdateTime = 0.f; - } -} - - -void output_statistics(void*) -{ - llinfos << "Number of orphans: " << gObjectList.getOrphanCount() << llendl; - llinfos << "Number of dead objects: " << gObjectList.mNumDeadObjects << llendl; - llinfos << "Num images: " << gTextureList.getNumImages() << llendl; - llinfos << "Texture usage: " << LLImageGL::sGlobalTextureMemoryInBytes << llendl; - llinfos << "Texture working set: " << LLImageGL::sBoundTextureMemoryInBytes << llendl; - llinfos << "Raw usage: " << LLImageRaw::sGlobalRawMemory << llendl; - llinfos << "Formatted usage: " << LLImageFormatted::sGlobalFormattedMemory << llendl; - llinfos << "Zombie Viewer Objects: " << LLViewerObject::getNumZombieObjects() << llendl; - llinfos << "Number of lights: " << gPipeline.getLightCount() << llendl; - - llinfos << "Memory Usage:" << llendl; - llinfos << "--------------------------------" << llendl; - llinfos << "Pipeline:" << llendl; - llinfos << llendl; - -#if LL_SMARTHEAP - llinfos << "--------------------------------" << llendl; - { - llinfos << "sizeof(LLVOVolume) = " << sizeof(LLVOVolume) << llendl; - - U32 total_pool_size = 0; - U32 total_used_size = 0; - MEM_POOL_INFO pool_info; - MEM_POOL_STATUS pool_status; - U32 pool_num = 0; - for(pool_status = MemPoolFirst( &pool_info, 1 ); - pool_status != MEM_POOL_END; - pool_status = MemPoolNext( &pool_info, 1 ) ) - { - llinfos << "Pool #" << pool_num << llendl; - if( MEM_POOL_OK != pool_status ) - { - llwarns << "Pool not ok" << llendl; - continue; - } - - llinfos << "Pool blockSizeFS " << pool_info.blockSizeFS - << " pageSize " << pool_info.pageSize - << llendl; - - U32 pool_count = MemPoolCount(pool_info.pool); - llinfos << "Blocks " << pool_count << llendl; - - U32 pool_size = MemPoolSize( pool_info.pool ); - if( pool_size == MEM_ERROR_RET ) - { - llinfos << "MemPoolSize() failed (" << pool_num << ")" << llendl; - } - else - { - llinfos << "MemPool Size " << pool_size / 1024 << "K" << llendl; - } - - total_pool_size += pool_size; - - if( !MemPoolLock( pool_info.pool ) ) - { - llinfos << "MemPoolLock failed (" << pool_num << ") " << llendl; - continue; - } - - U32 used_size = 0; - MEM_POOL_ENTRY entry; - entry.entry = NULL; - while( MemPoolWalk( pool_info.pool, &entry ) == MEM_POOL_OK ) - { - if( entry.isInUse ) - { - used_size += entry.size; - } - } - - MemPoolUnlock( pool_info.pool ); - - llinfos << "MemPool Used " << used_size/1024 << "K" << llendl; - total_used_size += used_size; - pool_num++; - } - - llinfos << "Total Pool Size " << total_pool_size/1024 << "K" << llendl; - llinfos << "Total Used Size " << total_used_size/1024 << "K" << llendl; - - } -#endif - - llinfos << "--------------------------------" << llendl; - llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl; - LLTexLayerStaticImageList::getInstance()->dumpByteCount(); - LLVOAvatarSelf::dumpScratchTextureByteCount(); - LLTexLayerSetBuffer::dumpTotalByteCount(); - LLVOAvatarSelf::dumpTotalLocalTextureByteCount(); - LLTexLayerParamAlpha::dumpCacheByteCount(); - LLVOAvatar::dumpBakedStatus(); - - llinfos << llendl; - - llinfos << "Object counts:" << llendl; - S32 i; - S32 obj_counts[256]; -// S32 app_angles[256]; - for (i = 0; i < 256; i++) - { - obj_counts[i] = 0; - } - for (i = 0; i < gObjectList.getNumObjects(); i++) - { - LLViewerObject *objectp = gObjectList.getObject(i); - if (objectp) - { - obj_counts[objectp->getPCode()]++; - } - } - for (i = 0; i < 256; i++) - { - if (obj_counts[i]) - { - llinfos << LLPrimitive::pCodeToString(i) << ":" << obj_counts[i] << llendl; - } - } -} - - U32 gTotalLandIn = 0, gTotalLandOut = 0; U32 gTotalWaterIn = 0, gTotalWaterOut = 0; @@ -565,20 +422,15 @@ U32 gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] extern U32 gVisCompared; extern U32 gVisTested; -std::map<S32,LLFrameTimer> gDebugTimers; -std::map<S32,std::string> gDebugTimerLabel; - -void init_statistics() -{ - // Label debug timers - gDebugTimerLabel[0] = "Texture"; -} +LLFrameTimer gTextureTimer; -void update_statistics(U32 frame_count) +void update_statistics() { gTotalWorldBytes += gVLManager.getTotalBytes(); gTotalObjectBytes += gObjectBits / 8; + LLViewerStats& stats = LLViewerStats::instance(); + // make sure we have a valid time delta for this frame if (gFrameIntervalSeconds > 0.f) { @@ -595,51 +447,47 @@ void update_statistics(U32 frame_count) LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds); } } - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail()); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip")); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); -#if 0 // 1.9.2 - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_OBJECTS, (F64)gSavedSettings.getS32("VertexShaderLevelObject")); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar")); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment")); -#endif - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame")); + stats.setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); + stats.setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail()); + stats.setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip")); + stats.setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); + + stats.setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame")); F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle"); F64 network_secs = gDebugView->mFastTimerView->getTime("Network"); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images")); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State")); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry")); + stats.setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs); + stats.setStat(LLViewerStats::ST_NETWORK_SECS, network_secs); + stats.setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images")); + stats.setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State")); + stats.setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry")); LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); if (cdp) { - LLViewerStats::getInstance()->mSimPingStat.addValue(cdp->getPingDelay()); + stats.mSimPingStat.addValue(cdp->getPingDelay()); gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1); gSimPingCount++; } else { - LLViewerStats::getInstance()->mSimPingStat.addValue(10000); + stats.mSimPingStat.addValue(10000); } - LLViewerStats::getInstance()->mFPSStat.addValue(1); + stats.mFPSStat.addValue(1); F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); - LLViewerStats::getInstance()->mLayersKBitStat.addValue(layer_bits/1024.f); - LLViewerStats::getInstance()->mObjectKBitStat.addValue(gObjectBits/1024.f); - LLViewerStats::getInstance()->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); - LLViewerStats::getInstance()->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); + stats.mLayersKBitStat.addValue(layer_bits/1024.f); + stats.mObjectKBitStat.addValue(gObjectBits/1024.f); + stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); + stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); gTransferManager.resetTransferBitsIn(LLTCT_ASSET); if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) { - gDebugTimers[0].pause(); + gTextureTimer.pause(); } else { - gDebugTimers[0].unpause(); + gTextureTimer.unpause(); } { @@ -651,7 +499,7 @@ void update_statistics(U32 frame_count) visible_avatar_frames = 1.f; avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames; } - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars); + stats.setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars); } LLWorld::getInstance()->updateNetStats(); LLWorld::getInstance()->requestCacheMisses(); @@ -667,15 +515,14 @@ void update_statistics(U32 frame_count) static LLFrameTimer texture_stats_timer; if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq) { - LLViewerStats::getInstance()->mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f); - LLViewerStats::getInstance()->mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets); + stats.mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f); + stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets); gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8; LLViewerTextureList::sTextureBits = 0; LLViewerTextureList::sTexturePackets = 0; texture_stats_timer.reset(); } } - } class ViewerStatsResponder : public LLHTTPClient::Responder @@ -783,12 +630,41 @@ void send_stats() "%-6s Class %d ", gGLManager.mGLVendorShort.substr(0,6).c_str(), (S32)LLFeatureManager::getInstance()->getGPUClass()) - + LLFeatureManager::getInstance()->getGPUString(); + + gGLManager.getRawGLString(); system["gpu"] = gpu_desc; system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass(); system["gpu_vendor"] = gGLManager.mGLVendorShort; system["gpu_version"] = gGLManager.mDriverVersionVendorString; + system["opengl_version"] = gGLManager.mGLVersionString; + + S32 shader_level = 0; + if (LLPipeline::sRenderDeferred) + { + if (LLPipeline::RenderShadowDetail > 0) + { + shader_level = 5; + } + else if (LLPipeline::RenderDeferredSSAO) + { + shader_level = 4; + } + else + { + shader_level = 3; + } + } + else if (gPipeline.canUseWindLightShadersOnObjects()) + { + shader_level = 2; + } + else if (gPipeline.canUseVertexShaders()) + { + shader_level = 1; + } + + + system["shader_level"] = shader_level; LLSD &download = body["downloads"]; @@ -835,10 +711,7 @@ void send_stats() S32 window_height = gViewerWindow->getWindowHeightRaw(); S32 window_size = (window_width * window_height) / 1024; misc["string_1"] = llformat("%d", window_size); - if (gDebugTimers.find(0) != gDebugTimers.end() && gFrameTimeSeconds > 0) - { - misc["string_2"] = llformat("Texture Time: %.2f, Total Time: %.2f", gDebugTimers[0].getElapsedTimeF32(), gFrameTimeSeconds); - } + misc["string_2"] = llformat("Texture Time: %.2f, Total Time: %.2f", gTextureTimer.getElapsedTimeF32(), gFrameTimeSeconds); // misc["int_1"] = LLSD::Integer(gSavedSettings.getU32("RenderQualityPerformance")); // Steve: 1.21 // misc["int_2"] = LLSD::Integer(gFrameStalls); // Steve: 1.21 @@ -860,3 +733,103 @@ void send_stats() LLHTTPClient::post(url, body, new ViewerStatsResponder()); } +LLFrameTimer& LLViewerStats::PhaseMap::getPhaseTimer(const std::string& phase_name) +{ + phase_map_t::iterator iter = mPhaseMap.find(phase_name); + if (iter == mPhaseMap.end()) + { + LLFrameTimer timer; + mPhaseMap[phase_name] = timer; + } + LLFrameTimer& timer = mPhaseMap[phase_name]; + return timer; +} + +void LLViewerStats::PhaseMap::startPhase(const std::string& phase_name) +{ + LLFrameTimer& timer = getPhaseTimer(phase_name); + lldebugs << "startPhase " << phase_name << llendl; + timer.unpause(); +} + +void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name) +{ + phase_map_t::iterator iter = mPhaseMap.find(phase_name); + if (iter != mPhaseMap.end()) + { + if (iter->second.getStarted()) + { + // Going from started to paused state - record stats. + recordPhaseStat(phase_name,iter->second.getElapsedTimeF32()); + } + lldebugs << "stopPhase " << phase_name << llendl; + iter->second.pause(); + } + else + { + lldebugs << "stopPhase " << phase_name << " is not started, no-op" << llendl; + } +} + +void LLViewerStats::PhaseMap::stopAllPhases() +{ + for (phase_map_t::iterator iter = mPhaseMap.begin(); + iter != mPhaseMap.end(); ++iter) + { + const std::string& phase_name = iter->first; + if (iter->second.getStarted()) + { + // Going from started to paused state - record stats. + recordPhaseStat(phase_name,iter->second.getElapsedTimeF32()); + } + lldebugs << "stopPhase (all) " << phase_name << llendl; + iter->second.pause(); + } +} + +void LLViewerStats::PhaseMap::clearPhases() +{ + lldebugs << "clearPhases" << llendl; + + mPhaseMap.clear(); +} + +LLSD LLViewerStats::PhaseMap::dumpPhases() +{ + LLSD result; + for (phase_map_t::iterator iter = mPhaseMap.begin(); iter != mPhaseMap.end(); ++iter) + { + const std::string& phase_name = iter->first; + result[phase_name]["completed"] = LLSD::Integer(!(iter->second.getStarted())); + result[phase_name]["elapsed"] = iter->second.getElapsedTimeF32(); + } + return result; +} + +// static initializer +//static +LLViewerStats::phase_stats_t LLViewerStats::PhaseMap::sStats; + +LLViewerStats::PhaseMap::PhaseMap() +{ +} + +// static +LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name) +{ + phase_stats_t::iterator it = sStats.find(phase_name); + if (it == sStats.end()) + { + LLViewerStats::StatsAccumulator new_stats; + sStats[phase_name] = new_stats; + } + return sStats[phase_name]; +} + +// static +void LLViewerStats::PhaseMap::recordPhaseStat(const std::string& phase_name, F32 value) +{ + LLViewerStats::StatsAccumulator& stats = getPhaseStats(phase_name); + stats.push(value); +} + diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index f91a1241fe..e02a4ccdc7 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -33,87 +33,90 @@ class LLViewerStats : public LLSingleton<LLViewerStats> { public: - LLStat mKBitStat; - LLStat mLayersKBitStat; - LLStat mObjectKBitStat; - LLStat mAssetKBitStat; - LLStat mTextureKBitStat; - LLStat mVFSPendingOperations; - LLStat mObjectsDrawnStat; - LLStat mObjectsCulledStat; - LLStat mObjectsTestedStat; - LLStat mObjectsComparedStat; - LLStat mObjectsOccludedStat; - LLStat mFPSStat; - LLStat mPacketsInStat; - LLStat mPacketsLostStat; - LLStat mPacketsOutStat; - LLStat mPacketsLostPercentStat; - LLStat mTexturePacketsStat; - LLStat mActualInKBitStat; // From the packet ring (when faking a bad connection) - LLStat mActualOutKBitStat; // From the packet ring (when faking a bad connection) - LLStat mTrianglesDrawnStat; + LLStat mKBitStat, + mLayersKBitStat, + mObjectKBitStat, + mAssetKBitStat, + mTextureKBitStat, + mVFSPendingOperations, + mObjectsDrawnStat, + mObjectsCulledStat, + mObjectsTestedStat, + mObjectsComparedStat, + mObjectsOccludedStat, + mFPSStat, + mPacketsInStat, + mPacketsLostStat, + mPacketsOutStat, + mPacketsLostPercentStat, + mTexturePacketsStat, + mActualInKBitStat, // From the packet ring (when faking a bad connection) + mActualOutKBitStat, // From the packet ring (when faking a bad connection) + mTrianglesDrawnStat; // Simulator stats - LLStat mSimTimeDilation; - - LLStat mSimFPS; - LLStat mSimPhysicsFPS; - LLStat mSimAgentUPS; - LLStat mSimScriptEPS; - - LLStat mSimFrameMsec; - LLStat mSimNetMsec; - LLStat mSimSimOtherMsec; - LLStat mSimSimPhysicsMsec; - - LLStat mSimSimPhysicsStepMsec; - LLStat mSimSimPhysicsShapeUpdateMsec; - LLStat mSimSimPhysicsOtherMsec; - - LLStat mSimAgentMsec; - LLStat mSimImagesMsec; - LLStat mSimScriptMsec; - LLStat mSimSpareMsec; - LLStat mSimSleepMsec; - LLStat mSimPumpIOMsec; - - LLStat mSimMainAgents; - LLStat mSimChildAgents; - LLStat mSimObjects; - LLStat mSimActiveObjects; - LLStat mSimActiveScripts; - - LLStat mSimInPPS; - LLStat mSimOutPPS; - LLStat mSimPendingDownloads; - LLStat mSimPendingUploads; - LLStat mSimPendingLocalUploads; - LLStat mSimTotalUnackedBytes; - - LLStat mPhysicsPinnedTasks; - LLStat mPhysicsLODTasks; - LLStat mPhysicsMemoryAllocated; - - LLStat mSimPingStat; - - LLStat mNumImagesStat; - LLStat mNumRawImagesStat; - LLStat mGLTexMemStat; - LLStat mGLBoundMemStat; - LLStat mRawMemStat; - LLStat mFormattedMemStat; - - LLStat mNumObjectsStat; - LLStat mNumActiveObjectsStat; - LLStat mNumNewObjectsStat; - LLStat mNumSizeCulledStat; - LLStat mNumVisCulledStat; + LLStat mSimTimeDilation, + + mSimFPS, + mSimPhysicsFPS, + mSimAgentUPS, + mSimScriptEPS, + + mSimFrameMsec, + mSimNetMsec, + mSimSimOtherMsec, + mSimSimPhysicsMsec, + + mSimSimPhysicsStepMsec, + mSimSimPhysicsShapeUpdateMsec, + mSimSimPhysicsOtherMsec, + mSimSimAIStepMsec, + mSimSimSkippedSilhouetteSteps, + mSimSimPctSteppedCharacters, + + mSimAgentMsec, + mSimImagesMsec, + mSimScriptMsec, + mSimSpareMsec, + mSimSleepMsec, + mSimPumpIOMsec, + + mSimMainAgents, + mSimChildAgents, + mSimObjects, + mSimActiveObjects, + mSimActiveScripts, + mSimPctScriptsRun, + + mSimInPPS, + mSimOutPPS, + mSimPendingDownloads, + mSimPendingUploads, + mSimPendingLocalUploads, + mSimTotalUnackedBytes, + + mPhysicsPinnedTasks, + mPhysicsLODTasks, + mPhysicsMemoryAllocated, + + mSimPingStat, + + mNumImagesStat, + mNumRawImagesStat, + mGLTexMemStat, + mGLBoundMemStat, + mRawMemStat, + mFormattedMemStat, + + mNumObjectsStat, + mNumActiveObjectsStat, + mNumNewObjectsStat, + mNumSizeCulledStat, + mNumVisCulledStat; void resetStats(); public: - // If you change this, please also add a corresponding text label - // in statTypeToText in llviewerstats.cpp + // If you change this, please also add a corresponding text label in llviewerstats.cpp enum EStatType { ST_VERSION = 0, @@ -178,7 +181,6 @@ public: ST_COUNT = 58 }; - LLViewerStats(); ~LLViewerStats(); @@ -244,7 +246,7 @@ public: inline F32 getStdDev() const { const F32 mean = getMean(); - return (mCount == 0) ? 0.f : sqrt( mSumOfSquares/mCount - (mean * mean) ); + return (mCount < 2) ? 0.f : sqrt(llmax(0.f,mSumOfSquares/mCount - (mean * mean))); } inline U32 getCount() const @@ -274,7 +276,28 @@ public: }; StatsAccumulator mAgentPositionSnaps; - + + // Phase tracking (originally put in for avatar rezzing), tracking + // progress of active/completed phases for activities like outfit changing. + typedef std::map<std::string,LLFrameTimer> phase_map_t; + typedef std::map<std::string,StatsAccumulator> phase_stats_t; + class PhaseMap + { + private: + phase_map_t mPhaseMap; + static phase_stats_t sStats; + public: + PhaseMap(); + LLFrameTimer& getPhaseTimer(const std::string& phase_name); + void startPhase(const std::string& phase_name); + void stopPhase(const std::string& phase_name); + void stopAllPhases(); + void clearPhases(); + LLSD dumpPhases(); + static StatsAccumulator& getPhaseStats(const std::string& phase_name); + static void recordPhaseStat(const std::string& phase_name, F32 value); + }; + private: F64 mStats[ST_COUNT]; @@ -284,14 +307,10 @@ private: static const F32 SEND_STATS_PERIOD = 300.0f; // The following are from (older?) statistics code found in appviewer. -void init_statistics(); -void reset_statistics(); -void output_statistics(void*); -void update_statistics(U32 frame_count); +void update_statistics(); void send_stats(); -extern std::map<S32,LLFrameTimer> gDebugTimers; -extern std::map<S32,std::string> gDebugTimerLabel; +extern LLFrameTimer gTextureTimer; extern U32 gTotalTextureBytes; extern U32 gTotalObjectBytes; extern U32 gTotalTextureBytesPerBoostLevel[] ; diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp index e9d21b4848..91e485d01b 100644 --- a/indra/newview/llviewerstatsrecorder.cpp +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -27,7 +27,6 @@ #include "llviewerprecompiledheaders.h" #include "llviewerstatsrecorder.h" -#if LL_RECORD_VIEWER_STATS #include "llfile.h" #include "llviewerregion.h" @@ -45,9 +44,8 @@ LLViewerStatsRecorder* LLViewerStatsRecorder::sInstance = NULL; LLViewerStatsRecorder::LLViewerStatsRecorder() : mObjectCacheFile(NULL), mTimer(), - mRegionp(NULL), - mStartTime(0.f), - mProcessingTime(0.f) + mStartTime(0.0), + mLastSnapshotTime(0.0) { if (NULL != sInstance) { @@ -61,112 +59,77 @@ LLViewerStatsRecorder::~LLViewerStatsRecorder() { if (mObjectCacheFile != NULL) { + // last chance snapshot + writeToLog(0.f); LLFile::close(mObjectCacheFile); mObjectCacheFile = NULL; } } -// static -void LLViewerStatsRecorder::initClass() -{ - sInstance = new LLViewerStatsRecorder(); -} - -// static -void LLViewerStatsRecorder::cleanupClass() -{ - delete sInstance; - sInstance = NULL; -} - - -void LLViewerStatsRecorder::initStatsRecorder(LLViewerRegion *regionp) -{ - if (mObjectCacheFile == NULL) - { - mStartTime = LLTimer::getTotalTime(); - mObjectCacheFile = LLFile::fopen(STATS_FILE_NAME, "wb"); - if (mObjectCacheFile) - { // Write column headers - std::ostringstream data_msg; - data_msg << "EventTime, " - << "ProcessingTime, " - << "CacheHits, " - << "CacheFullMisses, " - << "CacheCrcMisses, " - << "FullUpdates, " - << "TerseUpdates, " - << "CacheMissRequests, " - << "CacheMissResponses, " - << "CacheUpdateDupes, " - << "CacheUpdateChanges, " - << "CacheUpdateAdds, " - << "CacheUpdateReplacements, " - << "UpdateFailures" - << "\n"; - - fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); - } - } -} - -void LLViewerStatsRecorder::beginObjectUpdateEvents(LLViewerRegion *regionp) -{ - initStatsRecorder(regionp); - mRegionp = regionp; - mProcessingTime = LLTimer::getTotalTime(); - clearStats(); -} - void LLViewerStatsRecorder::clearStats() { mObjectCacheHitCount = 0; + mObjectCacheHitSize = 0; mObjectCacheMissFullCount = 0; + mObjectCacheMissFullSize = 0; mObjectCacheMissCrcCount = 0; + mObjectCacheMissCrcSize = 0; mObjectFullUpdates = 0; + mObjectFullUpdatesSize = 0; mObjectTerseUpdates = 0; + mObjectTerseUpdatesSize = 0; mObjectCacheMissRequests = 0; mObjectCacheMissResponses = 0; + mObjectCacheMissResponsesSize = 0; mObjectCacheUpdateDupes = 0; mObjectCacheUpdateChanges = 0; mObjectCacheUpdateAdds = 0; mObjectCacheUpdateReplacements = 0; mObjectUpdateFailures = 0; + mObjectUpdateFailuresSize = 0; + mTextureFetchSize = 0; } -void LLViewerStatsRecorder::recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type) +void LLViewerStatsRecorder::recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size) { mObjectUpdateFailures++; + mObjectUpdateFailuresSize += msg_size; } -void LLViewerStatsRecorder::recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type) +void LLViewerStatsRecorder::recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size) { if (LLViewerRegion::CACHE_MISS_TYPE_FULL == cache_miss_type) { mObjectCacheMissFullCount++; + mObjectCacheMissFullSize += msg_size; } else { mObjectCacheMissCrcCount++; + mObjectCacheMissCrcSize += msg_size; } } -void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp) +void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size) { switch (update_type) { case OUT_FULL: mObjectFullUpdates++; + mObjectFullUpdatesSize += msg_size; break; case OUT_TERSE_IMPROVED: mObjectTerseUpdates++; + mObjectTerseUpdatesSize += msg_size; break; case OUT_FULL_COMPRESSED: mObjectCacheMissResponses++; + mObjectCacheMissResponsesSize += msg_size; break; case OUT_FULL_CACHED: mObjectCacheHitCount++; + mObjectCacheHitSize += msg_size; break; default: llwarns << "Unknown update_type" << llendl; @@ -174,7 +137,7 @@ void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectU }; } -void LLViewerStatsRecorder::recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp) +void LLViewerStatsRecorder::recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size) { switch (update_result) { @@ -201,9 +164,15 @@ void LLViewerStatsRecorder::recordRequestCacheMissesEvent(S32 count) mObjectCacheMissRequests += count; } -void LLViewerStatsRecorder::endObjectUpdateEvents() +void LLViewerStatsRecorder::writeToLog( F32 interval ) { - llinfos << "ILX: " + F64 delta_time = LLTimer::getTotalSeconds() - mLastSnapshotTime; + S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures; + + if ( delta_time < interval || total_objects == 0) return; + + mLastSnapshotTime = LLTimer::getTotalSeconds(); + lldebugs << "ILX: " << mObjectCacheHitCount << " hits, " << mObjectCacheMissFullCount << " full misses, " << mObjectCacheMissCrcCount << " crc misses, " @@ -218,41 +187,81 @@ void LLViewerStatsRecorder::endObjectUpdateEvents() << mObjectUpdateFailures << " update failures" << llendl; - S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures; - if (mObjectCacheFile != NULL && - total_objects > 0) + if (mObjectCacheFile == NULL) { - std::ostringstream data_msg; - F32 processing32 = (F32) ((LLTimer::getTotalTime() - mProcessingTime) / 1000.0); - - data_msg << getTimeSinceStart() - << ", " << processing32 - << ", " << mObjectCacheHitCount - << ", " << mObjectCacheMissFullCount - << ", " << mObjectCacheMissCrcCount - << ", " << mObjectFullUpdates - << ", " << mObjectTerseUpdates - << ", " << mObjectCacheMissRequests - << ", " << mObjectCacheMissResponses - << ", " << mObjectCacheUpdateDupes - << ", " << mObjectCacheUpdateChanges - << ", " << mObjectCacheUpdateAdds - << ", " << mObjectCacheUpdateReplacements - << ", " << mObjectUpdateFailures - << "\n"; + mStartTime = LLTimer::getTotalSeconds(); + mObjectCacheFile = LLFile::fopen(STATS_FILE_NAME, "wb"); + if (mObjectCacheFile) + { // Write column headers + std::ostringstream data_msg; + data_msg << "EventTime(ms)\t" + << "Cache Hits\t" + << "Cache Full Misses\t" + << "Cache Crc Misses\t" + << "Full Updates\t" + << "Terse Updates\t" + << "Cache Miss Requests\t" + << "Cache Miss Responses\t" + << "Cache Update Dupes\t" + << "Cache Update Changes\t" + << "Cache Update Adds\t" + << "Cache Update Replacements\t" + << "Update Failures\t" + << "Cache Hits bps\t" + << "Cache Full Misses bps\t" + << "Cache Crc Misses bps\t" + << "Full Updates bps\t" + << "Terse Updates bps\t" + << "Cache Miss Responses bps\t" + << "Texture Fetch bps\t" + << "\n"; - fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); + fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); + } + else + { + llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl; + return; + } } + std::ostringstream data_msg; + + data_msg << getTimeSinceStart() + << "\t " << mObjectCacheHitCount + << "\t" << mObjectCacheMissFullCount + << "\t" << mObjectCacheMissCrcCount + << "\t" << mObjectFullUpdates + << "\t" << mObjectTerseUpdates + << "\t" << mObjectCacheMissRequests + << "\t" << mObjectCacheMissResponses + << "\t" << mObjectCacheUpdateDupes + << "\t" << mObjectCacheUpdateChanges + << "\t" << mObjectCacheUpdateAdds + << "\t" << mObjectCacheUpdateReplacements + << "\t" << mObjectUpdateFailures + << "\t" << (mObjectCacheHitSize * 8 / delta_time) + << "\t" << (mObjectCacheMissFullSize * 8 / delta_time) + << "\t" << (mObjectCacheMissCrcSize * 8 / delta_time) + << "\t" << (mObjectFullUpdatesSize * 8 / delta_time) + << "\t" << (mObjectTerseUpdatesSize * 8 / delta_time) + << "\t" << (mObjectCacheMissResponsesSize * 8 / delta_time) + << "\t" << (mTextureFetchSize * 8 / delta_time) + << "\n"; + + fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); clearStats(); } F32 LLViewerStatsRecorder::getTimeSinceStart() { - return (F32) ((LLTimer::getTotalTime() - mStartTime) / 1000.0); + return (F32) (LLTimer::getTotalSeconds() - mStartTime); } -#endif +void LLViewerStatsRecorder::recordTextureFetch( S32 msg_size ) +{ + mTextureFetchSize += msg_size; +} diff --git a/indra/newview/llviewerstatsrecorder.h b/indra/newview/llviewerstatsrecorder.h index 612ac380f7..d1744f4910 100644 --- a/indra/newview/llviewerstatsrecorder.h +++ b/indra/newview/llviewerstatsrecorder.h @@ -35,63 +35,111 @@ #define LL_RECORD_VIEWER_STATS 0 -#if LL_RECORD_VIEWER_STATS #include "llframetimer.h" #include "llviewerobject.h" #include "llviewerregion.h" class LLMutex; -class LLViewerRegion; class LLViewerObject; -class LLViewerStatsRecorder +class LLViewerStatsRecorder : public LLSingleton<LLViewerStatsRecorder> { public: + LOG_CLASS(LLViewerStatsRecorder); LLViewerStatsRecorder(); ~LLViewerStatsRecorder(); - static void initClass(); - static void cleanupClass(); - static LLViewerStatsRecorder* instance() {return sInstance; } + void objectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size) + { +#if LL_RECORD_VIEWER_STATS + recordObjectUpdateFailure(local_id, update_type, msg_size); +#endif + } - void initStatsRecorder(LLViewerRegion *regionp); + void cacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size) + { +#if LL_RECORD_VIEWER_STATS + recordCacheMissEvent(local_id, update_type, cache_miss_type, msg_size); +#endif + } - void beginObjectUpdateEvents(LLViewerRegion *regionp); - void recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type); - void recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type); - void recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp); - void recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp); - void recordRequestCacheMissesEvent(S32 count); - void endObjectUpdateEvents(); + void objectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size) + { +#if LL_RECORD_VIEWER_STATS + recordObjectUpdateEvent(local_id, update_type, objectp, msg_size); +#endif + } + + void cacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size) + { +#if LL_RECORD_VIEWER_STATS + recordCacheFullUpdate(local_id, update_type, update_result, objectp, msg_size); +#endif + } + + void requestCacheMissesEvent(S32 count) + { +#if LL_RECORD_VIEWER_STATS + recordRequestCacheMissesEvent(count); +#endif + } + + void textureFetch(S32 msg_size) + { +#if LL_RECORD_VIEWER_STATS + recordTextureFetch(msg_size); +#endif + } + + void log(F32 interval) + { +#if LL_RECORD_VIEWER_STATS + writeToLog(interval); +#endif + } F32 getTimeSinceStart(); private: + void recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size); + void recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size); + void recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size); + void recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size); + void recordRequestCacheMissesEvent(S32 count); + void recordTextureFetch(S32 msg_size); + void writeToLog(F32 interval); + static LLViewerStatsRecorder* sInstance; LLFILE * mObjectCacheFile; // File to write data into LLFrameTimer mTimer; - LLViewerRegion* mRegionp; F64 mStartTime; - F64 mProcessingTime; + F64 mLastSnapshotTime; S32 mObjectCacheHitCount; + S32 mObjectCacheHitSize; S32 mObjectCacheMissFullCount; + S32 mObjectCacheMissFullSize; S32 mObjectCacheMissCrcCount; + S32 mObjectCacheMissCrcSize; S32 mObjectFullUpdates; + S32 mObjectFullUpdatesSize; S32 mObjectTerseUpdates; + S32 mObjectTerseUpdatesSize; S32 mObjectCacheMissRequests; S32 mObjectCacheMissResponses; + S32 mObjectCacheMissResponsesSize; S32 mObjectCacheUpdateDupes; S32 mObjectCacheUpdateChanges; S32 mObjectCacheUpdateAdds; S32 mObjectCacheUpdateReplacements; S32 mObjectUpdateFailures; + S32 mObjectUpdateFailuresSize; + S32 mTextureFetchSize; void clearStats(); }; -#endif // LL_RECORD_VIEWER_STATS #endif // LLVIEWERSTATSRECORDER_H diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index b41ed00f17..122d8f4a96 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -187,7 +187,7 @@ public: else { width = EMBEDDED_ITEM_LABEL_PADDING + mImage->getWidth() + mStyle->getFont()->getWidth(mLabel.c_str()); - height = llmax(mImage->getHeight(), llceil(mStyle->getFont()->getLineHeight())); + height = llmax(mImage->getHeight(), mStyle->getFont()->getLineHeight()); } return false; } @@ -1144,6 +1144,14 @@ void LLViewerTextEditor::openEmbeddedTexture( LLInventoryItem* item, llwchar wc { preview->setAuxItem( item ); preview->setNotecardInfo(mNotecardInventoryID, mObjectID); + if (preview->hasString("Title")) + { + LLStringUtil::format_map_t args; + args["[NAME]"] = item->getName(); + LLUIString title = preview->getString("Title", args); + preview->setTitle(title.getString()); + } + preview->getChild<LLUICtrl>("desc")->setValue(item->getDescription()); } } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 786e2b73b1..08fcb60d03 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -39,7 +39,6 @@ #include "llimagebmp.h" #include "llimagej2c.h" #include "llimagetga.h" -#include "llmemtype.h" #include "llstl.h" #include "llvfile.h" #include "llvfs.h" @@ -62,11 +61,13 @@ #include "llmediaentry.h" #include "llvovolume.h" #include "llviewermedia.h" +#include "lltexturecache.h" /////////////////////////////////////////////////////////////////////////////// // statics LLPointer<LLViewerTexture> LLViewerTexture::sNullImagep = NULL; LLPointer<LLViewerTexture> LLViewerTexture::sBlackImagep = NULL; +LLPointer<LLViewerTexture> LLViewerTexture::sCheckerBoardImagep = NULL; LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sMissingAssetImagep = NULL; LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL; LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL; @@ -87,6 +88,7 @@ S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0; S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0; S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ; S8 LLViewerTexture::sCameraMovingDiscardBias = 0 ; +F32 LLViewerTexture::sCameraMovingBias = 0.0f ; S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64 ; const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez ; @@ -96,6 +98,9 @@ S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA ; BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE ; F32 LLViewerTexture::sCurrentTime = 0.0f ; BOOL LLViewerTexture::sUseTextureAtlas = FALSE ; +F32 LLViewerTexture::sTexelPixelRatio = 1.0f; + +LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF; const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by const F32 desired_discard_bias_max = (F32)MAX_DISCARD_LEVEL; // max number of levels to reduce image quality by @@ -175,7 +180,12 @@ LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id) } return tex ; } - + +LLViewerFetchedTexture* LLViewerTextureManager::findFetchedTexture(const LLUUID& id) +{ + return gTextureList.findImage(id); +} + LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id) { return LLViewerMediaTexture::findMediaTexture(media_id) ; @@ -347,6 +357,21 @@ void LLViewerTextureManager::init() LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, LLViewerTexture::BOOST_UI); LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ; + image_raw = new LLImageRaw(32,32,3); + data = image_raw->getData(); + + for (S32 i = 0; i < (32*32*3); i+=3) + { + S32 x = (i % (32*3)) / (3*16); + S32 y = i / (32*3*16); + U8 color = ((x + y) % 2) * 255; + data[i] = color; + data[i+1] = color; + data[i+2] = color; + } + + LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE); + LLViewerTexture::initClass() ; if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) @@ -367,6 +392,7 @@ void LLViewerTextureManager::cleanup() LLImageGL::sDefaultGLTexture = NULL ; LLViewerTexture::sNullImagep = NULL; LLViewerTexture::sBlackImagep = NULL; + LLViewerTexture::sCheckerBoardImagep = NULL; LLViewerFetchedTexture::sDefaultImagep = NULL; LLViewerFetchedTexture::sSmokeImagep = NULL; LLViewerFetchedTexture::sMissingAssetImagep = NULL; @@ -383,10 +409,10 @@ void LLViewerTextureManager::cleanup() void LLViewerTexture::initClass() { LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ; - - if(gAuditTexture) + + if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled")) { - LLImageGL::setHighlightTexture(LLViewerTexture::OTHER) ; + sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio"); } } @@ -417,11 +443,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 +472,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 +493,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 +509,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 @@ -513,7 +560,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ; F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed(); - sCameraMovingDiscardBias = (S8)llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1) ; + sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1); + sCameraMovingDiscardBias = (S8)(sCameraMovingBias); LLViewerTexture::sFreezeImageScalingDown = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) && (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ; @@ -575,6 +623,7 @@ LLViewerTexture::~LLViewerTexture() void LLViewerTexture::init(bool firstinit) { mBoostLevel = LLViewerTexture::BOOST_NONE; + mSelectedTime = 0.f; mFullWidth = 0; mFullHeight = 0; @@ -630,15 +679,18 @@ void LLViewerTexture::setBoostLevel(S32 level) if(mBoostLevel != level) { mBoostLevel = level ; - if(mBoostLevel != LLViewerTexture::BOOST_NONE) + if(mBoostLevel != LLViewerTexture::BOOST_NONE && + mBoostLevel != LLViewerTexture::BOOST_SELECTED) { setNoDelete() ; } - if(gAuditTexture) - { - setCategory(mBoostLevel); - } } + + if (mBoostLevel == LLViewerTexture::BOOST_SELECTED) + { + mSelectedTime = gFrameTimeSeconds; + } + } @@ -691,6 +743,7 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co mNeedsGLTexture = TRUE ; } + virtual_size *= sTexelPixelRatio; if(!mMaxVirtualSizeResetCounter) { //flag to reset the values because the old values are used. @@ -1195,7 +1248,7 @@ void LLViewerFetchedTexture::init(bool firstinit) mIsMissingAsset = FALSE; mLoadedCallbackDesiredDiscardLevel = S8_MAX; - mPauseLoadedCallBacks = TRUE ; + mPauseLoadedCallBacks = FALSE ; mNeedsCreateTexture = FALSE; @@ -1212,6 +1265,7 @@ void LLViewerFetchedTexture::init(bool firstinit) mRequestDeltaTime = 0.f; mForSculpt = FALSE ; mIsFetched = FALSE ; + mInFastCacheList = FALSE; mCachedRawImage = NULL ; mCachedRawDiscardLevel = -1 ; @@ -1225,6 +1279,8 @@ void LLViewerFetchedTexture::init(bool firstinit) mLastReferencedSavedRawImageTime = 0.0f ; mKeptSavedRawImageTime = 0.f ; mLastCallBackActiveTime = 0.f; + + mInDebug = FALSE; } LLViewerFetchedTexture::~LLViewerFetchedTexture() @@ -1266,6 +1322,39 @@ void LLViewerFetchedTexture::cleanup() mCachedRawDiscardLevel = -1 ; mCachedRawImageReady = FALSE ; mSavedRawImage = NULL ; + mSavedRawDiscardLevel = -1; +} + +//access the fast cache +void LLViewerFetchedTexture::loadFromFastCache() +{ + if(!mInFastCacheList) + { + return; //no need to access the fast cache. + } + mInFastCacheList = FALSE; + + mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel) ; + if(mRawImage.notNull()) + { + mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; + mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; + setTexelsPerImage(); + + if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE) + { + //discard all oversized textures. + destroyRawImage(); + setIsMissingAsset(); + mRawDiscardLevel = INVALID_DISCARD_LEVEL ; + } + else + { + mRequestedDiscardLevel = mDesiredDiscardLevel + 1; + mIsRawImageValid = TRUE; + addToCreateTexture() ; + } + } } void LLViewerFetchedTexture::setForSculpt() @@ -1273,9 +1362,10 @@ void LLViewerFetchedTexture::setForSculpt() static const S32 MAX_INTERVAL = 8 ; //frames mForSculpt = TRUE ; - if(isForSculptOnly() && !getBoundRecently()) + if(isForSculptOnly() && hasGLTexture() && !getBoundRecently()) { destroyGLTexture() ; //sculpt image does not need gl texture. + mTextureState = ACTIVE; } checkCachedRawSculptImage() ; setMaxVirtualSizeResetInterval(MAX_INTERVAL) ; @@ -1356,10 +1446,10 @@ void LLViewerFetchedTexture::dump() // ONLY called from LLViewerFetchedTextureList void LLViewerFetchedTexture::destroyTexture() { - if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory. - { - return ; - } + //if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory. + //{ + // return ; + //} if (mNeedsCreateTexture)//return if in the process of generating a new texture. { return ; @@ -1693,7 +1783,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority() S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired; ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY); priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR; - setAdditionalDecodePriority(1.0f) ;//boost the textures without any data so far. + setAdditionalDecodePriority(0.1f) ;//boost the textures without any data so far. } else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel)) { @@ -1794,8 +1884,6 @@ F32 LLViewerFetchedTexture::maxDecodePriority() void LLViewerFetchedTexture::setDecodePriority(F32 priority) { - llassert(!mInImageList); - mDecodePriority = priority; if(mDecodePriority < F_ALMOST_ZERO) @@ -1823,13 +1911,34 @@ void LLViewerFetchedTexture::updateVirtualSize() for(U32 i = 0 ; i < mNumFaces ; i++) { LLFace* facep = mFaceList[i] ; - if(facep->getDrawable()->isRecentlyVisible()) + if( facep ) { - addTextureStats(facep->getVirtualSize()) ; - setAdditionalDecodePriority(facep->getImportanceToCamera()) ; + LLDrawable* drawable = facep->getDrawable(); + if (drawable) + { + if(drawable->isRecentlyVisible()) + { + if (getBoostLevel() == LLViewerTexture::BOOST_NONE && + drawable->getVObj() && drawable->getVObj()->isSelected()) + { + setBoostLevel(LLViewerTexture::BOOST_SELECTED); + } + addTextureStats(facep->getVirtualSize()) ; + setAdditionalDecodePriority(facep->getImportanceToCamera()) ; + } + } } } + //reset whether or not a face was selected after 10 seconds + const F32 SELECTION_RESET_TIME = 10.f; + + if (getBoostLevel() == LLViewerTexture::BOOST_SELECTED && + gFrameTimeSeconds - mSelectedTime > SELECTION_RESET_TIME) + { + setBoostLevel(LLViewerTexture::BOOST_NONE); + } + if(mMaxVirtualSizeResetCounter > 0) { mMaxVirtualSizeResetCounter--; @@ -1856,9 +1965,25 @@ S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching() return current_discard ; } +bool LLViewerFetchedTexture::setDebugFetching(S32 debug_level) +{ + if(debug_level < 0) + { + mInDebug = FALSE; + return false; + } + mInDebug = TRUE; + + mDesiredDiscardLevel = debug_level; + + return true; +} + bool LLViewerFetchedTexture::updateFetch() { static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled"); + static LLCachedControl<F32> sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold"); + static LLCachedControl<S32> sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost"); if(textures_decode_disabled) { return false ; @@ -1891,6 +2016,10 @@ bool LLViewerFetchedTexture::updateFetch() { return false; // process any raw image data in callbacks before replacing } + if(mInFastCacheList) + { + return false; + } S32 current_discard = getCurrentDiscardLevelForFetching() ; S32 desired_discard = getDesiredDiscardLevel(); @@ -2008,6 +2137,10 @@ bool LLViewerFetchedTexture::updateFetch() { make_request = false; } + else if(mDesiredDiscardLevel > getMaxDiscardLevel()) + { + make_request = false; + } else if (mNeedsCreateTexture || mIsMissingAsset) { make_request = false; @@ -2016,23 +2149,34 @@ bool LLViewerFetchedTexture::updateFetch() { make_request = false; } + else if(mCachedRawImage.notNull() && (current_discard < 0 || current_discard > mCachedRawDiscardLevel)) + { + make_request = false; + switchToCachedImage() ; //use the cached raw data first + } //else if (!isJustBound() && mCachedRawImageReady) //{ // make_request = false; //} - if(make_request) + if (make_request) { - //load the texture progressively. + // Load the texture progressively: we try not to rush to the desired discard too fast. + // If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps + // This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around S32 delta_level = (mBoostLevel > LLViewerTexture::BOOST_NONE) ? 2 : 1 ; - if(current_discard < 0) + if (current_discard < 0) { desired_discard = llmax(desired_discard, getMaxDiscardLevel() - delta_level); } - else + else if (LLViewerTexture::sCameraMovingBias < sCameraMotionThreshold) { - desired_discard = llmax(desired_discard, current_discard - delta_level); + desired_discard = llmax(desired_discard, current_discard - sCameraMotionBoost); } + else + { + desired_discard = llmax(desired_discard, current_discard - delta_level); + } if (mIsFetching) { @@ -2100,6 +2244,35 @@ bool LLViewerFetchedTexture::updateFetch() return mIsFetching ? true : false; } +void LLViewerFetchedTexture::clearFetchedResults() +{ + if(mNeedsCreateTexture || mIsFetching) + { + return ; + } + + cleanup(); + destroyGLTexture(); + + if(getDiscardLevel() >= 0) //sculpty texture, force to invalidate + { + mGLTexturep->forceToInvalidateGLTexture(); + } +} + +void LLViewerFetchedTexture::forceToDeleteRequest() +{ + if (mHasFetcher) + { + mHasFetcher = FALSE; + mIsFetching = FALSE ; + } + + resetTextureStats(); + + mDesiredDiscardLevel = getMaxDiscardLevel() + 1; +} + void LLViewerFetchedTexture::setIsMissingAsset() { if (mUrl.empty()) @@ -2108,7 +2281,8 @@ void LLViewerFetchedTexture::setIsMissingAsset() } else { - llwarns << mUrl << ": Marking image as missing" << llendl; + //it is normal no map tile on an empty region. + //llwarns << mUrl << ": Marking image as missing" << llendl; } if (mHasFetcher) { @@ -2140,10 +2314,18 @@ void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_call mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel, (S8)discard_level) ; } - if(mPauseLoadedCallBacks && !pause) + if(mPauseLoadedCallBacks) { - unpauseLoadedCallbacks(src_callback_list) ; + if(!pause) + { + unpauseLoadedCallbacks(src_callback_list) ; + } } + else if(pause) + { + pauseLoadedCallbacks(src_callback_list) ; + } + LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause); mLoadedCallbackList.push_back(entryp); @@ -2269,6 +2451,7 @@ void LLViewerFetchedTexture::unpauseLoadedCallbacks(const LLLoadedCallbackEntry: } } mPauseLoadedCallBacks = FALSE ; + mLastCallBackActiveTime = sCurrentTime ; if(need_raw) { mSaveRawImage = TRUE ; @@ -2308,13 +2491,18 @@ void LLViewerFetchedTexture::pauseLoadedCallbacks(const LLLoadedCallbackEntry::s bool LLViewerFetchedTexture::doLoadedCallbacks() { - static const F32 MAX_INACTIVE_TIME = 120.f ; //seconds + static const F32 MAX_INACTIVE_TIME = 900.f ; //seconds if (mNeedsCreateTexture) { return false; } - if(sCurrentTime - mLastCallBackActiveTime > MAX_INACTIVE_TIME) + if(mPauseLoadedCallBacks) + { + destroyRawImage(); + return false; //paused + } + if(sCurrentTime - mLastCallBackActiveTime > MAX_INACTIVE_TIME && !mIsFetching) { clearCallbackEntryList() ; //remove all callbacks. return false ; @@ -2337,12 +2525,8 @@ bool LLViewerFetchedTexture::doLoadedCallbacks() // Remove ourself from the global list of textures with callbacks gTextureList.mCallbackList.erase(this); - } - if(mPauseLoadedCallBacks) - { - destroyRawImage(); - return res; //paused - } + return false ; + } S32 gl_discard = getDiscardLevel(); @@ -2604,7 +2788,11 @@ bool LLViewerFetchedTexture::needsToSaveRawImage() void LLViewerFetchedTexture::destroyRawImage() { - if (mAuxRawImage.notNull()) sAuxCount--; + if (mAuxRawImage.notNull()) + { + sAuxCount--; + mAuxRawImage = NULL; + } if (mRawImage.notNull()) { @@ -2618,12 +2806,12 @@ void LLViewerFetchedTexture::destroyRawImage() } setCachedRawImage() ; } + + mRawImage = NULL; + + mIsRawImageValid = FALSE; + mRawDiscardLevel = INVALID_DISCARD_LEVEL; } - - mRawImage = NULL; - mAuxRawImage = NULL; - mIsRawImageValid = FALSE; - mRawDiscardLevel = INVALID_DISCARD_LEVEL; } //use the mCachedRawImage to (re)generate the gl texture. @@ -3136,8 +3324,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() ; @@ -3258,10 +3451,14 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL sMediaMap.insert(std::make_pair(id, this)); mGLTexturep = gl_image ; + if(mGLTexturep.isNull()) { generateGLTexture() ; } + + mGLTexturep->setAllowCompression(false); + mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ; mIsPlaying = FALSE ; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index b96441127d..2e7949e9a3 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -139,6 +139,7 @@ public: OTHER, MAX_GL_IMAGE_CATEGORY }; + static S32 getTotalNumOfCategories() ; static S32 getIndexFromCategory(S32 category) ; static S32 getCategoryFromIndex(S32 index) ; @@ -263,6 +264,9 @@ protected: void reorganizeVolumeList() ; void setTexelsPerImage(); private: + friend class LLBumpImageList; + friend class LLUIImageList; + //note: do not make this function public. /*virtual*/ LLImageGL* getGLTexture() const ; virtual void switchToCachedImage(); @@ -271,6 +275,7 @@ private: protected: LLUUID mID; S32 mBoostLevel; // enum describing priority level + F32 mSelectedTime; // time texture was last selected S32 mFullWidth; S32 mFullHeight; BOOL mUseMipMaps ; @@ -309,6 +314,7 @@ protected: } LLGLTextureState; LLGLTextureState mTextureState ; + static F32 sTexelPixelRatio; public: static const U32 sCurrentFileVersion; static S32 sImageCount; @@ -323,6 +329,7 @@ public: static S32 sMaxTotalTextureMemInMegaBytes; static S32 sMaxDesiredTextureMemInBytes ; static S8 sCameraMovingDiscardBias; + static F32 sCameraMovingBias; static S32 sMaxSculptRez ; static S32 sMinLargeImageSize ; static S32 sMaxSmallImageSize ; @@ -330,8 +337,19 @@ public: static F32 sCurrentTime ; static BOOL sUseTextureAtlas ; + enum EDebugTexels + { + DEBUG_TEXELS_OFF, + DEBUG_TEXELS_CURRENT, + DEBUG_TEXELS_DESIRED, + DEBUG_TEXELS_FULL + }; + + static EDebugTexels sDebugTexelsMode; + static LLPointer<LLViewerTexture> sNullImagep; // Null texture for non-textured objects. static LLPointer<LLViewerTexture> sBlackImagep; // Texture to show NOTHING (pure black) + static LLPointer<LLViewerTexture> sCheckerBoardImagep; // Texture to show NOTHING (pure black) }; @@ -419,7 +437,11 @@ public: void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } bool updateFetch(); + bool setDebugFetching(S32 debug_level); + bool isInDebug() {return mInDebug;} + void clearFetchedResults(); //clear all fetched results, for debug use. + // Override the computation of discard levels if we know the exact output // size of the image. Used for UI textures to not decode, even if we have // more data. @@ -478,6 +500,10 @@ public: BOOL hasFetcher() const { return mHasFetcher;} void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;} + void forceToDeleteRequest(); + void loadFromFastCache(); + void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; } + bool isInFastCacheList() { return mInFastCacheList; } protected: /*virtual*/ void switchToCachedImage(); S32 getCurrentDiscardLevelForFetching() ; @@ -496,6 +522,8 @@ private: private: BOOL mFullyLoaded; + BOOL mInDebug; + BOOL mInFastCacheList; protected: std::string mLocalFileName; @@ -687,6 +715,7 @@ public: //"find-texture" just check if the texture exists, if yes, return it, otherwise return null. // static LLViewerTexture* findTexture(const LLUUID& id) ; + static LLViewerFetchedTexture* findFetchedTexture(const LLUUID& id) ; static LLViewerMediaTexture* findMediaTexture(const LLUUID& id) ; static LLViewerMediaTexture* createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; diff --git a/indra/newview/llviewertextureanim.cpp b/indra/newview/llviewertextureanim.cpp index 9f1ac7c49c..2b364851a7 100644 --- a/indra/newview/llviewertextureanim.cpp +++ b/indra/newview/llviewertextureanim.cpp @@ -27,21 +27,37 @@ #include "llviewerprecompiledheaders.h" #include "llviewertextureanim.h" +#include "llvovolume.h" #include "llmath.h" #include "llerror.h" -LLViewerTextureAnim::LLViewerTextureAnim() : LLTextureAnim() +std::vector<LLViewerTextureAnim*> LLViewerTextureAnim::sInstanceList; + +LLViewerTextureAnim::LLViewerTextureAnim(LLVOVolume* vobj) : LLTextureAnim() { + mVObj = vobj; mLastFrame = -1.f; // Force an update initially mLastTime = 0.f; mOffS = mOffT = 0; mScaleS = mScaleT = 1; mRot = 0; + + mInstanceIndex = sInstanceList.size(); + sInstanceList.push_back(this); } LLViewerTextureAnim::~LLViewerTextureAnim() { + S32 end_idx = sInstanceList.size()-1; + + if (end_idx != mInstanceIndex) + { + sInstanceList[mInstanceIndex] = sInstanceList[end_idx]; + sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex; + } + + sInstanceList.pop_back(); } void LLViewerTextureAnim::reset() @@ -50,6 +66,14 @@ void LLViewerTextureAnim::reset() mTimer.reset(); } +//static +void LLViewerTextureAnim::updateClass() +{ + for (std::vector<LLViewerTextureAnim*>::iterator iter = sInstanceList.begin(); iter != sInstanceList.end(); ++iter) + { + (*iter)->mVObj->animateTextures(); + } +} S32 LLViewerTextureAnim::animateTextures(F32 &off_s, F32 &off_t, F32 &scale_s, F32 &scale_t, diff --git a/indra/newview/llviewertextureanim.h b/indra/newview/llviewertextureanim.h index dd7bd0cb90..abbfabceb9 100644 --- a/indra/newview/llviewertextureanim.h +++ b/indra/newview/llviewertextureanim.h @@ -30,10 +30,18 @@ #include "lltextureanim.h" #include "llframetimer.h" +class LLVOVolume; + class LLViewerTextureAnim : public LLTextureAnim { +private: + static std::vector<LLViewerTextureAnim*> sInstanceList; + S32 mInstanceIndex; + public: - LLViewerTextureAnim(); + static void updateClass(); + + LLViewerTextureAnim(LLVOVolume* vobj); virtual ~LLViewerTextureAnim(); /*virtual*/ void reset(); @@ -51,6 +59,7 @@ public: F32 mRot; protected: + LLVOVolume* mVObj; LLFrameTimer mTimer; F64 mLastTime; F32 mLastFrame; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index cddf7dcfea..b9f5c432d0 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -58,6 +58,7 @@ #include "pipeline.h" #include "llappviewer.h" #include "llxuiparser.h" +#include "llviewerdisplay.h" //////////////////////////////////////////////////////////////////////////// @@ -66,12 +67,12 @@ void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL; U32 LLViewerTextureList::sTextureBits = 0; U32 LLViewerTextureList::sTexturePackets = 0; S32 LLViewerTextureList::sNumImages = 0; -LLStat LLViewerTextureList::sNumImagesStat(32, TRUE); -LLStat LLViewerTextureList::sNumRawImagesStat(32, TRUE); -LLStat LLViewerTextureList::sGLTexMemStat(32, TRUE); -LLStat LLViewerTextureList::sGLBoundMemStat(32, TRUE); -LLStat LLViewerTextureList::sRawMemStat(32, TRUE); -LLStat LLViewerTextureList::sFormattedMemStat(32, TRUE); +LLStat LLViewerTextureList::sNumImagesStat("Num Images", 32, TRUE); +LLStat LLViewerTextureList::sNumRawImagesStat("Num Raw Images", 32, TRUE); +LLStat LLViewerTextureList::sGLTexMemStat("GL Texture Mem", 32, TRUE); +LLStat LLViewerTextureList::sGLBoundMemStat("GL Bound Mem", 32, TRUE); +LLStat LLViewerTextureList::sRawMemStat("Raw Image Mem", 32, TRUE); +LLStat LLViewerTextureList::sFormattedMemStat("Formatted Image Mem", 32, TRUE); LLViewerTextureList gTextureList; static LLFastTimer::DeclareTimer FTM_PROCESS_IMAGES("Process Images"); @@ -275,6 +276,7 @@ void LLViewerTextureList::shutdown() // Flush all of the references mLoadingStreamList.clear(); mCreateTextureList.clear(); + mFastCacheList.clear(); mUUIDMap.clear(); @@ -452,6 +454,8 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, LLGLenum primary_format, LLHost request_from_host) { + static LLCachedControl<bool> fast_cache_fetching_enabled(gSavedSettings, "FastCacheFetchEnabled"); + LLPointer<LLViewerFetchedTexture> imagep ; switch(texture_type) { @@ -489,6 +493,11 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, imagep->forceActive() ; } + if(fast_cache_fetching_enabled) + { + mFastCacheList.insert(imagep); + imagep->setInFastCacheList(true); + } return imagep ; } @@ -502,6 +511,7 @@ LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id) void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) { + assert_main_thread(); llassert_always(mInitialized) ; llassert(image); if (image->isInImageList()) @@ -518,6 +528,7 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) { + assert_main_thread(); llassert_always(mInitialized) ; llassert(image); if (!image->isInImageList()) @@ -534,6 +545,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 ; } @@ -591,11 +603,25 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_MARK_DIRTY("Dirty Images"); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_PRIORITIES("Prioritize"); static LLFastTimer::DeclareTimer FTM_IMAGE_CALLBACKS("Callbacks"); static LLFastTimer::DeclareTimer FTM_IMAGE_FETCH("Fetch"); +static LLFastTimer::DeclareTimer FTM_FAST_CACHE_IMAGE_FETCH("Fast Cache Fetch"); static LLFastTimer::DeclareTimer FTM_IMAGE_CREATE("Create"); static LLFastTimer::DeclareTimer FTM_IMAGE_STATS("Stats"); void LLViewerTextureList::updateImages(F32 max_time) { + static BOOL cleared = FALSE; + if(gTeleportDisplay) + { + if(!cleared) + { + clearFetchingRequests(); + gPipeline.clearRebuildGroups(); + cleared = TRUE; + } + return; + } + cleared = FALSE; + LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec()); LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages); @@ -605,6 +631,11 @@ void LLViewerTextureList::updateImages(F32 max_time) LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory)); LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory)); + { + //loading from fast cache + LLFastTimer t(FTM_FAST_CACHE_IMAGE_FETCH); + max_time -= updateImagesLoadingFastCache(max_time); + } { LLFastTimer t(FTM_IMAGE_UPDATE_PRIORITIES); @@ -658,14 +689,32 @@ void LLViewerTextureList::updateImages(F32 max_time) } } +void LLViewerTextureList::clearFetchingRequests() +{ + if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) + { + return; + } + + LLAppViewer::getTextureFetch()->deleteAllRequests(); + + for (image_priority_list_t::iterator iter = mImageList.begin(); + iter != mImageList.end(); ++iter) + { + LLViewerFetchedTexture* imagep = *iter; + imagep->forceToDeleteRequest() ; + } +} + void LLViewerTextureList::updateImagesDecodePriorities() { // Update the decode priority for N images each frame { - const size_t max_update_count = llmin((S32) (1024*gFrameIntervalSeconds) + 1, 32); //target 1024 textures per second - S32 update_counter = llmin(max_update_count, mUUIDMap.size()/10); + static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32 + const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds) + 1, MAX_PRIO_UPDATES); + S32 update_counter = llmin(max_update_count, mUUIDMap.size()); uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID); - while(update_counter > 0 && !mUUIDMap.empty()) + while ((update_counter-- > 0) && !mUUIDMap.empty()) { if (iter == mUUIDMap.end()) { @@ -673,13 +722,19 @@ void LLViewerTextureList::updateImagesDecodePriorities() } mLastUpdateUUID = iter->first; LLPointer<LLViewerFetchedTexture> imagep = iter->second; - ++iter; // safe to incrament now + ++iter; // safe to increment now + + if(imagep->isInDebug()) + { + update_counter--; + continue; //is in debug, ignore. + } // // Flush formatted images using a lazy flush // const F32 LAZY_FLUSH_TIMEOUT = 30.f; // stop decoding - const F32 MAX_INACTIVE_TIME = 50.f; // actually delete + const F32 MAX_INACTIVE_TIME = 20.f; // actually delete S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference S32 num_refs = imagep->getNumRefs(); @@ -728,7 +783,16 @@ void LLViewerTextureList::updateImagesDecodePriorities() imagep->setInactive() ; } } - + + if (!imagep->isInImageList()) + { + continue; + } + if(imagep->isInFastCacheList()) + { + continue; //wait for loading from the fast cache. + } + imagep->processTextureStats(); F32 old_priority = imagep->getDecodePriority(); F32 old_priority_test = llmax(old_priority, 0.0f); @@ -738,15 +802,35 @@ void LLViewerTextureList::updateImagesDecodePriorities() if ((decode_priority_test < old_priority_test * .8f) || (decode_priority_test > old_priority_test * 1.25f)) { - removeImageFromList(imagep); + mImageList.erase(imagep) ; imagep->setDecodePriority(decode_priority); - addImageToList(imagep); + mImageList.insert(imagep); } - update_counter--; } } } +void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level) +{ + if(!tex->setDebugFetching(debug_level)) + { + return; + } + + const F32 DEBUG_PRIORITY = 100000.f; + F32 old_priority_test = llmax(tex->getDecodePriority(), 0.0f); + F32 decode_priority_test = DEBUG_PRIORITY; + + // Ignore < 20% difference + if ((decode_priority_test < old_priority_test * .8f) || + (decode_priority_test > old_priority_test * 1.25f)) + { + removeImageFromList(tex); + tex->setDecodePriority(decode_priority_test); + addImageToList(tex); + } +} + /* static U8 get_image_type(LLViewerFetchedTexture* imagep, LLHost target_host) { @@ -801,6 +885,36 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) return create_timer.getElapsedTimeF32(); } +F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time) +{ + if (gGLManager.mIsDisabled) return 0.0f; + if(mFastCacheList.empty()) + { + return 0.f; + } + + // + // loading texture raw data from the fast cache directly. + // + + LLTimer timer; + image_list_t::iterator enditer = mFastCacheList.begin(); + for (image_list_t::iterator iter = mFastCacheList.begin(); + iter != mFastCacheList.end();) + { + image_list_t::iterator curiter = iter++; + enditer = iter; + LLViewerFetchedTexture *imagep = *curiter; + imagep->loadFromFastCache(); + if (timer.getElapsedTimeF32() > max_time) + { + break; + } + } + mFastCacheList.erase(mFastCacheList.begin(), enditer); + return timer.getElapsedTimeF32(); +} + void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep) { if(!imagep) @@ -824,15 +938,24 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) { LLTimer image_op_timer; - // Update the decode priority for N images each frame - // Make a list with 32 high priority entries + 256 cycled entries - const size_t max_priority_count = llmin((S32) (256*10.f*gFrameIntervalSeconds)+1, 32); - const size_t max_update_count = llmin((S32) (1024*10.f*gFrameIntervalSeconds)+1, 256); + // Update fetch for N images each frame + static const S32 MAX_HIGH_PRIO_COUNT = gSavedSettings.getS32("TextureFetchUpdateHighPriority"); // default: 32 + static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority"); // default: 256 + static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority"); // default: 32 + static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0 + static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority"); // default: false + + size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds)+1, MAX_HIGH_PRIO_COUNT); + max_priority_count = llmin(max_priority_count, mImageList.size()); - // 32 high priority entries + size_t total_update_count = mUUIDMap.size(); + size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds)+1, MAX_UPDATE_COUNT); + max_update_count = llmin(max_update_count, total_update_count); + + // MAX_HIGH_PRIO_COUNT high priority entries typedef std::vector<LLViewerFetchedTexture*> entries_list_t; entries_list_t entries; - size_t update_counter = llmin(max_priority_count, mImageList.size()); + size_t update_counter = max_priority_count; image_priority_list_t::iterator iter1 = mImageList.begin(); while(update_counter > 0) { @@ -842,52 +965,47 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) update_counter--; } - // 256 cycled entries - update_counter = llmin(max_update_count, mUUIDMap.size()); + // MAX_UPDATE_COUNT cycled entries + update_counter = max_update_count; if(update_counter > 0) { uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID); - uuid_map_t::iterator iter2p = iter2; - while(update_counter > 0) + while ((update_counter > 0) && (total_update_count > 0)) { if (iter2 == mUUIDMap.end()) { iter2 = mUUIDMap.begin(); } - entries.push_back(iter2->second); - iter2p = iter2++; - update_counter--; + LLViewerFetchedTexture* imagep = iter2->second; + // Skip the textures where there's really nothing to do so to give some times to others. Also skip the texture if it's already in the high prio set. + if (!SKIP_LOW_PRIO || (SKIP_LOW_PRIO && ((imagep->getDecodePriority() > MIN_PRIORITY_THRESHOLD) || imagep->hasFetcher()))) + { + entries.push_back(imagep); + update_counter--; + } + + iter2++; + total_update_count--; } - - mLastFetchUUID = iter2p->first; } S32 fetch_count = 0; - S32 min_count = max_priority_count + max_update_count/4; + size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count)); + S32 min_count = max_priority_count + min_update_count; for (entries_list_t::iterator iter3 = entries.begin(); iter3 != entries.end(); ) { LLViewerFetchedTexture* imagep = *iter3++; - - bool fetching = imagep->updateFetch(); - if (fetching) + fetch_count += (imagep->updateFetch() ? 1 : 0); + if (min_count <= min_update_count) { - fetch_count++; + mLastFetchUUID = imagep->getID(); } - if (min_count <= 0 && image_op_timer.getElapsedTimeF32() > max_time) + if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time)) { break; } - min_count--; - } - //if (fetch_count == 0) - //{ - // gDebugTimers[0].pause(); - //} - //else - //{ - // gDebugTimers[0].unpause(); - //} + } return image_op_timer.getElapsedTimeF32(); } @@ -910,6 +1028,9 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) { LLTimer timer; + //loading from fast cache + updateImagesLoadingFastCache(max_time); + // Update texture stats and priorities std::vector<LLPointer<LLViewerFetchedTexture> > image_list; for (image_priority_list_t::iterator iter = mImageList.begin(); @@ -919,6 +1040,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) @@ -1027,7 +1150,6 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage { raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C(); - compressedImage->setRate(0.f); if (gSavedSettings.getBOOL("LosslessJ2CUpload") && (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)) @@ -1255,7 +1377,6 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d { static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic") ; - LLMemType mt1(LLMemType::MTYPE_APPFMTIMAGE); LLFastTimer t(FTM_PROCESS_IMAGES); // Receives image packet, copy into image object, @@ -1429,6 +1550,9 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st imagep->setAddressMode(LLTexUnit::TAM_CLAMP); + //don't compress UI images + imagep->getGLTexture()->setAllowCompression(false); + //all UI images are non-deletable imagep->setNoDelete(); @@ -1553,49 +1677,43 @@ struct UIImageDeclarations : public LLInitParam::Block<UIImageDeclarations> bool LLUIImageList::initFromFile() { - // construct path to canonical textures.xml in default skin dir - std::string base_file_path = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "default", "textures", "textures.xml"); + // Look for textures.xml in all the right places. Pass + // constraint=LLDir::ALL_SKINS because we want to overlay textures.xml + // from all the skins directories. + std::vector<std::string> textures_paths = + gDirUtilp->findSkinnedFilenames(LLDir::TEXTURES, "textures.xml", LLDir::ALL_SKINS); + std::vector<std::string>::const_iterator pi(textures_paths.begin()), pend(textures_paths.end()); + if (pi == pend) + { + llwarns << "No textures.xml found in skins directories" << llendl; + return false; + } + // The first (most generic) file gets special validations LLXMLNodePtr root; - - if (!LLXMLNode::parseFile(base_file_path, root, NULL)) + if (!LLXMLNode::parseFile(*pi, root, NULL)) { - llwarns << "Unable to parse UI image list file " << base_file_path << llendl; + llwarns << "Unable to parse UI image list file " << *pi << llendl; return false; } if (!root->hasAttribute("version")) { - llwarns << "No valid version number in UI image list file " << base_file_path << llendl; + llwarns << "No valid version number in UI image list file " << *pi << llendl; return false; } UIImageDeclarations images; LLXUIParser parser; - parser.readXUI(root, images, base_file_path); - - // add components defined in current skin - std::string skin_update_path = gDirUtilp->getSkinDir() - + gDirUtilp->getDirDelimiter() - + "textures" - + gDirUtilp->getDirDelimiter() - + "textures.xml"; - LLXMLNodePtr update_root; - if (skin_update_path != base_file_path - && LLXMLNode::parseFile(skin_update_path, update_root, NULL)) - { - parser.readXUI(update_root, images, skin_update_path); - } - - // add components defined in user override of current skin - skin_update_path = gDirUtilp->getUserSkinDir() - + gDirUtilp->getDirDelimiter() - + "textures" - + gDirUtilp->getDirDelimiter() - + "textures.xml"; - if (skin_update_path != base_file_path - && LLXMLNode::parseFile(skin_update_path, update_root, NULL)) - { - parser.readXUI(update_root, images, skin_update_path); + parser.readXUI(root, images, *pi); + + // add components defined in the rest of the skin paths + while (++pi != pend) + { + LLXMLNodePtr update_root; + if (LLXMLNode::parseFile(*pi, update_root, NULL)) + { + parser.readXUI(update_root, images, *pi); + } } if (!images.validateBlock()) return false; diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index e0a362596d..3dda973d3f 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -65,6 +65,7 @@ class LLViewerTextureList friend class LLTextureView; friend class LLViewerTextureManager; + friend class LLLocalBitmap; public: static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec); @@ -109,6 +110,9 @@ public: void doPreloadImages(); void doPrefetchImages(); + void clearFetchingRequests(); + void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level); + static S32 getMinVideoRamSetting(); static S32 getMaxVideoRamSetting(bool get_recommended = false); @@ -117,6 +121,7 @@ private: F32 updateImagesCreateTextures(F32 max_time); F32 updateImagesFetchTextures(F32 max_time); void updateImagesUpdateStats(); + F32 updateImagesLoadingFastCache(F32 max_time); void addImage(LLViewerFetchedTexture *image); void deleteImage(LLViewerFetchedTexture *image); @@ -163,13 +168,14 @@ private: // Request image from a specific host, used for baked avatar textures. // Implemented in header in case someone changes default params above. JC LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, LLHost host) - { return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); } + { return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); } public: typedef std::set<LLPointer<LLViewerFetchedTexture> > image_list_t; image_list_t mLoadingStreamList; image_list_t mCreateTextureList; image_list_t mCallbackList; + image_list_t mFastCacheList; // Note: just raw pointers because they are never referenced, just compared against std::set<LLViewerFetchedTexture*> mDirtyTextureList; diff --git a/indra/newview/llviewervisualparam.h b/indra/newview/llviewervisualparam.h index dd7751acd7..2826e6c316 100644 --- a/indra/newview/llviewervisualparam.h +++ b/indra/newview/llviewervisualparam.h @@ -65,6 +65,7 @@ protected: // VIRTUAL CLASS // a viewer side interface class for a generalized parametric modification of the avatar mesh //----------------------------------------------------------------------------- +LL_ALIGN_PREFIX(16) class LLViewerVisualParam : public LLVisualParam { public: @@ -83,11 +84,11 @@ public: // New Virtual functions virtual F32 getTotalDistortion() = 0; - virtual const LLVector3& getAvgDistortion() = 0; + virtual const LLVector4a& getAvgDistortion() = 0; virtual F32 getMaxDistortion() = 0; - virtual LLVector3 getVertexDistortion(S32 index, LLPolyMesh *mesh) = 0; - virtual const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **mesh) = 0; - virtual const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **mesh) = 0; + virtual LLVector4a getVertexDistortion(S32 index, LLPolyMesh *mesh) = 0; + virtual const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **mesh) = 0; + virtual const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **mesh) = 0; // interface methods F32 getDisplayOrder() const { return getInfo()->mEditGroupDisplayOrder; } @@ -104,6 +105,6 @@ public: BOOL getCrossWearable() const { return getInfo()->mCrossWearable; } -}; +} LL_ALIGN_POSTFIX(16); #endif // LL_LLViewerVisualParam_H diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 62e526a42f..e44a2cc4df 100644..100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -27,9 +27,6 @@ #include "llviewerprecompiledheaders.h" #include "llviewerwindow.h" -#if LL_WINDOWS -#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally -#endif // system library includes #include <stdio.h> @@ -40,8 +37,10 @@ #include "llagent.h" #include "llagentcamera.h" +#include "llcommunicationchannel.h" #include "llfloaterreg.h" #include "llmeshrepository.h" +#include "llnotificationhandler.h" #include "llpanellogin.h" #include "llviewerkeyboard.h" #include "llviewermenu.h" @@ -49,7 +48,6 @@ #include "llviewquery.h" #include "llxmltree.h" #include "llslurl.h" -//#include "llviewercamera.h" #include "llrender.h" #include "llvoiceclient.h" // for push-to-talk button handling @@ -60,6 +58,7 @@ // linden library includes #include "llaudioengine.h" // mute on minimize +#include "llchatentry.h" #include "indra_constants.h" #include "llassetstorage.h" #include "llerrorcontrol.h" @@ -81,6 +80,7 @@ #include "llmediaentry.h" #include "llurldispatcher.h" #include "raytrace.h" +#include "llstat.h" // newview includes #include "llagent.h" @@ -126,10 +126,13 @@ #include "llkeyboard.h" #include "lllineeditor.h" #include "llmenugl.h" +#include "llmenuoptionpathfindingrebakenavmesh.h" #include "llmodaldialog.h" #include "llmorphview.h" #include "llmoveview.h" #include "llnavigationbar.h" +#include "llnotificationhandler.h" +#include "llpaneltopinfobar.h" #include "llpopupview.h" #include "llpreviewtexture.h" #include "llprogressview.h" @@ -178,6 +181,7 @@ #include "llviewershadermgr.h" #include "llviewerstats.h" #include "llvoavatarself.h" +#include "llvopartgroup.h" #include "llvovolume.h" #include "llworld.h" #include "llworldmapview.h" @@ -188,7 +192,7 @@ #include "llviewerjoystick.h" #include "llviewernetwork.h" #include "llpostprocess.h" -#include "llnearbychatbar.h" +#include "llfloaterimnearbychat.h" #include "llagentui.h" #include "llwearablelist.h" @@ -198,7 +202,6 @@ #include "llfloaternotificationsconsole.h" -#include "llnearbychat.h" #include "llwindowlistener.h" #include "llviewerwindowlistener.h" #include "llpaneltopinfobar.h" @@ -335,27 +338,24 @@ public: if (gSavedSettings.getBOOL("DebugShowTime")) { - const U32 y_inc2 = 15; - for (std::map<S32,LLFrameTimer>::reverse_iterator iter = gDebugTimers.rbegin(); - iter != gDebugTimers.rend(); ++iter) { - S32 idx = iter->first; - LLFrameTimer& timer = iter->second; + const U32 y_inc2 = 15; + LLFrameTimer& timer = gTextureTimer; F32 time = timer.getElapsedTimeF32(); S32 hours = (S32)(time / (60*60)); S32 mins = (S32)((time - hours*(60*60)) / 60); S32 secs = (S32)((time - hours*(60*60) - mins*60)); - std::string label = gDebugTimerLabel[idx]; - if (label.empty()) label = llformat("Debug: %d", idx); - addText(xpos, ypos, llformat(" %s: %d:%02d:%02d", label.c_str(), hours,mins,secs)); ypos += y_inc2; + addText(xpos, ypos, llformat("Texture: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc2; } + { F32 time = gFrameTimeSeconds; S32 hours = (S32)(time / (60*60)); S32 mins = (S32)((time - hours*(60*60)) / 60); S32 secs = (S32)((time - hours*(60*60) - mins*60)); addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc; } + } #if LL_WINDOWS if (gSavedSettings.getBOOL("DebugShowMemory")) @@ -537,7 +537,10 @@ public: } - addText(xpos, ypos, llformat("%d MB Vertex Data (%d MB Pooled)", LLVertexBuffer::sAllocatedBytes/(1024*1024), LLVBOPool::sBytesPooled/(1024*1024))); + addText(xpos, ypos, llformat("%d MB Index Data (%d MB Pooled, %d KIndices)", LLVertexBuffer::sAllocatedIndexBytes/(1024*1024), LLVBOPool::sIndexBytesPooled/(1024*1024), LLVertexBuffer::sIndexCount/1024)); + ypos += y_inc; + + addText(xpos, ypos, llformat("%d MB Vertex Data (%d MB Pooled, %d KVerts)", LLVertexBuffer::sAllocatedBytes/(1024*1024), LLVBOPool::sBytesPooled/(1024*1024), LLVertexBuffer::sVertexCount/1024)); ypos += y_inc; addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount)); @@ -561,6 +564,9 @@ public: addText(xpos, ypos, llformat("%d Render Calls", gPipeline.mBatchCount)); ypos += y_inc; + addText(xpos, ypos, llformat("%d/%d Objects Active", gObjectList.getNumActiveObjects(), gObjectList.getNumObjects())); + ypos += y_inc; + addText(xpos, ypos, llformat("%d Matrix Ops", gPipeline.mMatrixOpCount)); ypos += y_inc; @@ -612,7 +618,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))); @@ -743,40 +751,41 @@ public: if (gSavedSettings.getBOOL("DebugShowTextureInfo")) { LLViewerObject* objectp = NULL ; - //objectp = = gAgentCamera.getFocusObject(); LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode(); if (nodep) { - objectp = nodep->getObject(); + objectp = nodep->getObject(); } + if (objectp && !objectp->isDead()) { S32 num_faces = objectp->mDrawable->getNumFaces() ; - + std::set<LLViewerFetchedTexture*> tex_list; + for(S32 i = 0 ; i < num_faces; i++) { LLFace* facep = objectp->mDrawable->getFace(i) ; if(facep) - { - //addText(xpos, ypos, llformat("ts_min: %.3f ts_max: %.3f tt_min: %.3f tt_max: %.3f", facep->mTexExtents[0].mV[0], facep->mTexExtents[1].mV[0], - // facep->mTexExtents[0].mV[1], facep->mTexExtents[1].mV[1])); - //ypos += y_inc; - - addText(xpos, ypos, llformat("v_size: %.3f: p_size: %.3f", facep->getVirtualSize(), facep->getPixelArea())); - ypos += y_inc; - - //const LLTextureEntry *tep = facep->getTextureEntry(); - //if(tep) - //{ - // addText(xpos, ypos, llformat("scale_s: %.3f: scale_t: %.3f", tep->mScaleS, tep->mScaleT)) ; - // ypos += y_inc; - //} - - LLViewerTexture* tex = facep->getTexture() ; + { + LLViewerFetchedTexture* tex = dynamic_cast<LLViewerFetchedTexture*>(facep->getTexture()) ; if(tex) { - addText(xpos, ypos, llformat("ID: %s v_size: %.3f", tex->getID().asString().c_str(), tex->getMaxVirtualSize())); + if(tex_list.find(tex) != tex_list.end()) + { + continue ; //already displayed. + } + tex_list.insert(tex); + + std::string uuid_str; + tex->getID().toString(uuid_str); + uuid_str = uuid_str.substr(0,7); + + addText(xpos, ypos, llformat("ID: %s v_size: %.3f", uuid_str.c_str(), tex->getMaxVirtualSize())); + ypos += y_inc; + + addText(xpos, ypos, llformat("discard level: %d desired level: %d Missing: %s", tex->getDiscardLevel(), + tex->getDesiredDiscardLevel(), tex->isMissingAsset() ? "Y" : "N")); ypos += y_inc; } } @@ -810,6 +819,20 @@ void LLViewerWindow::updateDebugText() // LLViewerWindow // +LLViewerWindow::Params::Params() +: title("title"), + name("name"), + x("x"), + y("y"), + width("width"), + height("height"), + min_width("min_width"), + min_height("min_height"), + fullscreen("fullscreen", false), + ignore_pixel_depth("ignore_pixel_depth", false) +{} + + BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down) { const char* buttonname = ""; @@ -1191,7 +1214,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(); } @@ -1503,18 +1527,13 @@ std::string LLViewerWindow::translateString(const char* tag, // // Classes // -LLViewerWindow::LLViewerWindow( - const std::string& title, const std::string& name, - S32 x, S32 y, - S32 width, S32 height, - BOOL fullscreen, BOOL ignore_pixel_depth) // fullscreen is no longer used - : - mWindow(NULL), +LLViewerWindow::LLViewerWindow(const Params& p) +: mWindow(NULL), mActive(true), mUIVisible(true), - mWindowRectRaw(0, height, width, 0), - mWindowRectScaled(0, height, width, 0), - mWorldViewRectRaw(0, height, width, 0), + mWindowRectRaw(0, p.height, p.width, 0), + mWindowRectScaled(0, p.height, p.width, 0), + mWorldViewRectRaw(0, p.height, p.width, 0), mLeftMouseDown(FALSE), mMiddleMouseDown(FALSE), mRightMouseDown(FALSE), @@ -1527,21 +1546,27 @@ LLViewerWindow::LLViewerWindow( mResDirty(false), mStatesDirty(false), mCurrResolutionIndex(0), + mProgressView(NULL), + mMouseVelocityStat(new LLStat("Mouse Velocity")) +{ // gKeyboard is still NULL, so it doesn't do LLWindowListener any good to // pass its value right now. Instead, pass it a nullary function that // will, when we later need it, return the value of gKeyboard. // boost::lambda::var() constructs such a functor on the fly. - mWindowListener(new LLWindowListener(this, boost::lambda::var(gKeyboard))), - mViewerWindowListener(new LLViewerWindowListener(this)), - mProgressView(NULL) -{ - LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert")); - LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal")); + mWindowListener.reset(new LLWindowListener(this, boost::lambda::var(gKeyboard))); + mViewerWindowListener.reset(new LLViewerWindowListener(this)); + + mSystemChannel.reset(new LLNotificationChannel("System", "Visible", LLNotificationFilters::includeEverything)); + mCommunicationChannel.reset(new LLCommunicationChannel("Communication", "Visible")); + mAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alerts", "alert")); + mModalAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alertmodal", "alertmodal")); - LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert); - LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert); - LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications")); + bool ignore = gSavedSettings.getBOOL("IgnoreAllNotifications"); + LLNotifications::instance().setIgnoreAllNotifications(ignore); + if (ignore) + { llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl; + } // Default to application directory. LLViewerWindow::sSnapshotBaseName = "Snapshot"; @@ -1550,12 +1575,12 @@ LLViewerWindow::LLViewerWindow( // create window mWindow = LLWindowManager::createWindow(this, - title, name, x, y, width, height, 0, - fullscreen, + p.title, p.name, p.x, p.y, p.width, p.height, 0, + p.fullscreen, gHeadlessClient, gSavedSettings.getBOOL("DisableVerticalSync"), !gHeadlessClient, - ignore_pixel_depth, + p.ignore_pixel_depth, gSavedSettings.getBOOL("RenderDeferred") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled if (!LLViewerShaderMgr::sInitialized) @@ -1588,10 +1613,12 @@ LLViewerWindow::LLViewerWindow( LL_WARNS("Window") << " Someone took over my signal/exception handler (post createWindow)!" << LL_ENDL; } + const bool do_not_enforce = false; + mWindow->setMinSize(p.min_width, p.min_height, do_not_enforce); // root view not set LLCoordScreen scr; mWindow->getSize(&scr); - if(fullscreen && ( scr.mX!=width || scr.mY!=height)) + if(p.fullscreen && ( scr.mX!=p.width || scr.mY!=p.height)) { llwarns << "Fullscreen has forced us in to a different resolution now using "<<scr.mX<<" x "<<scr.mY<<llendl; gSavedSettings.setS32("FullScreenWidth",scr.mX); @@ -1668,8 +1695,7 @@ LLViewerWindow::LLViewerWindow( LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"), mDisplayScale.mV[VX], mDisplayScale.mV[VY], - gDirUtilp->getAppRODataDir(), - LLUI::getXUIPaths()); + gDirUtilp->getAppRODataDir()); // Create container for all sub-views LLView::Params rvp; @@ -1689,9 +1715,6 @@ LLViewerWindow::LLViewerWindow( // Can't have spaces in settings.ini strings, so use underscores instead and convert them. LLStringUtil::replaceChar(mOverlayTitle, '_', ' '); - // sync the keyboard's setting with the saved setting - gSavedSettings.getControl("NumpadControl")->firePropertyChanged(); - mDebugText = new LLDebugText(this); mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale); @@ -1806,8 +1829,8 @@ void LLViewerWindow::initBase() gDebugView->init(); gToolTipView = getRootView()->getChild<LLToolTipView>("tooltip view"); - // Initialize busy response message when logged in - LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initBusyResponse)); + // Initialize do not disturb response message when logged in + LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initDoNotDisturbResponse)); // Add the progress bar view (startup view), which overrides everything mProgressView = getRootView()->findChild<LLProgressView>("progress_view"); @@ -1908,11 +1931,15 @@ void LLViewerWindow::initWorldUI() getRootView()->addChild(gHUDView); } - LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("stand_stop_flying_container"); + LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("state_management_buttons_container"); + LLPanelStandStopFlying* panel_stand_stop_flying = LLPanelStandStopFlying::getInstance(); panel_ssf_container->addChild(panel_stand_stop_flying); + panel_ssf_container->setVisible(TRUE); + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize(); + // Load and make the toolbars visible // Note: we need to load the toolbars only *after* the user is logged in and IW if (gToolBarView) @@ -1945,33 +1972,44 @@ 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 ; + + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->quit(); // Automatically deleted as children of mRootView. Fix the globals. gStatusBar = NULL; @@ -1997,6 +2035,12 @@ void LLViewerWindow::shutdownGL() gSky.cleanup(); stop_glerror(); + llinfos << "Cleaning up pipeline" << llendl; + gPipeline.cleanup(); + stop_glerror(); + + //MUST clean up pipeline before cleaning up wearables + llinfos << "Cleaning up wearables" << llendl; LLWearableList::instance().cleanup() ; gTextureList.shutdown(); @@ -2007,10 +2051,6 @@ void LLViewerWindow::shutdownGL() LLWorldMapView::cleanupTextures(); - llinfos << "Cleaning up pipeline" << llendl; - gPipeline.cleanup(); - stop_glerror(); - LLViewerTextureManager::cleanup() ; LLImageGL::cleanupClass() ; @@ -2038,6 +2078,8 @@ LLViewerWindow::~LLViewerWindow() delete mDebugText; mDebugText = NULL; + + delete mMouseVelocityStat; } @@ -2129,20 +2171,29 @@ void LLViewerWindow::reshape(S32 width, S32 height) sendShapeToSim(); // store new settings for the mode we are in, regardless - // Only save size if not maximized BOOL maximized = mWindow->getMaximized(); gSavedSettings.setBOOL("WindowMaximized", maximized); - LLCoordScreen window_size; - if (!maximized - && mWindow->getSize(&window_size)) + if (!maximized) { - gSavedSettings.setS32("WindowWidth", window_size.mX); - gSavedSettings.setS32("WindowHeight", window_size.mY); + U32 min_window_width=gSavedSettings.getU32("MinWindowWidth"); + U32 min_window_height=gSavedSettings.getU32("MinWindowHeight"); + // tell the OS specific window code about min window size + mWindow->setMinSize(min_window_width, min_window_height); + + LLCoordScreen window_rect; + if (mWindow->getSize(&window_rect)) + { + // Only save size if not maximized + gSavedSettings.setU32("WindowWidth", window_rect.mX); + gSavedSettings.setU32("WindowHeight", window_rect.mY); + } } LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height); + + LLLayoutStack::updateClass(); } } @@ -2346,7 +2397,7 @@ void LLViewerWindow::draw() gGL.matrixMode(LLRender::MM_MODELVIEW); LLUI::pushMatrix(); - LLUI::translate( (F32) screen_x, (F32) screen_y, 0.f); + LLUI::translate( (F32) screen_x, (F32) screen_y); top_ctrl->draw(); LLUI::popMatrix(); } @@ -2453,26 +2504,20 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) return TRUE; } - // Traverses up the hierarchy + LLFloater* focused_floaterp = gFloaterView->getFocusedFloater(); + std::string focusedFloaterName = (focused_floaterp ? focused_floaterp->getInstanceName() : ""); + if( keyboard_focus ) { - LLNearbyChatBar* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChatBar>("chat_bar"); - - if (nearby_chat) + if ((focusedFloaterName == "nearby_chat") || (focusedFloaterName == "im_container") || (focusedFloaterName == "impanel")) { - LLLineEditor* chat_editor = nearby_chat->getChatBox(); - - // arrow keys move avatar while chatting hack - if (chat_editor && chat_editor->hasFocus()) - { - // If text field is empty, there's no point in trying to move - // cursor with arrow keys, so allow movement - if (chat_editor->getText().empty() - || gSavedSettings.getBOOL("ArrowKeysAlwaysMove")) + if (gSavedSettings.getBOOL("ArrowKeysAlwaysMove")) { // let Control-Up and Control-Down through for chat line history, if (!(key == KEY_UP && mask == MASK_CONTROL) - && !(key == KEY_DOWN && mask == MASK_CONTROL)) + && !(key == KEY_DOWN && mask == MASK_CONTROL) + && !(key == KEY_UP && mask == MASK_ALT) + && !(key == KEY_DOWN && mask == MASK_ALT)) { switch(key) { @@ -2490,9 +2535,9 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) break; } } - } } } + if (keyboard_focus->handleKey(key, mask, FALSE)) { return TRUE; @@ -2523,11 +2568,19 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && !keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) ) { - LLLineEditor* chat_editor = LLFloaterReg::getTypedInstance<LLNearbyChatBar>("chat_bar")->getChatBox(); + // Initialize nearby chat if it's missing + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + if (!nearby_chat) + { + LLSD name("im_container"); + LLFloaterReg::toggleInstanceOrBringToFront(name); + } + + LLChatEntry* chat_editor = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->getChatBox(); if (chat_editor) { // passing NULL here, character will be added later when it is handled by character handler. - LLNearbyChatBar::getInstance()->startChat(NULL); + nearby_chat->startChat(NULL); return TRUE; } } @@ -2556,7 +2609,10 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask) if ((uni_char == 13 && mask != MASK_CONTROL) || (uni_char == 3 && mask == MASK_NONE)) { - return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN)); + if (mask != MASK_ALT) + { + return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN)); + } } // let menus handle navigation (jump) keys @@ -3133,8 +3189,7 @@ void LLViewerWindow::updateLayout() || (tool != LLToolPie::getInstance() // not default tool && tool != LLToolCompGun::getInstance() // not coming out of mouselook && !suppress_toolbox // not override in third person - && LLToolMgr::getInstance()->getCurrentToolset() != gFaceEditToolset // not special mode - && LLToolMgr::getInstance()->getCurrentToolset() != gMouselookToolset + && LLToolMgr::getInstance()->getCurrentToolset()->isShowFloaterTools() && (!captor || dynamic_cast<LLView*>(captor) != NULL))) // not dragging { // Force floater tools to be visible (unless minimized) @@ -3154,12 +3209,6 @@ void LLViewerWindow::updateLayout() //gMenuBarView->setItemVisible("BuildTools", gFloaterTools->getVisible()); } - LLFloaterBuildOptions* build_options_floater = LLFloaterReg::findTypedInstance<LLFloaterBuildOptions>("build_options"); - if (build_options_floater && build_options_floater->getVisible()) - { - build_options_floater->updateGridMode(); - } - // Always update console if(gConsole) { @@ -3209,7 +3258,7 @@ void LLViewerWindow::updateMouseDelta() mouse_vel.setVec((F32) dx, (F32) dy); } - mMouseVelocityStat.addValue(mouse_vel.magVec()); + mMouseVelocityStat->addValue(mouse_vel.magVec()); } void LLViewerWindow::updateKeyboardFocus() @@ -3494,8 +3543,11 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, { LLSelectNode* nodep = *iter; LLViewerObject* object = nodep->getObject(); + LLViewerObject *root_object = (object == NULL) ? NULL : object->getRootEdit(); BOOL this_object_movable = FALSE; - if (object->permMove() && (object->permModify() || selecting_linked_set)) + if (object->permMove() && !object->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + (object->permModify() || selecting_linked_set)) { moveable_object_selected = TRUE; this_object_movable = TRUE; @@ -4073,24 +4125,14 @@ void LLViewerWindow::resetSnapshotLoc() sSnapshotDir.clear(); } -static S32 BORDERHEIGHT = 0; -static S32 BORDERWIDTH = 0; - // static void LLViewerWindow::movieSize(S32 new_width, S32 new_height) { - LLCoordScreen size; + LLCoordWindow size; + LLCoordWindow new_size(new_width, new_height); gViewerWindow->getWindow()->getSize(&size); - if ( (size.mX != new_width + BORDERWIDTH) - ||(size.mY != new_height + BORDERHEIGHT)) - { - // use actual display dimensions, not virtual UI dimensions - S32 x = gViewerWindow->getWindowWidthRaw(); - S32 y = gViewerWindow->getWindowHeightRaw(); - BORDERWIDTH = size.mX - x; - BORDERHEIGHT = size.mY- y; - LLCoordScreen new_size(new_width + BORDERWIDTH, - new_height + BORDERHEIGHT); + if ( size != new_size ) + { gViewerWindow->getWindow()->setSize(new_size); } } @@ -4205,14 +4247,48 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei image_height = llmin(image_height, window_height); } + S32 original_width = 0; + S32 original_height = 0; + bool reset_deferred = false; + + LLRenderTarget scratch_space; + F32 scale_factor = 1.0f ; if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height)) { - // if image cropping or need to enlarge the scene, compute a scale_factor - F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; - snapshot_width = (S32)(ratio * image_width) ; - snapshot_height = (S32)(ratio * image_height) ; - scale_factor = llmax(1.0f, 1.0f / ratio) ; + if ((image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui) + { + if (scratch_space.allocate(image_width, image_height, GL_RGBA, true, true)) + { + original_width = gPipeline.mDeferredScreen.getWidth(); + original_height = gPipeline.mDeferredScreen.getHeight(); + + if (gPipeline.allocateScreenBuffer(image_width, image_height)) + { + window_width = image_width; + window_height = image_height; + snapshot_width = image_width; + snapshot_height = image_height; + reset_deferred = true; + mWorldViewRectRaw.set(0, image_height, image_width, 0); + scratch_space.bindTarget(); + } + else + { + scratch_space.release(); + gPipeline.allocateScreenBuffer(original_width, original_height); + } + } + } + + if (!reset_deferred) + { + // if image cropping or need to enlarge the scene, compute a scale_factor + F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; + snapshot_width = (S32)(ratio * image_width) ; + snapshot_height = (S32)(ratio * image_height) ; + scale_factor = llmax(1.0f, 1.0f / ratio) ; + } } if (show_ui && scale_factor > 1.f) @@ -4401,11 +4477,20 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei gPipeline.resetDrawOrders(); } + if (reset_deferred) + { + mWorldViewRectRaw = window_rect; + scratch_space.flush(); + scratch_space.release(); + gPipeline.allocateScreenBuffer(original_width, original_height); + + } + if (high_res) { send_agent_resume(); } - + return ret; } @@ -4641,6 +4726,8 @@ void LLViewerWindow::stopGL(BOOL save_state) LLVOAvatar::destroyGL(); stop_glerror(); + LLVOPartGroup::destroyGL(); + LLViewerDynamicTexture::destroyGL(); stop_glerror(); @@ -4694,6 +4781,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) gBumpImageList.restoreGL(); LLViewerDynamicTexture::restoreGL(); LLVOAvatar::restoreGL(); + LLVOPartGroup::restoreGL(); gResizeScreenTexture = TRUE; gWindowResized = TRUE; @@ -4723,11 +4811,13 @@ void LLViewerWindow::initFonts(F32 zoom_factor) { LLFontGL::destroyAllGL(); // Initialize with possibly different zoom factor + + LLFontManager::initClass(); + LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"), mDisplayScale.mV[VX] * zoom_factor, mDisplayScale.mV[VY] * zoom_factor, - gDirUtilp->getAppRODataDir(), - LLUI::getXUIPaths()); + gDirUtilp->getAppRODataDir()); // Force font reloads, which can be very slow LLFontGL::loadDefaultFonts(); } @@ -4737,8 +4827,11 @@ void LLViewerWindow::requestResolutionUpdate() mResDirty = true; } +static LLFastTimer::DeclareTimer FTM_WINDOW_CHECK_SETTINGS("Window Settings"); + void LLViewerWindow::checkSettings() { + LLFastTimer t(FTM_WINDOW_CHECK_SETTINGS); if (mStatesDirty) { gGL.refreshState(); @@ -4916,7 +5009,7 @@ S32 LLViewerWindow::getChatConsoleBottomPad() S32 offset = 0; if(gToolBarView) - offset += gToolBarView->getChild<LLView>("bottom_toolbar_panel")->getRect().getHeight(); + offset += gToolBarView->getBottomToolbar()->getRect().getHeight(); return offset; } @@ -4953,25 +5046,6 @@ LLRect LLViewerWindow::getChatConsoleRect() //---------------------------------------------------------------------------- -//static -bool LLViewerWindow::onAlert(const LLSD& notify) -{ - LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - - if (gHeadlessClient) - { - llinfos << "Alert: " << notification->getName() << llendl; - } - - // If we're in mouselook, the mouse is hidden and so the user can't click - // the dialog buttons. In that case, change to First Person instead. - if( gAgentCamera.cameraMouselook() ) - { - gAgentCamera.changeCameraToDefault(); - } - return false; -} - void LLViewerWindow::setUIVisibility(bool visible) { mUIVisible = visible; @@ -4991,8 +5065,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); } @@ -5174,9 +5248,11 @@ void LLPickInfo::getSurfaceInfo() if (objectp->mDrawable.notNull() && mObjectFace > -1) { LLFace* facep = objectp->mDrawable->getFace(mObjectFace); - + if (facep) + { mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); } + } // and XY coords: updateXYCoords(); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 0cb7f82b58..b33488fd78 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -41,15 +41,16 @@ #include "llcursortypes.h" #include "llwindowcallbacks.h" #include "lltimer.h" -#include "llstat.h" #include "llmousehandler.h" +#include "llnotifications.h" #include "llhandle.h" +#include "llinitparam.h" #include <boost/function.hpp> #include <boost/signals2.hpp> #include <boost/scoped_ptr.hpp> - +class LLStat; class LLView; class LLViewerObject; class LLUUID; @@ -133,7 +134,23 @@ public: // // CREATORS // - LLViewerWindow(const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, BOOL fullscreen, BOOL ignore_pixel_depth); + struct Params : public LLInitParam::Block<Params> + { + Mandatory<std::string> title, + name; + Mandatory<S32> x, + y, + width, + height, + min_width, + min_height; + Optional<bool> fullscreen, + ignore_pixel_depth; + + Params(); + }; + + LLViewerWindow(const Params& p); virtual ~LLViewerWindow(); void shutdownViews(); @@ -234,7 +251,7 @@ public: S32 getCurrentMouseDX() const { return mCurrentMouseDelta.mX; } S32 getCurrentMouseDY() const { return mCurrentMouseDelta.mY; } LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; } - LLStat * getMouseVelocityStat() { return &mMouseVelocityStat; } + LLStat* getMouseVelocityStat() { return mMouseVelocityStat; } BOOL getLeftMouseDown() const { return mLeftMouseDown; } BOOL getMiddleMouseDown() const { return mMiddleMouseDown; } BOOL getRightMouseDown() const { return mRightMouseDown; } @@ -384,7 +401,6 @@ public: private: bool shouldShowToolTipFor(LLMouseHandler *mh); - static bool onAlert(const LLSD& notify); void switchToolByMask(MASK mask); void destroyWindow(); @@ -401,6 +417,11 @@ private: bool mActive; bool mUIVisible; + LLNotificationChannelPtr mSystemChannel; + LLNotificationChannelPtr mCommunicationChannel; + LLNotificationChannelPtr mAlertsChannel; + LLNotificationChannelPtr mModalAlertsChannel; + LLRect mWindowRectRaw; // whole window, including UI LLRect mWindowRectScaled; // whole window, scaled by UI size LLRect mWorldViewRectRaw; // area of screen for 3D world @@ -411,7 +432,7 @@ private: LLCoordGL mCurrentMousePoint; // last mouse position in GL coords LLCoordGL mLastMousePoint; // Mouse point at last frame. LLCoordGL mCurrentMouseDelta; //amount mouse moved this frame - LLStat mMouseVelocityStat; + LLStat* mMouseVelocityStat; BOOL mLeftMouseDown; BOOL mMiddleMouseDown; BOOL mRightMouseDown; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index ec932501e5..abb5153480 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -457,8 +457,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, texturep->createGLTexture(0, raw); } texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); - LLSurface::sTextureUpdateTime += gen_timer.getElapsedTimeF32(); - LLSurface::sTexelsUpdated += (tex_x_end - tex_x_begin) * (tex_y_end - tex_y_begin); for (S32 i = 0; i < 4; i++) { diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 4c33716c32..c74d9f1292 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -62,6 +62,7 @@ #include "llhudmanager.h" #include "llhudnametag.h" #include "llhudtext.h" // for mText/mDebugText +#include "llinitparam.h" #include "llkeyframefallmotion.h" #include "llkeyframestandmotion.h" #include "llkeyframewalkmotion.h" @@ -101,6 +102,8 @@ #include "llvoicevisualizer.h" // Ventrella #include "lldebugmessagebox.h" +#include "llsdutil.h" + extern F32 SPEED_ADJUST_MAX; extern F32 SPEED_ADJUST_MAX_SEC; extern F32 ANIM_SPEED_MAX; @@ -149,10 +152,6 @@ const F32 PELVIS_LAG_WALKING = 0.4f; // ...while walking const F32 PELVIS_LAG_MOUSELOOK = 0.15f; const F32 MOUSELOOK_PELVIS_FOLLOW_FACTOR = 0.5f; const F32 PELVIS_LAG_WHEN_FOLLOW_CAM_IS_ON = 0.0001f; // not zero! - something gets divided by this! - -const F32 PELVIS_ROT_THRESHOLD_SLOW = 60.0f; // amount of deviation allowed between -const F32 PELVIS_ROT_THRESHOLD_FAST = 2.0f; // the pelvis and the view direction - // when moving fast & slow const F32 TORSO_NOISE_AMOUNT = 1.0f; // Amount of deviation from up-axis, in degrees const F32 TORSO_NOISE_SPEED = 0.2f; // Time scale factor on torso noise. @@ -193,6 +192,9 @@ const S32 MAX_BUBBLE_CHAT_LENGTH = DB_CHAT_MSG_STR_LEN; const S32 MAX_BUBBLE_CHAT_UTTERANCES = 12; const F32 CHAT_FADE_TIME = 8.0; const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f; +const F32 NAMETAG_UPDATE_THRESHOLD = 0.3f; +const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f; +const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f; const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0); @@ -224,55 +226,62 @@ struct LLTextureMaskData **/ //------------------------------------------------------------------------ -// LLVOBoneInfo +// LLVOAvatarBoneInfo // Trans/Scale/Rot etc. info about each avatar bone. Used by LLVOAvatarSkeleton. //------------------------------------------------------------------------ -class LLVOAvatarBoneInfo +struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarCollisionVolumeInfo> { - friend class LLVOAvatar; - friend class LLVOAvatarSkeletonInfo; -public: - LLVOAvatarBoneInfo() : mIsJoint(FALSE) {} - ~LLVOAvatarBoneInfo() + LLVOAvatarCollisionVolumeInfo() + : name("name"), + pos("pos"), + rot("rot"), + scale("scale") + {} + + Mandatory<std::string> name; + Mandatory<LLVector3> pos, + rot, + scale; +}; + +struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint> { - std::for_each(mChildList.begin(), mChildList.end(), DeletePointer()); - } - BOOL parseXml(LLXmlTreeNode* node); + Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> > bone; + Alternative<LLVOAvatarCollisionVolumeInfo> collision_volume; -private: - std::string mName; - BOOL mIsJoint; - LLVector3 mPos; - LLVector3 mRot; - LLVector3 mScale; - LLVector3 mPivot; - typedef std::vector<LLVOAvatarBoneInfo*> child_list_t; - child_list_t mChildList; + LLVOAvatarChildJoint() + : bone("bone"), + collision_volume("collision_volume") + {} +}; + +struct LLVOAvatarBoneInfo : public LLInitParam::Block<LLVOAvatarBoneInfo, LLVOAvatarCollisionVolumeInfo> +{ + LLVOAvatarBoneInfo() + : pivot("pivot") + {} + + Mandatory<LLVector3> pivot; + Multiple<LLVOAvatarChildJoint> children; }; //------------------------------------------------------------------------ // LLVOAvatarSkeletonInfo // Overall avatar skeleton //------------------------------------------------------------------------ -class LLVOAvatarSkeletonInfo +struct LLVOAvatarSkeletonInfo : public LLInitParam::Block<LLVOAvatarSkeletonInfo> { - friend class LLVOAvatar; -public: - LLVOAvatarSkeletonInfo() : - mNumBones(0), mNumCollisionVolumes(0) {} - ~LLVOAvatarSkeletonInfo() - { - std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer()); - } - BOOL parseXml(LLXmlTreeNode* node); - S32 getNumBones() const { return mNumBones; } - S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; } + LLVOAvatarSkeletonInfo() + : skeleton_root(""), + num_bones("num_bones"), + num_collision_volumes("num_collision_volumes"), + version("version") + {} -private: - S32 mNumBones; - S32 mNumCollisionVolumes; - typedef std::vector<LLVOAvatarBoneInfo*> bone_info_list_t; - bone_info_list_t mBoneInfoList; + Mandatory<std::string> version; + Mandatory<S32> num_bones, + num_collision_volumes; + Mandatory<LLVOAvatarChildJoint> skeleton_root; }; //----------------------------------------------------------------------------- @@ -597,7 +606,7 @@ private: // Static Data //----------------------------------------------------------------------------- LLXmlTree LLVOAvatar::sXMLTree; -LLXmlTree LLVOAvatar::sSkeletonXMLTree; +LLXMLNodePtr LLVOAvatar::sSkeletonXMLTree; LLVOAvatarSkeletonInfo* LLVOAvatar::sAvatarSkeletonInfo = NULL; LLVOAvatar::LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL; LLVOAvatarDictionary *LLVOAvatar::sAvatarDictionary = NULL; @@ -631,7 +640,6 @@ F32 LLVOAvatar::sLODFactor = 1.f; F32 LLVOAvatar::sPhysicsLODFactor = 1.f; BOOL LLVOAvatar::sUseImpostors = FALSE; BOOL LLVOAvatar::sJointDebug = FALSE; - F32 LLVOAvatar::sUnbakedTime = 0.f; F32 LLVOAvatar::sUnbakedUpdateTime = 0.f; F32 LLVOAvatar::sGreyTime = 0.f; @@ -651,6 +659,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 ), @@ -668,7 +678,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mNameString(), mTitle(), mNameAway(false), - mNameBusy(false), + mNameDoNotDisturb(false), mNameMute(false), mNameAppearance(false), mNameFriend(false), @@ -685,14 +695,17 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mNeedsSkin(FALSE), mLastSkinTime(0.f), mUpdatePeriod(1), + mFirstFullyVisible(TRUE), mFullyLoaded(FALSE), mPreviousFullyLoaded(FALSE), mFullyLoadedInitialized(FALSE), mSupportsAlphaLayers(FALSE), mLoadedCallbacksPaused(FALSE), - mHasPelvisOffset( FALSE ) + mHasPelvisOffset( FALSE ), + mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar")), + mLastRezzedStatus(-1) + { - LLMemType mt(LLMemType::MTYPE_AVATAR); //VTResume(); // VTune // mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline @@ -771,35 +784,50 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mLastPelvisFixup = 0.0f; } +std::string LLVOAvatar::avString() const +{ + std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); + return " Avatar '" + getFullname() + "' " + viz_string + " "; +} + +void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string comment) +{ + LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() + << "sec ]" + << avString() + << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() + << " Notification " << notification_name + << " : " << comment + << llendl; + + if (gSavedSettings.getBOOL("DebugAvatarRezTime")) + { + LLSD args; + args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); + args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); + args["NAME"] = getFullname(); + LLNotificationsUtil::add(notification_name,args); + } +} + //------------------------------------------------------------------------ // LLVOAvatar::~LLVOAvatar() //------------------------------------------------------------------------ LLVOAvatar::~LLVOAvatar() { - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) - { if (!mFullyLoaded) { - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left after " << (U32)mRuthDebugTimer.getElapsedTimeF32() << " seconds as cloud." << llendl; - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezLeftCloudNotification",args); + debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud"); } else { - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left." << llendl; - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezLeftNotification",args); + debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding"); } - } lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl; mRoot.removeAllChildren(); + mJointMap.clear(); deleteAndClearArray(mSkeleton); deleteAndClearArray(mCollisionVolumes); @@ -845,6 +873,8 @@ LLVOAvatar::~LLVOAvatar() mAnimationSources.clear(); LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ; + getPhases().clearPhases(); + lldebugs << "LLVOAvatar Destructor end" << llendl; } @@ -878,6 +908,55 @@ BOOL LLVOAvatar::isFullyBaked() return TRUE; } +BOOL LLVOAvatar::isFullyTextured() const +{ + for (S32 i = 0; i < mMeshLOD.size(); i++) + { + LLViewerJoint* joint = (LLViewerJoint*) mMeshLOD[i]; + if (i==MESH_ID_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT)) + { + continue; // don't care about skirt textures if we're not wearing one. + } + if (!joint) + { + continue; // nonexistent LOD OK. + } + std::vector<LLViewerJointMesh*>::iterator meshIter = joint->mMeshParts.begin(); + if (meshIter != joint->mMeshParts.end()) + { + LLViewerJointMesh *mesh = (LLViewerJointMesh *) *meshIter; + if (!mesh) + { + continue; // nonexistent mesh OK + } + if (mesh->mTexture.notNull() && mesh->mTexture->hasGLTexture()) + { + continue; // Mesh exists and has a baked texture. + } + if (mesh->mLayerSet && mesh->mLayerSet->hasComposite()) + { + continue; // Mesh exists and has a composite texture. + } + // Fail + return FALSE; + } + } + return TRUE; +} + +BOOL LLVOAvatar::hasGray() const +{ + return !getIsCloud() && !isFullyTextured(); +} + +S32 LLVOAvatar::getRezzedStatus() const +{ + if (getIsCloud()) return 0; + if (isFullyTextured()) return 2; + llassert(hasGray()); + return 1; // gray +} + void LLVOAvatar::deleteLayerSetCaches(bool clearAll) { for (U32 i = 0; i < mBakedTextureDatas.size(); i++) @@ -893,7 +972,7 @@ void LLVOAvatar::deleteLayerSetCaches(bool clearAll) } if (mBakedTextureDatas[i].mMaskTexName) { - glDeleteTextures(1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName)); + LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName)); mBakedTextureDatas[i].mMaskTexName = 0 ; } } @@ -925,6 +1004,31 @@ BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars) } // static +void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts) +{ + counts.clear(); + counts.resize(3); + for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + LLVOAvatar* inst = (LLVOAvatar*) *iter; + if (!inst) + continue; + S32 rez_status = inst->getRezzedStatus(); + counts[rez_status]++; + } +} + +// static +std::string LLVOAvatar::rezStatusToString(S32 rez_status) +{ + if (rez_status==0) return "cloud"; + if (rez_status==1) return "gray"; + if (rez_status==2) return "textured"; + return "unknown"; +} + +// static void LLVOAvatar::dumpBakedStatus() { LLVector3d camera_pos_global = gAgentCamera.getCameraPositionGlobal(); @@ -1120,18 +1224,6 @@ void LLVOAvatar::initClass() llerrs << "Error parsing skeleton file: " << skeleton_path << llendl; } - // Process XML data - - // avatar_skeleton.xml - if (sAvatarSkeletonInfo) - { //this can happen if a login attempt failed - delete sAvatarSkeletonInfo; - } - sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo; - if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot())) - { - llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl; - } // parse avatar_lad.xml if (sAvatarXmlInfo) { //this can happen if a login attempt failed @@ -1180,7 +1272,7 @@ void LLVOAvatar::initClass() void LLVOAvatar::cleanupClass() { deleteAndClear(sAvatarXmlInfo); - sSkeletonXMLTree.cleanup(); + sSkeletonXMLTree = NULL; sXMLTree.cleanup(); } @@ -1263,7 +1355,7 @@ void LLVOAvatar::initInstance(void) if (LLCharacter::sInstances.size() == 1) { LLKeyframeMotion::setVFS(gStaticVFS); - registerMotion( ANIM_AGENT_BUSY, LLNullMotion::create ); + registerMotion( ANIM_AGENT_DO_NOT_DISTURB, LLNullMotion::create ); registerMotion( ANIM_AGENT_CROUCH, LLKeyframeStandMotion::create ); registerMotion( ANIM_AGENT_CROUCHWALK, LLKeyframeWalkMotion::create ); registerMotion( ANIM_AGENT_EXPRESS_AFRAID, LLEmote::create ); @@ -1366,8 +1458,6 @@ void LLVOAvatar::onShift(const LLVector4a& shift_vector) const LLVector3& shift = reinterpret_cast<const LLVector3&>(shift_vector); mLastAnimExtents[0] += shift; mLastAnimExtents[1] += shift; - mNeedsImpostorUpdate = TRUE; - mNeedsAnimUpdate = TRUE; } void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) @@ -1647,38 +1737,42 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector //----------------------------------------------------------------------------- BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename) { - LLMemType mt(LLMemType::MTYPE_AVATAR); - //------------------------------------------------------------------------- // parse the file //------------------------------------------------------------------------- - BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE ); - if (!parsesuccess) + LLXMLNodePtr skeleton_xml; + BOOL parsesuccess = LLXMLNode::parseFile(filename, skeleton_xml, NULL); + + if (!parsesuccess || skeleton_xml.isNull()) { llerrs << "Can't parse skeleton file: " << filename << llendl; return FALSE; } - // now sanity check xml file - LLXmlTreeNode* root = sSkeletonXMLTree.getRoot(); - if (!root) + // Process XML data + if (sAvatarSkeletonInfo) + { //this can happen if a login attempt failed + delete sAvatarSkeletonInfo; + } + sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo; + + LLXUIParser parser; + parser.readXUI(skeleton_xml, *sAvatarSkeletonInfo, filename); + if (!sAvatarSkeletonInfo->validateBlock()) { - llerrs << "No root node found in avatar skeleton file: " << filename << llendl; - return FALSE; + llerrs << "Error parsing skeleton XML file: " << filename << llendl; } - if( !root->hasName( "linden_skeleton" ) ) + if( !skeleton_xml->hasName( "linden_skeleton" ) ) { llerrs << "Invalid avatar skeleton file header: " << filename << llendl; return FALSE; } - std::string version; - static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); - if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) + if (sAvatarSkeletonInfo->version() != "1.0") { - llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl; + llerrs << "Invalid avatar skeleton file version: " << sAvatarSkeletonInfo->version() << " in file: " << filename << llendl; return FALSE; } @@ -1687,14 +1781,11 @@ BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename) //----------------------------------------------------------------------------- // setupBone() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num) +//----------------------------------------------------------- +BOOL LLVOAvatar::setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num) { - LLMemType mt(LLMemType::MTYPE_AVATAR); - LLViewerJoint* joint = NULL; - - if (info->mIsJoint) + if (info.bone.isChosen()) { joint = (LLViewerJoint*)getCharacterJoint(joint_num); if (!joint) @@ -1702,7 +1793,23 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent llwarns << "Too many bones" << llendl; return FALSE; } - joint->setName( info->mName ); + joint->setName( info.bone().name ); + joint->setPosition(info.bone().pos); + joint->setRotation(mayaQ(info.bone().rot().mV[VX], info.bone().rot().mV[VY], info.bone().rot().mV[VZ], LLQuaternion::XYZ)); + joint->setScale(info.bone().scale); + joint->setSkinOffset( info.bone().pivot ); + joint_num++; + + for (LLInitParam::ParamIterator<LLVOAvatarChildJoint>::const_iterator child_it = info.bone().children.begin(), + end_it = info.bone().children.end(); + child_it != end_it; + ++child_it) + { + if (!setupBone(*child_it, joint, volume_num, joint_num)) + { + return FALSE; + } + } } else // collision volume { @@ -1712,7 +1819,11 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent return FALSE; } joint = (LLViewerJoint*)(&mCollisionVolumes[volume_num]); - joint->setName( info->mName ); + joint->setName( info.collision_volume.name); + joint->setPosition(info.collision_volume.pos); + joint->setRotation(mayaQ(info.collision_volume.rot().mV[VX], info.collision_volume.rot().mV[VY], info.collision_volume.rot().mV[VZ], LLQuaternion::XYZ)); + joint->setScale(info.collision_volume.scale); + volume_num++; } // add to parent @@ -1721,34 +1832,8 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent parent->addChild( joint ); } - joint->setPosition(info->mPos); - joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY], - info->mRot.mV[VZ], LLQuaternion::XYZ)); - joint->setScale(info->mScale); - joint->setDefaultFromCurrentXform(); - if (info->mIsJoint) - { - joint->setSkinOffset( info->mPivot ); - joint_num++; - } - else // collision volume - { - volume_num++; - } - - // setup children - LLVOAvatarBoneInfo::child_list_t::const_iterator iter; - for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter) - { - LLVOAvatarBoneInfo *child_info = *iter; - if (!setupBone(child_info, joint, volume_num, joint_num)) - { - return FALSE; - } - } - return TRUE; } @@ -1757,41 +1842,35 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent //----------------------------------------------------------------------------- BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info) { - LLMemType mt(LLMemType::MTYPE_AVATAR); - //------------------------------------------------------------------------- // allocate joints //------------------------------------------------------------------------- - if (!allocateCharacterJoints(info->mNumBones)) + if (!allocateCharacterJoints(info->num_bones)) { - llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl; + llerrs << "Can't allocate " << info->num_bones() << " joints" << llendl; return FALSE; } //------------------------------------------------------------------------- // allocate volumes //------------------------------------------------------------------------- - if (info->mNumCollisionVolumes) + if (info->num_collision_volumes) { - if (!allocateCollisionVolumes(info->mNumCollisionVolumes)) + if (!allocateCollisionVolumes(info->num_collision_volumes)) { - llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl; + llerrs << "Can't allocate " << info->num_collision_volumes() << " collision volumes" << llendl; return FALSE; } } S32 current_joint_num = 0; S32 current_volume_num = 0; - LLVOAvatarSkeletonInfo::bone_info_list_t::const_iterator iter; - for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter) + + if (!setupBone(info->skeleton_root, NULL, current_volume_num, current_joint_num)) { - LLVOAvatarBoneInfo *info = *iter; - if (!setupBone(info, NULL, current_volume_num, current_joint_num)) - { llerrs << "Error parsing bone in skeleton file" << llendl; return FALSE; } - } return TRUE; } @@ -1829,8 +1908,6 @@ void LLVOAvatar::startDefaultMotions() //----------------------------------------------------------------------------- void LLVOAvatar::buildCharacter() { - LLMemType mt(LLMemType::MTYPE_AVATAR); - //------------------------------------------------------------------------- // remove all references to our existing skeleton // so we can rebuild it @@ -1841,6 +1918,7 @@ void LLVOAvatar::buildCharacter() // remove all of mRoot's children //------------------------------------------------------------------------- mRoot.removeAllChildren(); + mJointMap.clear(); mIsBuilt = FALSE; //------------------------------------------------------------------------- @@ -1979,8 +2057,6 @@ void LLVOAvatar::buildCharacter() //----------------------------------------------------------------------------- void LLVOAvatar::releaseMeshData() { - LLMemType mt(LLMemType::MTYPE_AVATAR); - if (sInstances.size() < AVATAR_RELEASE_THRESHOLD || mIsDummy) { return; @@ -2001,13 +2077,19 @@ void LLVOAvatar::releaseMeshData() if (mDrawable.notNull()) { LLFace* facep = mDrawable->getFace(0); + if (facep) + { facep->setSize(0, 0); for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++) { facep = mDrawable->getFace(i); + if (facep) + { facep->setSize(0, 0); } } + } + } for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); @@ -2029,7 +2111,6 @@ void LLVOAvatar::releaseMeshData() void LLVOAvatar::restoreMeshData() { llassert(!isSelf()); - LLMemType mt(LLMemType::MTYPE_AVATAR); //llinfos << "Restoring" << llendl; mMeshValid = TRUE; @@ -2090,15 +2171,20 @@ void LLVOAvatar::updateMeshData() part_index-- ; } - LLFace* facep ; + LLFace* facep = NULL; if(f_num < mDrawable->getNumFaces()) { facep = mDrawable->getFace(f_num); } else { - facep = mDrawable->addFace(mDrawable->getFace(0)->getPool(), mDrawable->getFace(0)->getTexture()) ; + facep = mDrawable->getFace(0); + if (facep) + { + facep = mDrawable->addFace(facep->getPool(), facep->getTexture()) ; + } } + if (!facep) continue; // resize immediately facep->setSize(num_vertices, num_indices); @@ -2240,8 +2326,6 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, U32 block_num, const EObjectUpdateType update_type, LLDataPacker *dp) { - LLMemType mt(LLMemType::MTYPE_AVATAR); - LLVector3 old_vel = getVelocity(); const BOOL has_name = !getNVPair("FirstName"); @@ -2249,18 +2333,12 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); // Print out arrival information once we have name of avatar. - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) - { if (has_name && getNVPair("FirstName")) { mDebugExistenceTimer.reset(); - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezArrivedNotification",args); - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' arrived." << llendl; + debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived"); } - } + if(retval & LLViewerObject::INVALID_UPDATE) { if (isSelf()) @@ -2292,7 +2370,7 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) } } -static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Update Avatar"); +static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Avatar Update"); static LLFastTimer::DeclareTimer FTM_JOINT_UPDATE("Update Joints"); //------------------------------------------------------------------------ @@ -2325,20 +2403,19 @@ void LLVOAvatar::dumpAnimationState() //------------------------------------------------------------------------ // idleUpdate() //------------------------------------------------------------------------ -BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - LLMemType mt(LLMemType::MTYPE_AVATAR); LLFastTimer t(FTM_AVATAR_UPDATE); if (isDead()) { llinfos << "Warning! Idle on dead avatar" << llendl; - return TRUE; + return; } if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))) { - return TRUE; + return; } checkTextureLoading() ; @@ -2421,8 +2498,6 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) idleUpdateNameTag( root_pos_last ); idleUpdateRenderCost(); - - return TRUE; } void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) @@ -2594,7 +2669,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) if (isImpostor() && !mNeedsImpostorUpdate) { - LLVector4a ext[2]; + LL_ALIGN_16(LLVector4a ext[2]); F32 distance; LLVector3 angle; @@ -2766,16 +2841,16 @@ void LLVOAvatar::idleUpdateLoadingEffect() // update visibility when avatar is partially loaded if (updateIsFullyLoaded()) // changed? { - if (isFullyLoaded() && isSelf()) + if (isFullyLoaded() && mFirstFullyVisible && isSelf()) { - static bool first_fully_visible = true; - if (first_fully_visible) - { - llinfos << "self isFullyLoaded, first_fully_visible" << llendl; - - first_fully_visible = false; + LL_INFOS("Avatar") << avString() << "self isFullyLoaded, mFirstFullyVisible" << LL_ENDL; + mFirstFullyVisible = FALSE; LLAppearanceMgr::instance().onFirstFullyVisible(); } + if (isFullyLoaded() && mFirstFullyVisible && !isSelf()) + { + LL_INFOS("Avatar") << avString() << "other isFullyLoaded, mFirstFullyVisible" << LL_ENDL; + mFirstFullyVisible = FALSE; } if (isFullyLoaded()) { @@ -2919,43 +2994,43 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) return; } - BOOL new_name = FALSE; - if (visible_chat != mVisibleChat) + BOOL new_name = FALSE; + if (visible_chat != mVisibleChat) + { + mVisibleChat = visible_chat; + new_name = TRUE; + } + + if (sRenderGroupTitles != mRenderGroupTitles) + { + mRenderGroupTitles = sRenderGroupTitles; + new_name = TRUE; + } + + // First Calculate Alpha + // If alpha > 0, create mNameText if necessary, otherwise delete it + F32 alpha = 0.f; + if (mAppAngle > 5.f) + { + const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; + if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME) { - mVisibleChat = visible_chat; - new_name = TRUE; + alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION; } - - if (sRenderGroupTitles != mRenderGroupTitles) + else { - mRenderGroupTitles = sRenderGroupTitles; - new_name = TRUE; + // ...not fading, full alpha + alpha = 1.f; } - - // First Calculate Alpha - // If alpha > 0, create mNameText if necessary, otherwise delete it - F32 alpha = 0.f; - if (mAppAngle > 5.f) - { - const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; - if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME) - { - alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION; - } - else - { - // ...not fading, full alpha - alpha = 1.f; - } - } - else if (mAppAngle > 2.f) - { - // far away is faded out also - alpha = (mAppAngle-2.f)/3.f; - } + } + else if (mAppAngle > 2.f) + { + // far away is faded out also + alpha = (mAppAngle-2.f)/3.f; + } if (alpha <= 0.f) - { + { if (mNameText) { mNameText->markDead(); @@ -2965,37 +3040,36 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) return; } - if (!mNameText) - { + if (!mNameText) + { mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject( LLHUDObject::LL_HUD_NAME_TAG) ); //mNameText->setMass(10.f); - mNameText->setSourceObject(this); + mNameText->setSourceObject(this); mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP); - mNameText->setVisibleOffScreen(TRUE); - mNameText->setMaxLines(11); - mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); - sNumVisibleChatBubbles++; - new_name = TRUE; - } + mNameText->setVisibleOffScreen(TRUE); + mNameText->setMaxLines(11); + mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); + sNumVisibleChatBubbles++; + new_name = TRUE; + } - LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last); - mNameText->setPositionAgent(name_position); + idleUpdateNameTagPosition(root_pos_last); idleUpdateNameTagText(new_name); idleUpdateNameTagAlpha(new_name, alpha); } void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) - { - LLNameValue *title = getNVPair("Title"); - LLNameValue* firstname = getNVPair("FirstName"); - LLNameValue* lastname = getNVPair("LastName"); +{ + LLNameValue *title = getNVPair("Title"); + LLNameValue* firstname = getNVPair("FirstName"); + LLNameValue* lastname = getNVPair("LastName"); // Avatars must have a first and last name if (!firstname || !lastname) return; bool is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end(); - bool is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end(); + bool is_do_not_disturb = mSignaledAnimations.find(ANIM_AGENT_DO_NOT_DISTURB) != mSignaledAnimations.end(); bool is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end(); bool is_muted; if (isSelf()) @@ -3003,34 +3077,23 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) is_muted = false; } else - { + { is_muted = LLMuteList::getInstance()->isMuted(getID()); } bool is_friend = LLAvatarTracker::instance().isBuddy(getID()); bool is_cloud = getIsCloud(); - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) - { - if (is_appearance != mNameAppearance) - { - if (is_appearance) - { - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args); - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl; - } - else - { - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args); - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl; - } - } - } + if (is_appearance != mNameAppearance) + { + if (is_appearance) + { + debugAvatarRezTime("AvatarRezEnteredAppearanceNotification","entered appearance mode"); + } + else + { + debugAvatarRezTime("AvatarRezLeftAppearanceNotification","left appearance mode"); + } + } // Rebuild name tag if state change detected if (mNameString.empty() @@ -3038,41 +3101,41 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) || (!title && !mTitle.empty()) || (title && mTitle != title->getString()) || is_away != mNameAway - || is_busy != mNameBusy + || is_do_not_disturb != mNameDoNotDisturb || is_muted != mNameMute - || is_appearance != mNameAppearance + || is_appearance != mNameAppearance || is_friend != mNameFriend || is_cloud != mNameCloud) - { + { LLColor4 name_tag_color = getNameTagColor(is_friend); clearNameTag(); - if (is_away || is_muted || is_busy || is_appearance) - { + if (is_away || is_muted || is_do_not_disturb || is_appearance) + { std::string line; - if (is_away) - { - line += LLTrans::getString("AvatarAway"); + if (is_away) + { + line += LLTrans::getString("AvatarAway"); line += ", "; - } - if (is_busy) - { - line += LLTrans::getString("AvatarBusy"); + } + if (is_do_not_disturb) + { + line += LLTrans::getString("AvatarDoNotDisturb"); line += ", "; } if (is_muted) - { + { line += LLTrans::getString("AvatarMuted"); - line += ", "; - } + line += ", "; + } if (is_appearance) { line += LLTrans::getString("AvatarEditingAppearance"); line += ", "; - } + } if (is_cloud) - { + { line += LLTrans::getString("LoadingData"); line += ", "; } @@ -3084,138 +3147,136 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) if (sRenderGroupTitles && title && title->getString() && title->getString()[0] != '\0') - { + { std::string title_str = title->getString(); LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR); addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL, LLFontGL::getFontSansSerifSmall()); - } + } static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames"); static LLUICachedControl<bool> show_usernames("NameTagShowUsernames"); - if (LLAvatarNameCache::useDisplayNames()) + if (LLAvatarName::useDisplayNames()) { LLAvatarName av_name; if (!LLAvatarNameCache::get(getID(), &av_name)) { - // ...call this function back when the name arrives - // and force a rebuild - LLAvatarNameCache::get(getID(), - boost::bind(&LLVOAvatar::clearNameTag, this)); - } + // Force a rebuild at next idle + // Note: do not connect a callback on idle(). + clearNameTag(); + } // Might be blank if name not available yet, that's OK if (show_display_names) { - addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL, + addNameTagLine(av_name.getDisplayName(), name_tag_color, LLFontGL::NORMAL, LLFontGL::getFontSansSerif()); - } + } // Suppress SLID display if display name matches exactly (ugh) - if (show_usernames && !av_name.mIsDisplayNameDefault) - { + if (show_usernames && !av_name.isDisplayNameDefault()) + { // *HACK: Desaturate the color LLColor4 username_color = name_tag_color * 0.83f; - addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL, + addNameTagLine(av_name.getUserName(), username_color, LLFontGL::NORMAL, LLFontGL::getFontSansSerifSmall()); } - } + } else - { + { const LLFontGL* font = LLFontGL::getFontSansSerif(); - std::string full_name = - LLCacheName::buildFullName( firstname->getString(), lastname->getString() ); + std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() ); addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font); - } + } - mNameAway = is_away; - mNameBusy = is_busy; - mNameMute = is_muted; - mNameAppearance = is_appearance; + mNameAway = is_away; + mNameDoNotDisturb = is_do_not_disturb; + mNameMute = is_muted; + mNameAppearance = is_appearance; mNameFriend = is_friend; - mNameCloud = is_cloud; - mTitle = title ? title->getString() : ""; - LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); - new_name = TRUE; - } + mNameCloud = is_cloud; + mTitle = title ? title->getString() : ""; + LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); + new_name = TRUE; + } if (mVisibleChat) - { - mNameText->setFont(LLFontGL::getFontSansSerif()); + { + mNameText->setFont(LLFontGL::getFontSansSerif()); mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT); - mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); - - char line[MAX_STRING]; /* Flawfinder: ignore */ - line[0] = '\0'; - std::deque<LLChat>::iterator chat_iter = mChats.begin(); - mNameText->clearString(); - - LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" ); - LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); - LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f); - if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) - { - ++chat_iter; - } + mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); - for(; chat_iter != mChats.end(); ++chat_iter) - { - F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); - LLFontGL::StyleFlags style; - switch(chat_iter->mChatType) - { - case CHAT_TYPE_WHISPER: - style = LLFontGL::ITALIC; - break; - case CHAT_TYPE_SHOUT: - style = LLFontGL::BOLD; - break; - default: - style = LLFontGL::NORMAL; - break; - } - if (chat_fade_amt < 1.f) - { - F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); - mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style); - } - else if (chat_fade_amt < 2.f) - { - F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f); - mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style); - } - else if (chat_fade_amt < 3.f) - { - // *NOTE: only remove lines down to minimum number - mNameText->addLine(chat_iter->mText, old_chat, style); - } - } - mNameText->setVisibleOffScreen(TRUE); + char line[MAX_STRING]; /* Flawfinder: ignore */ + line[0] = '\0'; + std::deque<LLChat>::iterator chat_iter = mChats.begin(); + mNameText->clearString(); - if (mTyping) - { - S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1; - switch(dot_count) - { - case 1: - mNameText->addLine(".", new_chat); - break; - case 2: - mNameText->addLine("..", new_chat); - break; - case 3: - mNameText->addLine("...", new_chat); - break; - } + LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" ); + LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); + LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f); + if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) + { + ++chat_iter; + } - } + for(; chat_iter != mChats.end(); ++chat_iter) + { + F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); + LLFontGL::StyleFlags style; + switch(chat_iter->mChatType) + { + case CHAT_TYPE_WHISPER: + style = LLFontGL::ITALIC; + break; + case CHAT_TYPE_SHOUT: + style = LLFontGL::BOLD; + break; + default: + style = LLFontGL::NORMAL; + break; } - else + if (chat_fade_amt < 1.f) + { + F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); + mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style); + } + else if (chat_fade_amt < 2.f) { + F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f); + mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style); + } + else if (chat_fade_amt < 3.f) + { + // *NOTE: only remove lines down to minimum number + mNameText->addLine(chat_iter->mText, old_chat, style); + } + } + mNameText->setVisibleOffScreen(TRUE); + + if (mTyping) + { + S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1; + switch(dot_count) + { + case 1: + mNameText->addLine(".", new_chat); + break; + case 2: + mNameText->addLine("..", new_chat); + break; + case 3: + mNameText->addLine("...", new_chat); + break; + } + + } + } + else + { // ...not using chat bubbles, just names mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER); - mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); - mNameText->setVisibleOffScreen(FALSE); + mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); + mNameText->setVisibleOffScreen(FALSE); } } @@ -3238,10 +3299,11 @@ void LLVOAvatar::clearNameTag() { mNameString.clear(); if (mNameText) - { - mNameText->setLabel(""); + { + mNameText->setLabel(""); mNameText->setString( "" ); } + mTimeVisible.reset(); } //static @@ -3267,34 +3329,45 @@ void LLVOAvatar::invalidateNameTags() if (avatar->isDead()) continue; avatar->clearNameTag(); - } } // Compute name tag position during idle update -LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) +void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) { LLQuaternion root_rot = mRoot.getWorldRotation(); + LLQuaternion inv_root_rot = ~root_rot; LLVector3 pixel_right_vec; LLVector3 pixel_up_vec; LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec); LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin(); camera_to_av.normalize(); - LLVector3 local_camera_at = camera_to_av * ~root_rot; + LLVector3 local_camera_at = camera_to_av * inv_root_rot; LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis(); local_camera_up.normalize(); - local_camera_up = local_camera_up * ~root_rot; + local_camera_up = local_camera_up * inv_root_rot; - local_camera_up.scaleVec(mBodySize * 0.5f); - local_camera_at.scaleVec(mBodySize * 0.5f); + LLVector3 avatar_ellipsoid(mBodySize.mV[VX] * 0.4f, + mBodySize.mV[VY] * 0.4f, + mBodySize.mV[VZ] * NAMETAG_VERT_OFFSET_WEIGHT); - LLVector3 name_position = mRoot.getWorldPosition(); - name_position[VZ] -= mPelvisToFoot; - name_position[VZ] += (mBodySize[VZ]* 0.55f); + local_camera_up.scaleVec(avatar_ellipsoid); + local_camera_at.scaleVec(avatar_ellipsoid); + + LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot.getLastWorldPosition()) * inv_root_rot; + + if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD) + { + mTargetRootToHeadOffset = head_offset; + } + + mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLCriticalDamp::getInterpolant(0.2f)); + + LLVector3 name_position = mRoot.getLastWorldPosition() + (mCurRootToHeadOffset * root_rot); name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av)); - name_position += pixel_up_vec * 15.f; + name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET; - return name_position; + mNameText->setPositionAgent(name_position); } void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha) @@ -3317,20 +3390,18 @@ LLColor4 LLVOAvatar::getNameTagColor(bool is_friend) { color_name = "NameTagFriend"; } - else if (LLAvatarNameCache::useDisplayNames()) + else if (LLAvatarName::useDisplayNames()) { - // ...color based on whether username "matches" a computed display - // name + // ...color based on whether username "matches" a computed display name LLAvatarName av_name; - if (LLAvatarNameCache::get(getID(), &av_name) - && av_name.mIsDisplayNameDefault) + if (LLAvatarNameCache::get(getID(), &av_name) && av_name.isDisplayNameDefault()) { color_name = "NameTagMatch"; } else { color_name = "NameTagMismatch"; - } + } } else { @@ -3362,14 +3433,22 @@ void LLVOAvatar::slamPosition() mRoot.updateWorldMatrixChildren(); } +bool LLVOAvatar::isVisuallyMuted() const +{ + 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 //------------------------------------------------------------------------ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) { - LLMemType mt(LLMemType::MTYPE_AVATAR); - // clear debug text mDebugText.clear(); if (LLVOAvatar::sShowAnimationDebug) @@ -3400,8 +3479,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) } } - LLVector3d root_pos_global; - if (!mIsBuilt) { return FALSE; @@ -3416,20 +3493,20 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) mTimeVisible.reset(); } - //-------------------------------------------------------------------- // the rest should only be done occasionally for far away avatars //-------------------------------------------------------------------- - if (visible && !isSelf() && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter) + if (visible && (!isSelf() || isVisuallyMuted()) && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter) { const LLVector4a* ext = mDrawable->getSpatialExtents(); LLVector4a size; 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; } @@ -3460,6 +3537,11 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) visible = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0 ? TRUE : FALSE; } + else + { + mUpdatePeriod = 1; + } + // don't early out for your own avatar, as we rely on your animations playing reliably // for example, the "turn around" animation when entering customize avatar needs to trigger @@ -3638,7 +3720,11 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook(); LLVector3 pelvisDir( mRoot.getWorldMatrix().getFwdRow4().mV ); - F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, PELVIS_ROT_THRESHOLD_SLOW, PELVIS_ROT_THRESHOLD_FAST); + + static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow"); + static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast"); + + F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast); if (self_in_mouselook) { @@ -3809,10 +3895,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) if ( playSound ) { -// F32 gain = clamp_rescale( mSpeedAccum, -// AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED, -// AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN ); - const F32 STEP_VOLUME = 0.1f; const LLUUID& step_sound_id = getStepSound(); @@ -3945,7 +4027,7 @@ void LLVOAvatar::updateVisibility() LLNameValue* firstname = getNVPair("FirstName"); if (firstname) { - llinfos << "Avatar " << firstname->getString() << " updating visiblity" << llendl; + LL_DEBUGS("Avatar") << avString() << " updating visibility" << LL_ENDL; } else { @@ -4029,13 +4111,6 @@ void LLVOAvatar::updateVisibility() { releaseMeshData(); } - // this breaks off-screen chat bubbles - //if (mNameText) - //{ - // mNameText->markDead(); - // mNameText = NULL; - // sNumVisibleChatBubbles--; - //} } mVisible = visible; @@ -4051,46 +4126,6 @@ bool LLVOAvatar::shouldAlphaMask() } -U32 LLVOAvatar::renderSkinnedAttachments() -{ - /*U32 num_indices = 0; - - const U32 data_mask = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_NORMAL | - LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_COLOR | - LLVertexBuffer::MAP_WEIGHT4; - - for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - const LLViewerObject* attached_object = (*attachment_iter); - if (attached_object && !attached_object->isHUDAttachment()) - { - const LLDrawable* drawable = attached_object->mDrawable; - if (drawable) - { - for (S32 i = 0; i < drawable->getNumFaces(); ++i) - { - LLFace* face = drawable->getFace(i); - if (face->isState(LLFace::RIGGED)) - { - - } - } - } - } - - return num_indices;*/ - return 0; -} - //----------------------------------------------------------------------------- // renderSkinned() //----------------------------------------------------------------------------- @@ -4140,13 +4175,17 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) mNeedsSkin = FALSE; mLastSkinTime = gFrameTimeSeconds; - LLVertexBuffer* vb = mDrawable->getFace(0)->getVertexBuffer(); + LLFace * face = mDrawable->getFace(0); + if (face) + { + LLVertexBuffer* vb = face->getVertexBuffer(); if (vb) { vb->flush(); } } } + } else { mNeedsSkin = FALSE; @@ -4157,7 +4196,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) LLNameValue* firstname = getNVPair("FirstName"); if (firstname) { - llinfos << "Avatar " << firstname->getString() << " in render" << llendl; + LL_DEBUGS("Avatar") << avString() << " in render" << LL_ENDL; } else { @@ -4312,7 +4351,9 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) } // Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair) // TODO: 1.25 will be able to switch this logic back to calling isTextureVisible(); - if (getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha) + + if ( getImage(TEX_HAIR_BAKED, 0) + && getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha) { num_indices += mMeshLOD[MESH_ID_HAIR]->render(mAdjustedPixelArea, first_pass, mIsDummy); first_pass = FALSE; @@ -4456,7 +4497,20 @@ void LLVOAvatar::updateTextures() LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)texture_index); U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); const LLTextureEntry *te = getTE(texture_index); - const F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT); + + // getTE can return 0. + // Not sure yet why it does, but of course it crashes when te->mScale? gets used. + // Put safeguard in place so this corner case get better handling and does not result in a crash. + F32 texel_area_ratio = 1.0f; + if( te ) + { + texel_area_ratio = fabs(te->mScaleS * te->mScaleT); + } + else + { + llwarns << "getTE( " << texture_index << " ) returned 0" <<llendl; + } + LLViewerFetchedTexture *imagep = NULL; for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++) { @@ -4684,8 +4738,6 @@ const LLUUID& LLVOAvatar::getStepSound() const //----------------------------------------------------------------------------- void LLVOAvatar::processAnimationStateChanges() { - LLMemType mt(LLMemType::MTYPE_AVATAR); - if ( isAnyAnimationSignaled(AGENT_WALK_ANIMS, NUM_AGENT_WALK_ANIMS) ) { startMotion(ANIM_AGENT_WALK_ADJUST); @@ -4776,8 +4828,6 @@ void LLVOAvatar::processAnimationStateChanges() //----------------------------------------------------------------------------- BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL start ) { - LLMemType mt(LLMemType::MTYPE_AVATAR); - BOOL result = FALSE; if ( start ) // start animation @@ -4912,8 +4962,6 @@ LLUUID LLVOAvatar::remapMotionID(const LLUUID& id) //----------------------------------------------------------------------------- BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset) { - LLMemType mt(LLMemType::MTYPE_AVATAR); - lldebugs << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << llendl; LLUUID remap_id = remapMotionID(id); @@ -5015,7 +5063,7 @@ void LLVOAvatar::addDebugText(const std::string& text) //----------------------------------------------------------------------------- // getID() //----------------------------------------------------------------------------- -const LLUUID& LLVOAvatar::getID() +const LLUUID& LLVOAvatar::getID() const { return mID; } @@ -5026,7 +5074,20 @@ const LLUUID& LLVOAvatar::getID() // RN: avatar joints are multi-rooted to include screen-based attachments LLJoint *LLVOAvatar::getJoint( const std::string &name ) { - LLJoint* jointp = mRoot.findJoint(name); + joint_map_t::iterator iter = mJointMap.find(name); + + LLJoint* jointp = NULL; + + if (iter == mJointMap.end() || iter->second == NULL) + { //search for joint and cache found joint in lookup table + jointp = mRoot.findJoint(name); + mJointMap[name] = jointp; + } + else + { //return cached pointer + jointp = iter->second; + } + return jointp; } @@ -5413,18 +5474,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; } @@ -5741,8 +5790,6 @@ BOOL LLVOAvatar::isActive() const //----------------------------------------------------------------------------- void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent) { - LLMemType mt(LLMemType::MTYPE_AVATAR); - if (mDrawable.isNull()) { return; @@ -5788,7 +5835,6 @@ BOOL LLVOAvatar::updateJointLODs() F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor); F32 area_scale = 0.16f; - { if (isSelf()) { if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook()) @@ -5818,7 +5864,6 @@ BOOL LLVOAvatar::updateJointLODs() dirtyMesh(2); return TRUE; } - } return FALSE; } @@ -6107,14 +6152,9 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) if ( pVObj ) { const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj ); - if ( pSkinData ) - { - const int jointCnt = pSkinData->mJointNames.size(); - bool fullRig = ( jointCnt>=20 ) ? true : false; - if ( fullRig ) - { - const int bindCnt = pSkinData->mAlternateBindMatrix.size(); - if ( bindCnt > 0 ) + if (pSkinData + && pSkinData->mJointNames.size() > 20 // full rig + && pSkinData->mAlternateBindMatrix.size() > 0) { LLVOAvatar::resetJointPositionsToDefault(); //Need to handle the repositioning of the cam, updating rig data etc during outfit editing @@ -6129,8 +6169,6 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) } } } - } -} //----------------------------------------------------------------------------- // detachObject() //----------------------------------------------------------------------------- @@ -6279,11 +6317,7 @@ void LLVOAvatar::getOffObject() at_axis.mV[VZ] = 0.f; at_axis.normalize(); gAgent.resetAxes(at_axis); - - //reset orientation -// mRoot.setRotation(avWorldRot); gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f)); - gAgentCamera.setSitCamera(LLUUID::null); } } @@ -6333,7 +6367,6 @@ LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const } else { -// return LLColor4( .5f, .5f, .5f, .5f ); return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color } } @@ -6386,10 +6419,10 @@ BOOL LLVOAvatar::isVisible() const } // Determine if we have enough avatar data to render -BOOL LLVOAvatar::getIsCloud() +BOOL LLVOAvatar::getIsCloud() const { // Do we have a shape? - if (visualParamWeightsAreDefault()) + if ((const_cast<LLVOAvatar*>(this))->visualParamWeightsAreDefault()) { return TRUE; } @@ -6408,11 +6441,53 @@ BOOL LLVOAvatar::getIsCloud() return FALSE; } +void LLVOAvatar::updateRezzedStatusTimers() +{ + // State machine for rezzed status. Statuses are 0 = cloud, 1 = gray, 2 = textured. + // Purpose is to collect time data for each period of cloud or cloud+gray. + S32 rez_status = getRezzedStatus(); + if (rez_status != mLastRezzedStatus) + { + LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL; + bool is_cloud_or_gray = (rez_status==0 || rez_status==1); + bool was_cloud_or_gray = (mLastRezzedStatus==0 || mLastRezzedStatus==1); + bool is_cloud = (rez_status==0); + bool was_cloud = (mLastRezzedStatus==0); + + // Non-cloud to cloud + if (is_cloud && !was_cloud) + { + // start cloud timer. + getPhases().startPhase("cloud"); + } + else if (was_cloud && !is_cloud) + { + // stop cloud timer, which will capture stats. + getPhases().stopPhase("cloud"); + } + + // Non-cloud-or-gray to cloud-or-gray + if (is_cloud_or_gray && !was_cloud_or_gray) + { + // start cloud-or-gray timer. + getPhases().startPhase("cloud-or-gray"); + } + else if (was_cloud_or_gray && !is_cloud_or_gray) + { + // stop cloud-or-gray timer, which will capture stats. + getPhases().stopPhase("cloud-or-gray"); + } + + mLastRezzedStatus = rez_status; + } +} + // call periodically to keep isFullyLoaded up to date. // returns true if the value has changed. BOOL LLVOAvatar::updateIsFullyLoaded() { const BOOL loading = getIsCloud(); + updateRezzedStatusTimers(); updateRuthTimer(loading); return processFullyLoadedChange(loading); } @@ -6427,27 +6502,19 @@ void LLVOAvatar::updateRuthTimer(bool loading) if (mPreviousFullyLoaded) { mRuthTimer.reset(); - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) - { - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' became cloud." << llendl; - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezCloudNotification",args); - } - mRuthDebugTimer.reset(); + debugAvatarRezTime("AvatarRezCloudNotification","became cloud"); } const F32 LOADING_TIMEOUT__SECONDS = 120.f; if (mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT__SECONDS) { - llinfos << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' " + LL_DEBUGS("Avatar") << avString() + << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' " << "( Params loaded : " << !visualParamWeightsAreDefault() << " ) " << "( Lower : " << isTextureDefined(TEX_LOWER_BAKED) << " ) " << "( Upper : " << isTextureDefined(TEX_UPPER_BAKED) << " ) " << "( Head : " << isTextureDefined(TEX_HEAD_BAKED) << " )." - << llendl; + << LL_ENDL; LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID()); mRuthTimer.reset(); @@ -6464,20 +6531,13 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading) mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE); - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) - { if (!mPreviousFullyLoaded && !loading && mFullyLoaded) { - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' resolved in " << (U32)mRuthDebugTimer.getElapsedTimeF32() << " seconds." << llendl; - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezNotification",args); - } + debugAvatarRezTime("AvatarRezNotification","fully loaded"); } // did our loading state "change" from last call? + // runway - why are we updating every 30 calls even if nothing has changed? const S32 UPDATE_RATE = 30; BOOL changed = ((mFullyLoaded != mPreviousFullyLoaded) || // if the value is different from the previous call @@ -6493,10 +6553,7 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading) BOOL LLVOAvatar::isFullyLoaded() const { - if (gSavedSettings.getBOOL("RenderUnloadedAvatar")) - return TRUE; - else - return mFullyLoaded; + return (mRenderUnloadedAvatar || mFullyLoaded); } bool LLVOAvatar::isTooComplex() const @@ -6542,7 +6599,7 @@ void LLVOAvatar::updateMeshTextures() if(!isSelf()) { src_callback_list = &mCallbackTextureList ; - paused = mLoadedCallbacksPaused ; + paused = !isVisible(); } std::vector<BOOL> is_layer_baked; @@ -6920,7 +6977,7 @@ LLColor4 LLVOAvatar::getDummyColor() void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const { - llinfos << (isSelf() ? "Self: " : "Other: ") << context << llendl; + LL_DEBUGS("Avatar") << avString() << (isSelf() ? "Self: " : "Other: ") << context << LL_ENDL; for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); ++iter) @@ -6930,23 +6987,23 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const const LLViewerTexture* te_image = getImage(iter->first,0); if( !te_image ) { - llinfos << " " << texture_dict->mName << ": null ptr" << llendl; + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null ptr" << LL_ENDL; } else if( te_image->getID().isNull() ) { - llinfos << " " << texture_dict->mName << ": null UUID" << llendl; + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null UUID" << LL_ENDL; } else if( te_image->getID() == IMG_DEFAULT ) { - llinfos << " " << texture_dict->mName << ": IMG_DEFAULT" << llendl; + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT" << LL_ENDL; } else if( te_image->getID() == IMG_DEFAULT_AVATAR ) { - llinfos << " " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << llendl; + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << LL_ENDL; } else { - llinfos << " " << texture_dict->mName << ": " << te_image->getID() << llendl; + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": " << te_image->getID() << LL_ENDL; } } } @@ -7068,15 +7125,12 @@ LLBBox LLVOAvatar::getHUDBBox() const return bbox; } -void LLVOAvatar::rebuildHUD() -{ -} - //----------------------------------------------------------------------------- // onFirstTEMessageReceived() //----------------------------------------------------------------------------- void LLVOAvatar::onFirstTEMessageReceived() { + LL_INFOS("Avatar") << avString() << LL_ENDL; if( !mFirstTEMessageReceived ) { mFirstTEMessageReceived = TRUE; @@ -7086,7 +7140,7 @@ void LLVOAvatar::onFirstTEMessageReceived() if(!isSelf()) { src_callback_list = &mCallbackTextureList ; - paused = mLoadedCallbacksPaused ; + paused = !isVisible(); } for (U32 i = 0; i < mBakedTextureDatas.size(); i++) @@ -7105,6 +7159,7 @@ void LLVOAvatar::onFirstTEMessageReceived() image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ), src_callback_list, paused); } + LL_DEBUGS("Avatar") << avString() << "layer_baked, setting onInitialBakedTextureLoaded as callback" << LL_ENDL; image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ), src_callback_list, paused ); } @@ -7161,16 +7216,16 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) return; } - LLMemType mt(LLMemType::MTYPE_AVATAR); - -// llinfos << "processAvatarAppearance start " << mID << llendl; BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived; - mFirstAppearanceMessageReceived = TRUE; + LL_INFOS("Avatar") << avString() << "processAvatarAppearance start " << mID + << " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL; + + if( isSelf() ) { - llwarns << "Received AvatarAppearance for self" << llendl; + llwarns << avString() << "Received AvatarAppearance for self" << llendl; if( mFirstTEMessageReceived ) { // llinfos << "processAvatarAppearance end " << mID << llendl; @@ -7193,12 +7248,18 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) && baked_index != BAKED_SKIRT) { setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, - LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, + TRUE, + LLViewerTexture::BOOST_NONE, + LLViewerTexture::LOD_TEXTURE)); } } - if( !is_first_appearance_message ) + // runway - was + // if (!is_first_appearance_message ) + // which means it would be called on second appearance message - probably wrong. + if (is_first_appearance_message ) { onFirstTEMessageReceived(); } @@ -7219,6 +7280,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing if( num_blocks > 1 && !drop_visual_params_debug) { + LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL; BOOL params_changed = FALSE; BOOL interp_params = FALSE; @@ -7291,6 +7353,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) else { // AvatarAppearance message arrived without visual params + LL_DEBUGS("Avatar") << avString() << "no visual params" << LL_ENDL; if (drop_visual_params_debug) { llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << llendl; @@ -7356,7 +7419,6 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture if (!userdata) return; //llinfos << "onBakedTextureMasksLoaded: " << src_vi->getID() << llendl; - const LLMemType mt(LLMemType::MTYPE_AVATAR); const LLUUID id = src_vi->getID(); LLTextureMaskData* maskData = (LLTextureMaskData*) userdata; @@ -7375,7 +7437,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture } U32 gl_name; - LLImageGL::generateTextures(1, &gl_name ); + LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_ALPHA8, 1, &gl_name ); stop_glerror(); gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name); @@ -7412,7 +7474,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture maskData->mLastDiscardLevel = discard_level; if (self->mBakedTextureDatas[baked_index].mMaskTexName) { - LLImageGL::deleteTextures(1, &(self->mBakedTextureDatas[baked_index].mMaskTexName)); + LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, &(self->mBakedTextureDatas[baked_index].mMaskTexName)); } self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name; found_texture_id = true; @@ -7443,9 +7505,16 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture // static void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { + + LLUUID *avatar_idp = (LLUUID *)userdata; LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); + if (selfp) + { + LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL; + } + if (!success && selfp) { selfp->removeMissingBakedTextures(); @@ -7456,13 +7525,20 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTextu } } -void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) +// Static +void LLVOAvatar::onBakedTextureLoaded(BOOL success, + LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, + S32 discard_level, BOOL final, void* userdata) { //llinfos << "onBakedTextureLoaded: " << src_vi->getID() << llendl; LLUUID id = src_vi->getID(); LLUUID *avatar_idp = (LLUUID *)userdata; LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); + if (selfp) + { + LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << " id " << src_vi->getID() << LL_ENDL; + } if (selfp && !success) { @@ -7484,16 +7560,12 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_ // Called when baked texture is loaded and also when we start up with a baked texture void LLVOAvatar::useBakedTexture( const LLUUID& id ) { - /* if(id == head_baked->getID()) - mHeadBakedLoaded = TRUE; - mLastHeadBakedID = id; - mHeadMesh0.setTexture( head_baked ); - mHeadMesh1.setTexture( head_baked ); */ for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 ); if (id == image_baked->getID()) { + LL_DEBUGS("Avatar") << avString() << " i " << i << " id " << id << LL_ENDL; mBakedTextureDatas[i].mIsLoaded = true; mBakedTextureDatas[i].mLastTextureIndex = id; mBakedTextureDatas[i].mIsUsed = true; @@ -7533,12 +7605,16 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) void LLVOAvatar::dumpArchetypeXML( void* ) { LLAPRFile outfile; - outfile.open(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"new archetype.xml"), LL_APR_WB ); - apr_file_t* file = outfile.getFileHandle() ; + outfile.open(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"new archetype.xml"), LL_APR_WB ); + apr_file_t* file = outfile.getFileHandle(); if (!file) { return; } + else + { + llinfos << "xmlfile write handle obtained : " << gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"new archetype.xml") << llendl; + } apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" ); apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" ); @@ -7578,6 +7654,11 @@ void LLVOAvatar::dumpArchetypeXML( void* ) } apr_file_printf( file, "\t</archetype>\n" ); apr_file_printf( file, "\n</linden_genepool>\n" ); + //explictly close the file if it is still open which it should be + if (file) + { + outfile.close(); + } } @@ -7659,6 +7740,9 @@ void LLVOAvatar::cullAvatarsByPixelArea() } } + // runway - this doesn't detect gray/grey state. + // think we just need to be checking self av since it's the only + // one with lltexlayer stuff. S32 grey_avatars = 0; if (LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars)) { @@ -7719,111 +7803,111 @@ LLVOAvatar::LLVOAvatarXmlInfo::~LLVOAvatarXmlInfo() std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer()); } -//----------------------------------------------------------------------------- -// LLVOAvatarBoneInfo::parseXml() -//----------------------------------------------------------------------------- -BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node) -{ - if (node->hasName("bone")) - { - mIsJoint = TRUE; - static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); - if (!node->getFastAttributeString(name_string, mName)) - { - llwarns << "Bone without name" << llendl; - return FALSE; - } - } - else if (node->hasName("collision_volume")) - { - mIsJoint = FALSE; - static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); - if (!node->getFastAttributeString(name_string, mName)) - { - mName = "Collision Volume"; - } - } - else - { - llwarns << "Invalid node " << node->getName() << llendl; - return FALSE; - } - - static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos"); - if (!node->getFastAttributeVector3(pos_string, mPos)) - { - llwarns << "Bone without position" << llendl; - return FALSE; - } - - static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot"); - if (!node->getFastAttributeVector3(rot_string, mRot)) - { - llwarns << "Bone without rotation" << llendl; - return FALSE; - } - - static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); - if (!node->getFastAttributeVector3(scale_string, mScale)) - { - llwarns << "Bone without scale" << llendl; - return FALSE; - } - - if (mIsJoint) - { - static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot"); - if (!node->getFastAttributeVector3(pivot_string, mPivot)) - { - llwarns << "Bone without pivot" << llendl; - return FALSE; - } - } - - // parse children - LLXmlTreeNode* child; - for( child = node->getFirstChild(); child; child = node->getNextChild() ) - { - LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo; - if (!child_info->parseXml(child)) - { - delete child_info; - return FALSE; - } - mChildList.push_back(child_info); - } - return TRUE; -} - -//----------------------------------------------------------------------------- -// LLVOAvatarSkeletonInfo::parseXml() -//----------------------------------------------------------------------------- -BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node) -{ - static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones"); - if (!node->getFastAttributeS32(num_bones_string, mNumBones)) - { - llwarns << "Couldn't find number of bones." << llendl; - return FALSE; - } - - static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes"); - node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes); - - LLXmlTreeNode* child; - for( child = node->getFirstChild(); child; child = node->getNextChild() ) - { - LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo; - if (!info->parseXml(child)) - { - delete info; - llwarns << "Error parsing bone in skeleton file" << llendl; - return FALSE; - } - mBoneInfoList.push_back(info); - } - return TRUE; -} +////----------------------------------------------------------------------------- +//// LLVOAvatarBoneInfo::parseXml() +////----------------------------------------------------------------------------- +//BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node) +//{ +// if (node->hasName("bone")) +// { +// mIsJoint = TRUE; +// static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); +// if (!node->getFastAttributeString(name_string, mName)) +// { +// llwarns << "Bone without name" << llendl; +// return FALSE; +// } +// } +// else if (node->hasName("collision_volume")) +// { +// mIsJoint = FALSE; +// static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); +// if (!node->getFastAttributeString(name_string, mName)) +// { +// mName = "Collision Volume"; +// } +// } +// else +// { +// llwarns << "Invalid node " << node->getName() << llendl; +// return FALSE; +// } +// +// static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos"); +// if (!node->getFastAttributeVector3(pos_string, mPos)) +// { +// llwarns << "Bone without position" << llendl; +// return FALSE; +// } +// +// static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot"); +// if (!node->getFastAttributeVector3(rot_string, mRot)) +// { +// llwarns << "Bone without rotation" << llendl; +// return FALSE; +// } +// +// static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); +// if (!node->getFastAttributeVector3(scale_string, mScale)) +// { +// llwarns << "Bone without scale" << llendl; +// return FALSE; +// } +// +// if (mIsJoint) +// { +// static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot"); +// if (!node->getFastAttributeVector3(pivot_string, mPivot)) +// { +// llwarns << "Bone without pivot" << llendl; +// return FALSE; +// } +// } +// +// // parse children +// LLXmlTreeNode* child; +// for( child = node->getFirstChild(); child; child = node->getNextChild() ) +// { +// LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo; +// if (!child_info->parseXml(child)) +// { +// delete child_info; +// return FALSE; +// } +// mChildList.push_back(child_info); +// } +// return TRUE; +//} +// +////----------------------------------------------------------------------------- +//// LLVOAvatarSkeletonInfo::parseXml() +////----------------------------------------------------------------------------- +//BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node) +//{ +// static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones"); +// if (!node->getFastAttributeS32(num_bones_string, mNumBones)) +// { +// llwarns << "Couldn't find number of bones." << llendl; +// return FALSE; +// } +// +// static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes"); +// node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes); +// +// LLXmlTreeNode* child; +// for( child = node->getFirstChild(); child; child = node->getNextChild() ) +// { +// LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo; +// if (!info->parseXml(child)) +// { +// delete info; +// llwarns << "Error parsing bone in skeleton file" << llendl; +// return FALSE; +// } +// mBoneInfoList.push_back(info); +// } +// return TRUE; +//} //----------------------------------------------------------------------------- // parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree @@ -8249,7 +8333,7 @@ BOOL LLVOAvatar::updateLOD() BOOL res = updateJointLODs(); LLFace* facep = mDrawable->getFace(0); - if (!facep->getVertexBuffer()) + if (!facep || !facep->getVertexBuffer()) { dirtyMesh(2); } @@ -8297,7 +8381,7 @@ void LLVOAvatar::updateImpostors() BOOL LLVOAvatar::isImpostor() const { - return (sUseImpostors && mUpdatePeriod >= IMPOSTOR_PERIOD) ? TRUE : FALSE; + return (isVisuallyMuted() || (sUseImpostors && mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE; } @@ -8347,6 +8431,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; @@ -8457,7 +8546,9 @@ void LLVOAvatar::idleUpdateRenderCost() } } - setDebugText(llformat("%d", cost)); + + std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); + setDebugText(llformat("%s %d", viz_string.c_str(), cost)); mVisualComplexity = cost; F32 green = 1.f-llclamp(((F32) cost-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f); F32 red = llmin((F32) cost/(F32)ARC_LIMIT, 1.f); @@ -8526,6 +8617,12 @@ BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex te, U32 index return FALSE; } + if( !getImage( te, index ) ) + { + llwarns << "getImage( " << te << ", " << index << " ) returned 0" << llendl; + return FALSE; + } + return (getImage(te, index)->getID() != IMG_DEFAULT_AVATAR && getImage(te, index)->getID() != IMG_DEFAULT); } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index e53b8e3f4b..c59a3a150c 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -40,6 +40,7 @@ #include "lldrawpoolalpha.h" #include "llviewerobject.h" #include "llcharacter.h" +#include "llcontrol.h" #include "llviewerjointmesh.h" #include "llviewerjointattachment.h" #include "llrendertarget.h" @@ -47,6 +48,7 @@ #include "lltexglobalcolor.h" #include "lldriverparam.h" #include "material_codes.h" // LL_MCODE_END +#include "llviewerstats.h" extern const LLUUID ANIM_AGENT_BODY_NOISE; extern const LLUUID ANIM_AGENT_BREATHE_ROT; @@ -65,8 +67,9 @@ class LLVoiceVisualizer; class LLHUDNameTag; class LLHUDEffectSpiral; class LLTexGlobalColor; -class LLVOAvatarBoneInfo; -class LLVOAvatarSkeletonInfo; +struct LLVOAvatarBoneInfo; +struct LLVOAvatarChildJoint; +struct LLVOAvatarSkeletonInfo; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLVOAvatar @@ -77,6 +80,8 @@ class LLVOAvatar : public LLCharacter, public boost::signals2::trackable { + LOG_CLASS(LLVOAvatar); + public: friend class LLVOAvatarSelf; protected: @@ -89,6 +94,16 @@ protected: **/ public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVOAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); virtual void markDead(); static void initClass(); // Initialize data that's only init'd once per class. @@ -120,7 +135,7 @@ public: U32 block_num, const EObjectUpdateType update_type, LLDataPacker *dp); - virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); virtual BOOL updateLOD(); BOOL updateJointLODs(); void updateLODRiggedAttachments( void ); @@ -182,7 +197,7 @@ public: void resetSpecificJointPosition( const std::string& name ); virtual const char* getAnimationPrefix() { return "avatar"; } - virtual const LLUUID& getID(); + virtual const LLUUID& getID() const; virtual LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset); virtual LLJoint* findCollisionVolume(U32 volume_id); virtual S32 getCollisionVolumeID(std::string &name); @@ -211,7 +226,7 @@ public: bool isBuilt() const { return mIsBuilt; } private: //aligned members - LLVector4a mImpostorExtents[2]; + LL_ALIGN_16(LLVector4a mImpostorExtents[2]); private: BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients @@ -229,7 +244,7 @@ public: void idleUpdateWindEffect(); void idleUpdateNameTag(const LLVector3& root_pos_last); void idleUpdateNameTagText(BOOL new_name); - LLVector3 idleUpdateNameTagPosition(const LLVector3& root_pos_last); + void idleUpdateNameTagPosition(const LLVector3& root_pos_last); void idleUpdateNameTagAlpha(BOOL new_name, F32 alpha); LLColor4 getNameTagColor(bool is_friend); void clearNameTag(); @@ -274,14 +289,27 @@ public: public: BOOL isFullyLoaded() const; bool isTooComplex() const; - bool visualParamWeightsAreDefault(); + bool visualParamWeightsAreDefault(); + virtual BOOL getIsCloud() const; + BOOL isFullyTextured() const; + BOOL hasGray() const; + S32 getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = fully textured. + void updateRezzedStatusTimers(); + + S32 mLastRezzedStatus; + + LLViewerStats::PhaseMap& getPhases() + { + return mPhases; + } + protected: - virtual BOOL getIsCloud(); BOOL updateIsFullyLoaded(); BOOL processFullyLoadedChange(bool loading); void updateRuthTimer(bool loading); F32 calcMorphAmount(); private: + BOOL mFirstFullyVisible; BOOL mFullyLoaded; BOOL mPreviousFullyLoaded; BOOL mFullyLoadedInitialized; @@ -289,6 +317,28 @@ private: S32 mVisualComplexity; LLFrameTimer mFullyLoadedTimer; LLFrameTimer mRuthTimer; + +public: + class ScopedPhaseSetter + { + public: + ScopedPhaseSetter(LLVOAvatar *avatarp, std::string phase_name): + mAvatar(avatarp), mPhaseName(phase_name) + { + if (mAvatar) { mAvatar->getPhases().startPhase(mPhaseName); } + } + ~ScopedPhaseSetter() + { + if (mAvatar) { mAvatar->getPhases().stopPhase(mPhaseName); } + } + private: + std::string mPhaseName; + LLVOAvatar* mAvatar; + }; + +private: + LLViewerStats::PhaseMap mPhases; + protected: LLFrameTimer mInvisibleTimer; @@ -314,15 +364,21 @@ public: F32 mLastPelvisToFoot; F32 mPelvisFixup; F32 mLastPelvisFixup; + LLVector3 mCurRootToHeadOffset; + LLVector3 mTargetRootToHeadOffset; LLVector3 mHeadOffset; // current head position LLViewerJoint mRoot; + + typedef std::map<std::string, LLJoint*> joint_map_t; + joint_map_t mJointMap; + protected: static BOOL parseSkeletonFile(const std::string& filename); void buildCharacter(); virtual BOOL loadAvatar(); - BOOL setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 ¤t_volume_num, S32 ¤t_joint_num); + BOOL setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 ¤t_volume_num, S32 ¤t_joint_num); BOOL buildSkeleton(const LLVOAvatarSkeletonInfo *info); private: BOOL mIsBuilt; // state of deferred character building @@ -366,7 +422,7 @@ public: //-------------------------------------------------------------------- private: static LLXmlTree sXMLTree; // avatar config file - static LLXmlTree sSkeletonXMLTree; // avatar skeleton file + static LLXMLNodePtr sSkeletonXMLTree; // avatar skeleton file /** Skeleton ** ** @@ -379,10 +435,11 @@ private: public: U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0); + bool isVisuallyMuted() const; + U32 renderRigid(); U32 renderSkinned(EAvatarRenderPass pass); F32 getLastSkinTime() { return mLastSkinTime; } - U32 renderSkinnedAttachments(); U32 renderTransparent(BOOL first_pass); void renderCollisionVolumes(); static void deleteCachedImages(bool clearAll=true); @@ -390,6 +447,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(); @@ -450,6 +510,8 @@ private: F32 mImpostorDistance; F32 mImpostorPixelArea; LLVector3 mLastAnimExtents[2]; + + LLCachedControl<bool> mRenderUnloadedAvatar; //-------------------------------------------------------------------- // Wind rippling in clothes @@ -508,9 +570,10 @@ public: virtual BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; virtual BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const; -protected: BOOL isFullyBaked(); static BOOL areAllNearbyInstancesBaked(S32& grey_avatars); + static void getNearbyRezzedStats(std::vector<S32>& counts); + static std::string rezStatusToString(S32 status); //-------------------------------------------------------------------- // Baked textures @@ -725,7 +788,6 @@ public: public: BOOL hasHUDAttachment() const; LLBBox getHUDBBox() const; - void rebuildHUD(); void resetHUDAttachments(); BOOL canAttachMoreObjects() const; BOOL canAttachMoreObjects(U32 n) const; @@ -872,6 +934,7 @@ private: public: std::string getFullname() const; // Returns "FirstName LastName" + std::string avString() const; // Frequently used string in log messages "Avatar '<full name'" protected: static void getAnimLabels(LLDynamicArray<std::string>* labels); static void getAnimNames(LLDynamicArray<std::string>* names); @@ -879,7 +942,7 @@ private: std::string mNameString; // UTF-8 title + name + status std::string mTitle; bool mNameAway; - bool mNameBusy; + bool mNameDoNotDisturb; bool mNameMute; bool mNameAppearance; bool mNameFriend; @@ -973,7 +1036,9 @@ private: // Avatar Rez Metrics //-------------------------------------------------------------------- public: + void debugAvatarRezTime(std::string notification_name, std::string comment = ""); F32 debugGetExistenceTimeElapsedF32() const { return mDebugExistenceTimer.getElapsedTimeF32(); } + protected: LLFrameTimer mRuthDebugTimer; // For tracking how long it takes for av to rez LLFrameTimer mDebugExistenceTimer; // Debugging for how long the avatar has been in memory. diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 581912f844..e32fd3c3c8 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -58,6 +58,8 @@ #include "llappearancemgr.h" #include "llmeshrepository.h" #include "llvovolume.h" +#include "llsdutil.h" +#include "llstartup.h" #if LL_MSVC // disable boost::lexical_cast warning @@ -66,14 +68,48 @@ #include <boost/lexical_cast.hpp> -LLVOAvatarSelf *gAgentAvatarp = NULL; +LLPointer<LLVOAvatarSelf> gAgentAvatarp = NULL; + BOOL isAgentAvatarValid() { - return (gAgentAvatarp && + return (gAgentAvatarp.notNull() && (gAgentAvatarp->getRegion() != NULL) && (!gAgentAvatarp->isDead())); } +void selfStartPhase(const std::string& phase_name) +{ + if (isAgentAvatarValid()) + { + gAgentAvatarp->getPhases().startPhase(phase_name); + } +} + +void selfStopPhase(const std::string& phase_name) +{ + if (isAgentAvatarValid()) + { + gAgentAvatarp->getPhases().stopPhase(phase_name); + } +} + +void selfClearPhases() +{ + if (isAgentAvatarValid()) + { + gAgentAvatarp->getPhases().clearPhases(); + gAgentAvatarp->mLastRezzedStatus = -1; + } +} + +void selfStopAllPhases() +{ + if (isAgentAvatarValid()) + { + gAgentAvatarp->getPhases().stopAllPhases(); + } +} + using namespace LLVOAvatarDefines; /********************************************************************************* @@ -130,7 +166,8 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id, LLVOAvatar(id, pcode, regionp), mScreenp(NULL), mLastRegionHandle(0), - mRegionCrossingCount(0) + mRegionCrossingCount(0), + mInitialBakesLoaded(false) { gAgentWearables.setAvatarObject(this); @@ -163,6 +200,7 @@ void LLVOAvatarSelf::initInstance() { mDebugBakedTextureTimes[i][0] = -1.0f; mDebugBakedTextureTimes[i][1] = -1.0f; + mInitialBakeIDs[i] = LLUUID::null; } status &= buildMenus(); @@ -219,8 +257,6 @@ BOOL LLVOAvatarSelf::loadAvatarSelf() BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info) { - LLMemType mt(LLMemType::MTYPE_AVATAR); - // add special-purpose "screen" joint mScreenp = new LLViewerJoint("mScreen", NULL); // for now, put screen at origin, as it is only used during special @@ -365,9 +401,9 @@ BOOL LLVOAvatarSelf::buildMenus() item_params.label = sub_piemenu_name; } item_params.name =(item_params.label ); - item_params.on_click.function_name = "Attachment.Detach"; + item_params.on_click.function_name = "Attachment.DetachFromPoint"; item_params.on_click.parameter = iter->first; - item_params.on_enable.function_name = "Attachment.EnableDetach"; + item_params.on_enable.function_name = "Attachment.PointFilled"; item_params.on_enable.parameter = iter->first; LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params); @@ -614,8 +650,6 @@ BOOL LLVOAvatarSelf::loadLayersets() // virtual BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent) { - LLMemType mt(LLMemType::MTYPE_AVATAR); - // update screen joint size if (mScreenp) { @@ -630,15 +664,13 @@ BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent) } // virtual -BOOL LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - if (!isAgentAvatarValid()) + if (isAgentAvatarValid()) { - return TRUE; + LLVOAvatar::idleUpdate(agent, world, time); + idleUpdateTractorBeam(); } - LLVOAvatar::idleUpdate(agent, world, time); - idleUpdateTractorBeam(); - return TRUE; } // virtual @@ -757,10 +789,45 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id) LLViewerObject* object = gObjectList.findObject(source_id); if (object) { - object->mFlags &= ~FLAGS_ANIM_SOURCE; + object->setFlagsWithoutUpdate(FLAGS_ANIM_SOURCE, FALSE); } } +//virtual +U32 LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys, + void **user_data, + U32 block_num, + const EObjectUpdateType update_type, + LLDataPacker *dp) +{ + U32 retval = LLVOAvatar::processUpdateMessage(mesgsys,user_data,block_num,update_type,dp); + + if (mInitialBakesLoaded == false && retval == 0x0) + { + // call update textures to force the images to be created + updateMeshTextures(); + + // unpack the texture UUIDs to the texture slots + retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); + + // need to trigger a few operations to get the avatar to use the new bakes + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + const LLVOAvatarDefines::ETextureIndex te = mBakedTextureDatas[i].mTextureIndex; + LLUUID texture_id = getTEImage(te)->getID(); + setNewBakedTexture(te, texture_id); + mInitialBakeIDs[i] = texture_id; + } + + onFirstTEMessageReceived(); + + mInitialBakesLoaded = true; + } + + return retval; +} + + void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index) { if (te >= TEX_NUM_INDICES) @@ -937,8 +1004,6 @@ void LLVOAvatarSelf::idleUpdateTractorBeam() // virtual void LLVOAvatarSelf::restoreMeshData() { - LLMemType mt(LLMemType::MTYPE_AVATAR); - //llinfos << "Restoring" << llendl; mMeshValid = TRUE; updateJointLODs(); @@ -1574,7 +1639,7 @@ void LLVOAvatarSelf::invalidateAll() { invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, TRUE); } - mDebugSelfLoadTimer.reset(); + //mDebugSelfLoadTimer.reset(); } //----------------------------------------------------------------------------- @@ -1888,7 +1953,7 @@ void LLVOAvatarSelf::dumpTotalLocalTextureByteCount() llinfos << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << llendl; } -BOOL LLVOAvatarSelf::getIsCloud() +BOOL LLVOAvatarSelf::getIsCloud() const { // do we have our body parts? if (gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE) == 0 || @@ -1896,11 +1961,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 +1976,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 +2000,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; } @@ -2048,6 +2119,114 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const return text; } +// Dump avatar metrics data. +LLSD LLVOAvatarSelf::metricsData() +{ + // runway - add region info + LLSD result; + result["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus()); + std::vector<S32> rez_counts; + LLVOAvatar::getNearbyRezzedStats(rez_counts); + result["nearby"] = LLSD::emptyMap(); + for (S32 i=0; i<rez_counts.size(); ++i) + { + std::string rez_status_name = LLVOAvatar::rezStatusToString(i); + result["nearby"][rez_status_name] = rez_counts[i]; + } + result["timers"]["debug_existence"] = mDebugExistenceTimer.getElapsedTimeF32(); + result["timers"]["ruth_debug"] = mRuthDebugTimer.getElapsedTimeF32(); + result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32(); + result["timers"]["invisible"] = mInvisibleTimer.getElapsedTimeF32(); + result["timers"]["fully_loaded"] = mFullyLoadedTimer.getElapsedTimeF32(); + result["startup"] = LLStartUp::getPhases().dumpPhases(); + + return result; +} + +class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder +{ +public: + ViewerAppearanceChangeMetricsResponder( S32 expected_sequence, + volatile const S32 & live_sequence, + volatile bool & reporting_started): + mExpectedSequence(expected_sequence), + mLiveSequence(live_sequence), + mReportingStarted(reporting_started) + { + } + + virtual void completed(U32 status, + const std::string& reason, + const LLSD& content) + { + if (isGoodStatus(status)) + { + LL_DEBUGS("Avatar") << "OK" << LL_ENDL; + result(content); + } + else + { + LL_WARNS("Avatar") << "Failed " << status << " reason " << reason << LL_ENDL; + error(status,reason); + } + } + + // virtual + void error(U32 status_num, const std::string & reason) + { + } + + // virtual + void result(const LLSD & content) + { + if (mLiveSequence == mExpectedSequence) + { + mReportingStarted = true; + } + } + +private: + S32 mExpectedSequence; + volatile const S32 & mLiveSequence; + volatile bool & mReportingStarted; +}; + +void LLVOAvatarSelf::sendAppearanceChangeMetrics() +{ + // gAgentAvatarp->stopAllPhases(); + static volatile bool reporting_started(false); + static volatile S32 report_sequence(0); + + LLSD msg = metricsData(); + msg["message"] = "ViewerAppearanceChangeMetrics"; + msg["session_id"] = gAgentSessionID; + msg["agent_id"] = gAgentID; + msg["sequence"] = report_sequence; + msg["initial"] = !reporting_started; + msg["break"] = false; + + // Update sequence number + if (S32_MAX == ++report_sequence) + report_sequence = 0; + + LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL; + std::string caps_url; + if (getRegion()) + { + // runway - change here to activate. + caps_url = getRegion()->getCapability("ViewerMetrics"); + } + if (!caps_url.empty()) + { + LLCurlRequest::headers_t headers; + LLHTTPClient::post(caps_url, + msg, + new ViewerAppearanceChangeMetricsResponder(report_sequence, + report_sequence, + reporting_started)); + } +} + const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const { if (canGrabBakedTexture(baked_index)) @@ -2246,11 +2425,25 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) if (isAllLocalTextureDataFinal()) { LLNotificationsUtil::add("AvatarRezSelfBakedDoneNotification",args); + LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() + << "sec ]" + << avString() + << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() + << " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32() + << " Notification " << "AvatarRezSelfBakedDoneNotification" + << llendl; } else { args["STATUS"] = debugDumpAllLocalTextureDataInfo(); LLNotificationsUtil::add("AvatarRezSelfBakedUpdateNotification",args); + LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() + << "sec ]" + << avString() + << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() + << " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32() + << " Notification " << "AvatarRezSelfBakedUpdateNotification" + << llendl; } } @@ -2258,6 +2451,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) } } +// FIXME: This is not called consistently. Something may be broken. void LLVOAvatarSelf::outputRezDiagnostics() const { if(!gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime")) @@ -2266,11 +2460,11 @@ void LLVOAvatarSelf::outputRezDiagnostics() const } const F32 final_time = mDebugSelfLoadTimer.getElapsedTimeF32(); - llinfos << "REZTIME: Myself rez stats:" << llendl; - llinfos << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl; - llinfos << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl; - llinfos << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl; - llinfos << "\t Load time for each texture: " << llendl; + LL_DEBUGS("Avatar") << "REZTIME: Myself rez stats:" << llendl; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl; + LL_DEBUGS("Avatar") << "\t Load time for each texture: " << llendl; for (U32 i = 0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i) { std::stringstream out; @@ -2294,12 +2488,14 @@ void LLVOAvatarSelf::outputRezDiagnostics() const // Don't print out non-existent textures. if (j != 0) - llinfos << out.str() << llendl; + { + LL_DEBUGS("Avatar") << out.str() << LL_ENDL; + } } - llinfos << "\t Time points for each upload (start / finish)" << llendl; + LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << llendl; for (U32 i = 0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i) { - llinfos << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl; + LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl; } for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); @@ -2311,10 +2507,23 @@ void LLVOAvatarSelf::outputRezDiagnostics() const if (!layerset) continue; const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite(); if (!layerset_buffer) continue; - llinfos << layerset_buffer->dumpTextureInfo() << llendl; + LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << llendl; } } +void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const +{ + LL_INFOS("Avatar") + << avString() + << llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32()) + << LL_ENDL; +} + +void LLVOAvatarSelf::reportAvatarRezTime() const +{ + // TODO: report mDebugSelfLoadTimer.getElapsedTimeF32() somehow. +} + //----------------------------------------------------------------------------- // setCachedBakedTexture() // A baked texture id was received from a cache query, make it active @@ -2331,6 +2540,18 @@ void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid { if ( mBakedTextureDatas[i].mTextureIndex == te && mBakedTextureDatas[i].mTexLayerSet) { + if (mInitialBakeIDs[i] != LLUUID::null) + { + if (mInitialBakeIDs[i] == uuid) + { + llinfos << "baked texture correctly loaded at login! " << i << llendl; + } + else + { + llwarns << "baked texture does not match id loaded at login!" << i << llendl; + } + mInitialBakeIDs[i] = LLUUID::null; + } mBakedTextureDatas[i].mTexLayerSet->cancelUpload(); } } @@ -2458,6 +2679,20 @@ LLTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const return NULL; } +LLTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const +{ + /* switch(index) + case TEX_HEAD_BAKED: + case TEX_HEAD_BODYPAINT: + return mHeadLayerSet; */ + if (baked_index >= 0 && baked_index < BAKED_NUM_INDICES) + { + return mBakedTextureDatas[baked_index].mTexLayerSet; + } + return NULL; +} + + // static void LLVOAvatarSelf::onCustomizeStart() { @@ -2538,54 +2773,11 @@ BOOL LLVOAvatarSelf::needsRenderBeam() // static void LLVOAvatarSelf::deleteScratchTextures() { - if(gAuditTexture) - { - S32 total_tex_size = sScratchTexBytes ; - S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ; - - if( sScratchTexNames.checkData( GL_LUMINANCE ) ) - { - LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= tex_size ; - } - if( sScratchTexNames.checkData( GL_ALPHA ) ) - { - LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= tex_size ; - } - if( sScratchTexNames.checkData( GL_COLOR_INDEX ) ) - { - LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= tex_size ; - } - if( sScratchTexNames.checkData( LLRender::sGLCoreProfile ? GL_RG : GL_LUMINANCE_ALPHA ) ) - { - LLImageGL::decTextureCounter(tex_size, 2, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= 2 * tex_size ; - } - if( sScratchTexNames.checkData( GL_RGB ) ) - { - LLImageGL::decTextureCounter(tex_size, 3, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= 3 * tex_size ; - } - if( sScratchTexNames.checkData( GL_RGBA ) ) - { - LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= 4 * tex_size ; - } - //others - while(total_tex_size > 0) - { - LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= 4 * tex_size ; - } - } - for( LLGLuint* namep = sScratchTexNames.getFirstData(); namep; namep = sScratchTexNames.getNextData() ) { - LLImageGL::deleteTextures(1, (U32 *)namep ); + LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (U32 *)namep ); stop_glerror(); } diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 74ff47a3e4..7bd0c0bf93 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -41,6 +41,7 @@ struct LocalTextureData; class LLVOAvatarSelf : public LLVOAvatar { + LOG_CLASS(LLVOAvatarSelf); /******************************************************************************** ** ** @@ -48,6 +49,16 @@ class LLVOAvatarSelf : **/ public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVOAvatarSelf(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); virtual ~LLVOAvatarSelf(); virtual void markDead(); @@ -74,7 +85,7 @@ protected: //-------------------------------------------------------------------- public: /*virtual*/ void updateRegion(LLViewerRegion *regionp); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); //-------------------------------------------------------------------- // LLCharacter interface and related @@ -92,15 +103,27 @@ public: /*virtual*/ void updateVisualParams(); /*virtual*/ void idleUpdateAppearanceAnimation(); + /*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys, + void **user_data, + U32 block_num, + const EObjectUpdateType update_type, + LLDataPacker *dp); + private: // helper function. Passed in param is assumed to be in avatar's parameter list. BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE ); + /** Initialization ** ** *******************************************************************************/ +private: + LLUUID mInitialBakeIDs[6]; + bool mInitialBakesLoaded; + + /******************************************************************************** ** ** ** STATE @@ -120,7 +143,7 @@ public: // Loading state //-------------------------------------------------------------------- public: - /*virtual*/ BOOL getIsCloud(); + /*virtual*/ BOOL getIsCloud() const; //-------------------------------------------------------------------- // Region state @@ -228,6 +251,7 @@ public: void requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i); void requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i); LLTexLayerSet* getLayerSet(LLVOAvatarDefines::ETextureIndex index) const; + LLTexLayerSet* getLayerSet(LLVOAvatarDefines::EBakedTextureIndex baked_index) const; //-------------------------------------------------------------------- // Composites @@ -358,6 +382,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); @@ -366,6 +392,8 @@ public: const LLTexLayerSet* debugGetLayerSet(LLVOAvatarDefines::EBakedTextureIndex index) const { return mBakedTextureDatas[index].mTexLayerSet; } const std::string debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer const std::string debugDumpAllLocalTextureDataInfo() const; // Lists out which baked textures are at highest LOD + LLSD metricsData(); + void sendAppearanceChangeMetrics(); // send data associated with completing a change. private: LLFrameTimer mDebugSelfLoadTimer; F32 mDebugTimeWearablesLoaded; @@ -380,8 +408,13 @@ private: }; -extern LLVOAvatarSelf *gAgentAvatarp; +extern LLPointer<LLVOAvatarSelf> gAgentAvatarp; BOOL isAgentAvatarValid(); +void selfStartPhase(const std::string& phase_name); +void selfStopPhase(const std::string& phase_name); +void selfStopAllPhases(); +void selfClearPhases(); + #endif // LL_VO_AVATARSELF_H diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 8a79d564d3..4dca87652d 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -34,6 +34,7 @@ #include "llagentcamera.h" #include "llnotificationsutil.h" #include "lldrawable.h" +#include "lldrawpoolalpha.h" #include "llface.h" #include "llsky.h" #include "llsurface.h" @@ -276,17 +277,17 @@ BOOL LLVOGrass::isActive() const return TRUE; } -BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GRASS))) { - return TRUE; + return; } if (!mDrawable) { // So drones work. - return TRUE; + return; } if(LLVOTree::isTreeRenderingStopped()) //stop rendering grass @@ -296,14 +297,14 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) mNumBlades = 0 ; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); } - return TRUE ; + return; } else if(!mNumBlades)//restart grass rendering { mNumBlades = GRASS_MAX_BLADES ; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); - return TRUE ; + return; } if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime())) @@ -311,7 +312,7 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); } - return TRUE; + return; } @@ -380,8 +381,10 @@ BOOL LLVOGrass::updateLOD() { mNumBlades <<= 1; } - - face->setSize(mNumBlades*8, mNumBlades*12); + if (face) + { + face->setSize(mNumBlades*8, mNumBlades*12); + } gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); } else if (num_blades <= (mNumBlades >> 1)) @@ -391,7 +394,10 @@ BOOL LLVOGrass::updateLOD() mNumBlades >>=1; } - face->setSize(mNumBlades*8, mNumBlades*12); + if (face) + { + face->setSize(mNumBlades*8, mNumBlades*12); + } gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); return TRUE; } @@ -449,14 +455,16 @@ void LLVOGrass::plantBlades() } LLFace *face = mDrawable->getFace(0); + if (face) + { + face->setTexture(getTEImage(0)); + face->setState(LLFace::GLOBAL); + face->setSize(mNumBlades * 8, mNumBlades * 12); + face->setVertexBuffer(NULL); + face->setTEOffset(0); + face->mCenterLocal = mPosition + mRegionp->getOriginAgent(); + } - face->setTexture(getTEImage(0)); - face->setState(LLFace::GLOBAL); - face->setSize(mNumBlades * 8, mNumBlades * 12); - face->setVertexBuffer(NULL); - face->setTEOffset(0); - face->mCenterLocal = mPosition + mRegionp->getOriginAgent(); - mDepth = (face->mCenterLocal - LLViewerCamera::getInstance()->getOrigin())*LLViewerCamera::getInstance()->getAtAxis(); mDrawable->setPosition(face->mCenterLocal); mDrawable->movePartition(); @@ -486,6 +494,8 @@ void LLVOGrass::getGeometry(S32 idx, LLColor4U color(255,255,255,255); LLFace *face = mDrawable->getFace(idx); + if (!face) + return; F32 width = sSpeciesTable[mSpecies]->mBladeSizeX; F32 height = sSpeciesTable[mSpecies]->mBladeSizeY; @@ -594,6 +604,7 @@ U32 LLVOGrass::getPartitionType() const } LLGrassPartition::LLGrassPartition() +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB) { mDrawableType = LLPipeline::RENDER_TYPE_GRASS; mPartitionType = LLViewerRegion::PARTITION_GRASS; @@ -604,6 +615,142 @@ LLGrassPartition::LLGrassPartition() mBufferUsage = GL_DYNAMIC_DRAW_ARB; } +void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count) +{ + group->mBufferUsage = mBufferUsage; + + mFaceList.clear(); + + LLViewerCamera* camera = LLViewerCamera::getInstance(); + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + LLDrawable* drawablep = *i; + + if (drawablep->isDead()) + { + continue; + } + + LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get(); + obj->mDepth = 0.f; + + if (drawablep->isAnimating()) + { + group->mBufferUsage = GL_STREAM_DRAW_ARB; + } + + U32 count = 0; + for (S32 j = 0; j < drawablep->getNumFaces(); ++j) + { + drawablep->updateFaceSize(j); + + LLFace* facep = drawablep->getFace(j); + if ( !facep || !facep->hasGeometry()) + { + continue; + } + + if ((facep->getGeomCount() + vertex_count) <= 65536) + { + count++; + facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis(); + obj->mDepth += facep->mDistance; + + mFaceList.push_back(facep); + vertex_count += facep->getGeomCount(); + index_count += facep->getIndicesCount(); + llassert(facep->getIndicesCount() < 65536); + } + else + { + facep->clearVertexBuffer(); + } + } + + obj->mDepth /= count; + } +} + +static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB"); + +void LLGrassPartition::getGeometry(LLSpatialGroup* group) +{ + LLFastTimer ftm(FTM_REBUILD_GRASS_VB); + + std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater()); + + U32 index_count = 0; + U32 vertex_count = 0; + + group->clearDrawMap(); + + LLVertexBuffer* buffer = group->mVertexBuffer; + + LLStrider<U16> indicesp; + LLStrider<LLVector4a> verticesp; + LLStrider<LLVector3> normalsp; + LLStrider<LLVector2> texcoordsp; + LLStrider<LLColor4U> colorsp; + + buffer->getVertexStrider(verticesp); + buffer->getNormalStrider(normalsp); + buffer->getColorStrider(colorsp); + buffer->getTexCoord0Strider(texcoordsp); + buffer->getIndexStrider(indicesp); + + LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass]; + + for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i) + { + LLFace* facep = *i; + LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); + facep->setGeomIndex(vertex_count); + facep->setIndicesIndex(index_count); + facep->setVertexBuffer(buffer); + facep->setPoolType(LLDrawPool::POOL_ALPHA); + object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp); + + vertex_count += facep->getGeomCount(); + index_count += facep->getIndicesCount(); + + S32 idx = draw_vec.size()-1; + + BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); + F32 vsize = facep->getVirtualSize(); + + if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && + draw_vec[idx]->mTexture == facep->getTexture() && + (U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange && + //draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && + draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 && + draw_vec[idx]->mFullbright == fullbright) + { + draw_vec[idx]->mCount += facep->getIndicesCount(); + draw_vec[idx]->mEnd += facep->getGeomCount(); + draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); + } + else + { + U32 start = facep->getGeomIndex(); + U32 end = start + facep->getGeomCount()-1; + U32 offset = facep->getIndicesStart(); + U32 count = facep->getIndicesCount(); + LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), + //facep->getTexture(), + buffer, fullbright); + info->mExtents[0] = group->mObjectExtents[0]; + info->mExtents[1] = group->mObjectExtents[1]; + info->mVSize = vsize; + draw_vec.push_back(info); + //for alpha sorting + facep->setDrawInfo(info); + } + } + + buffer->flush(); + mFaceList.clear(); +} + // virtual void LLVOGrass::updateDrawable(BOOL force_damped) { diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h index 00a59facf7..b9835b8802 100644 --- a/indra/newview/llvograss.h +++ b/indra/newview/llvograss.h @@ -73,7 +73,7 @@ public: void plantBlades(); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. - BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face = -1, // which face to check, -1 = ALL_SIDES diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp index 0060f81ab5..97b7418b40 100644 --- a/indra/newview/llvoground.cpp +++ b/indra/newview/llvoground.cpp @@ -49,18 +49,8 @@ LLVOGround::~LLVOGround() { } -BOOL LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GROUND))) - { - return TRUE; - } - - /*if (mDrawable) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); - }*/ - return TRUE; } @@ -82,6 +72,7 @@ LLDrawable *LLVOGround::createDrawable(LLPipeline *pipeline) return mDrawable; } +// TO DO - this always returns TRUE, BOOL LLVOGround::updateGeometry(LLDrawable *drawable) { LLStrider<LLVector3> verticesp; @@ -96,6 +87,8 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable) if (drawable->getNumFaces() < 1) drawable->addFace(poolp, NULL); face = drawable->getFace(0); + if (!face) + return TRUE; if (!face->getVertexBuffer()) { diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h index 73b097327e..290579b4da 100644 --- a/indra/newview/llvoground.h +++ b/indra/newview/llvoground.h @@ -41,7 +41,7 @@ protected: public: LLVOGround(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); // Graphical stuff for objects - maybe broken out into render class // later? diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index bd12328a6b..ceff75a0cc 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -414,7 +414,7 @@ void LLVoiceChannel::doSetState(const EState& new_state) mState = new_state; if (!mStateChangedCallback.empty()) - mStateChangedCallback(old_state, mState, mCallDirection, mCallEndedByAgent); + mStateChangedCallback(old_state, mState, mCallDirection, mCallEndedByAgent, mSessionID); } //static diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h index b8597ee5cb..fed44974fd 100644 --- a/indra/newview/llvoicechannel.h +++ b/indra/newview/llvoicechannel.h @@ -52,7 +52,7 @@ public: OUTGOING_CALL } EDirection; - typedef boost::signals2::signal<void(const EState& old_state, const EState& new_state, const EDirection& direction, bool ended_by_agent)> state_changed_signal_t; + typedef boost::signals2::signal<void(const EState& old_state, const EState& new_state, const EDirection& direction, bool ended_by_agent, const LLUUID& session_id)> state_changed_signal_t; // on current channel changed signal typedef boost::function<void(const LLUUID& session_id)> channel_changed_callback_t; diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 730f022c50..b46c55321c 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -541,6 +541,7 @@ void LLVoiceClient::setMuteMic(bool muted) { mMuteMic = muted; updateMicMuteLogic(); + mMicroChangedSignal(); } @@ -551,6 +552,7 @@ void LLVoiceClient::setUserPTTState(bool ptt) { mUserPTTState = ptt; updateMicMuteLogic(); + mMicroChangedSignal(); } bool LLVoiceClient::getUserPTTState() diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index c9aeea35a9..714dd6a9f2 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -303,6 +303,9 @@ public: LLVoiceClient(); ~LLVoiceClient(); + typedef boost::signals2::signal<void(void)> micro_changed_signal_t; + micro_changed_signal_t mMicroChangedSignal; + void init(LLPumpIO *pump); // Call this once at application startup (creates connector) void terminate(); // Call this to clean up during shutdown @@ -401,6 +404,8 @@ public: void keyUp(KEY key, MASK mask); void middleMouseState(bool down); + boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); } + ///////////////////////////// // Accessors for data related to nearby speakers @@ -456,6 +461,7 @@ protected: LLVoiceModuleInterface* mVoiceModule; LLPumpIO *m_servicePump; + LLCachedControl<bool> mVoiceEffectEnabled; LLCachedControl<std::string> mVoiceEffectDefault; diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp index 47060720e7..b497f80560 100644 --- a/indra/newview/llvoicevisualizer.cpp +++ b/indra/newview/llvoicevisualizer.cpp @@ -73,17 +73,6 @@ const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE = 1.0f; const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code. const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL - -//------------------------------------------------------------------ -// handles parameter updates -//------------------------------------------------------------------ -static bool handleVoiceVisualizerPrefsChanged(const LLSD& newvalue) -{ - // Note: Ignore the specific event value, we look up the ones we want - LLVoiceVisualizer::setPreferences(); - return true; -} - //------------------------------------------------------------------ // Initialize the statics //------------------------------------------------------------------ @@ -106,7 +95,7 @@ F32 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f; // constructor //----------------------------------------------- LLVoiceVisualizer::LLVoiceVisualizer( const U8 type ) -:LLHUDEffect( type ) + : LLHUDEffect(type) { mCurrentTime = mTimer.getTotalSeconds(); mPreviousTime = mCurrentTime; @@ -150,12 +139,12 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type ) setPreferences(); // Set up our listener to get updates on all prefs values we care about. - gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); - gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); - gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); - gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); - gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); - gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2)); sPrefsInitialized = true; } @@ -217,6 +206,15 @@ void LLVoiceVisualizer::setSpeakingAmplitude( F32 a ) }//--------------------------------------------------- +//------------------------------------------------------------------ +// handles parameter updates +//------------------------------------------------------------------ +bool LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged(const LLSD& newvalue) +{ + // Note: Ignore the specific event value, we look up the ones we want + LLVoiceVisualizer::setPreferences(); + return true; +} //--------------------------------------------------- void LLVoiceVisualizer::setPreferences( ) @@ -526,10 +524,6 @@ void LLVoiceVisualizer::render() }//--------------------------------------------------- - - - - //--------------------------------------------------- void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p ) { @@ -615,11 +609,3 @@ void LLVoiceVisualizer::markDead() LLHUDEffect::markDead(); }//------------------------------------------------------------------ - - - - - - - - diff --git a/indra/newview/llvoicevisualizer.h b/indra/newview/llvoicevisualizer.h index e434c7f3f1..36c78252d1 100644 --- a/indra/newview/llvoicevisualizer.h +++ b/indra/newview/llvoicevisualizer.h @@ -71,10 +71,8 @@ class LLVoiceVisualizer : public LLHUDEffect // public methods //--------------------------------------------------- public: - LLVoiceVisualizer ( const U8 type ); //constructor + LLVoiceVisualizer( const U8 type ); //constructor ~LLVoiceVisualizer(); //destructor - - friend class LLHUDObject; void setVoiceSourceWorldPosition( const LLVector3 &p ); // this should be the position of the speaking avatar's head void setMinGesticulationAmplitude( F32 ); // the lower range of meaningful amplitude for setting gesticulation level @@ -85,8 +83,6 @@ class LLVoiceVisualizer : public LLHUDEffect void setStopSpeaking(); // tell me when the av stops speaking bool getCurrentlySpeaking(); // the get for the above set VoiceGesticulationLevel getCurrentGesticulationLevel(); // based on voice amplitude, I'll give you the current "energy level" of avatar speech - static void setPreferences( ); - static void lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats void lipSyncOohAah( F32& ooh, F32& aah ); void render(); // inherited from HUD Effect void packData(LLMessageSystem *mesgsys); // inherited from HUD Effect @@ -108,7 +104,10 @@ class LLVoiceVisualizer : public LLHUDEffect // private members //--------------------------------------------------- private: - + static bool handleVoiceVisualizerPrefsChanged(const LLSD& newvalue); + static void setPreferences( ); + static void lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats + struct SoundSymbol { F32 mWaveExpansion [ NUM_VOICE_SYMBOL_WAVES ]; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 8ecf4a80b7..f3342b7ff1 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 @@ -36,6 +34,7 @@ #include "llvoavatarself.h" #include "llbufferstream.h" #include "llfile.h" +#include "llmenugl.h" #ifdef LL_STANDALONE # include "expat.h" #else @@ -47,6 +46,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 @@ -61,7 +61,6 @@ #include "llviewerwindow.h" #include "llviewercamera.h" -#include "llfloaterfriends.h" //VIVOX, inorder to refresh communicate panel #include "llviewernetwork.h" #include "llnotificationsutil.h" @@ -72,6 +71,9 @@ #define USE_SESSION_GROUPS 0 +extern LLMenuBarGL* gMenuBarView; +extern void handle_voice_morphing_subscribe(); + const F32 VOLUME_SCALE_VIVOX = 0.01f; const F32 SPEAKING_TIMEOUT = 1.f; @@ -243,59 +245,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() : @@ -331,6 +295,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mCaptureDeviceDirty(false), mRenderDeviceDirty(false), mSpatialCoordsDirty(false), + mIsInitialized(false), mMuteMic(false), mMuteMicDirty(false), @@ -355,7 +320,9 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mCaptureBufferRecording(false), mCaptureBufferRecorded(false), mCaptureBufferPlaying(false), - mPlayRequestCount(0) + mPlayRequestCount(0), + + mAvatarNameCacheConnection() { mSpeakerVolume = scale_speaker_volume(0); @@ -388,6 +355,10 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : LLVivoxVoiceClient::~LLVivoxVoiceClient() { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } } //--------------------------------------------------- @@ -560,7 +531,7 @@ void LLVivoxVoiceClient::requestVoiceAccountProvision(S32 retries) { LLViewerRegion *region = gAgent.getRegion(); - if ( region && mVoiceEnabled ) + if ( region && (mVoiceEnabled || !mIsInitialized)) { std::string url = region->getCapability("ProvisionVoiceAccountRequest"); @@ -731,7 +702,7 @@ void LLVivoxVoiceClient::stateMachine() setVoiceEnabled(false); } - if(mVoiceEnabled) + if(mVoiceEnabled || !mIsInitialized) { updatePosition(); } @@ -776,7 +747,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateDisabled case stateDisabled: - if(mTuningMode || (mVoiceEnabled && !mAccountName.empty())) + if(mTuningMode || ((mVoiceEnabled || !mIsInitialized) && !mAccountName.empty())) { setState(stateStart); } @@ -791,7 +762,7 @@ void LLVivoxVoiceClient::stateMachine() } else if(!isGatewayRunning()) { - if(true) + if (true) // production build, not test { // Launch the voice daemon @@ -810,102 +781,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()); - - 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); - } + params.args.add("-ll"); + params.args.add(loglevel); + params.cwd = gDirUtilp->getAppRODataDir(); + sGatewayPtr = LLProcess::create(params); - // 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: @@ -1000,7 +902,7 @@ void LLVivoxVoiceClient::stateMachine() mTuningExitState = stateIdle; setState(stateMicTuningStart); } - else if(!mVoiceEnabled) + else if(!mVoiceEnabled && mIsInitialized) { // We never started up the connector. This will shut down the daemon. setState(stateConnectorStopped); @@ -1194,7 +1096,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateConnectorStart case stateConnectorStart: - if(!mVoiceEnabled) + if(!mVoiceEnabled && mIsInitialized) { // We were never logged in. This will shut down the connector. setState(stateLoggedOut); @@ -1212,7 +1114,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateConnectorStarted case stateConnectorStarted: // connector handle received - if(!mVoiceEnabled) + if(!mVoiceEnabled && mIsInitialized) { // We were never logged in. This will shut down the connector. setState(stateLoggedOut); @@ -1356,7 +1258,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateCreatingSessionGroup case stateCreatingSessionGroup: - if(mSessionTerminateRequested || !mVoiceEnabled) + if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized) { // *TODO: Question: is this the right way out of this state setState(stateSessionTerminated); @@ -1372,7 +1274,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateRetrievingParcelVoiceInfo case stateRetrievingParcelVoiceInfo: // wait until parcel voice info is received. - if(mSessionTerminateRequested || !mVoiceEnabled) + if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized) { // if a terminate request has been received, // bail and go to the stateSessionTerminated @@ -1392,7 +1294,7 @@ void LLVivoxVoiceClient::stateMachine() // Otherwise, if you log in but don't join a proximal channel (such as when your login location has voice disabled), your friends list won't sync. sendFriendsListUpdates(); - if(mSessionTerminateRequested || !mVoiceEnabled) + if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized) { // TODO: Question: Is this the right way out of this state? setState(stateSessionTerminated); @@ -1473,7 +1375,7 @@ void LLVivoxVoiceClient::stateMachine() } // joinedAudioSession() will transition from here to stateSessionJoined. - if(!mVoiceEnabled) + if(!mVoiceEnabled && mIsInitialized) { // User bailed out during connect -- jump straight to teardown. setState(stateSessionTerminated); @@ -1520,7 +1422,7 @@ void LLVivoxVoiceClient::stateMachine() notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINED); } - else if(!mVoiceEnabled) + else if(!mVoiceEnabled && mIsInitialized) { // User bailed out during connect -- jump straight to teardown. setState(stateSessionTerminated); @@ -1540,7 +1442,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateRunning case stateRunning: // steady state // Disabling voice or disconnect requested. - if(!mVoiceEnabled || mSessionTerminateRequested) + if(!mVoiceEnabled && mIsInitialized || mSessionTerminateRequested) { leaveAudioSession(); } @@ -1587,6 +1489,8 @@ void LLVivoxVoiceClient::stateMachine() mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS); sendPositionalUpdate(); } + + mIsInitialized = true; } break; @@ -1620,7 +1524,7 @@ void LLVivoxVoiceClient::stateMachine() // Always reset the terminate request flag when we get here. mSessionTerminateRequested = false; - if(mVoiceEnabled && !mRelogRequested) + if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested) { // Just leaving a channel, go back to stateNoChannel (the "logged in but have no channel" state). setState(stateNoChannel); @@ -1648,7 +1552,7 @@ void LLVivoxVoiceClient::stateMachine() mAccountHandle.clear(); cleanUp(); - if(mVoiceEnabled && !mRelogRequested) + if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested) { // User was logged out, but wants to be logged in. Send a new login request. setState(stateNeedsLogin); @@ -2774,7 +2678,7 @@ void LLVivoxVoiceClient::checkFriend(const LLUUID& id) // *NOTE: For now, we feed legacy names to Vivox because I don't know // if their service can support a mix of new and old clients with // different sorts of names. - std::string name = av_name.getLegacyName(); + std::string name = av_name.getAccountName(); const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id); bool canSeeMeOnline = false; @@ -3821,8 +3725,7 @@ void LLVivoxVoiceClient::participantUpdatedEvent( voice participant mIsModeratorMuted is changed after speakers are updated in Speaker Manager and event is not fired. - So, we have to call LLSpeakerMgr::update() here. In any case it is better than call it - in LLCallFloater::draw() + So, we have to call LLSpeakerMgr::update() here. */ LLVoiceChannel* voice_cnl = LLVoiceChannel::getCurrentVoiceChannel(); @@ -4048,7 +3951,7 @@ void LLVivoxVoiceClient::messageEvent( sessionState *session = findSession(sessionHandle); if(session) { - bool is_busy = gAgent.getBusy(); + bool is_do_not_disturb = gAgent.isDoNotDisturb(); bool is_muted = LLMuteList::getInstance()->isMuted(session->mCallerID, session->mName, LLMute::flagTextChat); bool is_linden = LLMuteList::getInstance()->isLinden(session->mName); bool quiet_chat = false; @@ -4062,10 +3965,10 @@ void LLVivoxVoiceClient::messageEvent( chat.mFromName = session->mName; chat.mSourceType = CHAT_SOURCE_AGENT; - if(is_busy && !is_linden) + if(is_do_not_disturb && !is_linden) { quiet_chat = true; - // TODO: Question: Return busy mode response here? Or maybe when session is started instead? + // TODO: Question: Return do not disturb mode response here? Or maybe when session is started instead? } LL_DEBUGS("Voice") << "adding message, name " << session->mName << " session " << session->mIMSessionID << ", target " << session->mCallerID << LL_ENDL; @@ -4073,6 +3976,7 @@ void LLVivoxVoiceClient::messageEvent( session->mCallerID, session->mName.c_str(), message.c_str(), + false, LLStringUtil::null, // default arg IM_NOTHING_SPECIAL, // default arg 0, // default arg @@ -6298,18 +6202,19 @@ void LLVivoxVoiceClient::notifyFriendObservers() void LLVivoxVoiceClient::lookupName(const LLUUID &id) { - LLAvatarNameCache::get(id, - boost::bind(&LLVivoxVoiceClient::onAvatarNameCache, - this, _1, _2)); + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(id, boost::bind(&LLVivoxVoiceClient::onAvatarNameCache, this, _1, _2)); } void LLVivoxVoiceClient::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) { - // For Vivox, we use the legacy name because I'm uncertain whether or - // not their service can tolerate switching to Username or Display Name - std::string legacy_name = av_name.getLegacyName(); - avatarNameResolved(agent_id, legacy_name); + mAvatarNameCacheConnection.disconnect(); + std::string display_name = av_name.getDisplayName(); + avatarNameResolved(agent_id, display_name); } void LLVivoxVoiceClient::avatarNameResolved(const LLUUID &id, const std::string &name) @@ -6838,10 +6743,106 @@ void LLVivoxVoiceClient::removeObserver(LLVoiceEffectObserver* observer) mVoiceFontObservers.erase(observer); } +// method checks the item in VoiceMorphing menu for appropriate current voice font +bool LLVivoxVoiceClient::onCheckVoiceEffect(const std::string& voice_effect_name) +{ + LLVoiceEffectInterface * effect_interfacep = LLVoiceClient::instance().getVoiceEffectInterface(); + if (NULL != effect_interfacep) + { + const LLUUID& currect_voice_effect_id = effect_interfacep->getVoiceEffect(); + + if (currect_voice_effect_id.isNull()) + { + if (voice_effect_name == "NoVoiceMorphing") + { + return true; + } + } + else + { + const LLSD& voice_effect_props = effect_interfacep->getVoiceEffectProperties(currect_voice_effect_id); + if (voice_effect_props["name"].asString() == voice_effect_name) + { + return true; + } + } + } + + return false; +} + +// method changes voice font for selected VoiceMorphing menu item +void LLVivoxVoiceClient::onClickVoiceEffect(const std::string& voice_effect_name) +{ + LLVoiceEffectInterface * effect_interfacep = LLVoiceClient::instance().getVoiceEffectInterface(); + if (NULL != effect_interfacep) + { + if (voice_effect_name == "NoVoiceMorphing") + { + effect_interfacep->setVoiceEffect(LLUUID()); + return; + } + const voice_effect_list_t& effect_list = effect_interfacep->getVoiceEffectList(); + if (!effect_list.empty()) + { + for (voice_effect_list_t::const_iterator it = effect_list.begin(); it != effect_list.end(); ++it) + { + if (voice_effect_name == it->first) + { + effect_interfacep->setVoiceEffect(it->second); + return; + } + } + } + } +} + +// it updates VoiceMorphing menu items in accordance with purchased properties +void LLVivoxVoiceClient::updateVoiceMorphingMenu() +{ + if (mVoiceFontListDirty) + { + LLVoiceEffectInterface * effect_interfacep = LLVoiceClient::instance().getVoiceEffectInterface(); + if (effect_interfacep) + { + const voice_effect_list_t& effect_list = effect_interfacep->getVoiceEffectList(); + if (!effect_list.empty()) + { + LLMenuGL * voice_morphing_menup = gMenuBarView->findChildMenuByName("VoiceMorphing", TRUE); + + if (NULL != voice_morphing_menup) + { + S32 items = voice_morphing_menup->getItemCount(); + if (items > 0) + { + voice_morphing_menup->erase(1, items - 3, false); + + S32 pos = 1; + for (voice_effect_list_t::const_iterator it = effect_list.begin(); it != effect_list.end(); ++it) + { + LLMenuItemCheckGL::Params p; + p.name = it->first; + p.label = it->first; + p.on_check.function(boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, this, it->first)); + p.on_click.function(boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, this, it->first)); + LLMenuItemCheckGL * voice_effect_itemp = LLUICtrlFactory::create<LLMenuItemCheckGL>(p); + voice_morphing_menup->insert(pos++, voice_effect_itemp, false); + } + + voice_morphing_menup->needsArrange(); + } + } + } + } + } +} + void LLVivoxVoiceClient::notifyVoiceFontObservers() { LL_DEBUGS("Voice") << "Notifying voice effect observers. Lists changed: " << mVoiceFontListDirty << LL_ENDL; + updateVoiceMorphingMenu(); + for (voice_font_observer_set_t::iterator it = mVoiceFontObservers.begin(); it != mVoiceFontObservers.end(); ) @@ -7020,7 +7021,6 @@ void LLVivoxVoiceClient::captureBufferPlayStopSendMessage() LLVivoxProtocolParser::LLVivoxProtocolParser() { - parser = NULL; parser = XML_ParserCreate(NULL); reset(); diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 1142a1a49c..574027de42 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -246,6 +246,8 @@ public: //@} + bool onCheckVoiceEffect(const std::string& voice_effect_name); + void onClickVoiceEffect(const std::string& voice_effect_name); protected: ////////////////////// @@ -641,6 +643,7 @@ protected: void lookupName(const LLUUID &id); void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); void avatarNameResolved(const LLUUID &id, const std::string &name); + boost::signals2::connection mAvatarNameCacheConnection; ///////////////////////////// // Voice fonts @@ -741,6 +744,8 @@ private: std::string mRenderDevice; bool mCaptureDeviceDirty; bool mRenderDeviceDirty; + + bool mIsInitialized; bool checkParcelChanged(bool update = false); @@ -851,6 +856,7 @@ private: void accountGetTemplateFontsSendMessage(); void sessionSetVoiceFontSendMessage(sessionState *session); + void updateVoiceMorphingMenu(); void notifyVoiceFontObservers(); typedef enum e_voice_font_type diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 5c10a80b07..0b34bbb90f 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -48,6 +48,120 @@ const F32 MAX_PART_LIFETIME = 120.f; extern U64 gFrameTime; +LLPointer<LLVertexBuffer> LLVOPartGroup::sVB = NULL; +S32 LLVOPartGroup::sVBSlotFree[]; +S32* LLVOPartGroup::sVBSlotCursor = NULL; + +void LLVOPartGroup::initClass() +{ + for (S32 i = 0; i < LL_MAX_PARTICLE_COUNT; ++i) + { + sVBSlotFree[i] = i; + } + + sVBSlotCursor = sVBSlotFree; +} + +//static +void LLVOPartGroup::restoreGL() +{ + sVB = new LLVertexBuffer(VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + U32 count = LL_MAX_PARTICLE_COUNT; + sVB->allocateBuffer(count*4, count*6, true); + + //indices and texcoords are always the same, set once + LLStrider<U16> indicesp; + + LLStrider<LLVector4a> verticesp; + + sVB->getIndexStrider(indicesp); + sVB->getVertexStrider(verticesp); + + LLVector4a v; + v.set(0,0,0,0); + + + U16 vert_offset = 0; + + for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++) + { + *indicesp++ = vert_offset + 0; + *indicesp++ = vert_offset + 1; + *indicesp++ = vert_offset + 2; + + *indicesp++ = vert_offset + 1; + *indicesp++ = vert_offset + 3; + *indicesp++ = vert_offset + 2; + + *verticesp++ = v; + + vert_offset += 4; + } + + LLStrider<LLVector2> texcoordsp; + sVB->getTexCoord0Strider(texcoordsp); + + for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++) + { + *texcoordsp++ = LLVector2(0.f, 1.f); + *texcoordsp++ = LLVector2(0.f, 0.f); + *texcoordsp++ = LLVector2(1.f, 1.f); + *texcoordsp++ = LLVector2(1.f, 0.f); + } + + sVB->flush(); + +} + +//static +void LLVOPartGroup::destroyGL() +{ + sVB = NULL; +} + +//static +S32 LLVOPartGroup::findAvailableVBSlot() +{ + if (sVBSlotCursor >= sVBSlotFree+LL_MAX_PARTICLE_COUNT) + { //no more available slots + return -1; + } + + S32 ret = *sVBSlotCursor; + sVBSlotCursor++; + + return ret; +} + +bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end) +{ + while (start < end) + { + if (*start == idx) + { //not allocated (in free list) + return false; + } + ++start; + } + + //allocated (not in free list) + return true; +} + +//static +void LLVOPartGroup::freeVBSlot(S32 idx) +{ + llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0); + //llassert(sVBSlotCursor > sVBSlotFree); + //llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT)); + + if (sVBSlotCursor > sVBSlotFree) + { + sVBSlotCursor--; + *sVBSlotCursor = idx; + } +} + LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) : LLAlphaObject(id, pcode, regionp), mViewerPartGroupp(NULL) @@ -62,7 +176,6 @@ LLVOPartGroup::~LLVOPartGroup() { } - BOOL LLVOPartGroup::isActive() const { return FALSE; @@ -83,9 +196,8 @@ void LLVOPartGroup::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) mDrawable->setPositionGroup(pos); } -BOOL LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - return TRUE; } void LLVOPartGroup::setPixelAreaAndAngle(LLAgent &agent) @@ -287,9 +399,6 @@ void LLVOPartGroup::getGeometry(S32 idx, const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx])); - U32 vert_offset = mDrawable->getFace(idx)->getGeomIndex(); - - LLVector4a part_pos_agent; part_pos_agent.load3(part.mPosAgent.mV); LLVector4a camera_agent; @@ -361,33 +470,18 @@ void LLVOPartGroup::getGeometry(S32 idx, verticesp->setAdd(ppamu, right); (*verticesp++).getF32ptr()[3] = 0.f; - //*verticesp++ = part_pos_agent + up - right; - //*verticesp++ = part_pos_agent - up - right; - //*verticesp++ = part_pos_agent + up + right; - //*verticesp++ = part_pos_agent - up + right; - *colorsp++ = part.mColor; *colorsp++ = part.mColor; *colorsp++ = part.mColor; *colorsp++ = part.mColor; - *texcoordsp++ = LLVector2(0.f, 1.f); - *texcoordsp++ = LLVector2(0.f, 0.f); - *texcoordsp++ = LLVector2(1.f, 1.f); - *texcoordsp++ = LLVector2(1.f, 0.f); - - *normalsp++ = normal; - *normalsp++ = normal; - *normalsp++ = normal; - *normalsp++ = normal; - - *indicesp++ = vert_offset + 0; - *indicesp++ = vert_offset + 1; - *indicesp++ = vert_offset + 2; - - *indicesp++ = vert_offset + 1; - *indicesp++ = vert_offset + 3; - *indicesp++ = vert_offset + 2; + if (!(part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK)) + { //not fullbright, needs normal + *normalsp++ = normal; + *normalsp++ = normal; + *normalsp++ = normal; + *normalsp++ = normal; + } } U32 LLVOPartGroup::getPartitionType() const @@ -412,6 +506,49 @@ LLHUDParticlePartition::LLHUDParticlePartition() : mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE; } +static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VBO("Particle VBO"); + +void LLParticlePartition::rebuildGeom(LLSpatialGroup* group) +{ + if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) + { + return; + } + + if (group->changeLOD()) + { + group->mLastUpdateDistance = group->mDistance; + group->mLastUpdateViewAngle = group->mViewAngle; + } + + LLFastTimer ftm(FTM_REBUILD_PARTICLE_VBO); + + group->clearDrawMap(); + + //get geometry count + U32 index_count = 0; + U32 vertex_count = 0; + + addGeometryCount(group, vertex_count, index_count); + + + if (vertex_count > 0 && index_count > 0) + { + group->mBuilt = 1.f; + //use one vertex buffer for all groups + group->mVertexBuffer = LLVOPartGroup::sVB; + getGeometry(group); + } + else + { + group->mVertexBuffer = NULL; + group->mBufferMap.clear(); + } + + group->mLastUpdateTime = gFrameTimeSeconds; + group->clearState(LLSpatialGroup::GEOM_DIRTY); +} + void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count) { group->mBufferUsage = mBufferUsage; @@ -419,7 +556,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co mFaceList.clear(); LLViewerCamera* camera = LLViewerCamera::getInstance(); - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { LLDrawable* drawablep = *i; @@ -431,11 +568,6 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get(); obj->mDepth = 0.f; - if (drawablep->isAnimating()) - { - group->mBufferUsage = GL_STREAM_DRAW_ARB; - } - U32 count = 0; for (S32 j = 0; j < drawablep->getNumFaces(); ++j) { @@ -447,13 +579,14 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co continue; } + vertex_count += facep->getGeomCount(); + index_count += facep->getIndicesCount(); + count++; facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis(); obj->mDepth += facep->mDistance; mFaceList.push_back(facep); - vertex_count += facep->getGeomCount(); - index_count += facep->getIndicesCount(); llassert(facep->getIndicesCount() < 65536); } @@ -461,15 +594,12 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co } } -static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB"); -static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VB("Particle VB"); + +static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_GEOM("Particle Geom"); void LLParticlePartition::getGeometry(LLSpatialGroup* group) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - LLFastTimer ftm(mDrawableType == LLPipeline::RENDER_TYPE_GRASS ? - FTM_REBUILD_GRASS_VB : - FTM_REBUILD_PARTICLE_VB); + LLFastTimer ftm(FTM_REBUILD_PARTICLE_GEOM); std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater()); @@ -489,21 +619,45 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) buffer->getVertexStrider(verticesp); buffer->getNormalStrider(normalsp); buffer->getColorStrider(colorsp); - buffer->getTexCoord0Strider(texcoordsp); - buffer->getIndexStrider(indicesp); - + LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass]; for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i) { LLFace* facep = *i; LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); - facep->setGeomIndex(vertex_count); - facep->setIndicesIndex(index_count); - facep->setVertexBuffer(buffer); - facep->setPoolType(LLDrawPool::POOL_ALPHA); - object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp); + + if (!facep->isState(LLFace::PARTICLE)) + { //set the indices of this face + S32 idx = LLVOPartGroup::findAvailableVBSlot(); + if (idx >= 0) + { + facep->setGeomIndex(idx*4); + facep->setIndicesIndex(idx*6); + facep->setVertexBuffer(LLVOPartGroup::sVB); + facep->setPoolType(LLDrawPool::POOL_ALPHA); + facep->setState(LLFace::PARTICLE); + } + else + { + continue; //out of space in particle buffer + } + } + + S32 geom_idx = (S32) facep->getGeomIndex(); + + LLStrider<U16> cur_idx = indicesp + facep->getIndicesStart(); + LLStrider<LLVector4a> cur_vert = verticesp + geom_idx; + LLStrider<LLVector3> cur_norm = normalsp + geom_idx; + LLStrider<LLVector2> cur_tc = texcoordsp + geom_idx; + LLStrider<LLColor4U> cur_col = colorsp + geom_idx; + + object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_idx); + llassert(facep->getGeomCount() == 4); + llassert(facep->getIndicesCount() == 6); + + vertex_count += facep->getGeomCount(); index_count += facep->getIndicesCount(); @@ -512,18 +666,31 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); F32 vsize = facep->getVirtualSize(); - if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && + bool batched = false; + + if (idx >= 0 && draw_vec[idx]->mTexture == facep->getTexture() && - (U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange && - //draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && - draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 && draw_vec[idx]->mFullbright == fullbright) { - draw_vec[idx]->mCount += facep->getIndicesCount(); - draw_vec[idx]->mEnd += facep->getGeomCount(); - draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); + if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1) + { + batched = true; + draw_vec[idx]->mCount += facep->getIndicesCount(); + draw_vec[idx]->mEnd += facep->getGeomCount(); + draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); + } + else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1) + { + batched = true; + draw_vec[idx]->mCount += facep->getIndicesCount(); + draw_vec[idx]->mStart -= facep->getGeomCount(); + draw_vec[idx]->mOffset = facep->getIndicesStart(); + draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); + } } - else + + + if (!batched) { U32 start = facep->getGeomIndex(); U32 end = start + facep->getGeomCount()-1; @@ -541,7 +708,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) } } - buffer->flush(); mFaceList.clear(); } diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h index e58fed86d9..42c1252d01 100644 --- a/indra/newview/llvopartgroup.h +++ b/indra/newview/llvopartgroup.h @@ -31,24 +31,39 @@ #include "v3math.h" #include "v3color.h" #include "llframetimer.h" +#include "llviewerpartsim.h" +#include "llvertexbuffer.h" class LLViewerPartGroup; class LLVOPartGroup : public LLAlphaObject { public: + + //vertex buffer for holding all particles + static LLPointer<LLVertexBuffer> sVB; + static S32 sVBSlotFree[LL_MAX_PARTICLE_COUNT]; + static S32* sVBSlotCursor; + + static void initClass(); + static void restoreGL(); + static void destroyGL(); + static S32 findAvailableVBSlot(); + static void freeVBSlot(S32 idx); + enum { - VERTEX_DATA_MASK = (1 << LLVertexBuffer::TYPE_VERTEX) | - (1 << LLVertexBuffer::TYPE_NORMAL) | - (1 << LLVertexBuffer::TYPE_TEXCOORD0) | - (1 << LLVertexBuffer::TYPE_COLOR) + VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_NORMAL | + LLVertexBuffer::MAP_TEXCOORD0 | + LLVertexBuffer::MAP_COLOR | + LLVertexBuffer::MAP_TEXTURE_INDEX }; LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. - BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); virtual F32 getBinRadius(); virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index e9db37821b..31358df85f 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -342,7 +342,7 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) blue_density = LLColor3(); blue_horizon = LLColor3(); haze_density = 0.f; - haze_horizon = LLColor3(); + haze_horizon = 1.f; density_multiplier = 0.f; max_y = 0.f; glow = LLColor3(); @@ -651,17 +651,17 @@ void LLVOSky::initAtmospherics(void) sunlight_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("sunlight_color", error)); ambient = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("ambient", error)); //lightnorm = LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error); - gamma = LLWLParamManager::getInstance()->mCurParams.getVector("gamma", error)[0]; + gamma = LLWLParamManager::getInstance()->mCurParams.getFloat("gamma", error); blue_density = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_density", error)); blue_horizon = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_horizon", error)); - haze_density = LLWLParamManager::getInstance()->mCurParams.getVector("haze_density", error)[0]; - haze_horizon = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("haze_horizon", error)); - density_multiplier = LLWLParamManager::getInstance()->mCurParams.getVector("density_multiplier", error)[0]; - max_y = LLWLParamManager::getInstance()->mCurParams.getVector("max_y", error)[0]; + haze_density = LLWLParamManager::getInstance()->mCurParams.getFloat("haze_density", error); + haze_horizon = LLWLParamManager::getInstance()->mCurParams.getFloat("haze_horizon", error); + density_multiplier = LLWLParamManager::getInstance()->mCurParams.getFloat("density_multiplier", error); + max_y = LLWLParamManager::getInstance()->mCurParams.getFloat("max_y", error); glow = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("glow", error)); - cloud_shadow = LLWLParamManager::getInstance()->mCurParams.getVector("cloud_shadow", error)[0]; + cloud_shadow = LLWLParamManager::getInstance()->mCurParams.getFloat("cloud_shadow", error); cloud_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_color", error)); - cloud_scale = LLWLParamManager::getInstance()->mCurParams.getVector("cloud_scale", error)[0]; + cloud_scale = LLWLParamManager::getInstance()->mCurParams.getFloat("cloud_scale", error); cloud_pos_density1 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density1", error)); cloud_pos_density2 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density2", error)); @@ -825,7 +825,7 @@ void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLCo // Haze color above cloud vary_HazeColor = (blue_horizon * blue_weight * (sunlight + ambient) - + componentMult(haze_horizon.mV[0] * haze_weight, sunlight * temp2.mV[0] + ambient) + + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + ambient) ); // Increase ambient when there are more clouds @@ -836,7 +836,7 @@ void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLCo // Haze color below cloud LLColor3 additiveColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient) - + componentMult(haze_horizon.mV[0] * haze_weight, sunlight * temp2.mV[0] + tmpAmbient) + + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + tmpAmbient) ); // Final atmosphere additive @@ -1002,7 +1002,7 @@ void LLVOSky::calcAtmospherics(void) //haze color vary_HazeColor = (blue_horizon * blue_weight * (sunlight*(1.f - cloud_shadow) + tmpAmbient) - + componentMult(haze_horizon.mV[0] * haze_weight, sunlight*(1.f - cloud_shadow) * temp2.mV[0] + tmpAmbient) + + componentMult(haze_horizon * haze_weight, sunlight*(1.f - cloud_shadow) * temp2.mV[0] + tmpAmbient) ); //brightness of surface both sunlight and ambient @@ -1052,9 +1052,8 @@ void LLVOSky::calcAtmospherics(void) mFadeColor.setAlpha(0); } -BOOL LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - return TRUE; } BOOL LLVOSky::updateSky() diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index d3a42583ea..2a150eccb9 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -410,7 +410,7 @@ public: LLColor3 blue_density; LLColor3 blue_horizon; F32 haze_density; - LLColor3 haze_horizon; + F32 haze_horizon; F32 density_multiplier; F32 max_y; LLColor3 glow; @@ -461,7 +461,7 @@ public: void cleanupGL(); void restoreGL(); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); BOOL updateSky(); // Graphical stuff for objects - maybe broken out into render class diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index c3a2e6a712..cb905d02da 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; @@ -80,9 +80,9 @@ public: glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); } if (data_mask & MAP_TEXCOORD3) - { //substitute tex coord 0 for tex coord 3 + { //substitute tex coord 1 for tex coord 3 glClientActiveTextureARB(GL_TEXTURE3_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); glClientActiveTextureARB(GL_TEXTURE0_ARB); } if (data_mask & MAP_TEXCOORD2) @@ -296,18 +296,20 @@ void LLVOSurfacePatch::updateFaceSize(S32 idx) } LLFace* facep = mDrawable->getFace(idx); - - S32 num_vertices = 0; - S32 num_indices = 0; - - if (mLastStride) + if (facep) { - getGeomSizesMain(mLastStride, num_vertices, num_indices); - getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices); - getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices); - } + S32 num_vertices = 0; + S32 num_indices = 0; + + if (mLastStride) + { + getGeomSizesMain(mLastStride, num_vertices, num_indices); + getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices); + getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices); + } - facep->setSize(num_vertices, num_indices); + facep->setSize(num_vertices, num_indices); + } } BOOL LLVOSurfacePatch::updateLOD() @@ -322,30 +324,32 @@ void LLVOSurfacePatch::getGeometry(LLStrider<LLVector3> &verticesp, LLStrider<U16> &indicesp) { LLFace* facep = mDrawable->getFace(0); + if (facep) + { + U32 index_offset = facep->getGeomIndex(); - U32 index_offset = facep->getGeomIndex(); - - updateMainGeometry(facep, - verticesp, - normalsp, - texCoords0p, - texCoords1p, - indicesp, - index_offset); - updateNorthGeometry(facep, - verticesp, - normalsp, - texCoords0p, - texCoords1p, - indicesp, - index_offset); - updateEastGeometry(facep, + updateMainGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, index_offset); + updateNorthGeometry(facep, + verticesp, + normalsp, + texCoords0p, + texCoords1p, + indicesp, + index_offset); + updateEastGeometry(facep, + verticesp, + normalsp, + texCoords0p, + texCoords1p, + indicesp, + index_offset); + } } void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, @@ -864,7 +868,11 @@ void LLVOSurfacePatch::dirtyGeom() if (mDrawable) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); - mDrawable->getFace(0)->setVertexBuffer(NULL); + LLFace* facep = mDrawable->getFace(0); + if (facep) + { + facep->setVertexBuffer(NULL); + } mDrawable->movePartition(); } } diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 6486fd24ea..6687ce432f 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -339,47 +339,13 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys, return retval; } -BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - const U16 FRAMES_PER_WIND_UPDATE = 20; // How many frames between wind update per tree - const F32 TREE_WIND_SENSITIVITY = 0.005f; - const F32 TREE_TRUNK_STIFFNESS = 0.1f; - if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TREE))) { - return TRUE; + return; } - if (gSavedSettings.getBOOL("RenderAnimateTrees")) - { - F32 mass_inv; - - // For all tree objects, update the trunk bending with the current wind - // Walk sprite list in order away from viewer - if (!(mFrameCount % FRAMES_PER_WIND_UPDATE)) - { - // If needed, Get latest wind for this tree - mWind = mRegionp->mWind.getVelocity(getPositionRegion()); - } - mFrameCount++; - - mass_inv = 1.f/(5.f + mDepth*mBranches*0.2f); - mTrunkVel += (mWind * mass_inv * TREE_WIND_SENSITIVITY); // Pull in direction of wind - mTrunkVel -= (mTrunkBend * mass_inv * TREE_TRUNK_STIFFNESS); // Restoring force in direction of trunk - mTrunkBend += mTrunkVel; - mTrunkVel *= 0.99f; // Add damping - - if (mTrunkBend.length() > 1.f) - { - mTrunkBend.normalize(); - } - - if (mTrunkVel.length() > 1.f) - { - mTrunkVel.normalize(); - } - } - S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor; @@ -392,46 +358,41 @@ BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } } - if (!gSavedSettings.getBOOL("RenderAnimateTrees")) + if (mReferenceBuffer.isNull()) { - if (mReferenceBuffer.isNull()) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); - } - else if (trunk_LOD != mTrunkLOD) + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); + } + else if (trunk_LOD != mTrunkLOD) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, FALSE); + } + else + { + // we're not animating but we may *still* need to + // regenerate the mesh if we moved, since position + // and rotation are baked into the mesh. + // *TODO: I don't know what's so special about trees + // that they don't get REBUILD_POSITION automatically + // at a higher level. + const LLVector3 &this_position = getPositionRegion(); + if (this_position != mLastPosition) { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, FALSE); + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION); + mLastPosition = this_position; } else { - // we're not animating but we may *still* need to - // regenerate the mesh if we moved, since position - // and rotation are baked into the mesh. - // *TODO: I don't know what's so special about trees - // that they don't get REBUILD_POSITION automatically - // at a higher level. - const LLVector3 &this_position = getPositionAgent(); - if (this_position != mLastPosition) + const LLQuaternion &this_rotation = getRotation(); + + if (this_rotation != mLastRotation) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION); - mLastPosition = this_position; - } - else - { - const LLQuaternion &this_rotation = getRotation(); - - if (this_rotation != mLastRotation) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION); - mLastRotation = this_rotation; - } + mLastRotation = this_rotation; } } } mTrunkLOD = trunk_LOD; - - return TRUE; } const F32 TREE_BLEND_MIN = 1.f; @@ -527,11 +488,16 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) if(mTrunkLOD >= sMAX_NUM_TREE_LOD_LEVELS) //do not display the tree. { mReferenceBuffer = NULL ; - mDrawable->getFace(0)->setVertexBuffer(NULL); + LLFace * facep = drawable->getFace(0); + if (facep) + { + facep->setVertexBuffer(NULL); + } return TRUE ; } - if (mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer()) + if (mDrawable->getFace(0) && + (mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer())) { const F32 SRR3 = 0.577350269f; // sqrt(1/3) const F32 SRR2 = 0.707106781f; // sqrt(1/2) @@ -544,6 +510,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) S32 lod; LLFace *face = drawable->getFace(0); + if (!face) return TRUE; face->mCenterAgent = getPositionAgent(); face->mCenterLocal = face->mCenterAgent; @@ -559,7 +526,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) max_vertices += sLODVertexCount[lod]; } - mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, gSavedSettings.getBOOL("RenderAnimateTrees") ? GL_STATIC_DRAW_ARB : 0); + mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, 0); mReferenceBuffer->allocateBuffer(max_vertices, max_indices, TRUE); LLStrider<LLVector3> vertices; @@ -863,15 +830,8 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) llassert(index_count == max_indices); } - if (gSavedSettings.getBOOL("RenderAnimateTrees")) - { - mDrawable->getFace(0)->setVertexBuffer(mReferenceBuffer); - } - else - { - //generate tree mesh - updateMesh(); - } + //generate tree mesh + updateMesh(); return TRUE; } @@ -881,10 +841,10 @@ void LLVOTree::updateMesh() LLMatrix4 matrix; // Translate to tree base HACK - adjustment in Z plants tree underground - const LLVector3 &pos_agent = getPositionAgent(); + const LLVector3 &pos_region = getPositionRegion(); //gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); LLMatrix4 trans_mat; - trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); + trans_mat.setTranslation(pos_region.mV[VX], pos_region.mV[VY], pos_region.mV[VZ] - 0.1f); trans_mat *= matrix; // Rotate to tree position and bend for current trunk/wind @@ -923,6 +883,7 @@ void LLVOTree::updateMesh() calcNumVerts(vert_count, index_count, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, mBranches); LLFace* facep = mDrawable->getFace(0); + if (!facep) return; LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); buff->allocateBuffer(vert_count, index_count, TRUE); facep->setVertexBuffer(buff); diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index 1e1deede26..52debc85ab 100644 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -59,7 +59,7 @@ public: void **user_data, U32 block_num, const EObjectUpdateType update_type, LLDataPacker *dp); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); // Graphical stuff for objects - maybe broken out into render class later? /*virtual*/ void render(LLAgent &agent); @@ -152,7 +152,6 @@ public: friend class LLDrawPoolTree; protected: LLVector3 mTrunkBend; // Accumulated wind (used for blowing trees) - LLVector3 mTrunkVel; // LLVector3 mWind; LLPointer<LLVertexBuffer> mReferenceBuffer; //reference geometry for generating tree mesh diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index baab191cb6..d94cd01a0b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -329,7 +329,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, { if (!mTextureAnimp) { - mTextureAnimp = new LLViewerTextureAnim(); + mTextureAnimp = new LLViewerTextureAnim(this); } else { @@ -431,7 +431,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, { if (!mTextureAnimp) { - mTextureAnimp = new LLViewerTextureAnim(); + mTextureAnimp = new LLViewerTextureAnim(this); } else { @@ -499,191 +499,168 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, void LLVOVolume::animateTextures() { - F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f; - S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot); - - if (result) + if (!mDead) { - if (!mTexAnimMode) - { - mFaceMappingChanged = TRUE; - gPipeline.markTextured(mDrawable); - } - mTexAnimMode = result | mTextureAnimp->mMode; - - S32 start=0, end=mDrawable->getNumFaces()-1; - if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end) - { - start = end = mTextureAnimp->mFace; - } - - for (S32 i = start; i <= end; i++) + F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f; + S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot); + + if (result) { - LLFace* facep = mDrawable->getFace(i); - if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; - - const LLTextureEntry* te = facep->getTextureEntry(); - - if (!te) + if (!mTexAnimMode) { - continue; + mFaceMappingChanged = TRUE; + gPipeline.markTextured(mDrawable); } - - if (!(result & LLViewerTextureAnim::ROTATE)) + mTexAnimMode = result | mTextureAnimp->mMode; + + S32 start=0, end=mDrawable->getNumFaces()-1; + if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end) { - te->getRotation(&rot); + start = end = mTextureAnimp->mFace; } - if (!(result & LLViewerTextureAnim::TRANSLATE)) - { - te->getOffset(&off_s,&off_t); - } - if (!(result & LLViewerTextureAnim::SCALE)) + + for (S32 i = start; i <= end; i++) { - te->getScale(&scale_s, &scale_t); - } + LLFace* facep = mDrawable->getFace(i); + if (!facep) continue; + if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; - if (!facep->mTextureMatrix) - { - facep->mTextureMatrix = new LLMatrix4(); - } + const LLTextureEntry* te = facep->getTextureEntry(); + + if (!te) + { + continue; + } + + if (!(result & LLViewerTextureAnim::ROTATE)) + { + te->getRotation(&rot); + } + if (!(result & LLViewerTextureAnim::TRANSLATE)) + { + te->getOffset(&off_s,&off_t); + } + if (!(result & LLViewerTextureAnim::SCALE)) + { + te->getScale(&scale_s, &scale_t); + } + + if (!facep->mTextureMatrix) + { + facep->mTextureMatrix = new LLMatrix4(); + } - LLMatrix4& tex_mat = *facep->mTextureMatrix; - tex_mat.setIdentity(); - LLVector3 trans ; + LLMatrix4& tex_mat = *facep->mTextureMatrix; + tex_mat.setIdentity(); + LLVector3 trans ; - if(facep->isAtlasInUse()) - { - // - //if use atlas for animated texture - //apply the following transform to the animation matrix. - // - - F32 tcoord_xoffset = 0.f ; - F32 tcoord_yoffset = 0.f ; - F32 tcoord_xscale = 1.f ; - F32 tcoord_yscale = 1.f ; if(facep->isAtlasInUse()) { - const LLVector2* tmp = facep->getTexCoordOffset() ; - tcoord_xoffset = tmp->mV[0] ; - tcoord_yoffset = tmp->mV[1] ; + // + //if use atlas for animated texture + //apply the following transform to the animation matrix. + // + + F32 tcoord_xoffset = 0.f ; + F32 tcoord_yoffset = 0.f ; + F32 tcoord_xscale = 1.f ; + F32 tcoord_yscale = 1.f ; + if(facep->isAtlasInUse()) + { + const LLVector2* tmp = facep->getTexCoordOffset() ; + tcoord_xoffset = tmp->mV[0] ; + tcoord_yoffset = tmp->mV[1] ; - tmp = facep->getTexCoordScale() ; - tcoord_xscale = tmp->mV[0] ; - tcoord_yscale = tmp->mV[1] ; - } - trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f)); + tmp = facep->getTexCoordScale() ; + tcoord_xscale = tmp->mV[0] ; + tcoord_yscale = tmp->mV[1] ; + } + trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f)); - tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f)); - } - else //non atlas - { - trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); - tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); - } + tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f)); + } + else //non atlas + { + trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); + tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); + } - LLVector3 scale(scale_s, scale_t, 1.f); - LLQuaternion quat; - quat.setQuat(rot, 0, 0, -1.f); + LLVector3 scale(scale_s, scale_t, 1.f); + LLQuaternion quat; + quat.setQuat(rot, 0, 0, -1.f); - tex_mat.rotate(quat); + tex_mat.rotate(quat); - LLMatrix4 mat; - mat.initAll(scale, LLQuaternion(), LLVector3()); - tex_mat *= mat; + LLMatrix4 mat; + mat.initAll(scale, LLQuaternion(), LLVector3()); + tex_mat *= mat; - tex_mat.translate(trans); + tex_mat.translate(trans); + } } - } - else - { - if (mTexAnimMode && mTextureAnimp->mRate == 0) + else { - U8 start, count; - - if (mTextureAnimp->mFace == -1) + if (mTexAnimMode && mTextureAnimp->mRate == 0) { - start = 0; - count = getNumTEs(); - } - else - { - start = (U8) mTextureAnimp->mFace; - count = 1; - } + U8 start, count; - for (S32 i = start; i < start + count; i++) - { - if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE) + if (mTextureAnimp->mFace == -1) { - setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT); + start = 0; + count = getNumTEs(); } - if (mTexAnimMode & LLViewerTextureAnim::SCALE) + else { - setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT); + start = (U8) mTextureAnimp->mFace; + count = 1; } - if (mTexAnimMode & LLViewerTextureAnim::ROTATE) + + for (S32 i = start; i < start + count; i++) { - setTERotation(i, mTextureAnimp->mRot); + if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE) + { + setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT); + } + if (mTexAnimMode & LLViewerTextureAnim::SCALE) + { + setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT); + } + if (mTexAnimMode & LLViewerTextureAnim::ROTATE) + { + setTERotation(i, mTextureAnimp->mRot); + } } - } - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - mTexAnimMode = 0; + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + mTexAnimMode = 0; + } } } } -BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) -{ - LLViewerObject::idleUpdate(agent, world, time); - - static LLFastTimer::DeclareTimer ftm("Volume"); - LLFastTimer t(ftm); - - if (mDead || mDrawable.isNull()) - { - return TRUE; - } - - /////////////////////// - // - // Do texture animation stuff - // - if (mTextureAnimp && gAnimateTextures) +void LLVOVolume::updateTextures() +{ + const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds + if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) { - animateTextures(); - } + updateTextureVirtualSize(); - // Dispatch to implementation - if (mVolumeImpl) - { - mVolumeImpl->doIdleUpdate(agent, world, time); - } - - const S32 MAX_ACTIVE_OBJECT_QUIET_FRAMES = 40; + if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive()) + { //delete vertex buffer to free up some VRAM + LLSpatialGroup* group = mDrawable->getSpatialGroup(); + if (group) + { + group->destroyGL(true); - if (mDrawable->isActive()) - { - if (mDrawable->isRoot() && - mDrawable->mQuietCount++ > MAX_ACTIVE_OBJECT_QUIET_FRAMES && - (!mDrawable->getParent() || !mDrawable->getParent()->isActive())) - { - mDrawable->makeStatic(); + //flag the group as having changed geometry so it gets a rebuild next time + //it becomes visible + group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); + } } - } - return TRUE; -} -void LLVOVolume::updateTextures() -{ - const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds - if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) - { - updateTextureVirtualSize(); - } + } } BOOL LLVOVolume::isVisible() const @@ -715,7 +692,18 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) if(!forced) { if(!isVisible()) - { + { //don't load textures for non-visible faces + const S32 num_faces = mDrawable->getNumFaces(); + for (S32 i = 0; i < num_faces; i++) + { + LLFace* face = mDrawable->getFace(i); + if (face) + { + face->setPixelArea(0.f); + face->setVirtualSize(0.f); + } + } + return ; } @@ -743,6 +731,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) for (S32 i = 0; i < num_faces; i++) { LLFace* face = mDrawable->getFace(i); + if (!face) continue; const LLTextureEntry *te = face->getTextureEntry(); LLViewerTexture *imagep = face->getTexture(); if (!imagep || !te || @@ -833,7 +822,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) } } - S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture + S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ; if (texture_discard >= 0 && //texture has some data available @@ -889,8 +878,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) BOOL LLVOVolume::isActive() const { - return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()) || - (mDrawable.notNull() && mDrawable->isActive()); + return !mStatic; } BOOL LLVOVolume::setMaterial(const U8 material) @@ -1062,9 +1050,33 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo } } + + static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback"); + + bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject && + (!mVolumeImpl || !mVolumeImpl->isVolumeUnique()); + + if (cache_in_vram) + { //this volume might be used as source data for a transform object, put it in vram + LLVolume* volume = getVolume(); + for (S32 i = 0; i < volume->getNumFaces(); ++i) + { + const LLVolumeFace& face = volume->getVolumeFace(i); + if (face.mVertexBuffer.notNull()) + { //already cached + break; + } + volume->genBinormals(i); + LLFace::cacheFaceInVRAM(face); + } + } + + return TRUE; } + + return FALSE; } @@ -1116,7 +1128,7 @@ void LLVOVolume::sculpt() S8 sculpt_components = 0; const U8* sculpt_data = NULL; - S32 discard_level = mSculptTexture->getDiscardLevel() ; + S32 discard_level = mSculptTexture->getCachedRawImageLevel() ; LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ; S32 max_discard = mSculptTexture->getMaxDiscardLevel(); @@ -1126,17 +1138,29 @@ void LLVOVolume::sculpt() S32 current_discard = getVolume()->getSculptLevel() ; if(current_discard < -2) { - llwarns << "WARNING!!: Current discard of sculpty at " << current_discard - << " is less than -2." << llendl; + static S32 low_sculpty_discard_warning_count = 100; + if (++low_sculpty_discard_warning_count >= 100) + { // Log first time, then every 100 afterwards otherwise this can flood the logs + llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() + << " at " << current_discard + << " is less than -2." << llendl; + low_sculpty_discard_warning_count = 0; + } // corrupted volume... don't update the sculpty return; } else if (current_discard > MAX_DISCARD_LEVEL) { - llwarns << "WARNING!!: Current discard of sculpty at " << current_discard - << " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl; - + static S32 high_sculpty_discard_warning_count = 100; + if (++high_sculpty_discard_warning_count >= 100) + { // Log first time, then every 100 afterwards otherwise this can flood the logs + llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() + << " at " << current_discard + << " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl; + high_sculpty_discard_warning_count = 0; + } + // corrupted volume... don't update the sculpty return; } @@ -1215,6 +1239,13 @@ BOOL LLVOVolume::calcLOD() if (mDrawable->isState(LLDrawable::RIGGED)) { LLVOAvatar* avatar = getAvatar(); + + // Not sure how this can really happen, but alas it does. Better exit here than crashing. + if( !avatar || !avatar->mDrawable ) + { + return FALSE; + } + distance = avatar->mDrawable->mDistanceWRTCamera; radius = avatar->getBinRadius(); } @@ -1246,7 +1277,8 @@ BOOL LLVOVolume::calcLOD() llround(radius, 0.01f)); - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO)) + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) && + mDrawable->getFace(0)) { //setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail)); @@ -1322,28 +1354,27 @@ BOOL LLVOVolume::setDrawableParent(LLDrawable* parentp) void LLVOVolume::updateFaceFlags() { - for (S32 i = 0; i < getVolume()->getNumFaces(); i++) + // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces() + for (S32 i = 0; i < getVolume()->getNumFaces() && i < mDrawable->getNumFaces(); i++) { LLFace *face = mDrawable->getFace(i); - if (!face) + if (face) { - return; - } - - BOOL fullbright = getTE(i)->getFullbright(); - face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); + BOOL fullbright = getTE(i)->getFullbright(); + face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); - if (fullbright || (mMaterial == LL_MCODE_LIGHT)) - { - face->setState(LLFace::FULLBRIGHT); - } - if (mDrawable->isLight()) - { - face->setState(LLFace::LIGHT); - } - if (isHUDAttachment()) - { - face->setState(LLFace::HUD_RENDER); + if (fullbright || (mMaterial == LL_MCODE_LIGHT)) + { + face->setState(LLFace::FULLBRIGHT); + } + if (mDrawable->isLight()) + { + face->setState(LLFace::LIGHT); + } + if (isHUDAttachment()) + { + face->setState(LLFace::HUD_RENDER); + } } } } @@ -1380,6 +1411,8 @@ void LLVOVolume::regenFaces() for (S32 i = 0; i < mNumFaces; i++) { LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i); + if (!facep) continue; + facep->setTEOffset(i); facep->setTexture(getTEImage(i)); facep->setViewerObject(this); @@ -1416,14 +1449,17 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED); -// bool rigged = false; + // bool rigged = false; LLVolume* volume = mRiggedVolume; if (!volume) { volume = getVolume(); } - for (S32 i = 0; i < getVolume()->getNumVolumeFaces(); i++) + // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces() + for (S32 i = 0; + i < getVolume()->getNumVolumeFaces() && i < mDrawable->getNumFaces() && i < getNumTEs(); + i++) { LLFace *face = mDrawable->getFace(i); if (!face) @@ -1459,7 +1495,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) updateRadius(); mDrawable->movePartition(); - + return res; } @@ -1471,11 +1507,11 @@ void LLVOVolume::preRebuild() } } -void LLVOVolume::updateRelativeXform() +void LLVOVolume::updateRelativeXform(bool force_identity) { if (mVolumeImpl) { - mVolumeImpl->updateRelativeXform(); + mVolumeImpl->updateRelativeXform(force_identity); return; } @@ -1495,15 +1531,16 @@ void LLVOVolume::updateRelativeXform() mRelativeXform.invert(); mRelativeXformInvTrans.transpose(); } - else if (drawable->isActive()) + else if (drawable->isActive() || force_identity) { // setup relative transforms LLQuaternion delta_rot; LLVector3 delta_pos, delta_scale; //matrix from local space to parent relative/global space - delta_rot = drawable->isSpatialRoot() ? LLQuaternion() : mDrawable->getRotation(); - delta_pos = drawable->isSpatialRoot() ? LLVector3(0,0,0) : mDrawable->getPosition(); + bool use_identity = force_identity || drawable->isSpatialRoot(); + delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation(); + delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition(); delta_scale = mDrawable->getScale(); // Vertex transform (4x4) @@ -1604,7 +1641,11 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) return res; } - dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); + LLSpatialGroup* group = drawable->getSpatialGroup(); + if (group) + { + group->dirtyMesh(); + } BOOL compiled = FALSE; @@ -1617,6 +1658,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) if (mVolumeChanged || mFaceMappingChanged ) { + dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); + compiled = TRUE; if (mVolumeChanged) @@ -1635,6 +1678,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) } else if ((mLODChanged) || (mSculptChanged)) { + dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); + LLVolume *old_volumep, *new_volumep; F32 old_lod, new_lod; S32 old_num_faces, new_num_faces ; @@ -1715,17 +1760,25 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) void LLVOVolume::updateFaceSize(S32 idx) { - LLFace* facep = mDrawable->getFace(idx); - if (idx >= getVolume()->getNumVolumeFaces()) + if( mDrawable->getNumFaces() <= idx ) { - facep->setSize(0,0, true); + return; } - else + + LLFace* facep = mDrawable->getFace(idx); + if (facep) { - const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); - facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices, - true); // <--- volume faces should be padded for 16-byte alignment + if (idx >= getVolume()->getNumVolumeFaces()) + { + facep->setSize(0,0, true); + } + else + { + const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); + facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices, + true); // <--- volume faces should be padded for 16-byte alignment + } } } @@ -1778,6 +1831,18 @@ void LLVOVolume::setNumTEs(const U8 num_tes) return ; } +//virtual +void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep) +{ + BOOL changed = (mTEImages[index] != imagep); + LLViewerObject::changeTEImage(index, imagep); + if (changed) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } +} + void LLVOVolume::setTEImage(const U8 te, LLViewerTexture *imagep) { BOOL changed = (mTEImages[te] != imagep); @@ -1815,9 +1880,13 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color) } else if (color != tep->getColor()) { - if (color.mV[3] != tep->getColor().mV[3]) + F32 old_alpha = tep->getColor().mV[3]; + if (color.mV[3] != old_alpha) { gPipeline.markTextured(mDrawable); + //treat this alpha change as an LoD update since render batches may need to get rebuilt + mLODChanged = TRUE; + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE); } retval = LLPrimitive::setTEColor(te, color); if (mDrawable.notNull() && retval) @@ -2386,7 +2455,12 @@ void LLVOVolume::addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) //add the face to show the media if it is in playing if(mDrawable) { - LLFace* facep = mDrawable->getFace(texture_index) ; + LLFace* facep(NULL); + if( texture_index < mDrawable->getNumFaces() ) + { + facep = mDrawable->getFace(texture_index) ; + } + if(facep) { LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ; @@ -3098,6 +3172,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const for (S32 i = 0; i < num_faces; ++i) { const LLFace* face = drawablep->getFace(i); + if (!face) continue; const LLTextureEntry* te = face->getTextureEntry(); const LLViewerTexture* img = face->getTexture(); @@ -3369,6 +3444,7 @@ F32 LLVOVolume::getBinRadius() for (S32 i = 0; i < mDrawable->getNumFaces(); i++) { LLFace* face = mDrawable->getFace(i); + if (!face) continue; if (face->getPoolType() == LLDrawPool::POOL_ALPHA && !face->canRenderAsMask()) { @@ -3450,9 +3526,12 @@ LLVector3 LLVOVolume::agentPositionToVolume(const LLVector3& pos) const { LLVector3 ret = pos - getRenderPosition(); ret = ret * ~getRenderRotation(); - LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); - LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); - ret.scaleVec(invObjScale); + if (!isVolumeGlobal()) + { + LLVector3 objScale = getScale(); + LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); + ret.scaleVec(invObjScale); + } return ret; } @@ -3470,8 +3549,12 @@ LLVector3 LLVOVolume::agentDirectionToVolume(const LLVector3& dir) const LLVector3 LLVOVolume::volumePositionToAgent(const LLVector3& dir) const { LLVector3 ret = dir; - LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); - ret.scaleVec(objScale); + if (!isVolumeGlobal()) + { + LLVector3 objScale = getScale(); + ret.scaleVec(objScale); + } + ret = ret * getRenderRotation(); ret += getRenderPosition(); @@ -3512,7 +3595,6 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf()) { updateRiggedVolume(); - genBBoxes(FALSE); volume = mRiggedVolume; transform = false; } @@ -3592,7 +3674,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e { LLFace* face = mDrawable->getFace(face_hit); - if (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))) + if (face && + (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))) { v_end = p; if (face_hitp != NULL) @@ -3768,82 +3851,86 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLVector4a* weight = vol_face.mWeights; - LLMatrix4a bind_shape_matrix; - bind_shape_matrix.loadu(skin->mBindShapeMatrix); - - LLVector4a* pos = dst_face.mPositions; - + if ( weight ) { - LLFastTimer t(FTM_SKIN_RIGGED); + LLMatrix4a bind_shape_matrix; + bind_shape_matrix.loadu(skin->mBindShapeMatrix); - for (U32 j = 0; j < dst_face.mNumVertices; ++j) + LLVector4a* pos = dst_face.mPositions; + + if( pos && weight && dst_face.mExtents ) { - LLMatrix4a final_mat; - final_mat.clear(); + LLFastTimer t(FTM_SKIN_RIGGED); - S32 idx[4]; + for (U32 j = 0; j < dst_face.mNumVertices; ++j) + { + LLMatrix4a final_mat; + final_mat.clear(); - LLVector4 wght; + S32 idx[4]; - F32 scale = 0.f; - for (U32 k = 0; k < 4; k++) - { - F32 w = weight[j][k]; + LLVector4 wght; - idx[k] = (S32) floorf(w); - wght[k] = w - floorf(w); - scale += wght[k]; - } + F32 scale = 0.f; + for (U32 k = 0; k < 4; k++) + { + F32 w = weight[j][k]; - wght *= 1.f/scale; + idx[k] = (S32) floorf(w); + wght[k] = w - floorf(w); + scale += wght[k]; + } - for (U32 k = 0; k < 4; k++) - { - F32 w = wght[k]; + wght *= 1.f/scale; - LLMatrix4a src; - src.setMul(mp[idx[k]], w); + for (U32 k = 0; k < 4; k++) + { + F32 w = wght[k]; - final_mat.add(src); - } + LLMatrix4a src; + src.setMul(mp[idx[k]], w); + + final_mat.add(src); + } - LLVector4a& v = vol_face.mPositions[j]; - LLVector4a t; - LLVector4a dst; - bind_shape_matrix.affineTransform(v, t); - final_mat.affineTransform(t, dst); - pos[j] = dst; - } + LLVector4a& v = vol_face.mPositions[j]; + LLVector4a t; + LLVector4a dst; + bind_shape_matrix.affineTransform(v, t); + final_mat.affineTransform(t, dst); + pos[j] = dst; + } - //update bounding box - LLVector4a& min = dst_face.mExtents[0]; - LLVector4a& max = dst_face.mExtents[1]; + //update bounding box + LLVector4a& min = dst_face.mExtents[0]; + LLVector4a& max = dst_face.mExtents[1]; - min = pos[0]; - max = pos[1]; + min = pos[0]; + max = pos[1]; - for (U32 j = 1; j < dst_face.mNumVertices; ++j) - { - min.setMin(min, pos[j]); - max.setMax(max, pos[j]); - } + for (U32 j = 1; j < dst_face.mNumVertices; ++j) + { + min.setMin(min, pos[j]); + max.setMax(max, pos[j]); + } - dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]); - dst_face.mCenter->mul(0.5f); + dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]); + dst_face.mCenter->mul(0.5f); - } + } - { - LLFastTimer t(FTM_RIGGED_OCTREE); - delete dst_face.mOctree; - dst_face.mOctree = NULL; + { + LLFastTimer t(FTM_RIGGED_OCTREE); + delete dst_face.mOctree; + dst_face.mOctree = NULL; - LLVector4a size; - size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]); - size.splat(size.getLength3().getF32()*0.5f); + LLVector4a size; + size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]); + size.splat(size.getLength3().getF32()*0.5f); - dst_face.createOctree(1.f); + dst_face.createOctree(1.f); + } } } } @@ -3902,9 +3989,11 @@ bool can_batch_texture(LLFace* facep) return true; } +static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face"); + void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); + LLFastTimer t(FTM_REGISTER_FACE); if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects) { @@ -3935,19 +4024,22 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, const LLMatrix4* model_mat = NULL; LLDrawable* drawable = facep->getDrawable(); - if (drawable->isActive()) + + if (drawable->isState(LLDrawable::ANIMATED_CHILD)) { - model_mat = &(drawable->getRenderMatrix()); + model_mat = &drawable->getWorldMatrix(); + } + else if (drawable->isActive()) + { + model_mat = &drawable->getRenderMatrix(); } else { model_mat = &(drawable->getRegion()->mRenderMatrix); - if (model_mat->isIdentity()) - { - model_mat = NULL; - } } + //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD))); + U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0; LLViewerTexture* tex = facep->getTexture(); @@ -4041,8 +4133,9 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group) } -static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume"); -static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt"); +static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume VB"); +static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_FACE_LIST("Build Face List"); +static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_GEN_DRAW_INFO("Gen Draw Info"); static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj) { @@ -4073,6 +4166,8 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj) void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { + + if (group->changeLOD()) { group->mLastUpdateDistance = group->mDistance; @@ -4084,18 +4179,43 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate) { - LLFastTimer ftm(FTM_REBUILD_VBO); - LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB); - rebuildMesh(group); } return; } + LLFastTimer ftm(FTM_REBUILD_VOLUME_VB); + group->mBuilt = 1.f; - LLFastTimer ftm(FTM_REBUILD_VBO); + + LLVOAvatar* pAvatarVO = NULL; - LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB); + 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; + + //cache object box size since it might be used for determining visibility + group->mObjectBoxSize = group->mObjectBounds[1].getLength3().getF32(); group->clearDrawMap(); @@ -4116,342 +4236,375 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool emissive = false; - //get all the faces into a list - for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) { - LLDrawable* drawablep = *drawable_iter; - - if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) + LLFastTimer t(FTM_REBUILD_VOLUME_FACE_LIST); + + //get all the faces into a list + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - continue; - } + LLDrawable* drawablep = *drawable_iter; + + if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) + { + continue; + } - if (drawablep->isAnimating()) - { //fall back to stream draw for animating verts - useage = GL_STREAM_DRAW_ARB; - } + if (drawablep->isAnimating()) + { //fall back to stream draw for animating verts + useage = GL_STREAM_DRAW_ARB; + } - LLVOVolume* vobj = drawablep->getVOVolume(); + LLVOVolume* vobj = drawablep->getVOVolume(); - if (vobj->isMesh() && - (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled())) - { - continue; - } + if (!vobj) + { + continue; + } - llassert_always(vobj); - vobj->updateTextureVirtualSize(true); - vobj->preRebuild(); + if (vobj->isMesh() && + (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled())) + { + continue; + } - drawablep->clearState(LLDrawable::HAS_ALPHA); + 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]); + } - bool rigged = vobj->isAttachment() && - vobj->isMesh() && - gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); + llassert_always(vobj); + vobj->updateTextureVirtualSize(true); + vobj->preRebuild(); - bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); + drawablep->clearState(LLDrawable::HAS_ALPHA); - bool is_rigged = false; + bool rigged = vobj->isAttachment() && + vobj->isMesh() && + gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); - //for each face - for (S32 i = 0; i < drawablep->getNumFaces(); i++) - { - LLFace* facep = drawablep->getFace(i); + bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); + + bool is_rigged = false; - //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render - // batch, it will recover its vertex buffer reference from the spatial group - facep->setVertexBuffer(NULL); + //for each face + for (S32 i = 0; i < drawablep->getNumFaces(); i++) + { + LLFace* facep = drawablep->getFace(i); + if (!facep) + { + continue; + } + + //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render + // batch, it will recover its vertex buffer reference from the spatial group + facep->setVertexBuffer(NULL); - //sum up face verts and indices - drawablep->updateFaceSize(i); + //sum up face verts and indices + drawablep->updateFaceSize(i); - if (rigged) - { - if (!facep->isState(LLFace::RIGGED)) - { //completely reset vertex buffer - facep->clearVertexBuffer(); - } + if (rigged) + { + if (!facep->isState(LLFace::RIGGED)) + { //completely reset vertex buffer + facep->clearVertexBuffer(); + } - facep->setState(LLFace::RIGGED); - is_rigged = true; + facep->setState(LLFace::RIGGED); + is_rigged = true; - //get drawpool of avatar with rigged face - LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj); + //get drawpool of avatar with rigged face + LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj); - //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; + //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. + bool pelvisGotSet = false; - if ( pAvatarVO ) - { - LLUUID currentId = vobj->getVolume()->getParams().getSculptID(); - const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj ); - - if ( pSkinData ) + if ( pAvatarVO ) { - const int bindCnt = pSkinData->mAlternateBindMatrix.size(); - if ( bindCnt > 0 ) - { - const int jointCnt = pSkinData->mJointNames.size(); - const F32 pelvisZOffset = pSkinData->mPelvisOffset; - bool fullRig = (jointCnt>=20) ? true : false; - if ( fullRig ) - { - for ( int i=0; i<jointCnt; ++i ) + LLUUID currentId = vobj->getVolume()->getParams().getSculptID(); + const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj ); + + if ( pSkinData ) + { + const int bindCnt = pSkinData->mAlternateBindMatrix.size(); + if ( bindCnt > 0 ) + { + const int jointCnt = pSkinData->mJointNames.size(); + const F32 pelvisZOffset = pSkinData->mPelvisOffset; + bool fullRig = (jointCnt>=20) ? true : false; + if ( fullRig ) { - std::string lookingForJoint = pSkinData->mJointNames[i].c_str(); - //llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl; - LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint ); - if ( pJoint && pJoint->getId() != currentId ) - { - pJoint->setId( currentId ); - const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation(); - //Set the joint position - pJoint->storeCurrentXform( jointPos ); - //If joint is a pelvis then handle old/new pelvis to foot values - if ( lookingForJoint == "mPelvis" ) - { + for ( int i=0; i<jointCnt; ++i ) + { + std::string lookingForJoint = pSkinData->mJointNames[i].c_str(); + //llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl; + LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint ); + if ( pJoint && pJoint->getId() != currentId ) + { + pJoint->setId( currentId ); + const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation(); + //Set the joint position pJoint->storeCurrentXform( jointPos ); - if ( !pAvatarVO->hasPelvisOffset() ) - { - pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset ); - //Trigger to rebuild viewer AV - pelvisGotSet = true; + //If joint is a pelvis then handle old/new pelvis to foot values + if ( lookingForJoint == "mPelvis" ) + { + pJoint->storeCurrentXform( jointPos ); + if ( !pAvatarVO->hasPelvisOffset() ) + { + pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset ); + //Trigger to rebuild viewer AV + pelvisGotSet = true; + } } - } + } } - } - } + } + } } } - } - //If we've set the pelvis to a new position we need to also rebuild some information that the - //viewer does at launch (e.g. body size etc.) - if ( pelvisGotSet ) - { - pAvatarVO->postPelvisSetRecalc(); - } - - if (pool) - { - const LLTextureEntry* te = facep->getTextureEntry(); - - //remove face from old pool if it exists - LLDrawPool* old_pool = facep->getPool(); - if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR) + //If we've set the pelvis to a new position we need to also rebuild some information that the + //viewer does at launch (e.g. body size etc.) + if ( pelvisGotSet ) { - ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep); + pAvatarVO->postPelvisSetRecalc(); } - //add face to new pool - LLViewerTexture* tex = facep->getTexture(); - U32 type = gPipeline.getPoolTypeFromTE(te, tex); - - if (type == LLDrawPool::POOL_ALPHA) + if (pool) { - if (te->getFullbright()) + const LLTextureEntry* te = facep->getTextureEntry(); + + //remove face from old pool if it exists + LLDrawPool* old_pool = facep->getPool(); + if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); + ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep); } - else + + //add face to new pool + LLViewerTexture* tex = facep->getTexture(); + U32 type = gPipeline.getPoolTypeFromTE(te, tex); + + if (type == LLDrawPool::POOL_ALPHA) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); + if (te->getColor().mV[3] > 0.f) + { + if (te->getFullbright()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); + } + } } - } - else if (te->getShiny()) - { - if (te->getFullbright()) + else if (te->getShiny()) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY); + if (te->getFullbright()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY); + } + else + { + if (LLPipeline::sRenderDeferred) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); + } + } } else { - if (LLPipeline::sRenderDeferred) + if (te->getFullbright()) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); } else { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); } } - } - else - { - if (te->getFullbright()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); - } - else + + if (te->getGlow()) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); } - } - if (te->getGlow()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); - } - - if (LLPipeline::sRenderDeferred) - { - if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) + if (LLPipeline::sRenderDeferred) { - if (te->getBumpmap()) + if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); - } - else - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); + if (te->getBumpmap()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); + } } } } - } - continue; - } - else - { - if (facep->isState(LLFace::RIGGED)) - { //face is not rigged but used to be, remove from rigged face pool - LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool(); - if (pool) - { - pool->removeRiggedFace(facep); + continue; + } + else + { + if (facep->isState(LLFace::RIGGED)) + { //face is not rigged but used to be, remove from rigged face pool + LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool(); + if (pool) + { + pool->removeRiggedFace(facep); + } + facep->clearState(LLFace::RIGGED); } - facep->clearState(LLFace::RIGGED); } - } - - if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0) - { - facep->clearVertexBuffer(); - continue; - } - - cur_total += facep->getGeomCount(); - - if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) - { - const LLTextureEntry* te = facep->getTextureEntry(); - LLViewerTexture* tex = facep->getTexture(); - if (te->getGlow() >= 1.f/255.f) + if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0) { - emissive = true; + facep->clearVertexBuffer(); + continue; } - if (facep->isState(LLFace::TEXTURE_ANIM)) - { - if (!vobj->mTexAnimMode) - { - facep->clearState(LLFace::TEXTURE_ANIM); - } - } + cur_total += facep->getGeomCount(); - BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); - U32 type = gPipeline.getPoolTypeFromTE(te, tex); - if (type != LLDrawPool::POOL_ALPHA && force_simple) + if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) { - type = LLDrawPool::POOL_SIMPLE; - } - facep->setPoolType(type); + const LLTextureEntry* te = facep->getTextureEntry(); + LLViewerTexture* tex = facep->getTexture(); - if (vobj->isHUDAttachment()) - { - facep->setState(LLFace::FULLBRIGHT); - } + if (te->getGlow() >= 1.f/255.f) + { + emissive = true; + } - if (vobj->mTextureAnimp && vobj->mTexAnimMode) - { - if (vobj->mTextureAnimp->mFace <= -1) + if (facep->isState(LLFace::TEXTURE_ANIM)) { - S32 face; - for (face = 0; face < vobj->getNumTEs(); face++) + if (!vobj->mTexAnimMode) { - drawablep->getFace(face)->setState(LLFace::TEXTURE_ANIM); + facep->clearState(LLFace::TEXTURE_ANIM); } } - else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs()) + + BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); + U32 type = gPipeline.getPoolTypeFromTE(te, tex); + if (type != LLDrawPool::POOL_ALPHA && force_simple) { - drawablep->getFace(vobj->mTextureAnimp->mFace)->setState(LLFace::TEXTURE_ANIM); + type = LLDrawPool::POOL_SIMPLE; } - } + facep->setPoolType(type); - if (type == LLDrawPool::POOL_ALPHA) - { - if (facep->canRenderAsMask()) - { //can be treated as alpha mask - simple_faces.push_back(facep); - } - else + if (vobj->isHUDAttachment()) { - drawablep->setState(LLDrawable::HAS_ALPHA); - alpha_faces.push_back(facep); + facep->setState(LLFace::FULLBRIGHT); } - } - else - { - if (drawablep->isState(LLDrawable::REBUILD_VOLUME)) + + if (vobj->mTextureAnimp && vobj->mTexAnimMode) { - facep->mLastUpdateTime = gFrameTimeSeconds; + if (vobj->mTextureAnimp->mFace <= -1) + { + S32 face; + for (face = 0; face < vobj->getNumTEs(); face++) + { + LLFace * facep = drawablep->getFace(face); + if (facep) + { + facep->setState(LLFace::TEXTURE_ANIM); + } + } + } + else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs()) + { + LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace); + if (facep) + { + facep->setState(LLFace::TEXTURE_ANIM); + } + } } - if (gPipeline.canUseWindLightShadersOnObjects() - && LLPipeline::sRenderBump) + if (type == LLDrawPool::POOL_ALPHA) { - if (te->getBumpmap()) - { //needs normal + binormal - bump_faces.push_back(facep); - } - else if (te->getShiny() || !te->getFullbright()) - { //needs normal + if (facep->canRenderAsMask()) + { //can be treated as alpha mask simple_faces.push_back(facep); } - else - { //doesn't need normal - facep->setState(LLFace::FULLBRIGHT); - fullbright_faces.push_back(facep); + else + { + if (te->getColor().mV[3] > 0.f) + { //only treat as alpha in the pipeline if < 100% transparent + drawablep->setState(LLDrawable::HAS_ALPHA); + } + alpha_faces.push_back(facep); } } else { - if (te->getBumpmap() && LLPipeline::sRenderBump) - { //needs normal + binormal - bump_faces.push_back(facep); + if (drawablep->isState(LLDrawable::REBUILD_VOLUME)) + { + facep->mLastUpdateTime = gFrameTimeSeconds; } - else if ((te->getShiny() && LLPipeline::sRenderBump) || - !(te->getFullbright() || bake_sunlight)) - { //needs normal - simple_faces.push_back(facep); + + if (gPipeline.canUseWindLightShadersOnObjects() + && LLPipeline::sRenderBump) + { + if (te->getBumpmap()) + { //needs normal + binormal + bump_faces.push_back(facep); + } + else if (te->getShiny() || !te->getFullbright()) + { //needs normal + simple_faces.push_back(facep); + } + else + { //doesn't need normal + facep->setState(LLFace::FULLBRIGHT); + fullbright_faces.push_back(facep); + } } - else - { //doesn't need normal - facep->setState(LLFace::FULLBRIGHT); - fullbright_faces.push_back(facep); + else + { + if (te->getBumpmap() && LLPipeline::sRenderBump) + { //needs normal + binormal + bump_faces.push_back(facep); + } + else if ((te->getShiny() && LLPipeline::sRenderBump) || + !(te->getFullbright() || bake_sunlight)) + { //needs normal + simple_faces.push_back(facep); + } + else + { //doesn't need normal + facep->setState(LLFace::FULLBRIGHT); + fullbright_faces.push_back(facep); + } } } } + else + { //face has no renderable geometry + facep->clearVertexBuffer(); + } } - else - { //face has no renderable geometry - facep->clearVertexBuffer(); - } - } - if (is_rigged) - { - drawablep->setState(LLDrawable::RIGGED); - } - else - { - drawablep->clearState(LLDrawable::RIGGED); + if (is_rigged) + { + drawablep->setState(LLDrawable::RIGGED); + } + else + { + drawablep->clearState(LLDrawable::RIGGED); + } } } @@ -4493,7 +4646,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (!LLPipeline::sDelayVBUpdate) { //drawables have been rebuilt, clear rebuild status - for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { LLDrawable* drawablep = *drawable_iter; drawablep->clearState(LLDrawable::REBUILD_ALL); @@ -4510,33 +4663,43 @@ 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"); -static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM_PARTIAL("Terse Rebuild"); void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { llassert(group); if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY)) { - LLFastTimer tm(FTM_VOLUME_GEOM); + LLFastTimer ftm(FTM_REBUILD_VOLUME_VB); + LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers + S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ; group->mBuilt = 1.f; std::set<LLVertexBuffer*> mapped_buffers; - for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL); LLDrawable* drawablep = *drawable_iter; - if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) ) + if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) { LLVOVolume* vobj = drawablep->getVOVolume(); vobj->preRebuild(); + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(true); + } + LLVolume* volume = vobj->getVolume(); for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { @@ -4546,8 +4709,15 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) LLVertexBuffer* buff = face->getVertexBuffer(); if (buff) { - face->getGeometryVolume(*volume, face->getTEOffset(), - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); + llassert(!face->isState(LLFace::RIGGED)); + + if (!face->getGeometryVolume(*volume, face->getTEOffset(), + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) + { //something's gone wrong with the vertex buffer accounting, rebuild this group + group->dirtyGeom(); + gPipeline.markRebuild(group, TRUE); + } + if (buff->isLocked()) { @@ -4556,6 +4726,12 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) } } } + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(); + } + drawablep->clearState(LLDrawable::REBUILD_ALL); } @@ -4578,16 +4754,19 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) if(num_mapped_veretx_buffer != LLVertexBuffer::sMappedCount) { llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ; - for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { LLDrawable* drawablep = *drawable_iter; for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { LLFace* face = drawablep->getFace(i); - LLVertexBuffer* buff = face->getVertexBuffer(); - if (face && buff && buff->isLocked()) + if (face) { - buff->flush(); + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff && buff->isLocked()) + { + buff->flush(); + } } } } @@ -4596,7 +4775,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } - llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO)); +// llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO)); } struct CompareBatchBreakerModified @@ -4622,21 +4801,49 @@ struct CompareBatchBreakerModified } }; +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_SORT("Draw Info Face Sort"); +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FACE_SIZE("Face Sizing"); +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_ALLOCATE("Allocate VB"); +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FIND_VB("Find VB"); +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB"); + + + + + void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures) { + LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); + + U32 buffer_usage = group->mBufferUsage; + +#if LL_DARWIN + // HACK from Leslie: + // Disable VBO usage for alpha on Mac OS X because it kills the framerate + // due to implicit calls to glTexSubImage that are beyond our control. + // (this works because the only calls here that sort by distance are alpha) + if (distance_sort) + { + buffer_usage = 0x0; + } +#endif + //calculate maximum number of vertices to store in a single buffer U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); - if (!distance_sort) { - //sort faces by things that break batches - std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified()); - } - else - { - //sort faces by distance - std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater()); + LLFastTimer t(FTM_GEN_DRAW_INFO_SORT); + if (!distance_sort) + { + //sort faces by things that break batches + std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified()); + } + else + { + //sort faces by distance + std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater()); + } } bool hud_group = group->isHUDGroup() ; @@ -4652,11 +4859,11 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: buffer_index = -1; } - S32 texture_index_channels = LLGLSLShader::sIndexedTextureChannels-1; //always reserve one for shiny for now just for simplicity + S32 texture_index_channels = 1; - if (gGLManager.mGLVersion < 3.1f) + if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) { - texture_index_channels = 1; + texture_index_channels = LLGLSLShader::sIndexedTextureChannels-1; //always reserve one for shiny for now just for simplicity; } if (LLPipeline::sRenderDeferred && distance_sort) @@ -4701,57 +4908,88 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: std::vector<LLViewerTexture*> texture_list; - if (batch_textures) { - U8 cur_tex = 0; - facep->setTextureIndex(cur_tex); - texture_list.push_back(tex); - - //if (can_batch_texture(facep)) + LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE); + if (batch_textures) { - while (i != faces.end()) - { - facep = *i; - if (facep->getTexture() != tex) + U8 cur_tex = 0; + facep->setTextureIndex(cur_tex); + texture_list.push_back(tex); + + if (can_batch_texture(facep)) + { //populate texture_list with any textures that can be batched + //move i to the next unbatchable face + while (i != faces.end()) { - if (distance_sort) - { //textures might be out of order, see if texture exists in current batch - bool found = false; - for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx) - { - if (facep->getTexture() == texture_list[tex_idx]) + facep = *i; + + if (!can_batch_texture(facep)) + { //face is bump mapped or has an animated texture matrix -- can't + //batch more than 1 texture at a time + break; + } + + if (facep->getTexture() != tex) + { + if (distance_sort) + { //textures might be out of order, see if texture exists in current batch + bool found = false; + for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx) { - cur_tex = tex_idx; - found = true; - break; + if (facep->getTexture() == texture_list[tex_idx]) + { + cur_tex = tex_idx; + found = true; + break; + } } - } - if (!found) + if (!found) + { + cur_tex = texture_list.size(); + } + } + else { - cur_tex = texture_list.size(); + cur_tex++; } - } - else - { - cur_tex++; - } - if (!can_batch_texture(facep)) - { //face is bump mapped or has an animated texture matrix -- can't - //batch more than 1 texture at a time - break; + if (cur_tex >= texture_index_channels) + { //cut batches when index channels are depleted + break; + } + + tex = facep->getTexture(); + + texture_list.push_back(tex); } - if (cur_tex >= texture_index_channels) - { //cut batches when index channels are depleted + if (geom_count + facep->getGeomCount() > max_vertices) + { //cut batches on geom count too big break; } - tex = facep->getTexture(); + ++i; + index_count += facep->getIndicesCount(); + geom_count += facep->getGeomCount(); - texture_list.push_back(tex); + facep->setTextureIndex(cur_tex); } + } + + tex = texture_list[0]; + } + else + { + while (i != faces.end() && + (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) + { + facep = *i; + + + //face has no texture index + facep->mDrawInfo = NULL; + facep->setTextureIndex(255); if (geom_count + facep->getGeomCount() > max_vertices) { //cut batches on geom count too big @@ -4761,68 +4999,21 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: ++i; index_count += facep->getIndicesCount(); geom_count += facep->getGeomCount(); - - facep->setTextureIndex(cur_tex); } } - - tex = texture_list[0]; } - else - { - while (i != faces.end() && - (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) - { - facep = *i; - - //face has no texture index - facep->mDrawInfo = NULL; - facep->setTextureIndex(255); - - if (geom_count + facep->getGeomCount() > max_vertices) - { //cut batches on geom count too big - break; - } - - ++i; - index_count += facep->getIndicesCount(); - geom_count += facep->getGeomCount(); - } - } - - //create/delete/resize vertex buffer if needed + //create vertex buffer LLVertexBuffer* buffer = NULL; - 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()) - { - buffer = found_iter->second[buffer_index]; - } - } - - if (!buffer) - { //create new buffer if needed - buffer = createVertexBuffer(mask, - group->mBufferUsage); + LLFastTimer t(FTM_GEN_DRAW_INFO_ALLOCATE); + buffer = createVertexBuffer(mask, buffer_usage); buffer->allocateBuffer(geom_count, index_count, TRUE); } - else - { //resize pre-existing buffer - if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != group->mBufferUsage || - buffer->getTypeMask() != mask) - { - buffer = createVertexBuffer(mask, - group->mBufferUsage); - buffer->allocateBuffer(geom_count, index_count, TRUE); - } - else - { - buffer->resizeBuffer(geom_count, index_count); - } - } + + group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize(); + buffer_map[mask][*face_iter].push_back(buffer); @@ -4853,10 +5044,25 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: LLVOVolume* vobj = drawablep->getVOVolume(); LLVolume* volume = vobj->getVolume(); + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(true); + } + U32 te_idx = facep->getTEOffset(); - facep->getGeometryVolume(*volume, te_idx, - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset); + llassert(!facep->isState(LLFace::RIGGED)); + + if (!facep->getGeometryVolume(*volume, te_idx, + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true)) + { + llwarns << "Failed to get geometry for face!" << llendl; + } + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(false); + } } } @@ -4873,6 +5079,11 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: fullbright = TRUE; } + if (hud_group) + { //all hud attachments are fullbright + fullbright = TRUE; + } + const LLTextureEntry* te = facep->getTextureEntry(); tex = facep->getTexture(); @@ -4881,7 +5092,11 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: if (is_alpha) { // can we safely treat this as an alpha mask? - if (facep->canRenderAsMask()) + if (facep->getFaceColor().mV[3] <= 0.f) + { //100% transparent, don't render unless we're highlighting transparent + registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE); + } + else if (facep->canRenderAsMask()) { if (te->getFullbright() || LLPipeline::sNoAlpha) { @@ -4896,14 +5111,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: { registerFace(group, facep, LLRenderPass::PASS_ALPHA); } - - if (LLPipeline::sRenderDeferred) - { - registerFace(group, facep, LLRenderPass::PASS_ALPHA_SHADOW); - } } else if (gPipeline.canUseVertexShaders() - && group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD && LLPipeline::sRenderBump && te->getShiny()) { //shiny @@ -4968,9 +5177,12 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } } - //not sure why this is here -- shiny HUD attachments maybe? -- davep 5/11/2010 - if (!is_alpha && te->getShiny() && LLPipeline::sRenderBump) - { + + if (!gPipeline.canUseVertexShaders() && + !is_alpha && + te->getShiny() && + LLPipeline::sRenderBump) + { //shiny as an extra pass when shaders are disabled registerFace(group, facep, LLRenderPass::PASS_SHINY); } } @@ -5014,7 +5226,8 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun mFaceList.clear(); //for each drawable - for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) + + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { LLDrawable* drawablep = *drawable_iter; @@ -5034,17 +5247,21 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun //sum up face verts and indices drawablep->updateFaceSize(i); LLFace* facep = drawablep->getFace(i); - if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) - { - vertex_count += facep->getGeomCount(); - index_count += facep->getIndicesCount(); - llassert(facep->getIndicesCount() < 65536); - //remember face (for sorting) - mFaceList.push_back(facep); - } - else + if (facep) { - facep->clearVertexBuffer(); + if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA && + facep->getGeomCount() + vertex_count <= 65536) + { + vertex_count += facep->getGeomCount(); + index_count += facep->getIndicesCount(); + + //remember face (for sorting) + mFaceList.push_back(facep); + } + else + { + facep->clearVertexBuffer(); + } } } } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 64457975f8..5482c80f2b 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -68,7 +68,7 @@ class LLVolumeInterface public: virtual ~LLVolumeInterface() { } virtual LLVolumeInterfaceType getInterfaceType() const = 0; - virtual BOOL doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) = 0; + virtual void doIdleUpdate() = 0; virtual BOOL doUpdateGeometry(LLDrawable *drawable) = 0; virtual LLVector3 getPivotPosition() const = 0; virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0; @@ -79,7 +79,7 @@ public: virtual bool isVolumeGlobal() const = 0; // Are we in global space? virtual bool isActive() const = 0; // Is this object currently active? virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const = 0; - virtual void updateRelativeXform() = 0; + virtual void updateRelativeXform(bool force_identity = false) = 0; virtual U32 getID() const = 0; virtual void preRebuild() = 0; }; @@ -114,8 +114,7 @@ public: void deleteFaces(); void animateTextures(); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); - + BOOL isVisible() const ; /*virtual*/ BOOL isActive() const; /*virtual*/ BOOL isAttachment() const; @@ -131,7 +130,8 @@ public: /*virtual*/ const LLMatrix4 getRenderMatrix() const; typedef std::map<LLUUID, S32> texture_cost_t; U32 getRenderCost(texture_cost_t &textures) const; - /*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL, F32* unscaled_value = NULL) const; + F32 getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_value) const; + /*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL) { return getStreamingCost(bytes, visible_bytes, NULL); } /*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const; /*virtual*/ U32 getHighLODTriangleCount(); @@ -173,6 +173,7 @@ public: /*virtual*/ void setScale(const LLVector3 &scale, BOOL damped); + /*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) ; /*virtual*/ void setNumTEs(const U8 num_tes); /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep); /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid); @@ -202,7 +203,7 @@ public: LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status); - void updateRelativeXform(); + void updateRelativeXform(bool force_identity = false); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ void updateFaceSize(S32 idx); /*virtual*/ BOOL updateLOD(); @@ -339,7 +340,8 @@ public: U8 mTexAnimMode; private: friend class LLDrawable; - + friend class LLFace; + BOOL mFaceMappingChanged; LLFrameTimer mTextureUpdateTimer; S32 mLOD; diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 7df50ec815..e8a1c3d1d6 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -100,17 +100,8 @@ void LLVOWater::updateTextures() } // Never gets called -BOOL LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - /*if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER))) - { - return TRUE; - } - if (mDrawable) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); - }*/ - return TRUE; } LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline) @@ -146,6 +137,10 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) drawable->addFace(poolp, NULL); } face = drawable->getFace(0); + if (!face) + { + return TRUE; + } // LLVector2 uvs[4]; // LLVector3 vtx[4]; @@ -160,14 +155,14 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) static const unsigned int vertices_per_quad = 4; static const unsigned int indices_per_quad = 6; - const S32 size = gSavedSettings.getBOOL("RenderTransparentWater") && !LLGLSLShader::sNoFixedFunction ? 16 : 1; + const S32 size = gSavedSettings.getBOOL("RenderTransparentWater") && LLGLSLShader::sNoFixedFunction ? 16 : 1; const S32 num_quads = size * size; face->setSize(vertices_per_quad * num_quads, 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); @@ -197,6 +192,13 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) F32 size_inv = 1.f / size; + F32 z_fudge = 0.f; + + if (getIsEdgePatch()) + { //bump edge patches down 10 cm to prevent aliasing along edges + z_fudge = -0.1f; + } + for (y = 0; y < size; y++) { for (x = 0; x < size; x++) @@ -205,6 +207,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) position_agent = getPositionAgent() - getScale() * 0.5f; position_agent.mV[VX] += (x + 0.5f) * step_x; position_agent.mV[VY] += (y + 0.5f) * step_y; + position_agent.mV[VZ] += z_fudge; *verticesp++ = position_agent - right + up; *verticesp++ = position_agent - right - up; diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h index ed709dd840..cf9323ef2e 100644 --- a/indra/newview/llvowater.h +++ b/indra/newview/llvowater.h @@ -58,7 +58,7 @@ public: static void initClass(); static void cleanupClass(); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index f1c5499d84..7f17fd3e56 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -92,9 +92,9 @@ void LLVOWLSky::initSunDirection(LLVector3 const & sun_direction, { } -BOOL LLVOWLSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOWLSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - return TRUE; + } BOOL LLVOWLSky::isActive(void) const @@ -301,7 +301,7 @@ void LLVOWLSky::restoreGL() gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); } -static LLFastTimer::DeclareTimer FTM_GEO_SKY("Sky Geometry"); +static LLFastTimer::DeclareTimer FTM_GEO_SKY("Windlight Sky Geometry"); BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) { @@ -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/llvowlsky.h b/indra/newview/llvowlsky.h index 825e13a203..729dced15e 100644 --- a/indra/newview/llvowlsky.h +++ b/indra/newview/llvowlsky.h @@ -53,7 +53,7 @@ public: void initSunDirection(LLVector3 const & sun_direction, LLVector3 const & sun_angular_velocity); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ BOOL isActive(void) const; /*virtual*/ LLDrawable * createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 20b34637b8..4f52ff9778 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -100,7 +100,7 @@ void LLWaterParamManager::loadPresetsFromDir(const std::string& dir) break; // no more files } - std::string path = dir + file; + std::string path = gDirUtilp->add(dir, file); if (!loadPreset(path)) { llwarns << "Error loading water preset from " << path << llendl; @@ -194,7 +194,7 @@ void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader) shader->uniform4fv("waterPlane", 1, mWaterPlane.mV); shader->uniform1f("waterFogDensity", getFogDensity()); shader->uniform1f("waterFogKS", mWaterFogKS); - shader->uniform4f("distance_multiplier", 0, 0, 0, 0); + shader->uniform1f("distance_multiplier", 0); } } diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index d8aa0b7d5c..402504933c 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -221,7 +221,7 @@ void LLWearable::createVisualParams() param->resetDrivenParams(); if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false)) { - if( !param->linkDrivenParams(boost::bind(avatar_function,gAgentAvatarp,_1 ), true)) + if( !param->linkDrivenParams(boost::bind(avatar_function,gAgentAvatarp.get(),_1 ), true)) { llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl; continue; @@ -810,6 +810,20 @@ const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const return NULL; } +std::vector<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq() +{ + std::vector<LLLocalTextureObject*> result; + + for(te_map_t::const_iterator iter = mTEMap.begin(); + iter != mTEMap.end(); iter++) + { + LLLocalTextureObject* lto = iter->second; + result.push_back(lto); + } + + return result; +} + void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject <o) { if( mTEMap.find(index) != mTEMap.end() ) diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h index fd614ade64..3d8c53a755 100644 --- a/indra/newview/llwearable.h +++ b/indra/newview/llwearable.h @@ -106,6 +106,7 @@ public: LLLocalTextureObject* getLocalTextureObject(S32 index); const LLLocalTextureObject* getLocalTextureObject(S32 index) const; + std::vector<LLLocalTextureObject*> getLocalTextureListSeq(); void setLocalTextureObject(S32 index, LLLocalTextureObject <o); void addVisualParam(LLVisualParam *param); 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/llweb.cpp b/indra/newview/llweb.cpp index d2d48dc68f..83337b386d 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -185,8 +185,8 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url, substitution["VERSION_PATCH"] = LLVersionInfo::getPatch(); substitution["VERSION_BUILD"] = LLVersionInfo::getBuild(); substitution["CHANNEL"] = LLVersionInfo::getChannel(); - substitution["GRID"] = LLGridManager::getInstance()->getGridLabel(); - substitution["GRID_LOWERCASE"] = utf8str_tolower(LLGridManager::getInstance()->getGridLabel()); + substitution["GRID"] = LLGridManager::getInstance()->getGridId(); + substitution["GRID_LOWERCASE"] = utf8str_tolower(LLGridManager::getInstance()->getGridId()); substitution["OS"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple(); substitution["SESSION_ID"] = gAgent.getSessionID(); substitution["FIRST_LOGIN"] = gAgent.isFirstLogin(); diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp index 2425b96678..be3e3ff30e 100644 --- a/indra/newview/llwlhandlers.cpp +++ b/indra/newview/llwlhandlers.cpp @@ -105,10 +105,16 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder() return; } - if (unvalidated_content[0]["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) + LLUUID regionId; + if( gAgent.getRegion() ) + { + regionId = gAgent.getRegion()->getRegionID(); + } + + if (unvalidated_content[0]["regionID"].asUUID() != regionId ) { LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting " - << gAgent.getRegion()->getRegionID() << " but got " << unvalidated_content[0]["regionID"].asUUID() + << regionId << " but got " << unvalidated_content[0]["regionID"].asUUID() << ") - ignoring..." << LL_ENDL; return; } diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index 55608a059f..6077208799 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -64,7 +64,6 @@ LLWLParamManager::LLWLParamManager() : //set the defaults for the controls - // index is from sWLUniforms in pipeline.cpp line 979 /// Sun Delta Terrain tweak variables. mSunDeltaYaw(180.0f), @@ -72,10 +71,10 @@ LLWLParamManager::LLWLParamManager() : mWLGamma(1.0f, "gamma"), mBlueHorizon(0.25f, 0.25f, 1.0f, 1.0f, "blue_horizon", "WLBlueHorizon"), - mHazeDensity(1.0f, 1.0f, 1.0f, 0.5f, "haze_density"), + mHazeDensity(1.0f, "haze_density"), mBlueDensity(0.25f, 0.25f, 0.25f, 1.0f, "blue_density", "WLBlueDensity"), mDensityMult(1.0f, "density_multiplier", 1000), - mHazeHorizon(1.0f, 1.0f, 1.0f, 0.5f, "haze_horizon"), + mHazeHorizon(1.0f, "haze_horizon"), mMaxAlt(4000.0f, "max_y"), // Lighting @@ -284,7 +283,7 @@ void LLWLParamManager::loadPresetsFromDir(const std::string& dir) break; // no more files } - std::string path = dir + file; + std::string path = gDirUtilp->add(dir, file); if (!loadPreset(path)) { llwarns << "Error loading sky preset from " << path << llendl; diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h index bc984b9126..72422500fc 100644 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -102,9 +102,8 @@ struct WLFloatControl { { } - inline WLFloatControl & operator = (LLVector4 const & val) { - x = val.mV[0]; - + inline WLFloatControl & operator = (F32 val) { + x = val; return *this; } @@ -340,10 +339,10 @@ public: /// Atmospherics WLColorControl mBlueHorizon; - WLColorControl mHazeDensity; + WLFloatControl mHazeDensity; WLColorControl mBlueDensity; WLFloatControl mDensityMult; - WLColorControl mHazeHorizon; + WLFloatControl mHazeHorizon; WLFloatControl mMaxAlt; /// Lighting diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp index 5bb7025031..b04d30db55 100644 --- a/indra/newview/llwlparamset.cpp +++ b/indra/newview/llwlparamset.cpp @@ -41,33 +41,7 @@ LLWLParamSet::LLWLParamSet(void) : mName("Unnamed Preset"), mCloudScrollXOffset(0.f), mCloudScrollYOffset(0.f) -{ -/* REMOVE or init the LLSD - const std::map<std::string, LLVector4>::value_type hardcodedPreset[] = { - std::make_pair("lightnorm", LLVector4(0.f, 0.707f, -0.707f, 0.f)), - std::make_pair("sunlight_color", LLVector4(0.6f, 0.6f, 2.83f, 2.27f)), - std::make_pair("ambient", LLVector4(0.27f, 0.33f, 0.44f, 1.19f)), - std::make_pair("blue_horizon", LLVector4(0.3f, 0.4f, 0.9f, 1.f)), - std::make_pair("blue_density", LLVector4(0.3f, 0.4f, 0.8f, 1.f)), - std::make_pair("haze_horizon", LLVector4(0.6f, 0.6f, 0.6f, 1.f)), - std::make_pair("haze_density", LLVector4(0.3f, 0.3f, 0.3f, 1.f)), - std::make_pair("cloud_shadow", LLVector4(0.f, 0.f, 0.f, 0.f)), - std::make_pair("density_multiplier", LLVector4(0.001f, 0.001f, 0.001f, 0.001f)), - std::make_pair("distance_multiplier", LLVector4(1.f, 1.f, 1.f, 1.f)), - std::make_pair("max_y", LLVector4(600.f, 600.f, 600.f, 0.f)), - std::make_pair("glow", LLVector4(15.f, 0.001f, -0.03125f, 0.f)), - std::make_pair("cloud_color", LLVector4(0.0f, 0.0f, 0.0f, 0.0f)), - std::make_pair("cloud_pos_density1", LLVector4(0.f, 0.f, 0.f, 1.f)), - std::make_pair("cloud_pos_density2", LLVector4(0.f, 0.f, 0.f, 1.f)), - std::make_pair("cloud_scale", LLVector4(0.42f, 0.f, 0.f, 1.f)), - std::make_pair("gamma", LLVector4(2.0f, 2.0f, 2.0f, 0.0f)), - }; - std::map<std::string, LLVector4>::value_type const * endHardcodedPreset = - hardcodedPreset + LL_ARRAY_SIZE(hardcodedPreset); - - mParamValues.insert(hardcodedPreset, endHardcodedPreset); -*/ -} +{} static LLFastTimer::DeclareTimer FTM_WL_PARAM_UPDATE("WL Param Update"); @@ -79,55 +53,78 @@ void LLWLParamSet::update(LLGLSLShader * shader) const i != mParamValues.endMap(); ++i) { - - const std::string& param = i->first; - if( param == "star_brightness" || param == "preset_num" || param == "sun_angle" || + if (param == "star_brightness" || param == "preset_num" || param == "sun_angle" || param == "east_angle" || param == "enable_cloud_scroll" || param == "cloud_scroll_rate" || param == "lightnorm" ) { continue; } - if(param == "cloud_pos_density1") + if (param == "cloud_pos_density1") { LLVector4 val; val.mV[0] = F32(i->second[0].asReal()) + mCloudScrollXOffset; val.mV[1] = F32(i->second[1].asReal()) + mCloudScrollYOffset; val.mV[2] = (F32) i->second[2].asReal(); val.mV[3] = (F32) i->second[3].asReal(); + stop_glerror(); shader->uniform4fv(param, 1, val.mV); stop_glerror(); - } + } + else if (param == "cloud_scale" || param == "cloud_shadow" || + param == "density_multiplier" || param == "distance_multiplier" || + param == "haze_density" || param == "haze_horizon" || + param == "max_y" ) + { + F32 val = (F32) i->second[0].asReal(); + + stop_glerror(); + shader->uniform1f(param, val); + stop_glerror(); + } else // param is the uniform name { - LLVector4 val; - // handle all the different cases - if(i->second.isArray() && i->second.size() == 4) + if (i->second.isArray() && i->second.size() == 4) { + LLVector4 val; + val.mV[0] = (F32) i->second[0].asReal(); val.mV[1] = (F32) i->second[1].asReal(); val.mV[2] = (F32) i->second[2].asReal(); val.mV[3] = (F32) i->second[3].asReal(); + + stop_glerror(); + shader->uniform4fv(param, 1, val.mV); + stop_glerror(); } - else if(i->second.isReal()) + else if (i->second.isReal()) { - val.mV[0] = (F32) i->second.asReal(); + F32 val = (F32) i->second.asReal(); + + stop_glerror(); + shader->uniform1f(param, val); + stop_glerror(); } - else if(i->second.isInteger()) + else if (i->second.isInteger()) { - val.mV[0] = (F32) i->second.asReal(); + S32 val = (S32) i->second.asInteger(); + + stop_glerror(); + shader->uniform1i(param, val); + stop_glerror(); } - else if(i->second.isBoolean()) + else if (i->second.isBoolean()) { - val.mV[0] = i->second.asBoolean(); + S32 val = (i->second.asBoolean() ? 1 : 0); + + stop_glerror(); + shader->uniform1i(param, val); + stop_glerror(); } - stop_glerror(); - shader->uniform4fv(param, 1, val.mV); - stop_glerror(); } } } @@ -148,7 +145,8 @@ void LLWLParamSet::set(const std::string& paramName, float x) } } -void LLWLParamSet::set(const std::string& paramName, float x, float y) { +void LLWLParamSet::set(const std::string& paramName, float x, float y) +{ mParamValues[paramName][0] = x; mParamValues[paramName][1] = y; } @@ -194,7 +192,6 @@ void LLWLParamSet::set(const std::string& paramName, const LLColor4 & val) LLVector4 LLWLParamSet::getVector(const std::string& paramName, bool& error) { - // test to see if right type LLSD cur_val = mParamValues.get(paramName); if (!cur_val.isArray()) @@ -215,7 +212,6 @@ LLVector4 LLWLParamSet::getVector(const std::string& paramName, bool& error) F32 LLWLParamSet::getFloat(const std::string& paramName, bool& error) { - // test to see if right type LLSD cur_val = mParamValues.get(paramName); if (cur_val.isArray() && cur_val.size() != 0) @@ -234,8 +230,6 @@ F32 LLWLParamSet::getFloat(const std::string& paramName, bool& error) return 0; } - - void LLWLParamSet::setSunAngle(float val) { // keep range 0 - 2pi @@ -263,7 +257,6 @@ void LLWLParamSet::setEastAngle(float val) mParamValues["east_angle"] = val; } - void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight) { // set up the iterators @@ -282,7 +275,6 @@ void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight) // Iterate through values for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter) { - // If param exists in both src and dest, set the holder variables, otherwise skip if(src.mParamValues.has(iter->first) && dest.mParamValues.has(iter->first)) { diff --git a/indra/newview/llwlparamset.h b/indra/newview/llwlparamset.h index 3c44ed3bb8..b087119dd5 100644 --- a/indra/newview/llwlparamset.h +++ b/indra/newview/llwlparamset.h @@ -110,7 +110,7 @@ public: /// \param error A flag to set if it's not the proper return type LLVector4 getVector(const std::string& paramName, bool& error); - /// Get an integer parameter + /// Get a float parameter /// \param paramName The name of the parameter to set. /// \param error A flag to set if it's not the proper return type F32 getFloat(const std::string& paramName, bool& error); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 6f6e0d2334..793becf0c8 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -138,7 +138,6 @@ void LLWorld::destroyClass() LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host) { - LLMemType mt(LLMemType::MTYPE_REGIONS); llinfos << "Add region with handle: " << region_handle << " on host " << host << llendl; LLViewerRegion *regionp = getRegionFromHandle(region_handle); if (regionp) @@ -644,7 +643,6 @@ void LLWorld::updateVisibilities() void LLWorld::updateRegions(F32 max_update_time) { - LLMemType mt_ur(LLMemType::MTYPE_IDLE_UPDATE_REGIONS); LLTimer update_timer; BOOL did_one = FALSE; @@ -657,7 +655,10 @@ void LLWorld::updateRegions(F32 max_update_time) if (did_one && max_time <= 0.f) break; max_time = llmin(max_time, max_update_time*.1f); - did_one |= regionp->idleUpdate(max_update_time); + if (regionp->idleUpdate(max_update_time)) + { + did_one = TRUE; + } } } @@ -818,14 +819,11 @@ void LLWorld::updateWaterObjects() max_x = (S32)region_x + range; max_y = (S32)region_y + range; - F32 height = 0.f; - for (region_list_t::iterator iter = mRegionList.begin(); iter != mRegionList.end(); ++iter) { LLViewerRegion* regionp = *iter; LLVOWater* waterp = regionp->getLand().getWaterObj(); - height += regionp->getWaterHeight(); if (waterp) { gObjectList.updateActive(waterp); @@ -840,6 +838,9 @@ void LLWorld::updateWaterObjects() } mHoleWaterObjects.clear(); + // Use the water height of the region we're on for areas where there is no region + F32 water_height = gAgent.getRegion()->getWaterHeight(); + // Now, get a list of the holes S32 x, y; for (x = min_x; x <= max_x; x += rwidth) @@ -848,12 +849,12 @@ void LLWorld::updateWaterObjects() { U64 region_handle = to_region_handle(x, y); if (!getRegionFromHandle(region_handle)) - { + { // No region at that area, so make water LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion()); waterp->setUseTexture(FALSE); waterp->setPositionGlobal(LLVector3d(x + rwidth/2, y + rwidth/2, - 256.f+DEFAULT_WATER_HEIGHT)); + 256.f + water_height)); waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f)); gPipeline.createObject(waterp); mHoleWaterObjects.push_back(waterp); @@ -910,8 +911,7 @@ void LLWorld::updateWaterObjects() } waterp->setRegion(gAgent.getRegion()); - LLVector3d water_pos(water_center_x, water_center_y, - DEFAULT_WATER_HEIGHT+256.f); + LLVector3d water_pos(water_center_x, water_center_y, 256.f + water_height) ; LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f); //stretch out to horizon @@ -1164,24 +1164,13 @@ void send_agent_resume() static LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& region_origin) { - LLVector3d pos_global; - LLVector3 pos_local; - U8 bits; + LLVector3d pos_local; - bits = compact_local & 0xFF; - pos_local.mV[VZ] = F32(bits) * 4.f; - compact_local >>= 8; + pos_local.mdV[VZ] = (compact_local & 0xFFU) * 4; + pos_local.mdV[VY] = (compact_local >> 8) & 0xFFU; + pos_local.mdV[VX] = (compact_local >> 16) & 0xFFU; - bits = compact_local & 0xFF; - pos_local.mV[VY] = (F32)bits; - compact_local >>= 8; - - bits = compact_local & 0xFF; - pos_local.mV[VX] = (F32)bits; - - pos_global.setVec( pos_local ); - pos_global += region_origin; - return pos_global; + return region_origin + pos_local; } void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positions, const LLVector3d& relative_to, F32 radius) const @@ -1202,22 +1191,22 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi iter != LLCharacter::sInstances.end(); ++iter) { LLVOAvatar* pVOAvatar = (LLVOAvatar*) *iter; - if(!pVOAvatar->isDead() && !pVOAvatar->isSelf()) + + if (!pVOAvatar->isDead() && !pVOAvatar->mIsDummy) { + LLVector3d pos_global = pVOAvatar->getPositionGlobal(); LLUUID uuid = pVOAvatar->getID(); - if(!uuid.isNull()) + + if (!uuid.isNull() + && dist_vec_squared(pos_global, relative_to) <= radius_squared) { - LLVector3d pos_global = pVOAvatar->getPositionGlobal(); - if(dist_vec_squared(pos_global, relative_to) <= radius_squared) + if(positions != NULL) { - if(positions != NULL) - { - positions->push_back(pos_global); - } - if(avatar_ids !=NULL) - { - avatar_ids->push_back(uuid); - } + positions->push_back(pos_global); + } + if(avatar_ids !=NULL) + { + avatar_ids->push_back(uuid); } } } @@ -1236,9 +1225,9 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi { LLUUID uuid = regionp->mMapAvatarIDs.get(i); // if this avatar doesn't already exist in the list, add it - if(uuid.notNull() && avatar_ids!=NULL && std::find(avatar_ids->begin(), avatar_ids->end(), uuid) == avatar_ids->end()) + if(uuid.notNull() && avatar_ids != NULL && std::find(avatar_ids->begin(), avatar_ids->end(), uuid) == avatar_ids->end()) { - if(positions != NULL) + if (positions != NULL) { positions->push_back(pos_global); } @@ -1249,6 +1238,11 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi } } +bool LLWorld::isRegionListed(const LLViewerRegion* region) const +{ + region_list_t::const_iterator it = find(mRegionList.begin(), mRegionList.end(), region); + return it != mRegionList.end(); +} LLHTTPRegistration<LLEstablishAgentCommunication> gHTTPRegistrationEstablishAgentCommunication( diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index d8ab4bc508..f350009d10 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -157,6 +157,11 @@ public: std::vector<LLVector3d>* positions = NULL, const LLVector3d& relative_to = LLVector3d(), F32 radius = FLT_MAX) const; + // Returns 'true' if the region is in mRegionList, + // 'false' if the region has been removed due to region change + // or if the circuit to this simulator had been lost. + bool isRegionListed(const LLViewerRegion* region) const; + private: region_list_t mActiveRegionList; region_list_t mRegionList; diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index e50851b8e7..ccc513b80d 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -77,6 +77,7 @@ LLUIImagePtr LLWorldMapView::sAvatarYouLargeImage = NULL; LLUIImagePtr LLWorldMapView::sAvatarLevelImage = NULL; LLUIImagePtr LLWorldMapView::sAvatarAboveImage = NULL; LLUIImagePtr LLWorldMapView::sAvatarBelowImage = NULL; +LLUIImagePtr LLWorldMapView::sAvatarUnknownImage = NULL; LLUIImagePtr LLWorldMapView::sTelehubImage = NULL; LLUIImagePtr LLWorldMapView::sInfohubImage = NULL; @@ -120,6 +121,7 @@ void LLWorldMapView::initClass() sAvatarLevelImage = LLUI::getUIImage("map_avatar_32.tga"); sAvatarAboveImage = LLUI::getUIImage("map_avatar_above_32.tga"); sAvatarBelowImage = LLUI::getUIImage("map_avatar_below_32.tga"); + sAvatarUnknownImage = LLUI::getUIImage("map_avatar_unknown_32.tga"); sHomeImage = LLUI::getUIImage("map_home.tga"); sTelehubImage = LLUI::getUIImage("map_telehub.tga"); @@ -149,6 +151,7 @@ void LLWorldMapView::cleanupClass() sAvatarLevelImage = NULL; sAvatarAboveImage = NULL; sAvatarBelowImage = NULL; + sAvatarUnknownImage = NULL; sTelehubImage = NULL; sInfohubImage = NULL; @@ -513,7 +516,7 @@ void LLWorldMapView::draw() TRUE, "You are here", "", - llround(LLFontGL::getFontSansSerifSmall()->getLineHeight())); // offset vertically by one line, to avoid overlap with target tracking + LLFontGL::getFontSansSerifSmall()->getLineHeight()); // offset vertically by one line, to avoid overlap with target tracking } // Draw the current agent viewing angle @@ -992,7 +995,7 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& const S32 TEXT_PADDING = DEFAULT_TRACKING_ARROW_SIZE + 2; S32 half_text_width = llfloor(font->getWidthF32(label) * 0.5f); text_x = llclamp(text_x, half_text_width + TEXT_PADDING, getRect().getWidth() - half_text_width - TEXT_PADDING); - text_y = llclamp(text_y + vert_offset, TEXT_PADDING + vert_offset, getRect().getHeight() - llround(font->getLineHeight()) - TEXT_PADDING - vert_offset); + text_y = llclamp(text_y + vert_offset, TEXT_PADDING + vert_offset, getRect().getHeight() - font->getLineHeight() - TEXT_PADDING - vert_offset); if (label != "") { @@ -1005,7 +1008,7 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& if (tooltip != "") { - text_y -= (S32)font->getLineHeight(); + text_y -= font->getLineHeight(); font->renderUTF8( tooltip, 0, @@ -1147,17 +1150,25 @@ void LLWorldMapView::drawAvatar(F32 x_pixels, F32 y_pixels, const LLColor4& color, F32 relative_z, - F32 dot_radius) + F32 dot_radius, + bool unknown_relative_z) { const F32 HEIGHT_THRESHOLD = 7.f; LLUIImagePtr dot_image = sAvatarLevelImage; - if(relative_z < -HEIGHT_THRESHOLD) + if (unknown_relative_z) { - dot_image = sAvatarBelowImage; + dot_image = sAvatarUnknownImage; } - else if(relative_z > HEIGHT_THRESHOLD) - { - dot_image = sAvatarAboveImage; + else + { + if(relative_z < -HEIGHT_THRESHOLD) + { + dot_image = sAvatarBelowImage; + } + else if(relative_z > HEIGHT_THRESHOLD) + { + dot_image = sAvatarAboveImage; + } } S32 dot_width = llround(dot_radius * 2.f); dot_image->draw(llround(x_pixels - dot_radius), @@ -1203,7 +1214,7 @@ void LLWorldMapView::drawIconName(F32 x_pixels, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); - text_y -= llround(LLFontGL::getFontSansSerif()->getLineHeight()); + text_y -= LLFontGL::getFontSansSerif()->getLineHeight(); // render text LLFontGL::getFontSansSerif()->renderUTF8(second_line, 0, @@ -1309,7 +1320,7 @@ void LLWorldMapView::drawTrackingCircle( const LLRect& rect, S32 x, S32 y, const gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); - gGL.translatef((F32)x, (F32)y, 0.f); + gGL.translatef((F32)x * LLUI::sGLScaleFactor.mV[VX], (F32)y * LLUI::sGLScaleFactor.mV[VY], 0.f); gl_washer_segment_2d(inner_radius, outer_radius, start_theta, end_theta, 40, color, color); gGL.popMatrix(); diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h index 9ab53b1ba3..a2a6dc53fb 100644 --- a/indra/newview/llworldmapview.h +++ b/indra/newview/llworldmapview.h @@ -112,7 +112,8 @@ public: F32 y_pixels, const LLColor4& color, F32 relative_z = 0.f, - F32 dot_radius = 3.f); + F32 dot_radius = 3.f, + bool reached_max_z = false); static void drawIconName(F32 x_pixels, F32 y_pixels, const LLColor4& color, @@ -138,6 +139,7 @@ public: static LLUIImagePtr sAvatarLevelImage; static LLUIImagePtr sAvatarAboveImage; static LLUIImagePtr sAvatarBelowImage; + static LLUIImagePtr sAvatarUnknownImage; static LLUIImagePtr sTelehubImage; static LLUIImagePtr sInfohubImage; diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index f483ba5af8..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: @@ -382,19 +401,11 @@ bool LLXMLRPCTransaction::Impl::process() // continue onward } } - - //const F32 MAX_PROCESSING_TIME = 0.05f; - //LLTimer timer; - - mCurlRequest->perform(); - - /*while (mCurlRequest->perform() > 0) + + if(!mCurlRequest->wait()) { - if (timer.getElapsedTimeF32() >= MAX_PROCESSING_TIME) - { - return false; - } - }*/ + return false ; + } while(1) { diff --git a/indra/newview/macutil_Prefix.h b/indra/newview/macutil_Prefix.h index fd8e927a08..b54a764a62 100644 --- a/indra/newview/macutil_Prefix.h +++ b/indra/newview/macutil_Prefix.h @@ -33,7 +33,7 @@ */ #include <Carbon/Carbon.h> +#include "fix_macros.h" -#undef check #undef verify #undef require diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d8e271811a..9f0e2906d0 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -35,7 +35,6 @@ #include "llviewercontrol.h" #include "llfasttimer.h" #include "llfontgl.h" -#include "llmemtype.h" #include "llnamevalue.h" #include "llpointer.h" #include "llprimitive.h" @@ -51,6 +50,10 @@ // newview includes #include "llagent.h" #include "llagentcamera.h" +#include "llappviewer.h" +#include "lltexturecache.h" +#include "lltexturefetch.h" +#include "llimageworker.h" #include "lldrawable.h" #include "lldrawpoolalpha.h" #include "lldrawpoolavatar.h" @@ -104,7 +107,10 @@ #include "lltoolpie.h" #include "llcurl.h" #include "llnotifications.h" - +#include "llpathinglib.h" +#include "llfloaterpathfindingconsole.h" +#include "llfloaterpathfindingcharacters.h" +#include "llpathfindingpathtool.h" #ifdef _DEBUG // Debug indices is disabled for now for debug performance - djs 4/24/02 @@ -113,6 +119,8 @@ //#define DEBUG_INDICES #endif +bool gShiftFrame = false; + //cached settings BOOL LLPipeline::RenderAvatarVP; BOOL LLPipeline::VertexShaderEnable; @@ -187,6 +195,7 @@ F32 LLPipeline::RenderShadowFOVCutoff; BOOL LLPipeline::CameraOffset; F32 LLPipeline::CameraMaxCoF; F32 LLPipeline::CameraDoFResScale; +F32 LLPipeline::RenderAutoHideSurfaceAreaLimit; const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f; const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f; @@ -203,17 +212,13 @@ extern S32 gBoxFrame; extern BOOL gDisplaySwapBuffers; extern BOOL gDebugGL; -// hack counter for rendering a fixed number of frames after toggling -// fullscreen to work around DEV-5361 -static S32 sDelayedVBOEnable = 0; - BOOL gAvatarBacklight = FALSE; BOOL gDebugPipeline = FALSE; LLPipeline gPipeline; const LLMatrix4* gGLLastMatrix = NULL; -LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Geometry"); +LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Render Geometry"); LLFastTimer::DeclareTimer FTM_RENDER_GRASS("Grass"); LLFastTimer::DeclareTimer FTM_RENDER_INVISIBLE("Invisible"); LLFastTimer::DeclareTimer FTM_RENDER_OCCLUSION("Occlusion"); @@ -230,8 +235,13 @@ LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump"); LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright"); LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow"); LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update"); +LLFastTimer::DeclareTimer FTM_PIPELINE_CREATE("Pipeline Create"); LLFastTimer::DeclareTimer FTM_POOLRENDER("RenderPool"); LLFastTimer::DeclareTimer FTM_POOLS("Pools"); +LLFastTimer::DeclareTimer FTM_DEFERRED_POOLRENDER("RenderPool (Deferred)"); +LLFastTimer::DeclareTimer FTM_DEFERRED_POOLS("Pools (Deferred)"); +LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLRENDER("RenderPool (Post)"); +LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLS("Pools (Post)"); LLFastTimer::DeclareTimer FTM_RENDER_BLOOM_FBO("First FBO"); LLFastTimer::DeclareTimer FTM_STATESORT("Sort Draw State"); LLFastTimer::DeclareTimer FTM_PIPELINE("Pipeline"); @@ -267,6 +277,7 @@ std::string gPoolNames[] = void drawBox(const LLVector3& c, const LLVector3& r); void drawBoxOutline(const LLVector3& pos, const LLVector3& size); U32 nhpo2(U32 v); +LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage); glh::matrix4f glh_copy_matrix(F32* src) { @@ -406,11 +417,14 @@ LLPipeline::LLPipeline() : mInitialized(FALSE), mVertexShadersEnabled(FALSE), mVertexShadersLoaded(0), + mTransformFeedbackPrimitives(0), mRenderDebugFeatureMask(0), mRenderDebugMask(0), mOldRenderDebugMask(0), + mMeshDirtyQueryObject(0), mGroupQ1Locked(false), mGroupQ2Locked(false), + mResetVertexBuffers(false), mLastRebuildPool(NULL), mAlphaPool(NULL), mSkyPool(NULL), @@ -434,10 +448,21 @@ LLPipeline::LLPipeline() : mLightFunc = 0; } -void LLPipeline::init() +void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name) { - LLMemType mt(LLMemType::MTYPE_PIPELINE_INIT); + LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(name); + if ( cntrl_ptr.isNull() ) + { + llwarns << "Global setting name not found:" << name << llendl; + } + else + { + cntrl_ptr->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + } +} +void LLPipeline::init() +{ refreshCachedSettings(); gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); @@ -506,9 +531,99 @@ void LLPipeline::init() mSpotLightFade[i] = 1.f; } + if (mCubeVB.isNull()) + { + mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); + } + mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); mDeferredVB->allocateBuffer(8, 0, true); setLightingDetail(-1); + + // + // Update all settings to trigger a cached settings refresh + // + connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaDeferred"); + connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaNonDeferred"); + connectRefreshCachedSettingsSafe("RenderUseFarClip"); + connectRefreshCachedSettingsSafe("RenderAvatarMaxVisible"); + connectRefreshCachedSettingsSafe("RenderDelayVBUpdate"); + connectRefreshCachedSettingsSafe("UseOcclusion"); + connectRefreshCachedSettingsSafe("VertexShaderEnable"); + connectRefreshCachedSettingsSafe("RenderAvatarVP"); + connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders"); + connectRefreshCachedSettingsSafe("RenderDeferred"); + connectRefreshCachedSettingsSafe("RenderDeferredSunWash"); + connectRefreshCachedSettingsSafe("RenderFSAASamples"); + connectRefreshCachedSettingsSafe("RenderResolutionDivisor"); + connectRefreshCachedSettingsSafe("RenderUIBuffer"); + connectRefreshCachedSettingsSafe("RenderShadowDetail"); + connectRefreshCachedSettingsSafe("RenderDeferredSSAO"); + connectRefreshCachedSettingsSafe("RenderShadowResolutionScale"); + connectRefreshCachedSettingsSafe("RenderLocalLights"); + connectRefreshCachedSettingsSafe("RenderDelayCreation"); + connectRefreshCachedSettingsSafe("RenderAnimateRes"); + connectRefreshCachedSettingsSafe("FreezeTime"); + connectRefreshCachedSettingsSafe("DebugBeaconLineWidth"); + connectRefreshCachedSettingsSafe("RenderHighlightBrightness"); + connectRefreshCachedSettingsSafe("RenderHighlightColor"); + connectRefreshCachedSettingsSafe("RenderHighlightThickness"); + connectRefreshCachedSettingsSafe("RenderSpotLightsInNondeferred"); + connectRefreshCachedSettingsSafe("PreviewAmbientColor"); + connectRefreshCachedSettingsSafe("PreviewDiffuse0"); + connectRefreshCachedSettingsSafe("PreviewSpecular0"); + connectRefreshCachedSettingsSafe("PreviewDiffuse1"); + connectRefreshCachedSettingsSafe("PreviewSpecular1"); + connectRefreshCachedSettingsSafe("PreviewDiffuse2"); + connectRefreshCachedSettingsSafe("PreviewSpecular2"); + connectRefreshCachedSettingsSafe("PreviewDirection0"); + connectRefreshCachedSettingsSafe("PreviewDirection1"); + connectRefreshCachedSettingsSafe("PreviewDirection2"); + connectRefreshCachedSettingsSafe("RenderGlowMinLuminance"); + connectRefreshCachedSettingsSafe("RenderGlowMaxExtractAlpha"); + connectRefreshCachedSettingsSafe("RenderGlowWarmthAmount"); + connectRefreshCachedSettingsSafe("RenderGlowLumWeights"); + connectRefreshCachedSettingsSafe("RenderGlowWarmthWeights"); + connectRefreshCachedSettingsSafe("RenderGlowResolutionPow"); + connectRefreshCachedSettingsSafe("RenderGlowIterations"); + connectRefreshCachedSettingsSafe("RenderGlowWidth"); + connectRefreshCachedSettingsSafe("RenderGlowStrength"); + connectRefreshCachedSettingsSafe("RenderDepthOfField"); + connectRefreshCachedSettingsSafe("CameraFocusTransitionTime"); + connectRefreshCachedSettingsSafe("CameraFNumber"); + connectRefreshCachedSettingsSafe("CameraFocalLength"); + connectRefreshCachedSettingsSafe("CameraFieldOfView"); + connectRefreshCachedSettingsSafe("RenderShadowNoise"); + connectRefreshCachedSettingsSafe("RenderShadowBlurSize"); + connectRefreshCachedSettingsSafe("RenderSSAOScale"); + connectRefreshCachedSettingsSafe("RenderSSAOMaxScale"); + connectRefreshCachedSettingsSafe("RenderSSAOFactor"); + connectRefreshCachedSettingsSafe("RenderSSAOEffect"); + connectRefreshCachedSettingsSafe("RenderShadowOffsetError"); + connectRefreshCachedSettingsSafe("RenderShadowBiasError"); + connectRefreshCachedSettingsSafe("RenderShadowOffset"); + connectRefreshCachedSettingsSafe("RenderShadowBias"); + connectRefreshCachedSettingsSafe("RenderSpotShadowOffset"); + connectRefreshCachedSettingsSafe("RenderSpotShadowBias"); + connectRefreshCachedSettingsSafe("RenderEdgeDepthCutoff"); + connectRefreshCachedSettingsSafe("RenderEdgeNormCutoff"); + connectRefreshCachedSettingsSafe("RenderShadowGaussian"); + connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor"); + connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric"); + connectRefreshCachedSettingsSafe("RenderReflectionDetail"); + connectRefreshCachedSettingsSafe("RenderHighlightFadeTime"); + connectRefreshCachedSettingsSafe("RenderShadowClipPlanes"); + connectRefreshCachedSettingsSafe("RenderShadowOrthoClipPlanes"); + connectRefreshCachedSettingsSafe("RenderShadowNearDist"); + connectRefreshCachedSettingsSafe("RenderFarClip"); + connectRefreshCachedSettingsSafe("RenderShadowSplitExponent"); + connectRefreshCachedSettingsSafe("RenderShadowErrorCutoff"); + connectRefreshCachedSettingsSafe("RenderShadowFOVCutoff"); + connectRefreshCachedSettingsSafe("CameraOffset"); + connectRefreshCachedSettingsSafe("CameraMaxCoF"); + connectRefreshCachedSettingsSafe("CameraDoFResScale"); + connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit"); + gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); } LLPipeline::~LLPipeline() @@ -588,6 +703,8 @@ void LLPipeline::cleanup() mInitialized = FALSE; mDeferredVB = NULL; + + mCubeVB = NULL; } //============================================================================ @@ -606,10 +723,14 @@ void LLPipeline::destroyGL() if (LLVertexBuffer::sEnableVBOs) { - // render 30 frames after switching to work around DEV-5361 - sDelayedVBOEnable = 30; LLVertexBuffer::sEnableVBOs = FALSE; } + + if (mMeshDirtyQueryObject) + { + glDeleteQueriesARB(1, &mMeshDirtyQueryObject); + mMeshDirtyQueryObject = 0; + } } static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture"); @@ -640,7 +761,16 @@ void LLPipeline::resizeScreenTexture() GLuint resX = gViewerWindow->getWorldViewWidthRaw(); GLuint resY = gViewerWindow->getWorldViewHeightRaw(); - allocateScreenBuffer(resX,resY); + if (!allocateScreenBuffer(resX,resY)) + { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled + //NOTE: if the session closes successfully after this call, deferred rendering will be + // disabled on future sessions + if (LLPipeline::sRenderDeferred) + { + gSavedSettings.setBOOL("RenderDeferred", FALSE); + LLPipeline::refreshCachedSettings(); + } + } } } @@ -655,18 +785,57 @@ void LLPipeline::allocatePhysicsBuffer() } } -void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) +bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) { refreshCachedSettings(); - U32 samples = RenderFSAASamples; + + bool save_settings = sRenderDeferred; + if (save_settings) + { + // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets + gSavedSettings.setBOOL("RenderInitError", TRUE); + gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); + } - //try to allocate screen buffers at requested resolution and samples + eFBOStatus ret = doAllocateScreenBuffer(resX, resY); + + if (save_settings) + { + // don't disable shaders on next session + gSavedSettings.setBOOL("RenderInitError", FALSE); + gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); + } + + if (ret == FBO_FAILURE) + { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled + //NOTE: if the session closes successfully after this call, deferred rendering will be + // disabled on future sessions + if (LLPipeline::sRenderDeferred) + { + gSavedSettings.setBOOL("RenderDeferred", FALSE); + LLPipeline::refreshCachedSettings(); + } + } + + return ret == FBO_SUCCESS_FULLRES; +} + + +LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY) +{ + // try to allocate screen buffers at requested resolution and samples // - on failure, shrink number of samples and try again // - if not multisampled, shrink resolution and try again (favor X resolution over Y) // Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state + U32 samples = RenderFSAASamples; + + eFBOStatus ret = FBO_SUCCESS_FULLRES; if (!allocateScreenBuffer(resX, resY, samples)) { + //failed to allocate at requested specification, return false + ret = FBO_FAILURE; + releaseScreenBuffers(); //reduce number of samples while (samples > 0) @@ -674,7 +843,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) samples /= 2; if (allocateScreenBuffer(resX, resY, samples)) { //success - return; + return FBO_SUCCESS_LOWRES; } releaseScreenBuffers(); } @@ -687,27 +856,27 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) resY /= 2; if (allocateScreenBuffer(resX, resY, samples)) { - return; + return FBO_SUCCESS_LOWRES; } releaseScreenBuffers(); resX /= 2; if (allocateScreenBuffer(resX, resY, samples)) { - return; + return FBO_SUCCESS_LOWRES; } releaseScreenBuffers(); } llwarns << "Unable to allocate screen buffer at any resolution!" << llendl; } -} + return ret; +} bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) { refreshCachedSettings(); - refreshRenderDeferred(); // remember these dimensions mScreenWidth = resX; @@ -742,7 +911,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; if (samples > 0) { - if (!mFXAABuffer.allocate(nhpo2(resX), nhpo2(resY), GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; + if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; } else { @@ -762,9 +931,10 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (shadow_detail > 0) { //allocate 4 sun shadow maps + U32 sun_shadow_map_width = ((U32(resX*scale)+1)&~1); // must be even to avoid a stripe in the horizontal shadow blur for (U32 i = 0; i < 4; i++) { - if (!mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false; + if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false; } } else @@ -775,14 +945,15 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) } } - U32 width = nhpo2(U32(resX*scale))/2; + U32 width = (U32) (resX*scale); U32 height = width; if (shadow_detail > 1) { //allocate two spot shadow maps + U32 spot_shadow_map_width = width; for (U32 i = 4; i < 6; i++) { - if (!mShadow[i].allocate(width, height, 0, TRUE, FALSE)) return false; + if (!mShadow[i].allocate(spot_shadow_map_width, height, 0, TRUE, FALSE)) return false; } } else @@ -792,6 +963,12 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) mShadow[i].release(); } } + + //HACK make screenbuffer allocations start failing after 30 seconds + if (gSavedSettings.getBOOL("SimulateFBOFailure")) + { + return false; + } } else { @@ -840,12 +1017,6 @@ void LLPipeline::updateRenderDeferred() } //static -void LLPipeline::refreshRenderDeferred() -{ - updateRenderDeferred(); -} - -//static void LLPipeline::refreshCachedSettings() { LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); @@ -856,6 +1027,7 @@ void LLPipeline::refreshCachedSettings() LLPipeline::sUseOcclusion = (!gUseWireframe + && LLGLSLShader::sNoFixedFunction && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery) ? 2 : 0; @@ -933,6 +1105,9 @@ void LLPipeline::refreshCachedSettings() CameraOffset = gSavedSettings.getBOOL("CameraOffset"); CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF"); CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale"); + RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit"); + + updateRenderDeferred(); } void LLPipeline::releaseGLBuffers() @@ -941,21 +1116,17 @@ void LLPipeline::releaseGLBuffers() if (mNoiseMap) { - LLImageGL::deleteTextures(1, &mNoiseMap); + LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mNoiseMap); mNoiseMap = 0; } if (mTrueNoiseMap) { - LLImageGL::deleteTextures(1, &mTrueNoiseMap); + LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mTrueNoiseMap); mTrueNoiseMap = 0; } - if (mLightFunc) - { - LLImageGL::deleteTextures(1, &mLightFunc); - mLightFunc = 0; - } + releaseLUTBuffers(); mWaterRef.release(); mWaterDis.release(); @@ -971,6 +1142,15 @@ void LLPipeline::releaseGLBuffers() LLVOAvatar::resetImpostors(); } +void LLPipeline::releaseLUTBuffers() +{ + if (mLightFunc) + { + LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R8, 0, 1, &mLightFunc); + mLightFunc = 0; + } +} + void LLPipeline::releaseScreenBuffers() { mUIScreen.release(); @@ -993,17 +1173,17 @@ void LLPipeline::releaseScreenBuffers() void LLPipeline::createGLBuffers() { stop_glerror(); - LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS); assertInitialized(); updateRenderDeferred(); if (LLPipeline::sWaterReflections) { //water reflection texture - U32 res = (U32) gSavedSettings.getS32("RenderWaterRefResolution"); + U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512); mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE); - mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE); + //always use FBO for mWaterDis so it can be used for avatar texture bakes + mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true); } mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE); @@ -1043,10 +1223,10 @@ void LLPipeline::createGLBuffers() noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f; } - LLImageGL::generateTextures(1, &mNoiseMap); + LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mNoiseMap); gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } @@ -1059,58 +1239,76 @@ void LLPipeline::createGLBuffers() noise[i] = ll_frand()*2.0-1.0; } - LLImageGL::generateTextures(1, &mTrueNoiseMap); + LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mTrueNoiseMap); gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } + createLUTBuffers(); + } + + gBumpImageList.restoreGL(); +} + +void LLPipeline::createLUTBuffers() +{ + if (sRenderDeferred) + { if (!mLightFunc) { U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); - U8* lg = new U8[lightResX*lightResY]; - + U8* ls = new U8[lightResX*lightResY]; + F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); + // Calculate the (normalized) Blinn-Phong specular lookup texture. for (U32 y = 0; y < lightResY; ++y) { for (U32 x = 0; x < lightResX; ++x) { - //spec func + ls[y*lightResX+x] = 0; F32 sa = (F32) x/(lightResX-1); F32 spec = (F32) y/(lightResY-1); - //lg[y*lightResX+x] = (U8) (powf(sa, 128.f*spec*spec)*255); - - //F32 sp = acosf(sa)/(1.f-spec); - - sa = powf(sa, gSavedSettings.getF32("RenderSpecularExponent")); - F32 a = acosf(sa*0.25f+0.75f); - F32 m = llmax(0.5f-spec*0.5f, 0.001f); - F32 t2 = tanf(a)/m; - t2 *= t2; - - F32 c4a = (3.f+4.f*cosf(2.f*a)+cosf(4.f*a))/8.f; - F32 bd = 1.f/(4.f*m*m*c4a)*powf(F_E, -t2); - - lg[y*lightResX+x] = (U8) (llclamp(bd, 0.f, 1.f)*255); + F32 n = spec * spec * specExp; + + // Nothing special here. Just your typical blinn-phong term. + spec = powf(sa, n); + + // Apply our normalization function. + // Note: This is the full equation that applies the full normalization curve, not an approximation. + // This is fine, given we only need to create our LUT once per buffer initialization. + // The only trade off is we have a really low dynamic range. + // This means we have to account for things not being able to exceed 0 to 1 in our shaders. + spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n))); + + // Always sample at a 1.0/2.2 curve. + // This "Gamma corrects" our specular term, boosting our lower exponent reflections. + spec = powf(spec, 1.f/2.2f); + + // Easy fix for our dynamic range problem: divide by 6 here, multiply by 6 in our shaders. + // This allows for our specular term to exceed a value of 1 in our shaders. + // This is something that can be important for energy conserving specular models where higher exponents can result in highlights that exceed a range of 0 to 1. + // Technically, we could just use an R16F texture, but driver support for R16F textures can be somewhat spotty at times. + // This works remarkably well for higher specular exponents, though banding can sometimes be seen on lower exponents. + // Combined with a bit of noise and trilinear filtering, the banding is hardly noticable. + ls[y*lightResX+x] = (U8)(llclamp(spec * (1.f / 6), 0.f, 1.f) * 255); } } - - LLImageGL::generateTextures(1, &mLightFunc); + + LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc); gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, lg); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); - - delete [] lg; + + delete [] ls; } } - - gBumpImageList.restoreGL(); } -void LLPipeline::restoreGL() + +void LLPipeline::restoreGL() { - LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_RESTORE_GL); assertInitialized(); if (mVertexShadersEnabled) @@ -1136,10 +1334,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; @@ -1170,7 +1370,6 @@ BOOL LLPipeline::canUseAntiAliasing() const void LLPipeline::unloadShaders() { - LLMemType mt_us(LLMemType::MTYPE_PIPELINE_UNLOAD_SHADERS); LLViewerShaderMgr::instance()->unloadShaders(); mVertexShadersLoaded = 0; @@ -1202,7 +1401,6 @@ S32 LLPipeline::getMaxLightingDetail() const S32 LLPipeline::setLightingDetail(S32 level) { - LLMemType mt_ld(LLMemType::MTYPE_PIPELINE_LIGHTING_DETAIL); refreshCachedSettings(); if (level < 0) @@ -1233,7 +1431,7 @@ public: { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->getData().empty()) + if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty()) { for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) { @@ -1364,7 +1562,6 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0) LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerTexture *tex0) { - LLMemType mt(LLMemType::MTYPE_PIPELINE); LLDrawPool *poolp = findPool(type, tex0); if (poolp) { @@ -1381,7 +1578,6 @@ LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerTexture *tex0) // static LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* imagep) { - LLMemType mt(LLMemType::MTYPE_PIPELINE); U32 type = getPoolTypeFromTE(te, imagep); return gPipeline.getPool(type, imagep); } @@ -1389,8 +1585,6 @@ LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* //static U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep) { - LLMemType mt_gpt(LLMemType::MTYPE_PIPELINE_GET_POOL_TYPE); - if (!te || !imagep) { return 0; @@ -1419,7 +1613,6 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima void LLPipeline::addPool(LLDrawPool *new_poolp) { - LLMemType mt_a(LLMemType::MTYPE_PIPELINE_ADD_POOL); assertInitialized(); mPools.insert(new_poolp); addToQuickLookup( new_poolp ); @@ -1427,7 +1620,6 @@ void LLPipeline::addPool(LLDrawPool *new_poolp) void LLPipeline::allocDrawable(LLViewerObject *vobj) { - LLMemType mt_ad(LLMemType::MTYPE_PIPELINE_ALLOCATE_DRAWABLE); LLDrawable *drawable = new LLDrawable(); vobj->mDrawable = drawable; @@ -1524,10 +1716,23 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) } -U32 LLPipeline::addObject(LLViewerObject *vobj) +//static +void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar) { - LLMemType mt_ao(LLMemType::MTYPE_PIPELINE_ADD_OBJECT); + LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET); + for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); + iter != gPipeline.mNearbyLights.end(); iter++) + { + if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar) + { + gPipeline.mLights.erase(iter->drawable); + gPipeline.mNearbyLights.erase(iter); + } + } +} +U32 LLPipeline::addObject(LLViewerObject *vobj) +{ if (RenderDelayCreation) { mCreateQ.push_back(vobj); @@ -1542,8 +1747,7 @@ U32 LLPipeline::addObject(LLViewerObject *vobj) void LLPipeline::createObjects(F32 max_dtime) { - LLFastTimer ftm(FTM_GEO_UPDATE); - LLMemType mt(LLMemType::MTYPE_PIPELINE_CREATE_OBJECTS); + LLFastTimer ftm(FTM_PIPELINE_CREATE); LLTimer update_timer; @@ -1703,7 +1907,21 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED); if (done) { + if (drawablep->isRoot()) + { + drawablep->makeStatic(); + } drawablep->clearState(LLDrawable::ON_MOVE_LIST); + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { //will likely not receive any future world matrix updates + // -- this keeps attachments from getting stuck in space and falling off your avatar + drawablep->clearState(LLDrawable::ANIMATED_CHILD); + markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, TRUE); + if (drawablep->getVObj()) + { + drawablep->getVObj()->dirtySpatialGroup(TRUE); + } + } iter = moved_list.erase(curiter); } } @@ -1715,7 +1933,6 @@ static LLFastTimer::DeclareTimer FTM_UPDATE_MOVE("Update Move"); void LLPipeline::updateMove() { LLFastTimer t(FTM_UPDATE_MOVE); - LLMemType mt_um(LLMemType::MTYPE_PIPELINE_UPDATE_MOVE); if (FreezeTime) { @@ -1824,11 +2041,12 @@ void LLPipeline::grabReferences(LLCullResult& result) void LLPipeline::clearReferences() { sCull = NULL; + mGroupSaveQ1.clear(); } void check_references(LLSpatialGroup* group, LLDrawable* drawable) { - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { if (drawable == *i) { @@ -1850,7 +2068,7 @@ void check_references(LLDrawable* drawable, LLFace* face) void check_references(LLSpatialGroup* group, LLFace* face) { - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { LLDrawable* drawable = *i; check_references(drawable, face); @@ -1862,25 +2080,25 @@ void LLPipeline::checkReferences(LLFace* face) #if 0 if (sCull) { - for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, face); } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, face); } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, face); } - for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) { LLDrawable* drawable = *iter; check_references(drawable, face); @@ -1894,25 +2112,25 @@ void LLPipeline::checkReferences(LLDrawable* drawable) #if 0 if (sCull) { - for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, drawable); } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, drawable); } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, drawable); } - for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) { if (drawable == *iter) { @@ -1945,19 +2163,19 @@ void LLPipeline::checkReferences(LLDrawInfo* draw_info) #if 0 if (sCull) { - for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, draw_info); } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, draw_info); } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, draw_info); @@ -1971,7 +2189,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group) #if 0 if (sCull) { - for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { if (group == *iter) { @@ -1979,7 +2197,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group) } } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) { if (group == *iter) { @@ -1987,7 +2205,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group) } } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { if (group == *iter) { @@ -2068,7 +2286,6 @@ static LLFastTimer::DeclareTimer FTM_CULL("Object Culling"); void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip, LLPlane* planep) { LLFastTimer t(FTM_CULL); - LLMemType mt_uc(LLMemType::MTYPE_PIPELINE_UPDATE_CULL); grabReferences(result); @@ -2098,8 +2315,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl gGLLastMatrix = NULL; gGL.loadMatrix(gGLLastModelView); - - LLVertexBuffer::unbind(); LLGLDisable blend(GL_BLEND); LLGLDisable test(GL_ALPHA_TEST); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -2143,7 +2358,16 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl { //if no shader is currently bound, use the occlusion shader instead of fixed function if we can // (shadow render uses a special shader that clamps to clip planes) bound_shader = true; - gOcclusionProgram.bind(); + gOcclusionCubeProgram.bind(); + } + + if (sUseOcclusion > 1) + { + if (mCubeVB.isNull()) + { //cube VB will be used for issuing occlusion queries + mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); + } + mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); } for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); @@ -2175,7 +2399,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl if (bound_shader) { - gOcclusionProgram.unbind(); + gOcclusionCubeProgram.unbind(); } camera.disableUserClipPlane(); @@ -2219,7 +2443,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) { - if (group->getData().empty()) + if (group->isEmpty()) { return; } @@ -2308,15 +2532,21 @@ void LLPipeline::doOcclusion(LLCamera& camera) { if (LLPipeline::sShadowRender) { - gDeferredShadowProgram.bind(); + gDeferredShadowCubeProgram.bind(); } else { - gOcclusionProgram.bind(); + gOcclusionCubeProgram.bind(); } } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) + if (mCubeVB.isNull()) + { //cube VB will be used for issuing occlusion queries + mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); + } + mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + + for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) { LLSpatialGroup* group = *iter; group->doOcclusion(&camera); @@ -2327,11 +2557,11 @@ void LLPipeline::doOcclusion(LLCamera& camera) { if (LLPipeline::sShadowRender) { - gDeferredShadowProgram.unbind(); + gDeferredShadowCubeProgram.unbind(); } else { - gOcclusionProgram.unbind(); + gOcclusionCubeProgram.unbind(); } } @@ -2350,22 +2580,93 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) return update_complete; } +static LLFastTimer::DeclareTimer FTM_SEED_VBO_POOLS("Seed VBO Pool"); + +static LLFastTimer::DeclareTimer FTM_UPDATE_GL("Update GL"); + void LLPipeline::updateGL() { - while (!LLGLUpdate::sGLQ.empty()) { - LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); - glu->updateGL(); - glu->mInQ = FALSE; - LLGLUpdate::sGLQ.pop_front(); + LLFastTimer t(FTM_UPDATE_GL); + while (!LLGLUpdate::sGLQ.empty()) + { + LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); + glu->updateGL(); + glu->mInQ = FALSE; + LLGLUpdate::sGLQ.pop_front(); + } + } + + { //seed VBO Pools + LLFastTimer t(FTM_SEED_VBO_POOLS); + LLVertexBuffer::seedPools(); } } +static LLFastTimer::DeclareTimer FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups"); + +void LLPipeline::clearRebuildGroups() +{ + LLSpatialGroup::sg_vector_t hudGroups; + + mGroupQ1Locked = true; + // Iterate through all drawables on the priority build queue, + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); + iter != mGroupQ1.end(); ++iter) + { + LLSpatialGroup* group = *iter; + + // If the group contains HUD objects, save the group + if (group->isHUDGroup()) + { + hudGroups.push_back(group); + } + // Else, no HUD objects so clear the build state + else + { + group->clearState(LLSpatialGroup::IN_BUILD_Q1); + } + } + + // Clear the group + mGroupQ1.clear(); + + // Copy the saved HUD groups back in + mGroupQ1.assign(hudGroups.begin(), hudGroups.end()); + mGroupQ1Locked = false; + + // Clear the HUD groups + hudGroups.clear(); + + mGroupQ2Locked = true; + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); + iter != mGroupQ2.end(); ++iter) + { + LLSpatialGroup* group = *iter; + + // If the group contains HUD objects, save the group + if (group->isHUDGroup()) + { + hudGroups.push_back(group); + } + // Else, no HUD objects so clear the build state + else + { + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + } + } + // Clear the group + mGroupQ2.clear(); + + // Copy the saved HUD groups back in + mGroupQ2.assign(hudGroups.begin(), hudGroups.end()); + mGroupQ2Locked = false; +} + void LLPipeline::rebuildPriorityGroups() { + LLFastTimer t(FTM_REBUILD_PRIORITY_GROUPS); LLTimer update_timer; - LLMemType mt(LLMemType::MTYPE_PIPELINE); - assertInitialized(); gMeshRepo.notifyLoadedMeshes(); @@ -2380,11 +2681,14 @@ void LLPipeline::rebuildPriorityGroups() group->clearState(LLSpatialGroup::IN_BUILD_Q1); } + mGroupSaveQ1 = mGroupQ1; mGroupQ1.clear(); mGroupQ1Locked = false; } - + +static LLFastTimer::DeclareTimer FTM_REBUILD_GROUPS("Rebuild Groups"); + void LLPipeline::rebuildGroups() { if (mGroupQ2.empty()) @@ -2392,6 +2696,7 @@ void LLPipeline::rebuildGroups() return; } + LLFastTimer t(FTM_REBUILD_GROUPS); mGroupQ2Locked = true; // Iterate through some drawables on the non-priority build queue S32 size = (S32) mGroupQ2.size(); @@ -2433,22 +2738,12 @@ void LLPipeline::rebuildGroups() void LLPipeline::updateGeom(F32 max_dtime) { LLTimer update_timer; - LLMemType mt(LLMemType::MTYPE_PIPELINE_UPDATE_GEOM); LLPointer<LLDrawable> drawablep; LLFastTimer t(FTM_GEO_UPDATE); assertInitialized(); - if (sDelayedVBOEnable > 0) - { - if (--sDelayedVBOEnable <= 0) - { - resetVertexBuffers(); - LLVertexBuffer::sEnableVBOs = TRUE; - } - } - // notify various object types to reset internal cost metrics, etc. // for now, only LLVOVolume does this to throttle LOD changes LLVOVolume::preUpdateGeom(); @@ -2536,14 +2831,13 @@ void LLPipeline::updateGeom(F32 max_dtime) void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) { - LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_VISIBLE); - if(drawablep && !drawablep->isDead()) { if (drawablep->isSpatialBridge()) { const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; llassert(root); // trying to catch a bad assumption + if (root && // // this test may not be needed, see above root->getVObj()->isAttachment()) { @@ -2566,6 +2860,7 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) } else { + sCull->pushDrawable(drawablep); } @@ -2575,8 +2870,6 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) { - LLMemType mt_mm(LLMemType::MTYPE_PIPELINE_MARK_MOVED); - if (!drawablep) { //llerrs << "Sending null drawable to moved list!" << llendl; @@ -2621,8 +2914,6 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) void LLPipeline::markShift(LLDrawable *drawablep) { - LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_SHIFT); - if (!drawablep || drawablep->isDead()) { return; @@ -2642,10 +2933,12 @@ void LLPipeline::markShift(LLDrawable *drawablep) } } +static LLFastTimer::DeclareTimer FTM_SHIFT_DRAWABLE("Shift Drawable"); +static LLFastTimer::DeclareTimer FTM_SHIFT_OCTREE("Shift Octree"); +static LLFastTimer::DeclareTimer FTM_SHIFT_HUD("Shift HUD"); + void LLPipeline::shiftObjects(const LLVector3 &offset) { - LLMemType mt(LLMemType::MTYPE_PIPELINE_SHIFT_OBJECTS); - assertInitialized(); glClear(GL_DEPTH_BUFFER_BIT); @@ -2654,42 +2947,51 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) LLVector4a offseta; offseta.load3(offset.mV); - for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); - iter != mShiftList.end(); iter++) { - LLDrawable *drawablep = *iter; - if (drawablep->isDead()) + LLFastTimer t(FTM_SHIFT_DRAWABLE); + + for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); + iter != mShiftList.end(); iter++) { - continue; - } - drawablep->shiftPos(offseta); - drawablep->clearState(LLDrawable::ON_SHIFT_LIST); + LLDrawable *drawablep = *iter; + if (drawablep->isDead()) + { + continue; + } + drawablep->shiftPos(offseta); + drawablep->clearState(LLDrawable::ON_SHIFT_LIST); + } + mShiftList.resize(0); } - mShiftList.resize(0); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + LLFastTimer t(FTM_SHIFT_OCTREE); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { - part->shift(offseta); + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->shift(offseta); + } } } } - LLHUDText::shiftAll(offset); - LLHUDNameTag::shiftAll(offset); + { + LLFastTimer t(FTM_SHIFT_HUD); + LLHUDText::shiftAll(offset); + LLHUDNameTag::shiftAll(offset); + } display_update_camera(); } void LLPipeline::markTextured(LLDrawable *drawablep) { - LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_TEXTURED); - if (drawablep && !drawablep->isDead() && assertInitialized()) { mRetexturedList.insert(drawablep); @@ -2715,8 +3017,10 @@ void LLPipeline::markPartitionMove(LLDrawable* drawable) } } +static LLFastTimer::DeclareTimer FTM_PROCESS_PARTITIONQ("PartitionQ"); void LLPipeline::processPartitionQ() { + LLFastTimer t(FTM_PROCESS_PARTITIONQ); for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter) { LLDrawable* drawable = *iter; @@ -2731,10 +3035,13 @@ void LLPipeline::processPartitionQ() mPartitionQ.clear(); } +void LLPipeline::markMeshDirty(LLSpatialGroup* group) +{ + mMeshDirtyGroup.push_back(group); +} + void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) { - LLMemType mt(LLMemType::MTYPE_PIPELINE); - if (group && !group->isDead() && group->mSpatialPartition) { if (group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD) @@ -2774,8 +3081,6 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority) { - LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_REBUILD); - if (drawablep && !drawablep->isDead() && assertInitialized()) { if (!drawablep->isState(LLDrawable::BUILT)) @@ -2822,12 +3127,11 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } LLFastTimer ftm(FTM_STATESORT); - LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT); //LLVertexBuffer::unbind(); grabReferences(result); - for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { LLSpatialGroup* group = *iter; group->checkOcclusion(); @@ -2838,7 +3142,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) else { group->setVisible(); - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { markVisible(*i, camera); } @@ -2853,9 +3157,9 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { LLSpatialGroup* last_group = NULL; - for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { - LLCullResult::bridge_list_t::iterator cur_iter = i; + LLCullResult::bridge_iterator cur_iter = i; LLSpatialBridge* bridge = *cur_iter; LLSpatialGroup* group = bridge->getSpatialGroup(); @@ -2885,7 +3189,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; group->checkOcclusion(); @@ -2907,7 +3211,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) { LLFastTimer ftm(FTM_STATESORT_DRAWABLE); - for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); + for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) { LLDrawable *drawablep = *iter; @@ -2923,10 +3227,9 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) { - LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT); if (group->changeLOD()) { - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { LLDrawable* drawablep = *i; stateSort(drawablep, camera); @@ -2942,7 +3245,6 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) { - LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT); if (bridge->getSpatialGroup()->changeLOD()) { bool force_update = false; @@ -2952,8 +3254,6 @@ void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) { - LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT); - if (!drawablep || drawablep->isDead() || !hasRenderType(drawablep->getRenderType())) @@ -3043,13 +3343,13 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } -void forAllDrawables(LLCullResult::sg_list_t::iterator begin, - LLCullResult::sg_list_t::iterator end, +void forAllDrawables(LLCullResult::sg_iterator begin, + LLCullResult::sg_iterator end, void (*func)(LLDrawable*)) { - for (LLCullResult::sg_list_t::iterator i = begin; i != end; ++i) + for (LLCullResult::sg_iterator i = begin; i != end; ++i) { - for (LLSpatialGroup::element_iter j = (*i)->getData().begin(); j != (*i)->getData().end(); ++j) + for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j) { func(*j); } @@ -3082,7 +3382,11 @@ void renderScriptedBeacons(LLDrawable* drawablep) S32 count = drawablep->getNumFaces(); for (face_id = 0; face_id < count; face_id++) { - gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); + LLFace * facep = drawablep->getFace(face_id); + if (facep) + { + gPipeline.mHighlightFaces.push_back(facep); + } } } } @@ -3108,11 +3412,15 @@ void renderScriptedTouchBeacons(LLDrawable* drawablep) S32 count = drawablep->getNumFaces(); for (face_id = 0; face_id < count; face_id++) { - gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); + LLFace * facep = drawablep->getFace(face_id); + if (facep) + { + gPipeline.mHighlightFaces.push_back(facep); } } } } +} void renderPhysicalBeacons(LLDrawable* drawablep) { @@ -3120,7 +3428,7 @@ void renderPhysicalBeacons(LLDrawable* drawablep) if (vobj && !vobj->isAvatar() //&& !vobj->getParent() - && vobj->usePhysics()) + && vobj->flagUsePhysics()) { if (gPipeline.sRenderBeacons) { @@ -3133,11 +3441,15 @@ void renderPhysicalBeacons(LLDrawable* drawablep) S32 count = drawablep->getNumFaces(); for (face_id = 0; face_id < count; face_id++) { - gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); + LLFace * facep = drawablep->getFace(face_id); + if (facep) + { + gPipeline.mHighlightFaces.push_back(facep); } } } } +} void renderMOAPBeacons(LLDrawable* drawablep) { @@ -3169,11 +3481,15 @@ void renderMOAPBeacons(LLDrawable* drawablep) S32 count = drawablep->getNumFaces(); for (face_id = 0; face_id < count; face_id++) { - gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); + LLFace * facep = drawablep->getFace(face_id); + if (facep) + { + gPipeline.mHighlightFaces.push_back(facep); } } } } +} void renderParticleBeacons(LLDrawable* drawablep) { @@ -3194,11 +3510,15 @@ void renderParticleBeacons(LLDrawable* drawablep) S32 count = drawablep->getNumFaces(); for (face_id = 0; face_id < count; face_id++) { - gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); + LLFace * facep = drawablep->getFace(face_id); + if (facep) + { + gPipeline.mHighlightFaces.push_back(facep); } } } } +} void renderSoundHighlights(LLDrawable* drawablep) { @@ -3212,22 +3532,25 @@ void renderSoundHighlights(LLDrawable* drawablep) S32 count = drawablep->getNumFaces(); for (face_id = 0; face_id < count; face_id++) { - gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); + LLFace * facep = drawablep->getFace(face_id); + if (facep) + { + gPipeline.mHighlightFaces.push_back(facep); } } } } +} void LLPipeline::postSort(LLCamera& camera) { - LLMemType mt(LLMemType::MTYPE_PIPELINE_POST_SORT); LLFastTimer ftm(FTM_STATESORT_POSTSORT); assertInitialized(); llpushcallstacks ; //rebuild drawable geometry - for (LLCullResult::sg_list_t::iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) + for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) { LLSpatialGroup* group = *i; if (!sUseOcclusion || @@ -3243,27 +3566,15 @@ void LLPipeline::postSort(LLCamera& camera) rebuildPriorityGroups(); llpushcallstacks ; - const S32 bin_count = 1024*8; - - static LLCullResult::drawinfo_list_t alpha_bins[bin_count]; - static U32 bin_size[bin_count]; - - //clear one bin per frame to avoid memory bloat - static S32 clear_idx = 0; - clear_idx = (1+clear_idx)%bin_count; - alpha_bins[clear_idx].clear(); - - for (U32 j = 0; j < bin_count; j++) - { - bin_size[j] = 0; - } - + //build render map - for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) + for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { LLSpatialGroup* group = *i; if (sUseOcclusion && - group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + group->isOcclusionState(LLSpatialGroup::OCCLUDED) || + (RenderAutoHideSurfaceAreaLimit > 0.f && + group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit*llmax(group->mObjectBoxSize, 10.f))) { continue; } @@ -3327,11 +3638,43 @@ void LLPipeline::postSort(LLCamera& camera) } } } + + //flush particle VB + LLVOPartGroup::sVB->flush(); + + /*bool use_transform_feedback = gTransformPositionProgram.mProgramObject && !mMeshDirtyGroup.empty(); + + if (use_transform_feedback) + { //place a query around potential transform feedback code for synchronization + mTransformFeedbackPrimitives = 0; + + if (!mMeshDirtyQueryObject) + { + glGenQueriesARB(1, &mMeshDirtyQueryObject); + } + + glBeginQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject); + }*/ + + //pack vertex buffers for groups that chose to delay their updates + for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter) + { + (*iter)->rebuildMesh(); + } + + /*if (use_transform_feedback) + { + glEndQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); + }*/ + + mMeshDirtyGroup.clear(); + if (!sShadowRender) { std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater()); } + llpushcallstacks ; // only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender) @@ -3405,7 +3748,11 @@ void LLPipeline::postSort(LLCamera& camera) { if (object->mDrawable) { - gPipeline.mSelectedFaces.push_back(object->mDrawable->getFace(te)); + LLFace * facep = object->mDrawable->getFace(te); + if (facep) + { + gPipeline.mSelectedFaces.push_back(facep); + } } return true; } @@ -3414,6 +3761,33 @@ void LLPipeline::postSort(LLCamera& camera) } } + /*static LLFastTimer::DeclareTimer FTM_TRANSFORM_WAIT("Transform Fence"); + static LLFastTimer::DeclareTimer FTM_TRANSFORM_DO_WORK("Transform Work"); + if (use_transform_feedback) + { //using transform feedback, wait for transform feedback to complete + LLFastTimer t(FTM_TRANSFORM_WAIT); + + S32 done = 0; + //glGetQueryivARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_CURRENT_QUERY, &count); + + glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done); + + while (!done) + { + { + LLFastTimer t(FTM_TRANSFORM_DO_WORK); + F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); + //do some useful 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 + } + glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done); + } + + mTransformFeedbackPrimitives = 0; + }*/ + //LLSpatialGroup::sNoDelete = FALSE; llpushcallstacks ; } @@ -3421,7 +3795,6 @@ void LLPipeline::postSort(LLCamera& camera) void render_hud_elements() { - LLMemType mt_rhe(LLMemType::MTYPE_PIPELINE_RENDER_HUD_ELS); LLFastTimer t(FTM_RENDER_UI); gPipeline.disableLights(); @@ -3476,8 +3849,6 @@ void render_hud_elements() void LLPipeline::renderHighlights() { - LLMemType mt(LLMemType::MTYPE_PIPELINE_RENDER_HL); - assertInitialized(); // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) @@ -3641,7 +4012,6 @@ U32 LLPipeline::sCurRenderPoolType = 0 ; void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) { - LLMemType mt(LLMemType::MTYPE_PIPELINE_RENDER_GEOM); LLFastTimer t(FTM_RENDER_GEOMETRY); assertInitialized(); @@ -3684,6 +4054,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); @@ -3708,6 +4079,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sDefaultImagep); LLViewerFetchedTexture::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP); + ////////////////////////////////////////////// // // Actually render all of the geometry @@ -3780,7 +4152,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) break; } - p->render(i); + if ( !p->getSkipRenderFlag() ) { p->render(i); } } poolp->endRenderPass(i); LLVertexBuffer::unbind(); @@ -3892,10 +4264,9 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) { LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); - LLMemType mt_rgd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED); LLFastTimer t(FTM_RENDER_GEOMETRY); - LLFastTimer t2(FTM_POOLS); + LLFastTimer t2(FTM_DEFERRED_POOLS); LLGLEnable cull(GL_CULL_FACE); @@ -3937,7 +4308,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) pool_set_t::iterator iter2 = iter1; if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) { - LLFastTimer t(FTM_POOLRENDER); + LLFastTimer t(FTM_DEFERRED_POOLRENDER); gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); @@ -3954,7 +4325,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) break; } - p->renderDeferred(i); + if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); } } poolp->endDeferredPass(i); LLVertexBuffer::unbind(); @@ -3989,8 +4360,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) void LLPipeline::renderGeomPostDeferred(LLCamera& camera) { - LLMemType mt_rgpd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_POST_DEF); - LLFastTimer t(FTM_POOLS); + LLFastTimer t(FTM_POST_DEFERRED_POOLS); U32 cur_type = 0; LLGLEnable cull(GL_CULL_FACE); @@ -4024,7 +4394,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) pool_set_t::iterator iter2 = iter1; if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0) { - LLFastTimer t(FTM_POOLRENDER); + LLFastTimer t(FTM_POST_DEFERRED_POOLRENDER); gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); @@ -4085,7 +4455,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) void LLPipeline::renderGeomShadow(LLCamera& camera) { - LLMemType mt_rgs(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_SHADOW); U32 cur_type = 0; LLGLEnable cull(GL_CULL_FACE); @@ -4214,7 +4583,7 @@ void LLPipeline::renderPhysicsDisplay() } } - for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { LLSpatialBridge* bridge = *i; if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) @@ -4239,18 +4608,343 @@ void LLPipeline::renderPhysicsDisplay() void LLPipeline::renderDebug() { - LLMemType mt(LLMemType::MTYPE_PIPELINE); - assertInitialized(); + bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD); + + if (!hud_only ) + { + //Render any navmesh geometry + LLPathingLib *llPathingLibInstance = LLPathingLib::getInstance(); + if ( llPathingLibInstance != NULL ) + { + //character floater renderables + + LLHandle<LLFloaterPathfindingCharacters> pathfindingCharacterHandle = LLFloaterPathfindingCharacters::getInstanceHandle(); + if ( !pathfindingCharacterHandle.isDead() ) + { + LLFloaterPathfindingCharacters *pathfindingCharacter = pathfindingCharacterHandle.get(); + + if ( pathfindingCharacter->getVisible() || gAgentCamera.cameraMouselook() ) + { + if (LLGLSLShader::sNoFixedFunction) + { + gPathfindingProgram.bind(); + gPathfindingProgram.uniform1f("tint", 1.f); + gPathfindingProgram.uniform1f("ambiance", 1.f); + gPathfindingProgram.uniform1f("alpha_scale", 1.f); + } + + //Requried character physics capsule render parameters + LLUUID id; + LLVector3 pos; + LLQuaternion rot; + + if ( pathfindingCharacter->isPhysicsCapsuleEnabled( id, pos, rot ) ) + { + if (LLGLSLShader::sNoFixedFunction) + { + //remove blending artifacts + gGL.setColorMask(false, false); + llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); + gGL.setColorMask(true, false); + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f("alpha_scale", 0.90f); + llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); + gPathfindingProgram.bind(); + } + else + { + llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); + } + } + } + } + + + //pathing console renderables + LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle(); + if (!pathfindingConsoleHandle.isDead()) + { + LLFloaterPathfindingConsole *pathfindingConsole = pathfindingConsoleHandle.get(); + + if ( pathfindingConsole->getVisible() || gAgentCamera.cameraMouselook() ) + { + F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance"); + + if (LLGLSLShader::sNoFixedFunction) + { + gPathfindingProgram.bind(); + + gPathfindingProgram.uniform1f("tint", 1.f); + gPathfindingProgram.uniform1f("ambiance", ambiance); + gPathfindingProgram.uniform1f("alpha_scale", 1.f); + } + + if ( !pathfindingConsole->isRenderWorld() ) + { + const LLColor4 clearColor = gSavedSettings.getColor4("PathfindingNavMeshClear"); + gGL.setColorMask(true, true); + glClearColor(clearColor.mV[0],clearColor.mV[1],clearColor.mV[2],0); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + gGL.setColorMask(true, false); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + + //NavMesh + if ( pathfindingConsole->isRenderNavMesh() ) + { + gGL.flush(); + glLineWidth(2.0f); + LLGLEnable cull(GL_CULL_FACE); + LLGLDisable blend(GL_BLEND); + + if ( pathfindingConsole->isRenderWorld() ) + { + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f("alpha_scale", 0.66f); + llPathingLibInstance->renderNavMesh(); + } + else + { + llPathingLibInstance->renderNavMesh(); + } + + //render edges + if (LLGLSLShader::sNoFixedFunction) + { + gPathfindingNoNormalsProgram.bind(); + gPathfindingNoNormalsProgram.uniform1f("tint", 1.f); + gPathfindingNoNormalsProgram.uniform1f("alpha_scale", 1.f); + llPathingLibInstance->renderNavMeshEdges(); + gPathfindingProgram.bind(); + } + else + { + llPathingLibInstance->renderNavMeshEdges(); + } + + gGL.flush(); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + glLineWidth(1.0f); + gGL.flush(); + } + //User designated path + if ( LLPathfindingPathTool::getInstance()->isRenderPath() ) + { + //The path + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.bind(); + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); + llPathingLibInstance->renderPath(); + gPathfindingProgram.bind(); + } + else + { + llPathingLibInstance->renderPath(); + } + //The bookends + if (LLGLSLShader::sNoFixedFunction) + { + //remove blending artifacts + gGL.setColorMask(false, false); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); + + gGL.setColorMask(true, false); + //render the bookends + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f("alpha_scale", 0.90f); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); + gPathfindingProgram.bind(); + } + else + { + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); + } + + } + + if ( pathfindingConsole->isRenderWaterPlane() ) + { + if (LLGLSLShader::sNoFixedFunction) + { + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f("alpha_scale", 0.90f); + llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() ); + } + else + { + llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() ); + } + } + //physics/exclusion shapes + if ( pathfindingConsole->isRenderAnyShapes() ) + { + U32 render_order[] = { + 1 << LLPathingLib::LLST_ObstacleObjects, + 1 << LLPathingLib::LLST_WalkableObjects, + 1 << LLPathingLib::LLST_ExclusionPhantoms, + 1 << LLPathingLib::LLST_MaterialPhantoms, + }; + + U32 flags = pathfindingConsole->getRenderShapeFlags(); + + for (U32 i = 0; i < 4; i++) + { + if (!(flags & render_order[i])) + { + continue; + } + + //turn off backface culling for volumes so they are visible when camera is inside volume + LLGLDisable cull(i >= 2 ? GL_CULL_FACE : 0); + + gGL.flush(); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + + //get rid of some z-fighting + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(1.0f, 1.0f); + + //render to depth first to avoid blending artifacts + gGL.setColorMask(false, false); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + gGL.setColorMask(true, false); + + //get rid of some z-fighting + glPolygonOffset(0.f, 0.f); + + LLGLEnable blend(GL_BLEND); + + { + gPathfindingProgram.uniform1f("ambiance", ambiance); + + { //draw solid overlay + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + gGL.flush(); + } + + LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE); + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + + F32 offset = gSavedSettings.getF32("PathfindingLineOffset"); + + if (pathfindingConsole->isRenderXRay()) + { + gPathfindingProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint")); + gPathfindingProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity")); + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); + + glPolygonOffset(offset, -offset); + + if (gSavedSettings.getBOOL("PathfindingXRayWireframe")) + { //draw hidden wireframe as darker and less opaque + gPathfindingProgram.uniform1f("ambiance", 1.f); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + } + else + { + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + gPathfindingProgram.uniform1f("ambiance", ambiance); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } + } + + { //draw visible wireframe as brighter, thicker and more opaque + glPolygonOffset(offset, offset); + gPathfindingProgram.uniform1f("ambiance", 1.f); + gPathfindingProgram.uniform1f("tint", 1.f); + gPathfindingProgram.uniform1f("alpha_scale", 1.f); + + glLineWidth(gSavedSettings.getF32("PathfindingLineWidth")); + LLGLDisable blendOut(GL_BLEND); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + gGL.flush(); + glLineWidth(1.f); + } + + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + } + } + + glPolygonOffset(0.f, 0.f); + + if ( pathfindingConsole->isRenderNavMesh() && pathfindingConsole->isRenderXRay() ) + { //render navmesh xray + F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance"); + + LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE); + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + + F32 offset = gSavedSettings.getF32("PathfindingLineOffset"); + glPolygonOffset(offset, -offset); + + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); + gGL.flush(); + glLineWidth(2.0f); + LLGLEnable cull(GL_CULL_FACE); + + gPathfindingProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint")); + gPathfindingProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity")); + + if (gSavedSettings.getBOOL("PathfindingXRayWireframe")) + { //draw hidden wireframe as darker and less opaque + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + gPathfindingProgram.uniform1f("ambiance", 1.f); + llPathingLibInstance->renderNavMesh(); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + else + { + gPathfindingProgram.uniform1f("ambiance", ambiance); + llPathingLibInstance->renderNavMesh(); + } + + //render edges + if (LLGLSLShader::sNoFixedFunction) + { + gPathfindingNoNormalsProgram.bind(); + gPathfindingNoNormalsProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint")); + gPathfindingNoNormalsProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity")); + llPathingLibInstance->renderNavMeshEdges(); + gPathfindingProgram.bind(); + } + else + { + llPathingLibInstance->renderNavMeshEdges(); + } + + gGL.flush(); + glLineWidth(1.0f); + } + + glPolygonOffset(0.f, 0.f); + + gGL.flush(); + if (LLGLSLShader::sNoFixedFunction) + { + gPathfindingProgram.unbind(); + } + } + } + } + } + gGL.color4f(1,1,1,1); gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); gGL.setColorMask(true, false); - bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD); - if (!hud_only && !mDebugBlips.empty()) { //render debug blips @@ -4309,7 +5003,7 @@ void LLPipeline::renderDebug() } } - for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { LLSpatialBridge* bridge = *i; if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) @@ -4561,9 +5255,11 @@ void LLPipeline::renderDebug() } } +static LLFastTimer::DeclareTimer FTM_REBUILD_POOLS("Rebuild Pools"); + void LLPipeline::rebuildPools() { - LLMemType mt(LLMemType::MTYPE_PIPELINE_REBUILD_POOLS); + LLFastTimer t(FTM_REBUILD_POOLS); assertInitialized(); @@ -4594,17 +5290,10 @@ void LLPipeline::rebuildPools() } max_count--; } - - if (isAgentAvatarValid()) - { - gAgentAvatarp->rebuildHUD(); - } } void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) { - LLMemType mt(LLMemType::MTYPE_PIPELINE_QUICK_LOOKUP); - assertInitialized(); switch( new_poolp->getType() ) @@ -4770,7 +5459,6 @@ void LLPipeline::removePool( LLDrawPool* poolp ) void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) { assertInitialized(); - LLMemType mt(LLMemType::MTYPE_PIPELINE); switch( poolp->getType() ) { case LLDrawPool::POOL_SIMPLE: @@ -5086,7 +5774,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) // crazy cast so that we can overwrite the fade value // even though gcc enforces sets as const // (fade value doesn't affect sort so this is safe) - Light* farthest_light = ((Light*) (&(*(mNearbyLights.rbegin())))); + Light* farthest_light = (const_cast<Light*>(&(*(mNearbyLights.rbegin())))); if (light->dist < farthest_light->dist) { if (farthest_light->fade >= 0.f) @@ -5215,7 +5903,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 @@ -5237,7 +5926,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 { @@ -5427,7 +6117,7 @@ void LLPipeline::enableLightsPreview() LLVector4 light_pos(dir0, 0.0f); - LLLightState* light = gGL.getLight(0); + LLLightState* light = gGL.getLight(1); light->enable(); light->setPosition(light_pos); @@ -5439,7 +6129,7 @@ void LLPipeline::enableLightsPreview() light_pos = LLVector4(dir1, 0.f); - light = gGL.getLight(1); + light = gGL.getLight(2); light->enable(); light->setPosition(light_pos); light->setDiffuse(diffuse1); @@ -5449,7 +6139,7 @@ void LLPipeline::enableLightsPreview() light->setSpotCutoff(180.f); light_pos = LLVector4(dir2, 0.f); - light = gGL.getLight(2); + light = gGL.getLight(3); light->enable(); light->setPosition(light_pos); light->setDiffuse(diffuse2); @@ -6099,7 +6789,7 @@ LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj) void LLPipeline::resetVertexBuffers(LLDrawable* drawable) { - if (!drawable || drawable->isDead()) + if (!drawable) { return; } @@ -6107,12 +6797,32 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable) for (S32 i = 0; i < drawable->getNumFaces(); i++) { LLFace* facep = drawable->getFace(i); - facep->clearVertexBuffer(); + if (facep) + { + facep->clearVertexBuffer(); + } } } void LLPipeline::resetVertexBuffers() { + mResetVertexBuffers = true; +} + +static LLFastTimer::DeclareTimer FTM_RESET_VB("Reset VB"); + +void LLPipeline::doResetVertexBuffers() +{ + if (!mResetVertexBuffers) + { + return; + } + + LLFastTimer t(FTM_RESET_VB); + mResetVertexBuffers = false; + + mCubeVB = NULL; + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { @@ -6131,18 +6841,26 @@ void LLPipeline::resetVertexBuffers() gSky.resetVertexBuffers(); + LLVOPartGroup::destroyGL(); + + if ( LLPathingLib::getInstance() ) + { + LLPathingLib::getInstance()->cleanupVBOManager(); + } + LLVOPartGroup::destroyGL(); + LLVertexBuffer::cleanupClass(); //delete all name pool caches LLGLNamePool::cleanupPools(); + + if (LLVertexBuffer::sGLCount > 0) { - llwarns << "VBO wipe failed." << llendl; + llwarns << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << llendl; } - llassert(LLVertexBuffer::sGLCount == 0); - LLVertexBuffer::unbind(); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); @@ -6157,15 +6875,16 @@ void LLPipeline::resetVertexBuffers() LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping); + + LLVOPartGroup::restoreGL(); } -void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture) +void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture) { - LLMemType mt_ro(LLMemType::MTYPE_PIPELINE_RENDER_OBJECTS); assertInitialized(); gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; - mSimplePool->pushBatches(type, mask); + mSimplePool->pushBatches(type, mask, texture, batch_texture); gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; } @@ -6234,7 +6953,6 @@ static LLFastTimer::DeclareTimer FTM_RENDER_BLOOM("Bloom"); void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) { - LLMemType mt_ru(LLMemType::MTYPE_PIPELINE_RENDER_BLOOM); if (!(gPipeline.canUseVertexShaders() && sRenderGlow)) { @@ -6252,17 +6970,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); @@ -6393,11 +7104,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGlowProgram.unbind(); - if (LLRenderTarget::sUseFBO) + /*if (LLRenderTarget::sUseFBO) { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); glBindFramebuffer(GL_FRAMEBUFFER, 0); - } + }*/ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; @@ -6464,15 +7175,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) } else { - LLViewerObject* obj = gAgentCamera.getFocusObject(); - if (obj) - { //focus on alt-zoom target - focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); - } - else - { //focus on your avatar - focus_point = gAgent.getPositionAgent(); - } + //focus on alt-zoom target + focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); } } @@ -6567,9 +7271,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) mDeferredLight.flush(); } + U32 dof_width = (U32) (mScreen.getWidth()*CameraDoFResScale); + U32 dof_height = (U32) (mScreen.getHeight()*CameraDoFResScale); + { //perform DoF sampling at half-res (preserve alpha channel) mScreen.bindTarget(); - glViewport(0,0,(GLsizei) (mScreen.getWidth()*CameraDoFResScale), (GLsizei) (mScreen.getHeight()*CameraDoFResScale)); + glViewport(0,0, dof_width, dof_height); gGL.setColorMask(true, false); shader = &gDeferredPostProgram; @@ -6582,7 +7289,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - + gGL.begin(LLRender::TRIANGLE_STRIP); gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); gGL.vertex2f(-1,-1); @@ -6627,6 +7334,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1); + shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height-1); gGL.begin(LLRender::TRIANGLE_STRIP); gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); @@ -6726,7 +7435,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); @@ -6746,11 +7461,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); @@ -6967,7 +7677,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n for (U32 i = 0; i < 4; i++) { - channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_TEXTURE); stop_glerror(); if (channel > -1) { @@ -6977,8 +7687,8 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); stop_glerror(); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); stop_glerror(); } } @@ -7027,13 +7737,12 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n cube_map->enable(channel); cube_map->bind(); F32* m = gGLModelView; - - + F32 mat[] = { m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9], m[10] }; - shader.uniform3fv(LLShaderMgr::DEFERRED_ENV_MAT, 3, mat); + shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat); } } @@ -7059,13 +7768,13 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n matrix_nondiag, matrix_nondiag, matrix_diag}; shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_SSAO_EFFECT_MAT, 1, GL_FALSE, ssao_effect_mat); - F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); - F32 shadow_bias_error = 1.f + RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); + //F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); + F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2])/3000.f; shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear()*2.f); - shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset*shadow_offset_error); - shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, RenderShadowBias*shadow_bias_error); + shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset); //*shadow_offset_error); + shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, RenderShadowBias+shadow_bias_error); shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_OFFSET, RenderSpotShadowOffset); shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_BIAS, RenderSpotShadowBias); @@ -7275,10 +7984,6 @@ void LLPipeline::renderDeferredLighting() gGL.popMatrix(); stop_glerror(); - //copy depth and stencil from deferred screen - //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), - // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - mScreen.bindTarget(); // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky glClearColor(0,0,0,0); @@ -7346,12 +8051,17 @@ void LLPipeline::renderDeferredLighting() std::list<LLVector4> light_colors; LLVertexBuffer::unbind(); - LLVector4a* v = (LLVector4a*) vert.get(); { bindDeferredShader(gDeferredLightProgram); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + + if (mCubeVB.isNull()) + { + mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); + } + mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) { @@ -7378,8 +8088,7 @@ void LLPipeline::renderDeferredLighting() F32 s = volume->getLightRadius()*1.5f; LLColor3 col = volume->getLightColor(); - col *= volume->getLightIntensity(); - + if (col.magVecSquared() < 0.001f) { continue; @@ -7398,25 +8107,7 @@ void LLPipeline::renderDeferredLighting() } sVisibleLightCount++; - - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); - - //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 - //meaning negative facing - mDeferredVB->getVertexStrider(vert); - v[0].set(c[0]-s,c[1]-s,c[2]-s); // 0 - 0000 - v[1].set(c[0]-s,c[1]-s,c[2]+s); // 1 - 0001 - v[2].set(c[0]-s,c[1]+s,c[2]-s); // 2 - 0010 - v[3].set(c[0]-s,c[1]+s,c[2]+s); // 3 - 0011 - - v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100 - v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101 - v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110 - v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111 - + if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || camera->getOrigin().mV[0] < c[0] - s - 0.2f || camera->getOrigin().mV[1] > c[1] + s + 0.2f || @@ -7434,16 +8125,13 @@ void LLPipeline::renderDeferredLighting() } LLFastTimer ftm(FTM_LOCAL_LIGHTS); - //glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); - gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); + gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s); gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); - //gGL.diffuseColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); gGL.syncMatrices(); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center)); + + mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); stop_glerror(); } } @@ -7456,6 +8144,9 @@ void LLPipeline::renderDeferredLighting() continue; } + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); + fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s)); light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); } @@ -7468,7 +8159,7 @@ void LLPipeline::renderDeferredLighting() LLGLDepthTest depth(GL_TRUE, GL_FALSE); bindDeferredShader(gDeferredSpotLightProgram); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); @@ -7486,37 +8177,17 @@ void LLPipeline::renderDeferredLighting() sVisibleLightCount++; - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); - 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 - //meaning negative facing - mDeferredVB->getVertexStrider(vert); - v[0].set(c[0]-s,c[1]-s,c[2]-s); // 0 - 0000 - v[1].set(c[0]-s,c[1]-s,c[2]+s); // 1 - 0001 - v[2].set(c[0]-s,c[1]+s,c[2]-s); // 2 - 0010 - v[3].set(c[0]-s,c[1]+s,c[2]+s); // 3 - 0011 - - v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100 - v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101 - v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110 - v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111 - gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); + gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s); gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); gGL.syncMatrices(); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center)); + + mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); } gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); unbindDeferredShader(gDeferredSpotLightProgram); @@ -7548,8 +8219,6 @@ void LLPipeline::renderDeferredLighting() LLVector4 light[max_count]; LLVector4 col[max_count]; -// glVertexPointer(2, GL_FLOAT, 0, vert); - F32 far_z = 0.f; while (!fullscreen_lights.empty()) @@ -7602,8 +8271,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); @@ -7826,9 +8494,9 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) for (U32 i = 0; i < 4; i++) { - if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE) > -1) + if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1) { - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); } } @@ -8079,6 +8747,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gGL.setColorMask(true, false); renderGeom(camera); + } LLPipeline::sUnderWaterRender = FALSE; @@ -8086,8 +8755,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate; - LLRenderTarget::unbindTarget(); - LLPipeline::sReflectionRender = FALSE; if (!LLRenderTarget::sUseFBO) @@ -8183,7 +8850,7 @@ static LLFastTimer::DeclareTimer FTM_SHADOW_RENDER("Render Shadows"); static LLFastTimer::DeclareTimer FTM_SHADOW_ALPHA("Alpha Shadow"); static LLFastTimer::DeclareTimer FTM_SHADOW_SIMPLE("Simple Shadow"); -void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, BOOL use_shader, BOOL use_occlusion) +void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, BOOL use_shader, BOOL use_occlusion, U32 target_width) { LLFastTimer t(FTM_SHADOW_RENDER); @@ -8195,12 +8862,19 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera } LLPipeline::sShadowRender = TRUE; - U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP, LLRenderPass::PASS_FULLBRIGHT_SHINY }; + U32 types[] = { + LLRenderPass::PASS_SIMPLE, + LLRenderPass::PASS_FULLBRIGHT, + LLRenderPass::PASS_SHINY, + LLRenderPass::PASS_BUMP, + LLRenderPass::PASS_FULLBRIGHT_SHINY + }; + LLGLEnable cull(GL_CULL_FACE); if (use_shader) { - gDeferredShadowProgram.bind(); + gDeferredShadowCubeProgram.bind(); } updateCull(shadow_cam, result); @@ -8217,17 +8891,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera stop_glerror(); gGLLastMatrix = NULL; - { - //LLGLDepthTest depth(GL_TRUE); - //glClear(GL_DEPTH_BUFFER_BIT); - } - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); stop_glerror(); - //glCullFace(GL_FRONT); - LLVertexBuffer::unbind(); { @@ -8235,11 +8902,16 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera { //occlusion program is general purpose depth-only no-textures gOcclusionProgram.bind(); } + else + { + gDeferredShadowProgram.bind(); + } gGL.diffuseColor4f(1,1,1,1); gGL.setColorMask(false, false); LLFastTimer ftm(FTM_SHADOW_SIMPLE); + gGL.getTexUnit(0)->disable(); for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) { @@ -8267,7 +8939,16 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera LLFastTimer ftm(FTM_SHADOW_ALPHA); gDeferredShadowAlphaMaskProgram.bind(); gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f); - renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE); + gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); + + U32 mask = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_TEXCOORD0 | + LLVertexBuffer::MAP_COLOR | + LLVertexBuffer::MAP_TEXTURE_INDEX; + + renderObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE); + renderObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE); + renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE); gDeferredTreeShadowProgram.bind(); gDeferredTreeShadowProgram.setMinimumAlpha(0.598f); renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); @@ -8275,7 +8956,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera //glCullFace(GL_BACK); - gDeferredShadowProgram.bind(); + gDeferredShadowCubeProgram.bind(); gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); doOcclusion(shadow_cam); @@ -8550,6 +9231,8 @@ void LLPipeline::generateHighlight(LLCamera& camera) } +static LLFastTimer::DeclareTimer FTM_GEN_SUN_SHADOW("Gen Sun Shadow"); + void LLPipeline::generateSunShadow(LLCamera& camera) { if (!sRenderDeferred || RenderShadowDetail <= 0) @@ -8557,6 +9240,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) return; } + LLFastTimer t(FTM_GEN_SUN_SHADOW); + BOOL skip_avatar_update = FALSE; if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) { @@ -8589,7 +9274,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_VOIDWATER, - LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW, + LLPipeline::RENDER_TYPE_PASS_ALPHA, + LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, LLPipeline::RENDER_TYPE_PASS_GRASS, LLPipeline::RENDER_TYPE_PASS_SIMPLE, LLPipeline::RENDER_TYPE_PASS_BUMP, @@ -8722,16 +9409,16 @@ void LLPipeline::generateSunShadow(LLCamera& camera) da = powf(da, split_exp.mV[2]); - F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da; - - + for (U32 i = 0; i < 4; ++i) { F32 x = (F32)(i+1)/4.f; x = powf(x, sxp); mSunClipPlanes.mV[i] = near_clip+range*x; } + + mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding } // convenience array of 4 near clip plane distances @@ -8788,8 +9475,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f; delta.normVec(); F32 dp = delta*pn; - frust[i] = eye + (delta*dist[j]*0.95f)/dp; - frust[i+4] = eye + (delta*dist[j+1]*1.05f)/dp; + frust[i] = eye + (delta*dist[j]*0.75f)/dp; + frust[i+4] = eye + (delta*dist[j+1]*1.25f)/dp; } shadow_cam.calcAgentFrustumPlanes(frust); @@ -9110,11 +9797,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadow[j].getViewport(gGLViewport); mShadow[j].clear(); + U32 target_width = mShadow[j].getWidth(); + { static LLCullResult result[4]; //LLGLEnable enable(GL_DEPTH_CLAMP_NV); - renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE); + renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width); } mShadow[j].flush(); @@ -9253,11 +9942,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadow[i+4].getViewport(gGLViewport); mShadow[i+4].clear(); + U32 target_width = mShadow[i+4].getWidth(); + static LLCullResult result[2]; LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; - renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); + renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width); mShadow[i+4].flush(); } @@ -9300,7 +9991,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) { - for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) + for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { LLSpatialGroup* group = *i; if (!group->isDead() && @@ -9313,9 +10004,14 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu } } +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_MARK_VISIBLE("Impostor Mark Visible"); +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_SETUP("Impostor Setup"); +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_BACKGROUND("Impostor Background"); +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_ALLOCATE("Impostor Allocate"); +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_RESIZE("Impostor Resize"); + void LLPipeline::generateImpostor(LLVOAvatar* avatar) { - LLMemType mt_gi(LLMemType::MTYPE_PIPELINE_GENERATE_IMPOSTOR); LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); @@ -9331,7 +10027,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) assertInitialized(); - BOOL muted = LLMuteList::getInstance()->isMuted(avatar->getID()); + bool muted = avatar->isVisuallyMuted(); pushRenderTypeMask(); @@ -9368,101 +10064,114 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) sImpostorRender = TRUE; LLViewerCamera* viewer_camera = LLViewerCamera::getInstance(); - markVisible(avatar->mDrawable, *viewer_camera); - LLVOAvatar::sUseImpostors = FALSE; - LLVOAvatar::attachment_map_t::iterator iter; - for (iter = avatar->mAttachmentPoints.begin(); - iter != avatar->mAttachmentPoints.end(); - ++iter) { - LLViewerJointAttachment *attachment = iter->second; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) + LLFastTimer t(FTM_IMPOSTOR_MARK_VISIBLE); + markVisible(avatar->mDrawable, *viewer_camera); + LLVOAvatar::sUseImpostors = FALSE; + + LLVOAvatar::attachment_map_t::iterator iter; + for (iter = avatar->mAttachmentPoints.begin(); + iter != avatar->mAttachmentPoints.end(); + ++iter) { - if (LLViewerObject* attached_object = (*attachment_iter)) + LLViewerJointAttachment *attachment = iter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); + if (LLViewerObject* attached_object = (*attachment_iter)) + { + markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); + } } } } stateSort(*LLViewerCamera::getInstance(), result); - const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); - LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); - LLCamera camera = *viewer_camera; - - camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis()); - LLVector2 tdim; + U32 resY = 0; + U32 resX = 0; + { + LLFastTimer t(FTM_IMPOSTOR_SETUP); + const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); + LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); - LLVector4a half_height; - half_height.setSub(ext[1], ext[0]); - half_height.mul(0.5f); + camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis()); + + LLVector4a half_height; + half_height.setSub(ext[1], ext[0]); + half_height.mul(0.5f); - LLVector4a left; - left.load3(camera.getLeftAxis().mV); - left.mul(left); - left.normalize3fast(); + LLVector4a left; + left.load3(camera.getLeftAxis().mV); + left.mul(left); + left.normalize3fast(); - LLVector4a up; - up.load3(camera.getUpAxis().mV); - up.mul(up); - up.normalize3fast(); + LLVector4a up; + up.load3(camera.getUpAxis().mV); + up.mul(up); + up.normalize3fast(); - tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); - tdim.mV[1] = fabsf(half_height.dot3(up).getF32()); + tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); + tdim.mV[1] = fabsf(half_height.dot3(up).getF32()); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); - F32 distance = (pos-camera.getOrigin()).length(); - F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; - F32 aspect = tdim.mV[0]/tdim.mV[1]; - glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); - glh_set_current_projection(persp); - gGL.loadMatrix(persp.m); + F32 distance = (pos-camera.getOrigin()).length(); + F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; + F32 aspect = tdim.mV[0]/tdim.mV[1]; + glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); + glh_set_current_projection(persp); + gGL.loadMatrix(persp.m); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - glh::matrix4f mat; - camera.getOpenGLTransform(mat.m); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + glh::matrix4f mat; + camera.getOpenGLTransform(mat.m); - mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; + mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; - gGL.loadMatrix(mat.m); - glh_set_current_modelview(mat); + gGL.loadMatrix(mat.m); + glh_set_current_modelview(mat); - glClearColor(0.0f,0.0f,0.0f,0.0f); - gGL.setColorMask(true, true); + glClearColor(0.0f,0.0f,0.0f,0.0f); + gGL.setColorMask(true, true); - // get the number of pixels per angle - F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView()); + // get the number of pixels per angle + F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView()); - //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing) - U32 resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512); - U32 resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512); + //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing) + resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512); + resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512); - if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() || - resY != avatar->mImpostor.getHeight()) - { - avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); + if (!avatar->mImpostor.isComplete()) + { + LLFastTimer t(FTM_IMPOSTOR_ALLOCATE); + avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); + + if (LLPipeline::sRenderDeferred) + { + addDeferredAttachments(avatar->mImpostor); + } - if (LLPipeline::sRenderDeferred) + gGL.getTexUnit(0)->bind(&avatar->mImpostor); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + } + else if(resX != avatar->mImpostor.getWidth() || + resY != avatar->mImpostor.getHeight()) { - addDeferredAttachments(avatar->mImpostor); + LLFastTimer t(FTM_IMPOSTOR_RESIZE); + avatar->mImpostor.resize(resX,resY,GL_RGBA); } - - gGL.getTexUnit(0)->bind(&avatar->mImpostor); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - } - avatar->mImpostor.bindTarget(); + avatar->mImpostor.bindTarget(); + } if (LLPipeline::sRenderDeferred) { @@ -9479,6 +10188,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) } { //create alpha mask based on depth buffer (grey out if muted) + LLFastTimer t(FTM_IMPOSTOR_BACKGROUND); if (LLPipeline::sRenderDeferred) { GLuint buff = GL_COLOR_ATTACHMENT0; @@ -9564,22 +10274,22 @@ BOOL LLPipeline::hasRenderBatches(const U32 type) const return sCull->getRenderMapSize(type) > 0; } -LLCullResult::drawinfo_list_t::iterator LLPipeline::beginRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type) { return sCull->beginRenderMap(type); } -LLCullResult::drawinfo_list_t::iterator LLPipeline::endRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type) { return sCull->endRenderMap(type); } -LLCullResult::sg_list_t::iterator LLPipeline::beginAlphaGroups() +LLCullResult::sg_iterator LLPipeline::beginAlphaGroups() { return sCull->beginAlphaGroups(); } -LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups() +LLCullResult::sg_iterator LLPipeline::endAlphaGroups() { return sCull->endAlphaGroups(); } @@ -9710,3 +10420,143 @@ void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color) mDebugBlips.push_back(blip); } +void LLPipeline::hidePermanentObjects( std::vector<U32>& restoreList ) +{ + //This method is used to hide any vo's from the object list that may have + //the permanent flag set. + + U32 objCnt = gObjectList.getNumObjects(); + for (U32 i = 0; i < objCnt; ++i) + { + LLViewerObject* pObject = gObjectList.getObject(i); + if ( pObject && pObject->flagObjectPermanent() ) + { + LLDrawable *pDrawable = pObject->mDrawable; + + if ( pDrawable ) + { + restoreList.push_back( i ); + hideDrawable( pDrawable ); + } + } + } + + skipRenderingOfTerrain( true ); +} + +void LLPipeline::restorePermanentObjects( const std::vector<U32>& restoreList ) +{ + //This method is used to restore(unhide) any vo's from the object list that may have + //been hidden because their permanency flag was set. + + std::vector<U32>::const_iterator itCurrent = restoreList.begin(); + std::vector<U32>::const_iterator itEnd = restoreList.end(); + + U32 objCnt = gObjectList.getNumObjects(); + + while ( itCurrent != itEnd ) + { + U32 index = *itCurrent; + LLViewerObject* pObject = NULL; + if ( index < objCnt ) + { + pObject = gObjectList.getObject( index ); + } + if ( pObject ) + { + LLDrawable *pDrawable = pObject->mDrawable; + if ( pDrawable ) + { + pDrawable->clearState( LLDrawable::FORCE_INVISIBLE ); + unhideDrawable( pDrawable ); + } + } + ++itCurrent; + } + + skipRenderingOfTerrain( false ); +} + +void LLPipeline::skipRenderingOfTerrain( BOOL flag ) +{ + pool_set_t::iterator iter = mPools.begin(); + while ( iter != mPools.end() ) + { + LLDrawPool* pPool = *iter; + U32 poolType = pPool->getType(); + if ( hasRenderType( pPool->getType() ) && poolType == LLDrawPool::POOL_TERRAIN ) + { + pPool->setSkipRenderFlag( flag ); + } + ++iter; + } +} + +void LLPipeline::hideObject( const LLUUID& id ) +{ + LLViewerObject *pVO = gObjectList.findObject( id ); + + if ( pVO ) + { + LLDrawable *pDrawable = pVO->mDrawable; + + if ( pDrawable ) + { + hideDrawable( pDrawable ); + } + } +} + +void LLPipeline::hideDrawable( LLDrawable *pDrawable ) +{ + pDrawable->setState( LLDrawable::FORCE_INVISIBLE ); + markRebuild( pDrawable, LLDrawable::REBUILD_ALL, TRUE ); + //hide the children + LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren(); + for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++ ) + { + LLViewerObject* child = *iter; + LLDrawable* drawable = child->mDrawable; + if ( drawable ) + { + drawable->setState( LLDrawable::FORCE_INVISIBLE ); + markRebuild( drawable, LLDrawable::REBUILD_ALL, TRUE ); + } + } +} +void LLPipeline::unhideDrawable( LLDrawable *pDrawable ) +{ + pDrawable->clearState( LLDrawable::FORCE_INVISIBLE ); + markRebuild( pDrawable, LLDrawable::REBUILD_ALL, TRUE ); + //restore children + LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren(); + for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + LLDrawable* drawable = child->mDrawable; + if ( drawable ) + { + drawable->clearState( LLDrawable::FORCE_INVISIBLE ); + markRebuild( drawable, LLDrawable::REBUILD_ALL, TRUE ); + } + } +} +void LLPipeline::restoreHiddenObject( const LLUUID& id ) +{ + LLViewerObject *pVO = gObjectList.findObject( id ); + + if ( pVO ) + { + LLDrawable *pDrawable = pVO->mDrawable; + if ( pDrawable ) + { + unhideDrawable( pDrawable ); + } + } +} + + + + diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 8b6532ca25..36abeca295 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -111,13 +111,33 @@ public: void destroyGL(); void restoreGL(); void resetVertexBuffers(); + void doResetVertexBuffers(); void resizeScreenTexture(); void releaseGLBuffers(); + void releaseLUTBuffers(); void releaseScreenBuffers(); void createGLBuffers(); + void createLUTBuffers(); - void allocateScreenBuffer(U32 resX, U32 resY); + //allocate the largest screen buffer possible up to resX, resY + //returns true if full size buffer allocated, false if some other size is allocated + bool allocateScreenBuffer(U32 resX, U32 resY); + + typedef enum { + FBO_SUCCESS_FULLRES = 0, + FBO_SUCCESS_LOWRES, + FBO_FAILURE + } eFBOStatus; + +private: + //implementation of above, wrapped for easy error handling + eFBOStatus doAllocateScreenBuffer(U32 resX, U32 resY); +public: + + //attempt to allocate screen buffers at resX, resY + //returns true if allocation successful, false otherwise bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples); + void allocatePhysicsBuffer(); void resetVertexBuffers(LLDrawable* drawable); @@ -148,6 +168,8 @@ public: void unlinkDrawable(LLDrawable*); + static void removeMutedAVsLights(LLVOAvatar*); + // Object related methods void markVisible(LLDrawable *drawablep, LLCamera& camera); void markOccluder(LLSpatialGroup* group); @@ -160,6 +182,7 @@ public: void markRebuild(LLSpatialGroup* group, BOOL priority = FALSE); void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE); void markPartitionMove(LLDrawable* drawablep); + void markMeshDirty(LLSpatialGroup* group); //get the object between start and end that's closest to start. LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, @@ -219,6 +242,7 @@ public: void updateGL(); void rebuildPriorityGroups(); void rebuildGroups(); + void clearRebuildGroups(); //calculate pixel area of given box from vantage point of given camera static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); @@ -231,7 +255,7 @@ public: void postSort(LLCamera& camera); void forAllVisibleDrawables(void (*func)(LLDrawable*)); - void renderObjects(U32 type, U32 mask, BOOL texture = TRUE); + void renderObjects(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_texture = FALSE); void renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture); void grabReferences(LLCullResult& result); @@ -261,7 +285,7 @@ public: void setHighlightObject(LLDrawable* obj) { mHighlightObject = obj; } - void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, BOOL use_shader = TRUE, BOOL use_occlusion = TRUE); + void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, BOOL use_shader, BOOL use_occlusion, U32 target_width); void renderHighlights(); void renderDebug(); void renderPhysicsDisplay(); @@ -290,10 +314,10 @@ public: void setLight(LLDrawable *drawablep, BOOL is_light); BOOL hasRenderBatches(const U32 type) const; - LLCullResult::drawinfo_list_t::iterator beginRenderMap(U32 type); - LLCullResult::drawinfo_list_t::iterator endRenderMap(U32 type); - LLCullResult::sg_list_t::iterator beginAlphaGroups(); - LLCullResult::sg_list_t::iterator endAlphaGroups(); + LLCullResult::drawinfo_iterator beginRenderMap(U32 type); + LLCullResult::drawinfo_iterator endRenderMap(U32 type); + LLCullResult::sg_iterator beginAlphaGroups(); + LLCullResult::sg_iterator endAlphaGroups(); void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES); @@ -359,13 +383,18 @@ public: static BOOL getRenderHighlights(void* data); static void updateRenderDeferred(); - static void refreshRenderDeferred(); static void refreshCachedSettings(); static void throttleNewMemoryAllocation(BOOL disable); void addDebugBlip(const LLVector3& position, const LLColor4& color); + void hidePermanentObjects( std::vector<U32>& restoreList ); + void restorePermanentObjects( const std::vector<U32>& restoreList ); + void skipRenderingOfTerrain( BOOL flag ); + void hideObject( const LLUUID& id ); + void restoreHiddenObject( const LLUUID& id ); + private: void unloadShaders(); void addToQuickLookup( LLDrawPool* new_poolp ); @@ -373,7 +402,9 @@ private: BOOL updateDrawableGeom(LLDrawable* drawable, BOOL priority); void assertInitializedDoError(); bool assertInitialized() { const bool is_init = isInit(); if (!is_init) assertInitializedDoError(); return is_init; }; - + void connectRefreshCachedSettingsSafe(const std::string name); + void hideDrawable( LLDrawable *pDrawable ); + void unhideDrawable( LLDrawable *pDrawable ); public: enum {GPU_CLASS_MAX = 3 }; @@ -408,7 +439,6 @@ public: RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA, RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK, RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, - RENDER_TYPE_PASS_ALPHA_SHADOW = LLRenderPass::PASS_ALPHA_SHADOW, // Following are object types (only used in drawable mRenderType) RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES, RENDER_TYPE_VOLUME, @@ -434,34 +464,36 @@ 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, + RENDER_DEBUG_TEXEL_DENSITY = 0x20000000 }; public: @@ -541,6 +573,9 @@ public: //utility buffer for rendering post effects, gets abused by renderDeferredLighting LLPointer<LLVertexBuffer> mDeferredVB; + //utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1] + LLPointer<LLVertexBuffer> mCubeVB; + //sun shadow map LLRenderTarget mShadow[6]; std::vector<LLVector3> mShadowFrustPoints[4]; @@ -592,6 +627,7 @@ public: BOOL mVertexShadersEnabled; S32 mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed + U32 mTransformFeedbackPrimitives; //number of primitives expected to be generated by transform feedback protected: BOOL mRenderTypeEnabled[NUM_RENDER_TYPES]; std::stack<std::string> mRenderTypeEnableStack; @@ -649,11 +685,18 @@ protected: LLSpatialGroup::sg_vector_t mGroupQ1; //priority LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority + LLSpatialGroup::sg_vector_t mGroupSaveQ1; // a place to save mGroupQ1 until it is safe to unref + + LLSpatialGroup::sg_vector_t mMeshDirtyGroup; //groups that need rebuildMesh called + U32 mMeshDirtyQueryObject; + LLDrawable::drawable_list_t mPartitionQ; //drawables that need to update their spatial partition radius bool mGroupQ2Locked; bool mGroupQ1Locked; + bool mResetVertexBuffers; //if true, clear vertex buffers on next update + LLViewerObject::vobj_list_t mCreateQ; LLDrawable::drawable_set_t mRetexturedList; @@ -847,6 +890,7 @@ public: static BOOL CameraOffset; static F32 CameraMaxCoF; static F32 CameraDoFResScale; + static F32 RenderAutoHideSurfaceAreaLimit; }; void render_bbox(const LLVector3 &min, const LLVector3 &max); diff --git a/indra/newview/res-sdl/lltoolpathfinding.BMP b/indra/newview/res-sdl/lltoolpathfinding.BMP Binary files differnew file mode 100644 index 0000000000..a567951b7a --- /dev/null +++ b/indra/newview/res-sdl/lltoolpathfinding.BMP diff --git a/indra/newview/res-sdl/lltoolpathfindingpathend.BMP b/indra/newview/res-sdl/lltoolpathfindingpathend.BMP Binary files differnew file mode 100644 index 0000000000..aacea8237f --- /dev/null +++ b/indra/newview/res-sdl/lltoolpathfindingpathend.BMP diff --git a/indra/newview/res-sdl/lltoolpathfindingpathendadd.BMP b/indra/newview/res-sdl/lltoolpathfindingpathendadd.BMP Binary files differnew file mode 100644 index 0000000000..fa19f3f105 --- /dev/null +++ b/indra/newview/res-sdl/lltoolpathfindingpathendadd.BMP diff --git a/indra/newview/res-sdl/lltoolpathfindingpathstart.BMP b/indra/newview/res-sdl/lltoolpathfindingpathstart.BMP Binary files differnew file mode 100644 index 0000000000..912b7f931a --- /dev/null +++ b/indra/newview/res-sdl/lltoolpathfindingpathstart.BMP diff --git a/indra/newview/res-sdl/lltoolpathfindingpathstartadd.BMP b/indra/newview/res-sdl/lltoolpathfindingpathstartadd.BMP Binary files differnew file mode 100644 index 0000000000..4e8999ae0b --- /dev/null +++ b/indra/newview/res-sdl/lltoolpathfindingpathstartadd.BMP diff --git a/indra/newview/res/lltoolpathfinding.cur b/indra/newview/res/lltoolpathfinding.cur Binary files differnew file mode 100644 index 0000000000..2aba2daa45 --- /dev/null +++ b/indra/newview/res/lltoolpathfinding.cur diff --git a/indra/newview/res/lltoolpathfindingpathend.cur b/indra/newview/res/lltoolpathfindingpathend.cur Binary files differnew file mode 100644 index 0000000000..e951a6956b --- /dev/null +++ b/indra/newview/res/lltoolpathfindingpathend.cur diff --git a/indra/newview/res/lltoolpathfindingpathendadd.cur b/indra/newview/res/lltoolpathfindingpathendadd.cur Binary files differnew file mode 100644 index 0000000000..0bf3201b23 --- /dev/null +++ b/indra/newview/res/lltoolpathfindingpathendadd.cur diff --git a/indra/newview/res/lltoolpathfindingpathstart.cur b/indra/newview/res/lltoolpathfindingpathstart.cur Binary files differnew file mode 100644 index 0000000000..fecc716990 --- /dev/null +++ b/indra/newview/res/lltoolpathfindingpathstart.cur diff --git a/indra/newview/res/lltoolpathfindingpathstartadd.cur b/indra/newview/res/lltoolpathfindingpathstartadd.cur Binary files differnew file mode 100644 index 0000000000..45e23e5161 --- /dev/null +++ b/indra/newview/res/lltoolpathfindingpathstartadd.cur diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index a53dece422..df75f3f697 100644 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -122,6 +122,12 @@ TOOLMEDIAOPEN CURSOR "toolmediaopen.cur" TOOLBUY CURSOR "toolbuy.cur" TOOLOPEN CURSOR "toolopen.cur" TOOLSIT CURSOR "toolsit.cur" +TOOLPATHFINDING CURSOR "lltoolpathfinding.cur" +TOOLPATHFINDINGPATHSTART CURSOR "lltoolpathfindingpathstart.cur" +TOOLPATHFINDINGPATHSTARTADD CURSOR "lltoolpathfindingpathstartadd.cur" +TOOLPATHFINDINGPATHEND CURSOR "lltoolpathfindingpathend.cur" +TOOLPATHFINDINGPATHENDADD CURSOR "lltoolpathfindingpathendadd.cur" +TOOLNO CURSOR "llno.cur" ///////////////////////////////////////////////////////////////////////////// // diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 8baaa14595..0de217fc0d 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -12,6 +12,9 @@ name="EmphasisColor_35" value="0.38 0.694 0.573 0.35" /> <color + name="BeaconColor" + value="0.749 0.298 0 1" /> + <color name="White" value="1 1 1 1" /> <color @@ -98,6 +101,21 @@ <color name="MdBlue" value=".07 .38 .51 1" /> + <color + name="LtRed" + value="1 0.2 0.2 1" /> + <color + name="LtGreen" + value="0.2 1 0.2 1" /> + <color + name="Red_80" + value="1 0 0 0.8" /> + <color + name="Green_80" + value="0 1 0 0.8" /> + <color + name="Blue_80" + value="0 0 1 0.8" /> <!-- This color name makes potentially unused colors show up bright purple. Leave this here until all Unused? are removed below, otherwise @@ -508,6 +526,9 @@ name="MenuItemHighlightBgColor" reference="EmphasisColor_35" /> <color + name="MenuItemFlashBgColor" + reference="BeaconColor" /> + <color name="MenuItemHighlightFgColor" reference="White" /> <color @@ -615,9 +636,33 @@ name="PanelFocusBackgroundColor" reference="DkGray2" /> <color + name="PanelNotificationBackground" + value="1 0.3 0.3 0" /> + <color name="ParcelHoverColor" reference="White" /> <color + name="PathfindingErrorColor" + reference="LtRed" /> + <color + name="PathfindingWarningColor" + reference="DrYellow" /> + <color + name="PathfindingGoodColor" + reference="LtGreen" /> + <color + name="PathfindingDefaultBeaconColor" + reference="Red_80" /> + <color + name="PathfindingDefaultBeaconTextColor" + reference="White" /> + <color + name="PathfindingLinksetBeaconColor" + reference="Blue_80" /> + <color + name="PathfindingCharacterBeaconColor" + reference="Red_80" /> + <color name="PieMenuBgColor" value="0.24 0.24 0.24 0.59" /> <color @@ -747,6 +792,9 @@ name="TitleBarFocusColor" reference="White_10" /> <color + name="ToastBackground" + value="0.3 0.3 0.3 0" /> + <color name="ToolTipBgColor" value="0.937 0.89 0.655 1" /> <color @@ -760,7 +808,7 @@ reference="LtGray" /> <color name="UserChatColor" - reference="White" /> + reference="Yellow" /> <color name="llOwnerSayChatColor" reference="LtYellow" /> diff --git a/indra/newview/skins/default/textures/bottomtray/Unread_IM.png b/indra/newview/skins/default/textures/bottomtray/Unread_IM.png Binary files differdeleted file mode 100644 index 5c0c85b864..0000000000 --- a/indra/newview/skins/default/textures/bottomtray/Unread_IM.png +++ /dev/null diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png Binary files differdeleted file mode 100644 index 857fa1e047..0000000000 --- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png +++ /dev/null diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png Binary files differdeleted file mode 100644 index 453bb53673..0000000000 --- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png +++ /dev/null diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png Binary files differdeleted file mode 100644 index 135a66ca0d..0000000000 --- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png +++ /dev/null diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png Binary files differdeleted file mode 100644 index a63aec5e6d..0000000000 --- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png +++ /dev/null diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png Binary files differdeleted file mode 100644 index 1719eb3e84..0000000000 --- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png +++ /dev/null diff --git a/indra/newview/skins/default/textures/checker.png b/indra/newview/skins/default/textures/checker.png Binary files differnew file mode 100644 index 0000000000..1ab87e3f02 --- /dev/null +++ b/indra/newview/skins/default/textures/checker.png diff --git a/indra/newview/skins/default/textures/icons/Conv_log_inbox.png b/indra/newview/skins/default/textures/icons/Conv_log_inbox.png Binary files differnew file mode 100644 index 0000000000..bb6ca28147 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Conv_log_inbox.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png Binary files differnew file mode 100755 index 0000000000..0631f16f3b --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png Binary files differnew file mode 100755 index 0000000000..578482f5ed --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png Binary files differnew file mode 100755 index 0000000000..7676131790 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png Binary files differnew file mode 100755 index 0000000000..2880eb766a --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png Binary files differnew file mode 100755 index 0000000000..d009c8f446 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png Binary files differnew file mode 100755 index 0000000000..8d82960e28 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png Binary files differnew file mode 100755 index 0000000000..f718d3fc60 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png Binary files differnew file mode 100755 index 0000000000..315e2c581a --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png Binary files differnew file mode 100755 index 0000000000..732ab02a20 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png Binary files differnew file mode 100755 index 0000000000..25a32cb2ba --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png Binary files differnew file mode 100755 index 0000000000..08debeb91f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png diff --git a/indra/newview/skins/default/textures/icons/Pathfinding_Dirty.png b/indra/newview/skins/default/textures/icons/Pathfinding_Dirty.png Binary files differnew file mode 100644 index 0000000000..cfa12cb7cc --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Pathfinding_Dirty.png diff --git a/indra/newview/skins/default/textures/icons/Pathfinding_Disabled.png b/indra/newview/skins/default/textures/icons/Pathfinding_Disabled.png Binary files differnew file mode 100644 index 0000000000..0622141848 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Pathfinding_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png Binary files differnew file mode 100644 index 0000000000..5ac4258b9d --- /dev/null +++ b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png diff --git a/indra/newview/skins/default/textures/map_avatar_unknown_32.tga b/indra/newview/skins/default/textures/map_avatar_unknown_32.tga Binary files differnew file mode 100644 index 0000000000..d1192478c6 --- /dev/null +++ b/indra/newview/skins/default/textures/map_avatar_unknown_32.tga diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 8702ebde2a..a07d7e4855 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -54,6 +54,8 @@ with the same filename but different name <texture name="Arrow_Down" file_name="widgets/Arrow_Down.png" preload="true" /> <texture name="Arrow_Up" file_name="widgets/Arrow_Up.png" preload="true" /> + <texture name="Arrow_Left" file_name="widgets/Arrow_Left.png" preload="true" /> + <texture name="Arrow_Right" file_name="widgets/Arrow_Right.png" preload="true" /> <texture name="AudioMute_Off" file_name="icons/AudioMute_Off.png" preload="false" /> <texture name="AudioMute_Over" file_name="icons/AudioMute_Over.png" preload="false" /> @@ -122,6 +124,8 @@ with the same filename but different name <texture name="Checkbox_Press" file_name="widgets/Checkbox_Press.png" preload="true" /> <texture name="Check_Mark" file_name="icons/check_mark.png" preload="true" /> + <texture name="Checker" file_name="checker.png" preload="false" /> + <texture name="Command_AboutLand_Icon" file_name="toolbar_icons/land.png" preload="true" /> <texture name="Command_Appearance_Icon" file_name="toolbar_icons/appearance.png" preload="true" /> <texture name="Command_Avatar_Icon" file_name="toolbar_icons/avatars.png" preload="true" /> @@ -137,6 +141,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" /> @@ -157,7 +162,22 @@ with the same filename but different name <texture name="ComboButton_On" file_name="widgets/ComboButton_On.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> <texture name="ComboButton_Off" file_name="widgets/ComboButton_Off.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> <texture name="ComboButton_UpOff" file_name="widgets/ComboButton_UpOff.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> + <texture name="Container" file_name="containers/Container.png" preload="false" /> + + <texture name="Conv_toolbar_add_person" file_name="icons/Conv_toolbar_add_person.png" preload="false" /> + <texture name="Conv_toolbar_arrow_ne" file_name="icons/Conv_toolbar_arrow_ne.png" preload="false" /> + <texture name="Conv_toolbar_arrow_sw" file_name="icons/Conv_toolbar_arrow_sw.png" preload="false" /> + <texture name="Conv_toolbar_call_log" file_name="icons/Conv_toolbar_call_log.png" preload="false" /> + <texture name="Conv_toolbar_close" file_name="icons/Conv_toolbar_close.png" preload="false" /> + <texture name="Conv_toolbar_collapse" file_name="icons/Conv_toolbar_collapse.png" preload="false" /> + <texture name="Conv_toolbar_expand" file_name="icons/Conv_toolbar_expand.png" preload="false" /> + <texture name="Conv_toolbar_hang_up" file_name="icons/Conv_toolbar_hang_up.png" preload="false" /> + <texture name="Conv_toolbar_open_call" file_name="icons/Conv_toolbar_open_call.png" preload="false" /> + <texture name="Conv_toolbar_plus" file_name="icons/Conv_toolbar_plus.png" preload="false" /> + <texture name="Conv_toolbar_sort" file_name="icons/Conv_toolbar_sort.png" preload="false" /> + <texture name="Conv_log_inbox" file_name="icons/Conv_log_inbox.png" preload="false" /> + <texture name="Copy" file_name="icons/Copy.png" preload="false" /> <texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" /> @@ -343,6 +363,8 @@ with the same filename but different name <texture name="NavBar_BG_NoFav_Bevel" file_name="navbar/NavBar_BG_NoFav_Bevel.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" /> <texture name="NavBar_BG_NoNav_Bevel" file_name="navbar/NavBar_BG_NoNav_Bevel.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" /> + <texture name="Nearby_chat_icon" file_name="icons/nearby_chat_icon.png" preload="false" /> + <texture name="Notices_Unread" file_name="bottomtray/Notices_Unread.png" preload="true" /> <texture name="NoEntryLines" file_name="world/NoEntryLines.png" use_mips="true" preload="false" /> @@ -386,22 +408,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" /> @@ -439,6 +448,9 @@ with the same filename but different name <texture name="Parcel_Voice_Light" file_name="icons/Parcel_Voice_Light.png" preload="false" /> <texture name="Parcel_VoiceNo_Light" file_name="icons/Parcel_VoiceNo_Light.png" preload="false" /> + <texture name="Pathfinding_Dirty" file_name="icons/Pathfinding_Dirty.png" preload="false" /> + <texture name="Pathfinding_Disabled" file_name="icons/Pathfinding_Disabled.png" preload="false" /> + <texture name="Pause_Off" file_name="icons/Pause_Off.png" preload="false" /> <texture name="Pause_Over" file_name="icons/Pause_Over.png" preload="false" /> <texture name="Pause_Press" file_name="icons/Pause_Press.png" preload="false" /> @@ -630,7 +642,6 @@ with the same filename but different name <texture name="TrashItem_Press" file_name="icons/TrashItem_Press.png" preload="false" /> <texture name="Unread_Chiclet" file_name="bottomtray/Unread_Chiclet.png" preload="false" /> - <texture name="Unread_IM" file_name="bottomtray/Unread_IM.png" preload="false" /> <texture name="UpArrow_Off" file_name="icons/UpArrow_Off.png" preload="false" /> @@ -643,12 +654,6 @@ with the same filename but different name <texture name="VoicePTT_Off" file_name="bottomtray/VoicePTT_Off.png" preload="false" /> <texture name="VoicePTT_On" file_name="bottomtray/VoicePTT_On.png" preload="false" /> - <texture name="VoicePTT_Lvl1_Dark" file_name="bottomtray/VoicePTT_Lvl1_Dark.png" preload="false" /> - <texture name="VoicePTT_Lvl2_Dark" file_name="bottomtray/VoicePTT_Lvl2_Dark.png" preload="false" /> - <texture name="VoicePTT_Lvl3_Dark" file_name="bottomtray/VoicePTT_Lvl3_Dark.png" preload="false" /> - <texture name="VoicePTT_Off_Dark" file_name="bottomtray/VoicePTT_Off_Dark.png" preload="false" /> - <texture name="VoicePTT_On_Dark" file_name="bottomtray/VoicePTT_On_Dark.png" preload="false" /> - <texture name="Wearables_Divider" file_name="windows/Wearables_Divider.png" preload="false" /> <texture name="Web_Profile_Off" file_name="icons/Web_Profile_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 Binary files differnew file mode 100644 index 0000000000..0f3db1c47c --- /dev/null +++ b/indra/newview/skins/default/textures/toolbar_icons/outbox.png diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Left.png b/indra/newview/skins/default/textures/widgets/Arrow_Left.png Binary files differnew file mode 100644 index 0000000000..a424282839 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/Arrow_Left.png diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Right.png b/indra/newview/skins/default/textures/widgets/Arrow_Right.png Binary files differnew file mode 100644 index 0000000000..e32bee8f34 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/Arrow_Right.png diff --git a/indra/newview/skins/default/xui/da/floater_camera.xml b/indra/newview/skins/default/xui/da/floater_camera.xml index 5b7ef6db54..b5d5e8bc08 100644 --- a/indra/newview/skins/default/xui/da/floater_camera.xml +++ b/indra/newview/skins/default/xui/da/floater_camera.xml @@ -9,15 +9,6 @@ <floater.string name="move_tooltip"> Flyt kamera op og ned, til venstre og højre </floater.string> - <floater.string name="camera_modes_title"> - Kamera valg - </floater.string> - <floater.string name="pan_mode_title"> - Kredsløb zoom panorering - </floater.string> - <floater.string name="presets_mode_title"> - Forvalg - </floater.string> <floater.string name="free_mode_title"> Se objekt </floater.string> diff --git a/indra/newview/skins/default/xui/da/floater_model_wizard.xml b/indra/newview/skins/default/xui/da/floater_model_wizard.xml deleted file mode 100644 index 8ad443581a..0000000000 --- a/indra/newview/skins/default/xui/da/floater_model_wizard.xml +++ /dev/null @@ -1,241 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Model Wizard" title="UPLOAD MODEL WIZARD"> - <button label="5. Upload" name="upload_btn"/> - <button label="4. Review" name="review_btn"/> - <button label="3. Physics" name="physics2_btn"/> - <button label="3. Physics" name="physics_btn"/> - <button label="2. Optimize" name="optimize_btn"/> - <button label="1. Choose File" name="choose_file_btn"/> - <panel name="choose_file_panel"> - <panel name="header_panel"> - <text name="header_text"> - Upload Model - </text> - </panel> - <text name="description"> - This wizard will help you import mesh models to Second Life. First specify a file containing the model you wish to import. Second Life supports COLLADA (.dae) files. - </text> - <panel name="content"> - <text name="Cache location"> - Filename: - </text> - <button label="Browse..." label_selected="Browse..." name="browse"/> - <text name="dimensions"> - X: Y: Z: - </text> - <text name="dimension_dividers"> - | | - </text> - </panel> - </panel> - <panel name="optimize_panel"> - <panel name="header_panel"> - <text name="header_text"> - Optimize - </text> - </panel> - <text name="description"> - This wizard has optimized your model to improve performance. You may adjust the results of the optimization process bellow or click Next to continue. - </text> - <panel name="content"> - <text name="high_detail_text"> - Generate Level of Detail: High - </text> - <text name="medium_detail_text"> - Generate Level of Detail: Medium - </text> - <text name="low_detail_text"> - Generate Level of Detail: Low - </text> - <text name="lowest_detail_text"> - Generate Level of Detail: Lowest - </text> - </panel> - <panel name="content2"> - <text name="lod_label"> - Model Preview: - </text> - <combo_box name="preview_lod_combo2" tool_tip="LOD to view in preview render"> - <combo_item name="high"> - High - </combo_item> - <combo_item name="medium"> - Medium - </combo_item> - <combo_item name="low"> - Low - </combo_item> - <combo_item name="lowest"> - Lowest - </combo_item> - </combo_box> - <text name="streaming cost"> - Resource Cost: [COST] - </text> - <text name="dimensions"> - X: Y: Z: - </text> - <text name="dimension_dividers"> - | | - </text> - </panel> - </panel> - <panel name="physics_panel"> - <panel name="header_panel"> - <text name="header_text"> - Physics - </text> - </panel> - <text name="description"> - The wizard will create a physical shape, which determines how the object interacts with other objects and avatars. Set the slider to the detail level most appropriate for how your object will be used: - </text> - <panel name="content"> - <text name="streaming cost"> - Resource Cost: [COST] - </text> - </panel> - </panel> - <panel name="physics2_panel"> - <panel name="header_panel"> - <text name="header_text"> - Physics - </text> - </panel> - <text name="description"> - Preview the physics shape below then click Next to continue. To modify the physics shape, click the Back button. - </text> - <panel name="content"> - <text name="lod_label"> - Model Preview: - </text> - <combo_box name="preview_lod_combo3" tool_tip="LOD to view in preview render"> - <combo_item name="high"> - High - </combo_item> - <combo_item name="medium"> - Medium - </combo_item> - <combo_item name="low"> - Low - </combo_item> - <combo_item name="lowest"> - Lowest - </combo_item> - </combo_box> - <text name="dimensions"> - X: Y: Z: - </text> - <text name="dimension_dividers"> - | | - </text> - <text name="streaming cost"> - Resource Cost: [COST] - </text> - </panel> - </panel> - <panel name="review_panel"> - <panel name="header_panel"> - <text name="header_text"> - Review - </text> - </panel> - <text name="description"> - Review the details below then click. Upload to upload your model. Your L$ balance will be charged when you click Upload. - </text> - <panel name="content"> - <text name="lod_label"> - Model Preview: - </text> - <combo_box name="preview_lod_combo" tool_tip="LOD to view in preview render"> - <combo_item name="high"> - High - </combo_item> - <combo_item name="medium"> - Medium - </combo_item> - <combo_item name="low"> - Low - </combo_item> - <combo_item name="lowest"> - Lowest - </combo_item> - </combo_box> - <text name="dimensions"> - X: Y: Z: - </text> - <text name="dimension_dividers"> - | | - </text> - </panel> - <text name="streaming cost"> - Resource Cost: [COST] - </text> - <text name="physics cost"> - Physics Cost: [COST] - </text> - </panel> - <panel name="upload_panel"> - <panel name="header_panel"> - <text name="header_text"> - Upload Complete! - </text> - </panel> - <text name="description"> - Congratulations! Your model has been sucessfully uploaded. You will find the model in the Objects folder in your inventory. - </text> - </panel> - <button label="<< Back" name="back"/> - <button label="Next >>" name="next"/> - <button label="Upload" name="upload" tool_tip="Upload to simulator"/> - <button label="Cancel" name="cancel"/> - <button label="Close" name="close"/> - <spinner name="import_scale" value="1.0"/> - <string name="status_idle"> - Idle - </string> - <string name="status_reading_file"> - Loading... - </string> - <string name="status_generating_meshes"> - Generating Meshes... - </string> - <string name="status_vertex_number_overflow"> - Error: Vertex number is more than 65534, aborted! - </string> - <string name="high"> - High - </string> - <string name="medium"> - Medium - </string> - <string name="low"> - Low - </string> - <string name="lowest"> - Lowest - </string> - <string name="mesh_status_good"> - Ship it! - </string> - <string name="mesh_status_na"> - N/A - </string> - <string name="mesh_status_none"> - None - </string> - <string name="mesh_status_submesh_mismatch"> - Levels of detail have a different number of textureable faces. - </string> - <string name="mesh_status_mesh_mismatch"> - Levels of detail have a different number of mesh instances. - </string> - <string name="mesh_status_too_many_vertices"> - Level of detail has too many vertices. - </string> - <string name="mesh_status_missing_lod"> - Missing required level of detail. - </string> - <string name="layer_all"> - All - </string> -</floater> diff --git a/indra/newview/skins/default/xui/da/menu_im_well_button.xml b/indra/newview/skins/default/xui/da/menu_im_well_button.xml deleted file mode 100644 index 4889230919..0000000000 --- a/indra/newview/skins/default/xui/da/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<context_menu name="IM Well Button Context Menu"> - <menu_item_call label="Luk alle" name="Close All"/> -</context_menu> diff --git a/indra/newview/skins/default/xui/da/menu_viewer.xml b/indra/newview/skins/default/xui/da/menu_viewer.xml index c2f7d26dc9..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 'Hjem'" 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"/> @@ -121,6 +118,7 @@ <menu_item_call label="Model..." name="Upload Model"/> <menu_item_call label="Model Wizard..." name="Upload Model Wizard"/> <menu_item_call label="Mange (L$[COST] pr. fil)..." name="Bulk Upload"/> + <menu_item_call label="Sæt standardværdier for upload rettigheder" name="perm prefs"/> </menu> <menu_item_call label="Fortyd" name="Undo"/> <menu_item_call label="Gendan" name="Redo"/> @@ -154,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"/> @@ -181,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"/> @@ -193,13 +188,6 @@ <menu_item_check label=""Joystick Flycam"" 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"/> @@ -275,9 +263,8 @@ <menu_item_call label="Mist en netværkspakke" name="Drop a Packet"/> </menu> <menu_item_call label="Stød, skub & slag" name="Bumps, Pushes &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> @@ -299,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"/> @@ -325,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/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml index 3ccdfc036a..33b876bdb9 100644 --- a/indra/newview/skins/default/xui/da/notifications.xml +++ b/indra/newview/skins/default/xui/da/notifications.xml @@ -438,7 +438,7 @@ Tilbyd venskab til [NAME]? </form> </notification> <notification name="RemoveFromFriends"> - Ønsker du at fjerne [NAME] fra din venneliste? + Ønsker du at fjerne <nolink>[NAME]</nolink> fra din venneliste? </notification> <notification name="ConfirmItemDeleteHasLinks"> Mindst en af genstandene har lænkede genstande der peger pÃ¥ den. Hvis du sletter denne genstand, vil lænkninger ikke virke mere. Det anbefales kraftigt at fjerne lænkninger først. @@ -481,7 +481,6 @@ Du kan bruge [SECOND_LIFE] normalt og andre personer vil se dig korrekt. [APP_NAME] installationen er færdig. Hvis det er første gang du bruger [SECOND_LIFE], skal du først oprette en konto for at logge pÃ¥. -Vend tilbage til [http://join.secondlife.com secondlife.com] for at oprette en ny konto? </notification> <notification name="LoginPacketNeverReceived"> Der er problemer med at koble pÃ¥. Der kan være et problem med din Internet forbindelse eller [SECOND_LIFE_GRID]. @@ -1023,10 +1022,10 @@ Henvis til dette fra en hjemmeside for at give andre nem adgang til denne lokati Erstattet manglende tøj/kropsdele med standard. </notification> <notification name="FriendOnline"> - [NAME] er logget pÃ¥ + <nolink>[NAME]</nolink> er logget pÃ¥ </notification> <notification name="FriendOffline"> - [NAME] er logget af + <nolink>[NAME]</nolink> er logget af </notification> <notification name="AddSelfFriend"> Selvom du nok er meget sød, kan du ikke tilføje dig selv som ven. @@ -1404,10 +1403,10 @@ Prøv igen om lidt. (Som udgangspunkt, vil du være i stand til at se den andens online status) </notification> <notification name="FriendshipAccepted"> - [NAME] accepterede dit tilbud om venskab. + <nolink>[NAME]</nolink> accepterede dit tilbud om venskab. </notification> <notification name="FriendshipDeclined"> - [NAME] afviste dit tilbud om venskab. + <nolink>[NAME]</nolink> afviste dit tilbud om venskab. </notification> <notification name="FriendshipAcceptedByMe"> Tilbud om venskab accepteret. diff --git a/indra/newview/skins/default/xui/da/panel_login.xml b/indra/newview/skins/default/xui/da/panel_login.xml index 2e0f726e1a..b7cb76d4cb 100644 --- a/indra/newview/skins/default/xui/da/panel_login.xml +++ b/indra/newview/skins/default/xui/da/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + LOG PÃ… + </text> <text name="username_text"> Brugernavn: </text> @@ -15,15 +15,8 @@ <text name="password_text"> Password: </text> - <check_box label="Husk password" name="remember_check"/> - <button label="Log pÃ¥" name="connect_btn"/> - <text name="mode_selection_text"> - Tilstand: - </text> - <combo_box name="mode_combo" tool_tip="Vælg ønsket tilstand. Vælg basis for hurtig og nem udforskning og chat. Vælg avanceret for at fÃ¥ adgang til flere muligheder."> - <combo_box.item label="Basis" name="Basic"/> - <combo_box.item label="Avanceret" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Start ved: </text> @@ -33,16 +26,21 @@ <combo_box.item label="<Indtast regionnavn>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Opret bruger + <layout_panel name="links_login_panel"> + <text name="login_help"> + Hjælp til login </text> <text name="forgot_password_text"> Har du glemt brugernavn eller password? </text> - <text name="login_help"> - Hjælp til login + <button label="Log pÃ¥" name="connect_btn"/> + <check_box label="Husk password" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + CREATE YǾUR ACCǾUNT </text> + <button name="create_new_account_btn" label="Opret bruger"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/da/panel_my_profile.xml b/indra/newview/skins/default/xui/da/panel_my_profile.xml deleted file mode 100644 index 94da58389f..0000000000 --- a/indra/newview/skins/default/xui/da/panel_my_profile.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Profil" name="panel_profile"> - <string name="no_partner_text" value="Ingen"/> - <string name="no_group_text" value="Ingen"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="scroll_content_panel"> - <panel name="second_life_image_panel"> - <text name="display_name_descr_text"> - Brugernavn - </text> - <text name="name_descr_text"> - Visningsnavn - </text> - <button label="Profil" name="see_profile_btn" tool_tip="Se profil for denne avatar"/> - </panel> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml index 949cbcbd7b..eb104201f8 100644 --- a/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="chat_bar"> +<panel name="nearby_chat"> <line_editor label="Klik her for at chatte." name="chat_box" tool_tip="Tryk pÃ¥ enter for at tale, Ctrl-Enter for at rÃ¥be."/> <button name="show_nearby_chat" tool_tip="Viser/skjuler log for chat nærved"/> </panel> diff --git a/indra/newview/skins/default/xui/da/panel_notes.xml b/indra/newview/skins/default/xui/da/panel_notes.xml deleted file mode 100644 index 7d8097f6ff..0000000000 --- a/indra/newview/skins/default/xui/da/panel_notes.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Noter & Privatliv" name="panel_notes"> - <layout_stack name="layout"> - <layout_panel name="notes_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <text name="status_message" value="Min private noter:"/> - <text name="status_message2" value="Tillad denne person at:"/> - <check_box label="Se min online status" name="status_check"/> - <check_box label="Se mig pÃ¥ kortet" name="map_check"/> - <check_box label="Editére, slette og tage mine objekter" name="objects_check"/> - </panel> - </scroll_container> - </layout_panel> - <layout_panel name="notes_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Tilføj ven" name="add_friend" tool_tip="Tilbyd venskab til beboer"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="Ã…ben session med personlige beskeder"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Opkald" name="call" tool_tip="Opkald til denne beboer"/> - </layout_panel> - <layout_panel name="show_on_map_btn_lp"> - <button label="Kort" name="show_on_map_btn" tool_tip="Vis denne beboer pÃ¥ kortet"/> - </layout_panel> - <layout_panel name="teleport_btn_lp"> - <button label="Teleportér" name="teleport" tool_tip="Tilbyd teleport"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/da/panel_profile.xml b/indra/newview/skins/default/xui/da/panel_profile.xml deleted file mode 100644 index db85eb23a8..0000000000 --- a/indra/newview/skins/default/xui/da/panel_profile.xml +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Profil" name="panel_profile"> - <string name="no_partner_text" value="Ingen"/> - <string name="no_group_text" value="Ingen"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <panel name="second_life_image_panel"> - <text name="title_sl_descr_text" value="[SECOND_LIFE]:"/> - </panel> - <panel name="first_life_image_panel"> - <text name="title_rw_descr_text" value="Real World:"/> - </panel> - <text name="title_member_text" value="Beboer siden:"/> - <text name="title_acc_status_text" value="Konto status:"/> - <text name="title_partner_text" value="Partner:"/> - <panel name="partner_data_panel"> - <text initial_value="(henter)" name="partner_text"/> - </panel> - <text name="title_groups_text" value="Grupper:"/> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> - <layout_stack name="layout_verb_buttons"> - <layout_panel name="profile_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Tilføj ven" name="add_friend" tool_tip="Tilbyd venskab til beboeren"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="Personlig besked" name="im" tool_tip="Ã…ben session med personlig besked"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Opkald" name="call" tool_tip="Opkald til denne beboer"/> - </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="Teleportér" name="teleport" tool_tip="Tilbyd teleport"/> - </layout_panel> - <layout_panel name="overflow_btn_lp"> - <menu_button label="â–¼" name="overflow_btn" tool_tip="Betal eller del beholdning med denne beboer"/> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="profile_me_buttons_panel"> - <button label="Redigér profil" name="edit_profile_btn" tool_tip="Redigér din personlige information"/> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/da/panel_profile_view.xml b/indra/newview/skins/default/xui/da/panel_profile_view.xml deleted file mode 100644 index e6e8ca4d10..0000000000 --- a/indra/newview/skins/default/xui/da/panel_profile_view.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_target_profile"> - <string name="status_online"> - Online - </string> - <string name="status_offline"> - Offline - </string> - <text name="display_name_label" value="Visningsnavn:"/> - <text name="solo_username_label" value="Brugernavn:"/> - <text name="status" value="Online"/> - <text name="user_name_small" value="Se pÃ¥ mig med dette enormt ekstremt super lange navn"/> - <button name="copy_to_clipboard" tool_tip="Kopiér til udskriftsholder"/> - <text name="user_label" value="Brugernavn:"/> - <tab_container name="tabs"> - <panel label="PROFIL" name="panel_profile"/> - <panel label="FAVORITTER" name="panel_picks"/> - <panel label="NOTER & PRIVATLIV" name="panel_notes"/> - </tab_container> -</panel> diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index 165d47c931..11d100eeff 100644 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -560,6 +560,9 @@ Prøv venligst om lidt igen. <string name="mesh"> mesh </string> + <string name="AvatarEditingAppearance"> + (Redigering Udseende) + </string> <string name="AvatarAway"> Væk </string> diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml index 145cc1e30b..4387a61963 100644 --- a/indra/newview/skins/default/xui/de/floater_about.xml +++ b/indra/newview/skins/default/xui/de/floater_about.xml @@ -66,33 +66,34 @@ Voice-Serverversion: [VOICE_VERSION] </panel> <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. + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion. + APR Copyright (C) 2011 The Apache Software Foundation + Collada DOM Copyright 2006 Sony Computer Entertainment Inc. + cURL Copyright (C) 1996-2010, 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, 2006 David Turner, Robert Wilhelm und Werner Lemberg. + 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) 2002, Xiphophorus. + OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. + PCRE Copyright (c) 1997-2012 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-2012 Jean-loup Gailly und Mark Adler. -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..44922fbe78 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 in anderen Parzellen können Avatare in 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> @@ -459,12 +458,12 @@ Nur große Parzellen können in der Suche aufgeführt werden. <text name="Limit access to this parcel to:"> Zugang zu dieser Parzelle </text> - <check_box label="Öffentlichen Zugang erlauben [MATURITY]" name="public_access"/> + <check_box label="Öffentlichen Zugang gestatten (bei Deaktivierung dieser Option werden Bannlinien generiert)" name="public_access"/> <text name="Only Allow" width="400"> - Zugang auf Einwohner beschränken, die überprüft wurden von: + Zugang nur Einwohnern gestatten, die: </text> - <check_box label="Zahlungsinformation gespeichert [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Einwohner ohne Zahlungsinformation nicht zulassen."/> - <check_box label="Altersüberprüfung [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Einwohner ohne Altersüberprüfung nicht zulassen. Weitere Informationen finden Sie im [SUPPORT_SITE]."/> + <check_box label="Zahlungsinformationen hinterlegt haben [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Um diese Parzelle besuchen zu können, müssen Einwohner Zahlungsinformationen hinterlegt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/> + <check_box label="Sind mindestens 18 Jahre alt [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Nur Einwohner, die mindestens 18 Jahre alt sind, können diese Parzelle betreten. Weitere Informationen finden Sie unter [SUPPORT_SITE]."/> <check_box label="Gruppenzugang erlauben: [GROUP]" name="GroupCheck" tool_tip="Gruppe im Register „Allgemein“ festlegen."/> <check_box label="Pässe verkaufen an:" name="PassCheck" tool_tip="Ermöglicht befristeten Zugang zu dieser Parzelle"/> <combo_box name="pass_combo"> diff --git a/indra/newview/skins/default/xui/de/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/de/floater_animation_anim_preview.xml new file mode 100644 index 0000000000..3dc554b120 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_animation_anim_preview.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Anim Preview" title="ANIMATION.ANIM"> + <text name="name_label"> + Name: + </text> + <text name="description_label"> + Beschreibung: + </text> + <button label="Hochladen (L$ [AMOUNT])" name="ok_btn"/> + <button label="Abbrechen" label_selected="Abbrechen" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_animation_preview.xml b/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml index 82a4a51d07..9a6f5e0166 100644 --- a/indra/newview/skins/default/xui/de/floater_animation_preview.xml +++ b/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview" title=""> +<floater name="Animation Preview"> <floater.string name="failed_to_initialize"> Bewegung konnte nicht initialisiert werden </floater.string> @@ -9,7 +9,7 @@ Maximal erlaubt sind [MAX_LENGTH] Sekunden. </floater.string> <floater.string name="failed_file_read"> - Animationsdatei konnte nicht gelesen werden. + Animationsdatei kann nicht gelesen werden. [STATUS] </floater.string> @@ -17,16 +17,16 @@ Maximal erlaubt sind [MAX_LENGTH] Sekunden. OK </floater.string> <floater.string name="E_ST_EOF"> - Unvollständige Datei + Vorzeitiges Dateiende. </floater.string> <floater.string name="E_ST_NO_CONSTRAINT"> Constraint-Definition kann nicht gelesen werden. </floater.string> <floater.string name="E_ST_NO_FILE"> - BVH-Datei kann nicht geöffnet werden + BVH-Datei kann nicht geöffnet werden. </floater.string> <floater.string name="E_ST_NO_HIER"> - Ungültiger HIERARCHY-Titel. + Ungültige HIERARCHY-Kopfzeile. </floater.string> <floater.string name="E_ST_NO_JOINT"> ROOT oder JOINT nicht gefunden. @@ -35,16 +35,16 @@ Maximal erlaubt sind [MAX_LENGTH] Sekunden. JOINT-Name nicht erfasst. </floater.string> <floater.string name="E_ST_NO_OFFSET"> - VERSATZ nicht gefunden. + OFFSET nicht gefunden. </floater.string> <floater.string name="E_ST_NO_CHANNELS"> CHANNELS nicht gefunden. </floater.string> <floater.string name="E_ST_NO_ROTATION"> - Kann Rotations-Reihenfolge nicht erfassen. + Rotationsreihenfolge kann nicht erfasst werden. </floater.string> <floater.string name="E_ST_NO_AXIS"> - Kann Rotations-Achse nicht erfassen. + Rotationsachse kann nicht erfasst werden. </floater.string> <floater.string name="E_ST_NO_MOTION"> MOTION nicht gefunden. @@ -56,74 +56,73 @@ Maximal erlaubt sind [MAX_LENGTH] Sekunden. Bildzeit kann nicht erfasst werden. </floater.string> <floater.string name="E_ST_NO_POS"> - Positions-Werte können nicht erfasst werden. + Positionswerte können nicht erfasst werden. </floater.string> <floater.string name="E_ST_NO_ROT"> - Kann Rotations-Werte nicht erfassen. + Rotationswerte können nicht erfasst werden. </floater.string> <floater.string name="E_ST_NO_XLT_FILE"> - Datei kann nicht geöffnet werden + Transformationsdatei kann nicht geöffnet werden. </floater.string> <floater.string name="E_ST_NO_XLT_HEADER"> - Übersetzungstitel kann nicht gelesen werden. + Transformationskopfzeile kann nicht gelesen werden. </floater.string> <floater.string name="E_ST_NO_XLT_NAME"> - Übersetzungsnamen können nicht geladen werden. + Transformationsnamen können nicht gelesen werden. </floater.string> <floater.string name="E_ST_NO_XLT_IGNORE"> - Ignorier-Wert kann nicht gelesen werden. + Ignorieren-Transformationswert kann nicht gelesen werden. </floater.string> <floater.string name="E_ST_NO_XLT_RELATIVE"> - Übersetzungs-Wert kann nicht gelesen werden. + Relativer Transformationswert kann nicht gelesen werden. </floater.string> <floater.string name="E_ST_NO_XLT_OUTNAME"> - Outname-Wert kann nicht gelesen werden. + Outname-Transformationswert kann nicht gelesen werden. </floater.string> <floater.string name="E_ST_NO_XLT_MATRIX"> - Übersetzungsmatrix kann nicht geladen werden. + Transformationsmatrix kann nicht gelesen werden. </floater.string> <floater.string name="E_ST_NO_XLT_MERGECHILD"> - Mergechild-Name nicht erfasst. + Mergechild-Name kann nicht erfasst werden. </floater.string> <floater.string name="E_ST_NO_XLT_MERGEPARENT"> - Mergeparent-Name nicht erfasst. + Mergeparent-Name kann nicht erfasst werden. </floater.string> <floater.string name="E_ST_NO_XLT_PRIORITY"> - Prioritätswert kann nicht erfasst werden. + Priority-Wert kann nicht erfasst werden. </floater.string> <floater.string name="E_ST_NO_XLT_LOOP"> Loop-Wert kann nicht erfasst werden. </floater.string> <floater.string name="E_ST_NO_XLT_EASEIN"> - Easeln-Wert kann nicht erfasst werden. + EaseIn-Werte können nicht erfasst werden. </floater.string> <floater.string name="E_ST_NO_XLT_EASEOUT"> - easeOut-Wert kann nicht erfasst werden. + EaseOut-Werte können nicht erfasst werden. </floater.string> <floater.string name="E_ST_NO_XLT_HAND"> - Hand-Morph-Wert nicht erfasst. + Hand-Morph-Wert kann nicht erfasst werden. </floater.string> <floater.string name="E_ST_NO_XLT_EMOTE"> Emote-Name kann nicht gelesen werden. </floater.string> <floater.string name="E_ST_BAD_ROOT"> - Falscher Root-Joint-Name, "hip" verwenden. + Falscher Root-Joint-Name, „hip“ verwenden. </floater.string> <text name="name_label"> Name: </text> - <line_editor name="name_form"/> <text name="description_label"> Beschreibung: </text> <spinner label="Priorität" name="priority" tool_tip="Steuert, welche Animationen von dieser Animation überschrieben werden können"/> - <check_box bottom_delta="-18" label="Schleife" name="loop_check" tool_tip="Erzeugt eine Animationsschleife"/> - <spinner label="In (%)" name="loop_in_point" tool_tip="Anfang einer Animationsschleife festlegen"/> + <check_box label="Schleife" name="loop_check" tool_tip="Erzeugt eine Animationsschleife"/> + <spinner label="Ein (%)" name="loop_in_point" tool_tip="Anfang einer Animationsschleife festlegen"/> <spinner label="Aus (%)" name="loop_out_point" tool_tip="Ende einer Animationsschleife festlegen"/> <text name="hand_label"> Handhaltung </text> - <combo_box label="" name="hand_pose_combo" tool_tip="Steuert während der Animation die Bewegung der Hände"> + <combo_box name="hand_pose_combo" tool_tip="Steuert während der Animation die Bewegung der Hände"> <combo_box.item label="Dehnen" name="Spread"/> <combo_box.item label="Entspannt" name="Relaxed"/> <combo_box.item label="Beide zeigen" name="PointBoth"/> @@ -135,21 +134,21 @@ Maximal erlaubt sind [MAX_LENGTH] Sekunden. <combo_box.item label="Nach rechts zeigen" name="PointRight"/> <combo_box.item label="Rechte Faust" name="FistRight"/> <combo_box.item label="Rechts salutieren" name="SaluteRight"/> - <combo_box.item label="Tippt" name="Typing"/> - <combo_box.item label="Friedensrecht" name="PeaceRight"/> + <combo_box.item label="Tippen" name="Typing"/> + <combo_box.item label="Friedensgeste rechts" name="PeaceRight"/> </combo_box> <text name="emote_label"> Ausdruck </text> - <combo_box label="" name="emote_combo" tool_tip="Steuert Gesichtsregungen während der Animation"> - <item label="(Keiner)" name="[None]" value=""/> + <combo_box name="emote_combo" tool_tip="Steuert Gesichtsregungen während der Animation"> + <item label="(Keine)" name="[None]" value=""/> <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> <item label="Ängstlich" name="Afraid" value="Ängstlich"/> <item label="Verärgert" name="Angry" value="Verärgert"/> - <item label="Grinst" name="BigSmile" value="Grinsend"/> + <item label="Grinst" name="BigSmile" value="Grinst"/> <item label="Gelangweilt" name="Bored" value="Gelangweilt"/> <item label="Weinen" name="Cry" value="Weinen"/> - <item label="Verachten" name="Disdain" value="Verachten"/> + <item label="Verachtung" name="Disdain" value="Verachtung"/> <item label="Verlegen" name="Embarrassed" value="Verlegen"/> <item label="Stirnrunzeln" name="Frown" value="Stirnrunzeln"/> <item label="Küssen" name="Kiss" value="Küssen"/> @@ -157,32 +156,31 @@ Maximal erlaubt sind [MAX_LENGTH] Sekunden. <item label="Bäääh" name="Plllppt" value="Bäääh"/> <item label="Angewidert" name="Repulsed" value="Angewidert"/> <item label="Traurig" name="Sad" value="Traurig"/> - <item label="Schulterzucken" name="Shrug" value="Schulterzucken"/> + <item label="Achselzucken" name="Shrug" value="Achselzucken"/> <item label="Lächeln" name="Smile" value="Lächeln"/> <item label="Überraschung" name="Surprise" value="Überraschung"/> <item label="Zwinkern" name="Wink" value="Zwinkern"/> <item label="Sorgenvoll" name="Worry" value="Sorgenvoll"/> </combo_box> - <text name="preview_label" width="97"> + <text name="preview_label"> Vorschau während: </text> - <combo_box label="" left_delta="107" name="preview_base_anim" tool_tip="Hiermit können Sie das Verhalten Ihres Avatars testen, während Ihr Avatar normale Bewegungen ausführt."> - <item label="Stehend" name="Standing" value="Stehend"/> - <item label="Geht" name="Walking" value="Gehend"/> - <item label="Sitzt" name="Sitting" value="Sitzend"/> + <combo_box name="preview_base_anim" tool_tip="Hiermit können Sie das Verhalten Ihres Avatars testen, während Ihr Avatar normale Bewegungen ausführt."> + <item label="Stehen" name="Standing" value="Stehen"/> + <item label="Gehen" name="Walking" value="Gehen"/> + <item label="Sitzen" name="Sitting" value="Sitzen"/> <item label="Fliegen" name="Flying" value="Fliegen"/> </combo_box> - <spinner label="Eingang glätten (s)" label_width="105" name="ease_in_time" tool_tip="Einblendungsgeschwindigkeit von Animationen (in Sekunden)" width="175"/> - <spinner bottom_delta="-20" label="Ausgang glätten (s)" label_width="105" left="10" name="ease_out_time" tool_tip="Ausblendegeschwindigkeit von Animationen (in Sekunden)" width="175"/> - <button bottom_delta="-32" label="" name="play_btn" tool_tip="Ihre Animation abspielen"/> - <button name="pause_btn" tool_tip="Ihre Animation pausieren"/> - <button label="" name="stop_btn" tool_tip="Animation anhalten"/> - <slider label="" name="playback_slider"/> + <spinner label="Einblenden (s)" name="ease_in_time" tool_tip="Einblendungszeit für Animationen (in Sekunden)"/> + <spinner label="Ausblenden (s)" name="ease_out_time" tool_tip="Ausblendungszeit für Animationen (in Sekunden)"/> + <button name="play_btn" tool_tip="Animation abspielen"/> + <button name="pause_btn" tool_tip="Animation unterbrechen"/> + <button name="stop_btn" tool_tip="Animation anhalten"/> <text name="bad_animation_text"> - Animationsdatei konnte nicht gelesen werden. + Animationsdatei kann nicht gelesen werden. Wir empfehlen exportierte BVH-Dateien aus Poser 4. </text> - <button label="Hochladen ([AMOUNT] L$)" name="ok_btn" width="160"/> - <button label="Abbrechen" left="180" name="cancel_btn" width="88"/> + <button label="Hochladen (L$ [AMOUNT])" name="ok_btn"/> + <button label="Abbrechen" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/de/floater_autoreplace.xml b/indra/newview/skins/default/xui/de/floater_autoreplace.xml new file mode 100644 index 0000000000..0c774990ef --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="Einstellungen für automatische Ersetzung..."> + <check_box label="Automatische Ersetzung aktivieren..." name="autoreplace_enable" tool_tip="Eines oder mehrere Schlüsselwörter bei der Eingabe von Chat-Text durch die entsprechende Ersetzung substituieren"/> + <button label="Liste importieren..." name="autoreplace_import_list" tool_tip="Exportierte Liste aus einer Datei laden."/> + <button label="Liste exportieren..." name="autoreplace_export_list" tool_tip="Ausgewählte Liste zur Weitergabe in einer Datei speichern."/> + <button label="Neue Liste..." name="autoreplace_new_list" tool_tip="Neue Liste erstellen."/> + <button label="Liste löschen" name="autoreplace_delete_list" tool_tip="Ausgewählte Liste löschen."/> + <button name="autoreplace_list_up" tool_tip="Dieser Liste eine höhere Priorität einräumen."/> + <button name="autoreplace_list_down" tool_tip="Dieser Liste eine niedrigere Priorität einräumen."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Schlüsselwort" name="keyword"/> + <scroll_list.columns label="Ersetzung" name="replacement"/> + </scroll_list> + <button label="Hinzufügen..." name="autoreplace_add_entry"/> + <button label="Entfernen" name="autoreplace_delete_entry"/> + <button label="Eintrag speichern" name="autoreplace_save_entry" tool_tip="Diesen Eintrag speichern."/> + <button label="Änderungen speichern" name="autoreplace_save_changes" tool_tip="Alle Änderungen speichern."/> + <button label="Abbrechen" name="autoreplace_cancel" tool_tip="Alle Änderungen löschen."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </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 bbf1c8af60..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> @@ -9,15 +9,6 @@ <floater.string name="move_tooltip"> Kamera nach oben, unten, links und rechts bewegen </floater.string> - <floater.string name="camera_modes_title"> - Kameramodi - </floater.string> - <floater.string name="pan_mode_title"> - Kreisen - Zoomen - Schwenken - </floater.string> - <floater.string name="presets_mode_title"> - Ansichten - </floater.string> <floater.string name="free_mode_title"> Objekt ansehen </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..ab77d4dae5 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> +<floater name="nearby_chat" title="CHAT IN DER NÄHE"> + <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..fd6c9a0875 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"> @@ -25,6 +25,10 @@ VBO aktivieren: </text> <check_box initial_value="true" label="OpenGL Vertex-Buffer-Objekte aktivieren" name="vbo" tool_tip="Wenn Sie über moderne Grafikhardware verfügen, können Sie durch Aktivieren dieser Option die Geschwindigkeit verbessern. Bei alter Hardware sind die VBO oft schlecht implementiert, was zu Abstürzen führen kann, wenn diese Option aktiviert ist."/> + <text name="tc label"> + S3TC aktivieren: + </text> + <check_box initial_value="true" label="Texturkomprimierung aktivieren (Neustart erforderlich)" name="texture compression" tool_tip="Komprimiert Texturen im Videospeicher, damit höher auflösende Texturen geladen werden können (leichte Beeinträchtigung der Farbqualität)."/> <slider label="Texturen-Cache (MB):" name="GraphicsCardTextureMemory" tool_tip="Speicherplatz, der für Texturen zur Verfügung steht. In der Regel handelt es sich um Grafikkartenspeicher. Ein kleinerer Wert kann die Geschwindigkeit erhöhen, aber auch zu Texturunschärfen führen."/> <spinner label="Nebeldistanzverhältnis:" name="fog"/> <button label="OK" label_selected="OK" name="OK"/> diff --git a/indra/newview/skins/default/xui/de/floater_inventory.xml b/indra/newview/skins/default/xui/de/floater_inventory.xml deleted file mode 100644 index d9b7c30fd2..0000000000 --- a/indra/newview/skins/default/xui/de/floater_inventory.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="MEIN INVENTAR"> - <floater.string name="Title"> - MEIN INVENTAR - </floater.string> - <floater.string name="TitleFetching"> - MEIN INVENTAR ([ITEM_COUNT] Objekte werden abgerufen...) [FILTER] - </floater.string> - <floater.string name="TitleCompleted"> - MEIN INVENTAR ([ITEM_COUNT] Objekte) [FILTER] - </floater.string> - <floater.string name="Fetched"> - Abgerufen - </floater.string> - <panel label="Inventar" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/de/floater_merchant_outbox.xml new file mode 100644 index 0000000000..a412b530a4 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_merchant_outbox.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_merchant_outbox" title="HÄNDLER-OUTBOX"> + <string name="OutboxFolderCount1"> + 1 Ordner + </string> + <string name="OutboxFolderCountN"> + [NUM] Ordner + </string> + <string name="OutboxImporting"> + Ordner übertragen... + </string> + <string name="OutboxInitializing"> + Initialisieren... + </string> + <panel label=""> + <panel> + <panel name="outbox_inventory_placeholder_panel"> + <text name="outbox_inventory_placeholder_title"> + Laden... + </text> + </panel> + </panel> + <panel> + <button label="In Marktplatz übertragen" name="outbox_import_btn" tool_tip="In meinen Marktplatz-Laden verschieben"/> + </panel> + </panel> +</floater> 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..4285462bc8 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> @@ -89,19 +92,54 @@ <text initial_value="Dreiecke" name="triangles" value="Dreiecke"/> <text initial_value="Scheitelpunkte" name="vertices" value="Scheitelpunkte"/> <text initial_value="Hoch" name="high_label" value="Hoch"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Aus Datei laden"/> + <item name="Generate" value="Generieren"/> + </combo_box> <button label="Durchsuchen..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="Dreiecklimit"/> + <item name="Error Threshold" value="Fehlerschwelle"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Mittel" name="medium_label" value="Mittel"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Aus Datei laden"/> + <item name="Generate" value="Generieren"/> + <item name="Use LoD above" value="Detailstufe oben verwenden"/> + </combo_box> <button label="Durchsuchen..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="Dreiecklimit"/> + <item name="Error Threshold" value="Fehlerschwelle"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Niedrig" name="low_label" value="Niedrig"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Aus Datei laden"/> + <item name="Generate" value="Generieren"/> + <item name="Use LoD above" value="Detailstufe oben verwenden"/> + </combo_box> <button label="Durchsuchen..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="Dreiecklimit"/> + <item name="Error Threshold" value="Fehlerschwelle"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="Niedrigste" name="lowest_label" value="Niedrigste"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Aus Datei laden"/> + <item name="Generate" value="Generieren"/> + <item name="Use LoD above" value="Detailstufe oben verwenden"/> + </combo_box> <button label="Durchsuchen..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="Dreiecklimit"/> + <item name="Error Threshold" value="Fehlerschwelle"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Normalen generieren" name="gen_normals"/> @@ -137,7 +175,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 deleted file mode 100644 index 354a505901..0000000000 --- a/indra/newview/skins/default/xui/de/floater_model_wizard.xml +++ /dev/null @@ -1,205 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Model Wizard" title="ASSISTENT ZUM HOCHLADEN VON MODELLEN"> - <button label="5. Hochladen" name="upload_btn"/> - <button label="4. Überprüfen" name="review_btn"/> - <button label="3. Physik" name="physics_btn"/> - <button label="2. Optimieren" name="optimize_btn"/> - <button label="1. Datei auswählen" name="choose_file_btn"/> - <panel name="choose_file_panel"> - <panel name="header_panel"> - <text name="header_text"> - Modelldatei auswählen - </text> - </panel> - <panel name="content"> - <text name="advanced_users_text"> - Fortgeschrittene Benutzer: Wenn Sie bereits mit Tools zur Erstellung von 3D-Inhalten vertraut sind, können Sie den erweiterten Uploader verwenden. - </text> - <button label="Auf Erweitert wechseln" name="switch_to_advanced"/> - <text name="Cache location"> - Hochzuladende Modelldatei auswählen - </text> - <button label="Durchsuchen..." label_selected="Durchsuchen..." name="browse"/> - <text name="dimensions"> - X Y Z - </text> - <text name="warning_label"> - ACHTUNG: - </text> - <text name="warning_text"> - Sie können den letzten Schritt nicht abschließen (Modell auf Second Life-Server hochladen). [secondlife:///app/floater/learn_more Weitere Infos], wie Sie Ihr Konto zum Hochladen von Netzmodellen einrichten. - </text> - </panel> - </panel> - <panel name="optimize_panel"> - <panel name="header_panel"> - <text name="header_text"> - Modell optimieren - </text> - </panel> - <text name="description"> - Wir haben das Modell auf Leistung optimiert. Sie können es bei Bedarf weiter anpassen. - </text> - <panel name="content"> - <text name="high_detail_text"> - Detailstufe generieren: Hoch - </text> - <text name="medium_detail_text"> - Detailstufe generieren: Mittel - </text> - <text name="low_detail_text"> - Detailstufe generieren: Niedrig - </text> - <text name="lowest_detail_text"> - Detailstufe generieren: Niedrigste - </text> - </panel> - <panel name="content2"> - <button label="Geometrie neu berechnen" name="recalculate_geometry_btn"/> - <text name="lod_label"> - Geometrievorschau - </text> - <combo_box name="preview_lod_combo" tool_tip="Detailstufe zur Anzeige in Vorschaudarstellung"> - <combo_item name="high"> - Viel Details - </combo_item> - <combo_item name="medium"> - Mittlere Details - </combo_item> - <combo_item name="low"> - Wenig Details - </combo_item> - <combo_item name="lowest"> - Wenigste Details - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="physics_panel"> - <panel name="header_panel"> - <text name="header_text"> - Physik anpassen - </text> - </panel> - <text name="description"> - Wir erstellen eine Form für die Außenhülle des Modells. Passen Sie die Detailstufe der Form wie für den beabsichtigten Zweck erforderlich an. - </text> - <panel name="content"> - <button label="Physik neu berechnen" name="recalculate_physics_btn"/> - <button label="Neu berechnen..." name="recalculating_physics_btn"/> - <text name="lod_label"> - Physikvorschau - </text> - <combo_box name="preview_lod_combo2" tool_tip="Detailstufe zur Anzeige in Vorschaudarstellung"> - <combo_item name="high"> - Viel Details - </combo_item> - <combo_item name="medium"> - Mittlere Details - </combo_item> - <combo_item name="low"> - Wenig Details - </combo_item> - <combo_item name="lowest"> - Wenigste Details - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="review_panel"> - <panel name="header_panel"> - <text name="header_text"> - Überprüfen - </text> - </panel> - <panel name="content"> - <text name="review_prim_equiv"> - Auswirkung auf Parzelle/Region: Prim-Äquivalenzwert [EQUIV] - </text> - <text name="review_fee"> - Die für das Hochladen anfallende Gebühr in Höhe von [FEE] L$ wird von Ihrem Konto abgebucht. - </text> - <text name="review_confirmation"> - Durch Klicken auf „Hochladen“ bestätigen Sie, dass Sie die erforderlichen Rechte für das im Modell enthaltene Material besitzen. - </text> - </panel> - </panel> - <panel name="upload_panel"> - <panel name="header_panel"> - <text name="header_text"> - Upload abgeschlossen - </text> - </panel> - <text name="model_uploaded_text"> - Ihr Modell wurde hochgeladen. - </text> - <text name="inventory_text"> - Sie finden das Modell im Objektordner Ihres Inventars. - </text> - <text name="charged_fee"> - Von Ihrem Konto wurden [FEE] L$ abgebucht. - </text> - </panel> - <button label="<< Zurück" name="back"/> - <button label="Weiter >>" name="next"/> - <button label="Gewichte und Gebühr berechnen >>" name="calculate"/> - <button label="Berechnen..." name="calculating"/> - <button label="Hochladen" name="upload" tool_tip="An Simulator hochladen"/> - <button label="Abbrechen" name="cancel"/> - <button label="Schließen" name="close"/> - <spinner name="import_scale" value="1,0"/> - <string name="status_idle"> - Inaktiv - </string> - <string name="status_parse_error"> - DAE-Parsing-Fehler. Details siehe Protokoll. - </string> - <string name="status_reading_file"> - Laden... - </string> - <string name="status_generating_meshes"> - Netze werden generiert... - </string> - <string name="status_vertex_number_overflow"> - Fehler: Anzahl von Vertices überschreitet 65534. Operation abgebrochen. - </string> - <string name="bad_element"> - Fehler: ungültiges Element. - </string> - <string name="high"> - Hoch - </string> - <string name="medium"> - Mittel - </string> - <string name="low"> - Niedrig - </string> - <string name="lowest"> - Niedrigste - </string> - <string name="mesh_status_good"> - Ausliefern - </string> - <string name="mesh_status_na"> - -- - </string> - <string name="mesh_status_none"> - Keine - </string> - <string name="mesh_status_submesh_mismatch"> - Detailstufen haben unterschiedliche Anzahl texturfähiger Flächen. - </string> - <string name="mesh_status_mesh_mismatch"> - Detailstufen haben unterschiedliche Anzahl von Netzinstanzen. - </string> - <string name="mesh_status_too_many_vertices"> - Detailstufe hat zu viele Vertices. - </string> - <string name="mesh_status_missing_lod"> - Erforderliche Detailstufe fehlt. - </string> - <string name="layer_all"> - Alle - </string> -</floater> 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_nearby_chat.xml b/indra/newview/skins/default/xui/de/floater_nearby_chat.xml deleted file mode 100644 index 2aabbb18f2..0000000000 --- a/indra/newview/skins/default/xui/de/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="CHAT IN DER NÄHE"> - <check_box label="Chat übersetzen" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/de/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..7096dbc156 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="Pathfinding-Figuren"> + <floater.string name="messaging_get_inprogress"> + Pathfinding-Figuren werden abgerufen... + </floater.string> + <floater.string name="messaging_get_error"> + Fehler beim Abrufen von Pathfinding-Figuren. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Keine Pathfinding-Figuren. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] Figuren von [NUM_TOTAL] ausgewählt. + </floater.string> + <floater.string name="messaging_not_enabled"> + Pathfinding ist in dieser Region nicht aktiviert. + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Laden] + </floater.string> + <floater.string name="character_owner_unknown"> + [Unbekannt] + </floater.string> + <floater.string name="character_owner_group"> + [Gruppe] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Name" name="name"/> + <scroll_list.columns label="Beschreibung" name="description"/> + <scroll_list.columns label="Eigentümer" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="Höhe" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + Figuren: + </text> + <button label="Liste aktualisieren" name="refresh_objects_list"/> + <button label="Alle auswählen" name="select_all_objects"/> + <button label="Keine auswählen" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + Aktionen für ausgewählte Figuren: + </text> + <check_box label="Beacon anzeigen" name="show_beacon"/> + <check_box label="Physikkapsel anzeigen" name="show_physics_capsule"/> + <button label="Nehmen" name="take_objects"/> + <button label="Kopie nehmen" name="take_copy_objects"/> + <button label="Dorthin teleportieren" name="teleport_me_to_object" tool_tip="Nur aktiviert, wenn eine Figur ausgewählt ist."/> + <button label="Zurückgeben" name="return_objects"/> + <button label="Löschen" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/de/floater_pathfinding_console.xml new file mode 100644 index 0000000000..ebf8f01632 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="Pathfinding-Ansicht/-Test"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + Pathfinding-Bibliotheksimplementierung nicht gefunden. + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + Pathfinding ist in dieser Region nicht aktiviert. + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + Warten, bis Region geladen ist. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Navmesh-Status wird geprüft. + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Navmesh wird heruntergeladen. + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + Navmesh hat sich auf dem Server geändert. Neuestes Navmesh wird heruntergeladen. + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + Neuestes Navmesh wurde heruntergeladen. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + Navmesh kann nicht heruntergeladen werden. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + Navmesh weist ausstehende Änderungen auf. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + Navmesh wird erstellt. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + Einige Navmesh-Regionen weisen ausstehende Änderungen auf. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + Einige Navmesh-Regionen werden erstellt. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + Einige Navmesh-Regionen weisen ausstehende Änderungen auf und andere werden erstellt. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + Navmesh ist aktuell. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + Pathfinding-Bibliotheksimplementierung nicht gefunden. + </floater.string> + <floater.string name="pathing_region_not_enabled"> + Pathfinding ist in dieser Region nicht aktiviert. + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Bitte wählen Sie Anfangs- und Endpunkte aus. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Bitte wählen Sie einen Anfangspunkt aus. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Bitte wählen Sie einen Endpunkt aus. + </floater.string> + <floater.string name="pathing_path_valid"> + Pfad wird orange dargestellt. + </floater.string> + <floater.string name="pathing_path_invalid"> + Zwischen den gewählten Punkten wurde kein Pfad gefunden. + </floater.string> + <floater.string name="pathing_error"> + Fehler bei der Pfaderstellung aufgetreten. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Anzeigen" name="view_panel"> + <text name="show_label"> + Anzeigen: + </text> + <check_box label="Welt" name="show_world"/> + <check_box label="Nur bewegliche Objekte" name="show_world_movables_only"/> + <check_box label="Navmesh" name="show_navmesh"/> + <text name="show_walkability_label"> + Begehbarkeitskarte anzeigen: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="Nicht anzeigen" name="show_heatmap_mode_none"/> + <combo_box.item label="Figurentyp A" name="show_heatmap_mode_a"/> + <combo_box.item label="Figurentyp B" name="show_heatmap_mode_b"/> + <combo_box.item label="Figurentyp C" name="show_heatmap_mode_c"/> + <combo_box.item label="Figurentyp D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Begehbare Objekte" name="show_walkables"/> + <check_box label="Materialvolumen" name="show_material_volumes"/> + <check_box label="Statische Hinternisse" name="show_static_obstacles"/> + <check_box label="Ausschlussvolumen" name="show_exclusion_volumes"/> + <check_box label="Wasserebene" name="show_water_plane"/> + <check_box label="Mit Röntgenblick" name="show_xray"/> + </panel> + <panel label="Pfad testen" name="test_panel"> + <text name="ctrl_click_label"> + Bei gedrückter Strg-Taste klicken, um Anfangspunkt auszuwählen. + </text> + <text name="shift_click_label"> + Bei gedrückter Umschalttaste klicken, um Endpunkt auszuwählen. + </text> + <text name="character_width_label"> + Figurenbreite + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + Figurentyp + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Keine" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Pfad löschen" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..0d3ba59efb --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Pathfinding-Linksets"> + <floater.string name="messaging_get_inprogress"> + Pathfinding-Linksets werden abgerufen... + </floater.string> + <floater.string name="messaging_get_error"> + Fehler beim Abrufen von Pathfinding-Linksets. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Ausgewählte Pathfinding-Linksets werden geändert... + </floater.string> + <floater.string name="messaging_set_error"> + Fehler beim Ändern der ausgewählten Pathfinding-Linksets. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Keine Pathfinding-Linksets. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] Linksets von [NUM_TOTAL] ausgewählt. + </floater.string> + <floater.string name="messaging_not_enabled"> + Pathfinding ist in dieser Region nicht aktiviert. + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terrain] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Laden] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Unbekannt] + </floater.string> + <floater.string name="linkset_owner_group"> + [Gruppe] + </floater.string> + <floater.string name="linkset_is_scripted"> + Ja + </floater.string> + <floater.string name="linkset_is_not_scripted"> + Nein + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + Unbekannt + </floater.string> + <floater.string name="linkset_use_walkable"> + Begehbar + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Statisches Hinternis + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Bewegliches Hinternis + </floater.string> + <floater.string name="linkset_use_material_volume"> + Materialvolumen + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + Ausschlussvolumen + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Bewegliches Phantom + </floater.string> + <floater.string name="linkset_is_terrain"> + [nicht änderbar] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [beschränkt] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [konkav] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [beschränkt,konkav] + </floater.string> + <floater.string name="linkset_choose_use"> + Linkset-Nutzung auswählen... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="Nach Linkset-Nutzung filtern..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Begehbar" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Statisches Hinternis" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Bewegliches Hinternis" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Materialvolumen" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="Ausschlussvolumen" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Bewegliches Phantom" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Anwenden" name="apply_filters"/> + <button label="Entfernen" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Name (Hauptprim)" name="name"/> + <scroll_list.columns label="Beschreibung (Hauptprim)" name="description"/> + <scroll_list.columns label="Eigentümer" name="owner"/> + <scroll_list.columns label="Geskriptet" name="scripted"/> + <scroll_list.columns label="Belastung" name="land_impact"/> + <scroll_list.columns label="Abstand" name="dist_from_you"/> + <scroll_list.columns label="Linkset-Nutzung" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + Linksets: + </text> + <button label="Liste aktualisieren" name="refresh_objects_list"/> + <button label="Alle auswählen" name="select_all_objects"/> + <button label="Keine auswählen" name="select_none_objects"/> + </panel> + <panel> + <check_box label="Beacon anzeigen" name="show_beacon"/> + <button label="Nehmen" name="take_objects"/> + <button label="Kopie nehmen" name="take_copy_objects"/> + <button label="Dorthin teleportieren" name="teleport_me_to_object"/> + <button label="Zurückgeben" name="return_objects"/> + <button label="Löschen" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + Begehbarkeit: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="Begehbarkeit für Figuren vom Typ A. Ein Beispiel für diesen Typ wäre „Humanoid“."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="Begehbarkeit für Figuren vom Typ B. Ein Beispiel für diesen Typ wäre „Kreatur“."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="Begehbarkeit für Figuren vom Typ C. Ein Beispiel für diesen Typ wäre „Mechanisch“."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="Begehbarkeit für Figuren vom Typ D. Ein Beispiel für diesen Typ wäre „Anderer“."/> + <button label="Änderungen übernehmen" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Humanoid) + </text> + <text name="suggested_use_b_label"> + (Kreatur) + </text> + <text name="suggested_use_c_label"> + (Mechanisch) + </text> + <text name="suggested_use_d_label"> + (Anderer) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_postcard.xml b/indra/newview/skins/default/xui/de/floater_postcard.xml deleted file mode 100644 index 28af0183cb..0000000000 --- a/indra/newview/skins/default/xui/de/floater_postcard.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="FOTO EMAILEN"> - <text name="to_label"> - E-Mail des Empfängers: - </text> - <text name="from_label"> - Ihre E-Mail: - </text> - <text name="name_label"> - Ihr Name: - </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> - <text name="fine_print"> - Wenn sich der Empfänger bei SL anmeldet, erhalten Sie einen Empfehlungsbonus. - </text> - <button label="Abbrechen" name="cancel_btn"/> - <button label="Senden" name="send_btn"/> - <text name="default_subject"> - Postkarte aus [SECOND_LIFE]. - </text> - <text name="default_message"> - Sehen Sie hier! - </text> - <string name="upload_message"> - Wird gesendet... - </string> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_preview_animation.xml b/indra/newview/skins/default/xui/de/floater_preview_animation.xml index 3dcdb52555..2dd47a27ad 100644 --- a/indra/newview/skins/default/xui/de/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/de/floater_preview_animation.xml @@ -7,6 +7,6 @@ Beschreibung: </text> <line_editor left="108" name="desc" width="160"/> - <button label="Inworld abspielen" label_selected="Stopp" name="Anim play btn" tool_tip="Diese Animation so wiedergeben, dass andere sie sehen können." width="116"/> - <button label="Lokal abspielen" label_selected="Stopp" left="171" name="Anim audition btn" tool_tip="Diese Animation so wiedergeben, dass nur Sie sie sehen." width="116"/> + <button label="Inworld abspielen" label_selected="Stopp" name="Inworld" tool_tip="Diese Animation so wiedergeben, dass andere sie sehen können."/> + <button label="Lokal wiedergeben" label_selected="Stopp" name="Locally" tool_tip="Diese Animation so wiedergeben, dass nur Sie sie sehen."/> </floater> 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_spellcheck.xml b/indra/newview/skins/default/xui/de/floater_spellcheck.xml new file mode 100644 index 0000000000..213db277b6 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="Einstellungen für Rechtschreibprüfung"> + <check_box label="Rechtschreibprüfung aktivieren" name="spellcheck_enable"/> + <text name="spellcheck_main"> + Hauptwörterbuch: + </text> + <text label="Protokolle:" name="spellcheck_additional"> + Zusätzliche Wörterbücher: + </text> + <text name="spellcheck_available"> + Verfügbar + </text> + <text name="spellcheck_active"> + Aktiv + </text> + <button label="Entfernen" name="spellcheck_remove_btn"/> + <button label="Importieren..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/de/floater_spellcheck_import.xml new file mode 100644 index 0000000000..374c0fc0d2 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Wörterbuch importieren"> + <button label="Durchsuchen" label_selected="Durchsuchen" name="dictionary_path_browse"/> + <button label="Importieren" name="ok_btn"/> + <button label="Abbrechen" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_stats.xml b/indra/newview/skins/default/xui/de/floater_stats.xml index f6dc9fe15d..f3239f73c7 100644 --- a/indra/newview/skins/default/xui/de/floater_stats.xml +++ b/indra/newview/skins/default/xui/de/floater_stats.xml @@ -14,8 +14,11 @@ <stat_bar label="Pro Sek. gezeichnete KTris" name="ktrissec"/> <stat_bar label="Objektanzahl" name="objs"/> <stat_bar label="Neue Objekte" name="newobjs"/> + <stat_bar label="Objektcache-Trefferrate" name="object_cache_hits"/> </stat_view> <stat_view label="Textur" name="texture"> + <stat_bar label="Cache-Trefferrate" name="texture_cache_hits"/> + <stat_bar label="Cache-Leselatenz" name="texture_cache_read_latency"/> <stat_bar label="Zählen" name="numimagesstat"/> <stat_bar label="Rohanzahl" name="numrawimagesstat"/> <stat_bar label="GL Sp" name="gltexmemstat"/> @@ -50,7 +53,13 @@ <stat_bar label="Objekte" name="simobjects"/> <stat_bar label="Aktive Objekte" name="simactiveobjects"/> <stat_bar label="Aktive Skripts" name="simactivescripts"/> + <stat_bar label="Skripts ausgeführt" name="simpctscriptsrun"/> <stat_bar label="Skript-Events" name="simscripteps"/> + <stat_view label="Pathfinding" name="simpathfinding"> + <stat_bar label="AI-Schrittzeit" name="simsimaistepmsec"/> + <stat_bar label="Übersprungene Silhouettenschritte" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Figuren aktualisiert" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_bar label="Paketeingang" name="siminpps"/> <stat_bar label="Paketausgang" name="simoutpps"/> <stat_bar label="Ausstehende Downloads" name="simpendingdownloads"/> diff --git a/indra/newview/skins/default/xui/de/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/de/floater_test_layout_stacks.xml new file mode 100644 index 0000000000..429447c378 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_test_layout_stacks.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="LAYOUTSTACK-TESTS"/> diff --git a/indra/newview/skins/default/xui/de/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/de/floater_test_text_vertical_aligment.xml new file mode 100644 index 0000000000..506d2b013a --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_test_text_vertical_aligment.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="TEST-FENSTER"/> diff --git a/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml index 8944c79c7d..9585622516 100644 --- a/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml @@ -1,24 +1,36 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="texture picker" title="TEXTUR AUSWÄHLEN"> - <string name="choose_picture"> + <floater.string name="choose_picture"> Zum Auswählen eines Bildes hier klicken - </string> + </floater.string> + <floater.string name="pick title"> + Auswählen: + </floater.string> <text name="Multiple"> Mehrere Texturen </text> + <radio_group name="mode_selection"> + <radio_item label="Inventar" name="inventory" value="0"/> + <radio_item label="Lokal" name="local" value="1"/> + </radio_group> <text name="unknown"> Größe: [DIMENSIONS] </text> <button label="Standard" label_selected="Standard" name="Default"/> - <button label="Keine" label_selected="Keine" name="None"/> <button label="Leer" label_selected="Leer" name="Blank"/> - <check_box label="Ordner anzeigen" name="show_folders_check"/> - <search_editor label="Texturen filtern" name="inventory search editor"/> - <check_box label="Jetzt übernehmen" name="apply_immediate_check"/> + <button label="Keine" label_selected="Keine" name="None"/> <button label="" label_selected="" name="Pipette"/> - <button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/> + <check_box initial_value="true" label="Live-Vorschau" name="apply_immediate_check"/> + <text name="preview_disabled" value="Vorschau deaktiviert"/> + <filter_editor label="Texturen filtern" name="inventory search editor"/> + <check_box initial_value="false" label="Ordner anzeigen" name="show_folders_check"/> + <button label="Hinzufügen" label_selected="Hinzufügen" name="l_add_btn"/> + <button label="Entfernen" label_selected="Entfernen" name="l_rem_btn"/> + <button label="Hochladen" label_selected="Hochladen" name="l_upl_btn"/> + <scroll_list name="l_name_list"> + <column label="Name" name="unit_name"/> + <column label="ID" name="unit_id_HIDDEN"/> + </scroll_list> <button label="OK" label_selected="OK" name="Select"/> - <text name="pick title"> - Auswählen: - </text> + <button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/de/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/de/floater_texture_fetch_debugger.xml new file mode 100644 index 0000000000..97b0364832 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_texture_fetch_debugger.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="TexFetchDebugger" title="Debugger für Texturabruffehler"> + <text name="total_num_fetched_label"> + 1, Gesamtzahl abgerufener Texturen: [NUM] + </text> + <text name="total_num_fetching_requests_label"> + 2, Gesamtzahl von Abrufanforderungen: [NUM] + </text> + <text name="total_num_cache_hits_label"> + 3, Gesamtzahl von Cachetreffern: [NUM] + </text> + <text name="total_num_visible_tex_label"> + 4, Gesamtzahl sichtbarer Texturen: [NUM] + </text> + <text name="total_num_visible_tex_fetch_req_label"> + 5, Gesamtzahl von Abrufanforderungen für sichtbare Texturen: [NUM] + </text> + <text name="total_fetched_data_label"> + 6, Gesamtmenge abgerufener Daten: [SIZE1] KB, decodierte Daten: [SIZE2] KB, [PIXEL] MPixel + </text> + <text name="total_fetched_vis_data_label"> + 7, Gesamtmenge sichtbarer Daten: [SIZE1] KB, decodierte Daten: [SIZE2] KB + </text> + <text name="total_fetched_rendered_data_label"> + 8, Gesamtmenge dargestellter Daten: [SIZE1] KB, decodierte Daten: [SIZE2] KB, [PIXEL] MPixel + </text> + <text name="total_time_cache_read_label"> + 9, Gesamtzeit Cache-Lesezugriffe: [TIME] s + </text> + <text name="total_time_cache_write_label"> + 10, Gesamtzeit Cache-Schreibzugriffe: [TIME] s + </text> + <text name="total_time_decode_label"> + 11, Gesamtzeit Decodierung: [TIME] s + </text> + <text name="total_time_gl_label"> + 12, Gesamtzeit GL-Texturerstellung: [TIME] s + </text> + <text name="total_time_http_label"> + 13, Gesamtzeit HTTP-Abrufe: [TIME] s + </text> + <text name="total_time_fetch_label"> + 14, Gesamtzeit für alle Abrufe: [TIME] s + </text> + <text name="total_time_refetch_vis_cache_label"> + 15, Neuabruf sichtbarer Texturen aus Cache, Zeit: [TIME] s, Abrufmenge: [SIZE2] KB, [PIXEL] MPixel + </text> + <text name="total_time_refetch_all_cache_label"> + 16, Neuabruf aller Texturen aus Cache, Zeit: [TIME] s, Abrufmenge: [SIZE2] KB, [PIXEL] MPixel + </text> + <text name="total_time_refetch_vis_http_label"> + 17, Neuabruf sichtbarer Texturen von HTTP, Zeit: [TIME] s, Abrufmenge: [SIZE2] KB, [PIXEL] MPixel + </text> + <text name="total_time_refetch_all_http_label"> + 18, Neuabruf aller Texturen von HTTP, Zeit: [TIME] s, Abrufmenge: [SIZE2] KB, [PIXEL] MPixel + </text> + <spinner label="19, Verhältnis Texel/Pixel:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, Texturquelle: + </text> + <radio_group name="texture_source"> + <radio_item label="Cache + HTTP" name="0"/> + <radio_item label="Nur HTTP" name="1"/> + </radio_group> + <button label="Starten" name="start_btn"/> + <button label="Zurücksetzen" name="clear_btn"/> + <button label="Schließen" name="close_btn"/> + <button label="Cache-Lesezugriff" name="cacheread_btn"/> + <button label="Cache-Schreibzugriff" name="cachewrite_btn"/> + <button label="HTTP" name="http_btn"/> + <button label="Decodieren" name="decode_btn"/> + <button label="GL-Textur" name="gl_btn"/> + <button label="Neuabruf sichtbarer Texturen (Cache)" name="refetchviscache_btn"/> + <button label="Neuabruf des gesamten Cache" name="refetchallcache_btn"/> + <button label="Neuabruf sichtbarer Texturen (HTTP)" name="refetchvishttp_btn"/> + <button label="Neuabruf des gesamten HTTP" name="refetchallhttp_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_tools.xml b/indra/newview/skins/default/xui/de/floater_tools.xml index cf1d03f32d..5f5c34a5cf 100644 --- a/indra/newview/skins/default/xui/de/floater_tools.xml +++ b/indra/newview/skins/default/xui/de/floater_tools.xml @@ -1,5 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="toolbox floater" short_title="BAU-WERKZEUGE" title=""> + <floater.string name="grid_screen_text"> + Bildschirm + </floater.string> + <floater.string name="grid_local_text"> + Lokal + </floater.string> + <floater.string name="grid_world_text"> + Welt + </floater.string> + <floater.string name="grid_reference_text"> + Referenz + </floater.string> + <floater.string name="grid_attachment_text"> + Anhang + </floater.string> <floater.string name="status_rotate"> An den farbigen Bändern ziehen, um das Objekt zu drehen </floater.string> @@ -63,7 +78,12 @@ </text> <check_box initial_value="true" label="Texturen dehnen" name="checkbox stretch textures" top_pad="-5"/> <check_box initial_value="true" label="Einrasten" name="checkbox snap to grid" top_pad="15"/> - <button label="Optionen..." label_selected="Optionen..." name="Options..." tool_tip="Mehr Raster-Optionen anzeigen"/> + <combo_box name="combobox grid mode" tool_tip="Wählen Sie das gewünschte Rasterlineal zum Positionieren des Objekts aus."> + <combo_box.item label="Welt" name="World"/> + <combo_box.item label="Lokal" name="Local"/> + <combo_box.item label="Referenz" name="Reference"/> + </combo_box> + <button label="" label_selected="Optionen..." name="Options..." tool_tip="Mehr Raster-Optionen anzeigen"/> <button label="" label_selected="" name="ToolCube" tool_tip="Würfel"/> <button label="" label_selected="" name="ToolPrism" tool_tip="Prisma"/> <button label="" label_selected="" name="ToolPyramid" tool_tip="Pyramide"/> @@ -128,6 +148,12 @@ <panel.string name="text modify info 4"> Sie können diese Objekte nicht bearbeiten. </panel.string> + <panel.string name="text modify info 5"> + Dieses Objekt kann nicht über eine Regionsgrenze hinweg geändert werden + </panel.string> + <panel.string name="text modify info 6"> + Diese Objekte können nicht über eine Regionsgrenze hinweg geändert werden + </panel.string> <panel.string name="text modify warning"> Gesamtes Objekt wählen, um Berechtigungen festzulegen. </panel.string> @@ -177,12 +203,12 @@ <combo_box.item label="Zoom" name="Zoom"/> </combo_box> <check_box label="Zum Verkauf:" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Kopie" name="Copy"/> <combo_box.item label="Inhalt" name="Contents"/> <combo_box.item label="Original" name="Original"/> </combo_box> - <spinner label="Preis: L$" name="Edit Cost"/> <check_box label="In Suche anzeigen" name="search_check" tool_tip="Dieses Objekt in Suchergebnissen anzeigen"/> <panel name="perms_build"> <text name="perm_modify"> @@ -218,6 +244,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Pathfinding-Attribute: + </text> + </panel> </panel> <panel label="Objekt" name="Object"> <check_box label="Gesperrt" name="checkbox locked" tool_tip="Verhindert, dass das Objekt verschoben oder gelöscht wird. Oft beim Bauen nützlich, um unbeabsichtigte Bearbeitungen zu vermeiden."/> diff --git a/indra/newview/skins/default/xui/de/floater_top_objects.xml b/indra/newview/skins/default/xui/de/floater_top_objects.xml index d2055a53db..f8130c6379 100644 --- a/indra/newview/skins/default/xui/de/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/de/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> Zeit </floater.string> - <floater.string name="scripts_mono_time_label"> - Mono-Uhrzeit: - </floater.string> <floater.string name="top_colliders_title"> Top-Kollisionsobjekte </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="Name" name="name" width="135"/> <scroll_list.columns label="Eigentümer" name="owner"/> <scroll_list.columns label="Position" name="location" width="125"/> + <scroll_list.columns label="Parzelle" name="parcel"/> <scroll_list.columns label="Uhrzeit" name="time"/> - <scroll_list.columns label="Mono-Uhrzeit:" name="mono_time"/> <scroll_list.columns label="URLs" name="URLs"/> + <scroll_list.columns label="Speicher (KB)" name="memory"/> </scroll_list> <text name="id_text"> Objekt-ID: @@ -42,12 +40,16 @@ <button label="Beacon anzeigen" name="show_beacon_btn"/> <text name="obj_name_text"> Objektname: - </text> + </text> <button label="Filter" name="filter_object_btn"/> <text name="owner_name_text"> Eigentümer: - </text> + </text> <button label="Filter" name="filter_owner_btn"/> + <text name="parcel_name_text"> + Parzelle: + </text> + <button label="Filtern" name="filter_parcel_btn"/> <button label="Aktualisieren" name="refresh_btn"/> <button label="Auswahl zurückgeben" name="return_selected_btn" width="134"/> <button label="Alle zurückgeben" left="150" name="return_all_btn" width="134"/> 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/floater_voice_effect.xml b/indra/newview/skins/default/xui/de/floater_voice_effect.xml index 3dc0fc2322..413a46525c 100644 --- a/indra/newview/skins/default/xui/de/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/de/floater_voice_effect.xml @@ -42,13 +42,16 @@ <string name="effect_Demon"> Dämon </string> + <string name="effect_Female Elf"> + Weibliche Elfe + </string> <string name="effect_Flirty"> Kokett </string> <string name="effect_Foxy"> Attraktiv </string> - <string name="effect_Halloween_2010_Bonus"> + <string name="effect_Halloween 2010 Bonus"> Bonus_Halloween_2010 </string> <string name="effect_Helium"> @@ -57,9 +60,18 @@ <string name="effect_Husky"> Rauchig </string> + <string name="effect_Husky Whisper"> + Rauchiges Flüstern + </string> <string name="effect_Intercom"> Intercom </string> + <string name="effect_Julia"> + Julia + </string> + <string name="effect_Lo Lilt"> + Leises Trällern + </string> <string name="effect_Macho"> Macho </string> @@ -69,6 +81,9 @@ <string name="effect_Mini"> Mini </string> + <string name="effect_Model"> + Modell + </string> <string name="effect_Nano"> Nano </string> @@ -90,6 +105,9 @@ <string name="effect_Roxanne"> Roxanne </string> + <string name="effect_Rumble"> + Rumpeln + </string> <string name="effect_Sabrina"> Sabrina </string> @@ -102,6 +120,9 @@ <string name="effect_Shorty"> Shorty </string> + <string name="effect_Smaller"> + Kleiner + </string> <string name="effect_Sneaky"> Hinterhältig </string> diff --git a/indra/newview/skins/default/xui/de/floater_window_size.xml b/indra/newview/skins/default/xui/de/floater_window_size.xml index a2a53e0567..6502f002a1 100644 --- a/indra/newview/skins/default/xui/de/floater_window_size.xml +++ b/indra/newview/skins/default/xui/de/floater_window_size.xml @@ -7,10 +7,17 @@ Fenstergröße einstellen: </text> <combo_box name="window_size_combo" tool_tip="Breite x Höhe"> - <combo_box.item label="1000 x 700 (Standard)" name="item0"/> - <combo_box.item label="1024 x 768" name="item1"/> - <combo_box.item label="1280 x 720 (720p)" name="item2"/> - <combo_box.item label="1920 x 1080 (1080p)" name="item3"/> + <combo_box.item label="1000 x 700 (Standard)" name="item1"/> + <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/> + <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/> + <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/> + <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/> + <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/> + <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/> + <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/> + <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/> + <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/> + <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/> </combo_box> <button label="Festlegen" name="set_btn"/> <button label="Abbrechen" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/de/menu_bottomtray.xml b/indra/newview/skins/default/xui/de/menu_bottomtray.xml deleted file mode 100644 index cb0082f944..0000000000 --- a/indra/newview/skins/default/xui/de/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="Schaltfläche „Sprechen“" name="EnableVoiceChat"/> - <menu_item_check label="Schaltfläche Gesten" name="ShowGestureButton"/> - <menu_item_check label="Schaltfläche Bewegungssteuerung" name="ShowMoveButton"/> - <menu_item_check label="Schaltfläche Ansicht" name="ShowCameraButton"/> - <menu_item_check label="Schaltfläche Foto" name="ShowSnapshotButton"/> - <menu_item_check label="Schaltfläche „Bauen“" name="ShowBuildButton"/> - <menu_item_check label="Schaltfläche „Suchen“" name="ShowSearchButton"/> - <menu_item_check label="Schaltfläche „Karte“" name="ShowWorldMapButton"/> - <menu_item_check label="Minikarten-Schaltfläche" name="ShowMiniMapButton"/> - <menu_item_call label="Ausschneiden" name="NearbyChatBar_Cut"/> - <menu_item_call label="Kopieren" name="NearbyChatBar_Copy"/> - <menu_item_call label="Einfügen" name="NearbyChatBar_Paste"/> - <menu_item_call label="Löschen" name="NearbyChatBar_Delete"/> - <menu_item_call label="Alle auswählen" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/de/menu_im_well_button.xml b/indra/newview/skins/default/xui/de/menu_im_well_button.xml deleted file mode 100644 index f464b71f4a..0000000000 --- a/indra/newview/skins/default/xui/de/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<context_menu name="IM Well Button Context Menu"> - <menu_item_call label="Alle schließen" name="Close All"/> -</context_menu> diff --git a/indra/newview/skins/default/xui/de/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/de/menu_inspect_object_gear.xml index 7c47913e30..73e0029b76 100644 --- a/indra/newview/skins/default/xui/de/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/de/menu_inspect_object_gear.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<menu name="Gear Menu"> +<toggleable_menu name="Gear Menu"> <menu_item_call label="Berühren" name="touch"/> <menu_item_call label="Sitzen" name="sit"/> <menu_item_call label="Bezahlen" name="pay"/> @@ -12,7 +12,8 @@ <menu_item_call label="Hinzufügen" name="add"/> <menu_item_call label="Melden" name="report"/> <menu_item_call label="Ignorieren" name="block"/> + <menu_item_call label="Freischalten" name="unblock"/> <menu_item_call label="Hineinzoomen" name="zoom_in"/> <menu_item_call label="Entfernen" name="remove"/> <menu_item_call label="Weitere Infos" name="more_info"/> -</menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/de/menu_inventory.xml b/indra/newview/skins/default/xui/de/menu_inventory.xml index 733a0b85c3..cd2fca313e 100644 --- a/indra/newview/skins/default/xui/de/menu_inventory.xml +++ b/indra/newview/skins/default/xui/de/menu_inventory.xml @@ -59,6 +59,7 @@ <menu_item_call label="Eigenschaften" name="Properties"/> <menu_item_call label="Umbenennen" name="Rename"/> <menu_item_call label="Asset-UUID kopieren" name="Copy Asset UUID"/> + <menu_item_call label="Ausschneiden" name="Cut"/> <menu_item_call label="Kopieren" name="Copy"/> <menu_item_call label="Einfügen" name="Paste"/> <menu_item_call label="Als Link einfügen" name="Paste As Link"/> @@ -67,6 +68,7 @@ <menu_item_call label="Systemordner löschen" name="Delete System Folder"/> <menu_item_call label="Konferenz-Chat starten" name="Conference Chat Folder"/> <menu_item_call label="Wiedergeben/Abspielen" name="Sound Play"/> + <menu_item_call label="SLurl kopieren" name="url_copy"/> <menu_item_call label="Landmarken-Info" name="About Landmark"/> <menu_item_call label="Inworld abspielen" name="Animation Play"/> <menu_item_call label="Lokal abspielen" name="Animation Audition"/> @@ -84,6 +86,6 @@ <menu_item_call label="Hinzufügen" name="Wearable Add"/> <menu_item_call label="Ausziehen" name="Take Off"/> <menu_item_call label="In Händler-Outbox kopieren" name="Merchant Copy"/> - <menu_item_call label="In Händler-Outbox verschieben" name="Merchant Move"/> + <menu_item_call label="In Marktplatz übertragen" name="Marketplace Send"/> <menu_item_call label="--keine Optionen--" name="--no options--"/> </menu> diff --git a/indra/newview/skins/default/xui/de/menu_login.xml b/indra/newview/skins/default/xui/de/menu_login.xml index c90205fbe4..b43b41a5dc 100644 --- a/indra/newview/skins/default/xui/de/menu_login.xml +++ b/indra/newview/skins/default/xui/de/menu_login.xml @@ -17,8 +17,8 @@ <menu_item_call label="Fenstergröße einstellen..." name="Set Window Size..."/> <menu_item_call label="Servicebedingungen anzeigen" name="TOS"/> <menu_item_call label="Wichtige Meldung anzeigen" name="Critical"/> - <menu_item_call label="Test Medienbrowser" name="Web Browser Test"/> <menu_item_call label="Web Content Floater Debug Test" name="Web Content Floater Debug Test"/> + <menu label="Protokollierungsstufe festlegen" name="Set Logging Level"/> <menu_item_check label="Grid-Auswahl anzeigen" name="Show Grid Picker"/> <menu_item_call label="Benachrichtigungs-Konsole anzeigen" name="Show Notifications Console"/> </menu> diff --git a/indra/newview/skins/default/xui/de/menu_mode_change.xml b/indra/newview/skins/default/xui/de/menu_mode_change.xml deleted file mode 100644 index b8090018b7..0000000000 --- a/indra/newview/skins/default/xui/de/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="Basis" name="BasicMode"/> - <menu_item_check label="Erweitert" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/de/menu_object.xml b/indra/newview/skins/default/xui/de/menu_object.xml index 412bd3ac04..9f44ced928 100644 --- a/indra/newview/skins/default/xui/de/menu_object.xml +++ b/indra/newview/skins/default/xui/de/menu_object.xml @@ -5,6 +5,8 @@ </menu_item_call> <menu_item_call label="Bearbeiten" name="Edit..."/> <menu_item_call label="Bauen" name="Build"/> + <menu_item_call label="In Linksets anzeigen" name="show_in_linksets"/> + <menu_item_call label="In Figuren anzeigen" name="show_in_characters"/> <menu_item_call label="Öffnen" name="Open"/> <menu_item_call label="Hier sitzen" name="Object Sit"/> <menu_item_call label="Aufstehen" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/de/menu_text_editor.xml b/indra/newview/skins/default/xui/de/menu_text_editor.xml index c00186c13e..2e33ed3416 100644 --- a/indra/newview/skins/default/xui/de/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/de/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(unbekannt)" name="Suggestion 1"/> + <menu_item_call label="(unbekannt)" name="Suggestion 2"/> + <menu_item_call label="(unbekannt)" name="Suggestion 3"/> + <menu_item_call label="(unbekannt)" name="Suggestion 4"/> + <menu_item_call label="(unbekannt)" name="Suggestion 5"/> + <menu_item_call label="Zum Wörterbuch hinzufügen" name="Add to Dictionary"/> + <menu_item_call label="Zur Ignorieren-Liste hinzufügen" name="Add to Ignore"/> <menu_item_call label="Ausschneiden" name="Cut"/> <menu_item_call label="Kopieren" name="Copy"/> <menu_item_call label="Einfügen" name="Paste"/> 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 e6135aa100..845df1f050 100644 --- a/indra/newview/skins/default/xui/de/menu_viewer.xml +++ b/indra/newview/skins/default/xui/de/menu_viewer.xml @@ -1,55 +1,62 @@ <?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"/> <menu_item_check label="Immer rennen" name="Always Run"/> <menu_item_call label="Animation meines Avatars stoppen" name="Stop Animating My Avatar"/> + <menu_item_call label="Gehen/Rennen/Fliegen..." name="Walk / run / fly"/> </menu> <menu label="Status" name="Status"> <menu_item_call label="Abwesend" name="Set Away"/> <menu_item_call label="Beschäftigt" name="Set Busy"/> </menu> - <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="L$ kaufen..." name="Buy and Sell L$"/> + <menu_item_call label="Händler-Outbox..." name="MerchantOutbox"/> + <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_check label="HUD-Anhänge anzeigen" name="Show HUD Attachments"/> <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_item_call label="Blockierliste" name="Block List"/> </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 +65,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 label="Sonne" name="Sun"> <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"/> @@ -120,6 +126,11 @@ <menu_item_call label="Skripts auf ausführen einstellen" name="Set Scripts to Running"/> <menu_item_call label="Skripts auf nicht ausführen einstellen" name="Set Scripts to Not Running"/> </menu> + <menu label="Pathfinding" name="Pathfinding"> + <menu_item_call label="Linksets..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="Figuren..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="Anzeigen/Testen..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Optionen" name="Options"> <menu_item_check label="Erweiterte Berechtigungen anzeigen" name="DebugPermissions"/> <menu_item_check label="Nur meine Objekte auswählen" name="Select Only My Objects"/> @@ -140,11 +151,13 @@ <menu_item_call label="Animation ([COST] L$)..." name="Upload Animation"/> <menu_item_call label="Modell..." name="Upload Model"/> <menu_item_call label="Mehrfach-Upload ([COST] L$ pro Datei)..." name="Bulk Upload"/> + <menu_item_call label="Hochlade-Berechtigungen (Standard) festlegen" name="perm prefs"/> </menu> <menu_item_call label="Rückgängig" name="Undo"/> <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"/> @@ -168,26 +181,25 @@ <menu_item_check label="Partikel ausblenden" name="Hide Particles"/> <menu_item_check label="Auswahl ausblenden" name="Hide Selected"/> <menu_item_check label="Durchsichtig hervorheben" name="Highlight Transparent"/> - <menu_item_check label="HUD-Anhänge anzeigen" name="Show HUD Attachments"/> <menu_item_check label="Fadenkreuz für Mouselook anzeigen" name="ShowCrosshairs"/> </menu> <menu label="Darstellungstypen" name="Rendering Types"> - <menu_item_check label="Einfach" name="Simple"/> - <menu_item_check label="Alpha" name="Alpha"/> - <menu_item_check label="Baum" name="Tree"/> - <menu_item_check label="Avatare" name="Character"/> - <menu_item_check label="Flächenpatch" name="Surface Patch"/> - <menu_item_check label="Himmel" name="Sky"/> - <menu_item_check label="Wasser" name="Water"/> - <menu_item_check label="Boden" name="Ground"/> - <menu_item_check label="Volumen" name="Volume"/> - <menu_item_check label="Gras" name="Grass"/> - <menu_item_check label="Wolken" name="Clouds"/> - <menu_item_check label="Partikel" name="Particles"/> - <menu_item_check label="Unebenheiten" name="Bump"/> + <menu_item_check label="Einfach" name="Rendering Type Simple"/> + <menu_item_check label="Alpha" name="Rendering Type Alpha"/> + <menu_item_check label="Baum" name="Rendering Type Tree"/> + <menu_item_check label="Avatare" name="Rendering Type Character"/> + <menu_item_check label="Flächenpatch" name="Rendering Type Surface Patch"/> + <menu_item_check label="Himmel" name="Rendering Type Sky"/> + <menu_item_check label="Wasser" name="Rendering Type Water"/> + <menu_item_check label="Boden" name="Rendering Type Ground"/> + <menu_item_check label="Volumen" name="Rendering Type Volume"/> + <menu_item_check label="Gras" name="Rendering Type Grass"/> + <menu_item_check label="Wolken" name="Rendering Type Clouds"/> + <menu_item_check label="Partikel" name="Rendering Type Particles"/> + <menu_item_check label="Unebenheiten" name="Rendering Type Bump"/> </menu> <menu label="Rendering-Eigenschaften" name="Rendering Features"> - <menu_item_check label="UI" name="UI"/> + <menu_item_check label="UI" name="ToggleUI"/> <menu_item_check label="Ausgewählt" name="Selected"/> <menu_item_check label="Farblich hervorgehoben" name="Highlighted"/> <menu_item_check label="Dynamische Texturen" name="Dynamic Textures"/> @@ -199,11 +211,8 @@ <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"/> @@ -212,13 +221,6 @@ <menu_item_check label="Joystick-Flycam" name="Joystick Flycam"/> <menu_item_call label="Ansicht zurücksetzen" name="Reset View"/> <menu_item_call label="Letzten Chatter ansehen" name="Look at Last Chatter"/> - <menu label="Bauwerkzeug auswählen" name="Select Tool"> - <menu_item_call label="Fokus-Werkzeug" name="Focus"/> - <menu_item_call label="Werkzeug „Bewegen“" name="Move"/> - <menu_item_call label="Bearbeiten" name="Edit"/> - <menu_item_call label="Werkzeug „Erstellen"" name="Create"/> - <menu_item_call label="Land-Werkzeug" name="Land"/> - </menu> <menu_item_call label="Hineinzoomen" name="Zoom In"/> <menu_item_call label="Zoom-Standard" name="Zoom Default"/> <menu_item_call label="Wegzoomen" name="Zoom Out"/> @@ -231,11 +233,10 @@ <menu_item_check label="Textur" name="Texture Console"/> <menu_item_check label="Fehler beseitigen" name="Debug Console"/> <menu_item_call label="Meldungen" name="Notifications"/> - <menu_item_check label="Texturgröße" name="Texture Size"/> - <menu_item_check label="Texture-Kategorie" name="Texture Category"/> <menu_item_check label="Schnelle Timer" name="Fast Timers"/> <menu_item_check label="Speicher" name="Memory"/> <menu_item_check label="Szenestatistiken" name="Scene Statistics"/> + <menu_item_call label="Debug-Konsole für Texturabruffehler" name="Texture Fetch Debug Console"/> <menu_item_call label="Info zu Region in Fenster Fehler beseitigen" name="Region Info to Debug Console"/> <menu_item_call label="Gruppeninfo in Fenster Fehler beseitigen" name="Group Info to Debug Console"/> <menu_item_call label="Info zu Fähigkeiten in Fenster Fehler beseitigen" name="Capabilities Info to Debug Console"/> @@ -289,8 +290,16 @@ <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="Byte in Anhängen" name="attachment bytes"/> <menu_item_check label="Formen" name="Sculpt"/> + <menu label="Texturdichte" name="Texture Density"> + <menu_item_check label="Keine" name="None"/> + <menu_item_check label="Aktuelle" name="Current"/> + <menu_item_check label="Gewünschte" name="Desired"/> + <menu_item_check label="Volle" name="Full"/> + </menu> </menu> <menu label="Rendering" name="Rendering"> <menu_item_check label="Achsen" name="Axes"/> @@ -301,7 +310,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)"/> @@ -309,7 +317,6 @@ <menu_item_check label="Animationstexturen" name="Animation Textures"/> <menu_item_check label="Texturen deaktivieren" name="Disable Textures"/> <menu_item_check label="Voll-Res-Texturen" name="Rull Res Textures"/> - <menu_item_check label="Texturen prüfen" name="Audit Textures"/> <menu_item_check label="Textur-Atlas (experimentell)" name="Texture Atlas"/> <menu_item_check label="Angehängte Lichter rendern" name="Render Attached Lights"/> <menu_item_check label="Angehängte Partikel rendern" name="Render Attached Particles"/> @@ -332,9 +339,8 @@ <menu_item_call label="Aufnahme starten" name="Start Record"/> <menu_item_call label="Aufnahme stoppen" name="Stop Record"/> </menu> - <menu label="Welt" name="World"> + <menu label="Welt" name="DevelopWorld"> <menu_item_check label="Sonnen-Override für Sim" name="Sim Sun Override"/> - <menu_item_check label="Pulsierender Strahl" name="Cheesy Beacon"/> <menu_item_check label="Festgelegtes Wetter" name="Fixed Weather"/> <menu_item_call label="Regionsobjekt-Cache ausgeben" name="Dump Region Object Cache"/> </menu> @@ -366,18 +372,17 @@ </menu> <menu label="Avatar" name="Character"> <menu label="Geladene Textur nehmen" name="Grab Baked Texture"> - <menu_item_call label="Iris" name="Iris"/> - <menu_item_call label="Kopf" name="Head"/> - <menu_item_call label="Oberkörper" name="Upper Body"/> - <menu_item_call label="Unterkörper" name="Lower Body"/> - <menu_item_call label="Rock" name="Skirt"/> + <menu_item_call label="Iris" name="Grab Iris"/> + <menu_item_call label="Kopf" name="Grab Head"/> + <menu_item_call label="Oberkörper" name="Grab Upper Body"/> + <menu_item_call label="Unterkörper" name="Grab Lower Body"/> + <menu_item_call label="Rock" name="Grab Skirt"/> </menu> <menu label="Avatar-Tests" name="Character Tests"> <menu_item_call label="Aussehen als XML speichern" name="Appearance To XML"/> <menu_item_call label="Avatargeometry ein-/ausschalten" name="Toggle Character Geometry"/> <menu_item_call label="Männlich testen" name="Test Male"/> <menu_item_call label="Weiblich testen" name="Test Female"/> - <menu_item_call label="PG ein-/ausschalten" name="Toggle PG"/> <menu_item_check label="Avatarauswahl zulassen" name="Allow Select Avatar"/> </menu> <menu_item_call label="Param auf Standard erzwingen" name="Force Params to Default"/> @@ -398,20 +403,28 @@ <menu_item_check label="HTTP-Texturen" name="HTTP Textures"/> <menu_item_check label="HTTP-Inventar" name="HTTP Inventory"/> <menu_item_call label="Bilder komprimieren" name="Compress Images"/> + <menu_item_call label="Visual Leak Detector aktivieren" name="Enable Visual Leak Detector"/> <menu_item_check label="Ausgabe Fehlerbeseitigung ausgeben" name="Output Debug Minidump"/> <menu_item_check label="Bei nächster Ausführung Fenster öffnen" name="Console Window"/> + <menu label="Protokollierungsstufe festlegen" name="Set Logging Level"> + <menu_item_check label="Debug" name="Debug"/> + <menu_item_check label="Info" name="Info"/> + <menu_item_check label="Warnung" name="Warning"/> + <menu_item_check label="Fehler" name="Error"/> + <menu_item_check label="Keine" name="None"/> + </menu> <menu_item_call label="Admin-Status anfordern" name="Request Admin Options"/> <menu_item_call label="Admin-Status verlassen" name="Leave Admin Options"/> <menu_item_check label="Admin-Menü anzeigen" name="View Admin Options"/> </menu> <menu label="Admin" name="Admin"> - <menu label="Object"> - <menu_item_call label="Kopie nehmen" name="Take Copy"/> - <menu_item_call label="Besitzer zu mir zwingen" name="Force Owner To Me"/> - <menu_item_call label="Erlaubnis des Besitzers erzwingen" name="Force Owner Permissive"/> + <menu label="Objekt" name="AdminObject"> + <menu_item_call label="Kopie nehmen" name="Admin Take Copy"/> + <menu_item_call label="Mich zum Besitzer machen" name="Force Owner To Me"/> + <menu_item_call label="Besitzererlaubnis erzwingen" name="Force Owner Permissive"/> <menu_item_call label="Löschen" name="Delete"/> - <menu_item_call label="Fest" name="Lock"/> - <menu_item_call label="Asset-ID zulassen" name="Get Assets IDs"/> + <menu_item_call label="Sperren" name="Lock"/> + <menu_item_call label="Asset-IDs abrufen" name="Get Assets IDs"/> </menu> <menu label="Parzelle" name="Parcel"> <menu_item_call label="Besitzer zu mir zwingen" name="Owner To Me"/> @@ -442,14 +455,14 @@ <menu_item_call label="Physik" name="Physics"/> <menu_item_call label="Alle Kleider" name="All Clothes"/> </menu> - <menu label="Hilfe" name="Help"> + <menu label="Hilfe" name="DeprecatedHelp"> <menu_item_call label="Offizielles Linden-Blog" name="Official Linden Blog"/> <menu_item_call label="Scripting-Portal" name="Scripting Portal"/> <menu label="Fehlermeldungen" name="Bug Reporting"> <menu_item_call label="Allgemeiner Probleme-Tracker" name="Public Issue Tracker"/> <menu_item_call label="Hilfe zum Allgemeinen Probleme-Tracker" name="Publc Issue Tracker Help"/> <menu_item_call label="Fehlermeldungs-1x1" name="Bug Reporing 101"/> - <menu_item_call label="Sicherheitsfragen" name="Security Issues"/> + <menu_item_call label="Sicherheitsprobleme" name="Security Issues"/> <menu_item_call label="QA-Wiki" name="QA Wiki"/> </menu> </menu> diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index fc38608df5..4b7a60b4eb 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -86,17 +92,38 @@ Stellen Sie sicher, dass Ihre Internetverbindung funktioniert. <usetemplate canceltext="Abbrechen" name="yesnocancelbuttons" notext="Nicht speichern" yestext="Speichern"/> </notification> <notification name="ConfirmNoCopyToOutbox"> - Ihnen fehlt die Berechtigung zum Kopieren dieses Artikels in die Händler-Outbox. Möchten Sie wirklich den folgenden Artikel verschieben? - [ITEM_NAME] - <usetemplate name="okcancelbuttons" notext="Nein" yestext="Ja"/> + Sie sind nicht berechtigt, einen oder mehrere dieser Artikel in die Händler-Outbox zu kopieren. Sie können sie verschieben oder zurücklassen. + <usetemplate name="okcancelbuttons" notext="Artikel nicht verschieben" yestext="Artikel verschieben"/> + </notification> + <notification name="OutboxFolderCreated"> + Für jeden Artikel, den Sie in die oberste Ebene Ihrer Händler-Outbox übertragen haben, wurde ein neuer Ordner erstellt. + <usetemplate ignoretext="Neuer Ordner in Händler-Outbox erstellt" name="okignore" yestext="OK"/> + </notification> + <notification name="OutboxImportComplete"> + Erfolg + +Alle Ordner wurden erfolgreich an den Marktplatz übertragen. + <usetemplate ignoretext="Alle Ordner an den Marktplatz übertragen" name="okignore" yestext="OK"/> + </notification> + <notification name="OutboxImportHadErrors"> + Einige Ordner wurden nicht übertragen + +Beim Übertragen bestimmter Ordner an den Marktplatz ist ein Fehler aufgetreten. Diese Ordner befinden sich noch in Ihrer Händler-Outbox. + +Weitere Informationen finden Sie im [[MARKETPLACE_IMPORTS_URL] Fehlerprotokoll]. + <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="OutboxUploadComplete"> - Marktplatz-Upload abgeschlossen. - <usetemplate name="okbutton" yestext="Hurra!"/> + <notification name="OutboxImportFailed"> + Übertragung fehlgeschlagen + +Aufgrund eines System- oder Netzwerkfehlers wurden keine Ordner an den Marktplatz übertragen. Versuchen Sie es später erneut. + <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="OutboxUploadHadErrors"> - Marktplatz-Upload mit Fehlern abgeschlossen. Korrigieren Sie die Fehler in Ihrer Outbox und versuchen Sie es erneut. Vielen Dank! - <usetemplate name="okbutton" yestext="Erneut versuchen"/> + <notification name="OutboxInitFailed"> + Marktplatzinitialisierung fehlgeschlagen + +Marktplatzinitialisierung aufgrund eines System- oder Netzwerkfehlers fehlgeschlagen. Versuchen Sie es später erneut. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CompileQueueSaveText"> Der Text für ein Skript konnte aus folgendem Grund nicht hochgeladen werden: [REASON]. Bitte versuchen Sie es erneut. @@ -346,13 +373,19 @@ Sie müssen den Benutzernamen Ihres Avatars eingeben. Sie benötigen ein Konto, um [SECOND_LIFE] betreten zu können. Möchten Sie jetzt ein Konto erstellen? <url name="url"> - https://join.secondlife.com/index.php?lang=de-DE + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Erneut versuchen" yestext="Neues Benutzerkonto anlegen"/> </notification> <notification name="InvalidCredentialFormat"> Sie müssen entweder den Benutzernamen oder den Vor- und Nachnamen Ihres Avatars in das Feld „Benutzername“ eingeben und die Anmeldung dann erneut versuchen. </notification> + <notification name="InvalidGrid"> + „[GRID]“ ist keine gültige Grid-ID. + </notification> + <notification name="InvalidLocationSLURL"> + Ihre Startposition gibt kein gültiges Grid an. + </notification> <notification name="DeleteClassified"> Anzeige „[NAME]“ löschen? Gebühren werden nicht rückerstattet. @@ -458,8 +491,8 @@ Das Objekt ist möglicherweise außer Reichweite oder wurde gelöscht. Ein kompiliertes Skript konnte aus folgendem Grund nicht gespeichert werden: [REASON]. Speichern Sie das Skript bitte später. </notification> <notification name="StartRegionEmpty"> - Sie haben keine Start-Region festgelegt. -Bitte geben Sie den Namen der Region im Feld „Startposition“ ein oder wählen Sie „Mein letzter Standort“ oder „Mein Zuhause“ als Startposition aus. + Ihre Startregion ist nicht definiert. +Geben Sie den Namen der Region im Feld „Startposition“ ein oder wählen Sie „Mein letzter Standort“ oder „Mein Zuhause“ als Startposition aus. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CouldNotStartStopScript"> @@ -481,6 +514,15 @@ Weitere Informationen finden Sie auf [_URL]. </url> <usetemplate ignoretext="Meine Hardware wird nicht unterstützt" name="okcancelignore" notext="Nein" yestext="Ja"/> </notification> + <notification name="IntelOldDriver"> + Wahrscheinlich gibt es einen neueren Treiber für Ihren Grafikchip. Durch Aktualisieren der Grafiktreiber lässt sich die Leistung u. U. beträchtlich verbessern. + + Unter [_URL] nach aktualisierten Treibern suchen? + <url name="url"> + http://www.intel.com/p/de_DE/support/detect/graphics + </url> + <usetemplate ignoretext="Mein Grafiktreiber ist veraltet" name="okcancelignore" notext="Nein" yestext="Ja"/> + </notification> <notification name="UnknownGPU"> Ihr System verwendet eine Grafikkarte, die [APP_NAME] nicht erkennt. Dies passiert dann, wenn die neue Hardware noch nicht mit [APP_NAME] getestet wurde. Wahrscheinlich wird das Programm richtig ausgeführt, aber Sie müssen eventuell ein paar Grafikeinstellungen vornehmen. @@ -577,6 +619,9 @@ Sie können maximal [MAX] Objekte verknüpfen. Stellen Sie sicher, dass kein Objekt gesperrt ist und alle Objekte Ihnen gehören. </notification> + <notification name="CannotLinkPermanent"> + Objekte können nicht über Regionsgrenzen hinweg verknüpft werden. + </notification> <notification name="CannotLinkDifferentOwners"> Verknüpfung nicht möglich, da nicht alle Objekte denselben Eigentümer haben. @@ -656,7 +701,7 @@ Erwartet wurde [VALIDS] Ausgabedatei konnte nicht erstellt werden: [FILE] </notification> <notification name="DoNotSupportBulkAnimationUpload"> - Der Mehrfach-Upload von Animationsdateien wird zurzeit von [APP_NAME] nicht unterstützt. + Der Bulk-Upload von BVH-Animationsdateien wird zurzeit von [APP_NAME] nicht unterstützt. </notification> <notification name="CannotUploadReason"> Datei [FILE] kann aus folgendem Grund nicht hochgeladen werden: [REASON] @@ -961,6 +1006,41 @@ Sie sind nicht berechtigt, Land für die aktive Gruppe zu kaufen. <button name="Cancel" text="Abbrechen"/> </form> </notification> + <notification label="Automatische Ersetzungsliste hinzufügen" name="AddAutoReplaceList"> + Name für neue Liste: + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="Automatische Ersetzungsliste umbenennen" name="RenameAutoReplaceList"> + Der Name „[DUPNAME]“ wird bereits verwendet. + Geben Sie einen neuen eindeutigen Namen ein: + <form name="form"> + <button name="ReplaceList" text="Aktuelle Liste ersetzen"/> + <button name="SetName" text="Neuen Namen verwenden"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + Das Schlüsselwort muss ein einziges Wort sein; die Ersetzungszeichenfolge darf nicht leer sein. + </notification> + <notification name="InvalidAutoReplaceList"> + Diese Ersetzungsliste ist nicht gültig. + </notification> + <notification name="SpellingDictImportRequired"> + Sie müssen eine Datei, einen Namen und eine Sprache angeben. + </notification> + <notification name="SpellingDictIsSecondary"> + Das Wörterbuch [DIC_NAME] scheint keine „aff“-Datei zu haben und ist deshalb ein sekundäres Wörterbuch. +Es kann als zusätzliches Wörterbuch verwendet werden, aber nicht als Hauptwörterbuch. + +Weitere Informationen finden Sie unter https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries. + </notification> + <notification name="SpellingDictImportFailed"> + Kopieren nicht möglich: + [FROM_NAME] + in + [TO_NAME] + </notification> <notification label="Outfit speichern" name="SaveOutfitAs"> Mein aktuelles Outfit als neues Outfit speichern: <form name="form"> @@ -992,7 +1072,7 @@ Sie sind nicht berechtigt, Land für die aktive Gruppe zu kaufen. </form> </notification> <notification name="RemoveFromFriends"> - Möchten Sie [NAME] aus Ihrer Freundesliste entfernen? + Möchten Sie <nolink>[NAME]</nolink> aus Ihrer Freundesliste entfernen? <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> </notification> <notification name="RemoveMultipleFromFriends"> @@ -1124,8 +1204,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] @@ -1136,7 +1221,7 @@ Der Gruppe „[GROUP_NAME]“ [AREA] m² an Land schenken? Sie wurden zur nächstgelegenen Region teleportiert. </notification> <notification name="AvatarMovedLast"> - Ihr letzter Standort ist zurzeit nicht verfügbar. + Ihr angeforderter Standort ist zurzeit nicht verfügbar. Sie wurden zur nächstgelegenen Region teleportiert. </notification> <notification name="AvatarMovedHome"> @@ -1155,8 +1240,7 @@ Sie können [SECOND_LIFE] normal verwenden. Andere Benutzer können Sie korrekt Installation von [APP_NAME] vollständig abgeschlossen. Falls Sie [SECOND_LIFE] zum ersten Mal verwenden, müssen Sie zuerst ein Konto erstellen, bevor Sie sich anmelden können. -Zurück zu [http://join.secondlife.com secondlife.com], um ein neues Konto zu erstellen? - <usetemplate name="okcancelbuttons" notext="Weiter" yestext="Neues Konto..."/> + <usetemplate name="okcancelbuttons" notext="Weiter" yestext="Konto erstellen..."/> </notification> <notification name="LoginPacketNeverReceived"> Es gibt Probleme mit der Verbindung. Möglicherweise besteht ein Problem mit Ihrer Internetverbindung oder dem [SECOND_LIFE_GRID]. @@ -1443,7 +1527,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 gegenwärtig Mitglied der Gruppe <nolink>[GROUP]</nolink>. Diese Gruppe verlassen? <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> </notification> @@ -1673,83 +1757,128 @@ Tausende Regionen werden verändert und der Spaceserver wird dadurch stark belas <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> </notification> <notification name="RegionEntryAccessBlocked"> - Sie dürfen diese Region aufgrund Ihrer Alterseinstufung nicht betreten. Der Grund hierfür ist möglicherweise, dass Sie nicht altersüberprüft sind. - -Bitte vergewissern Sie sich, dass Sie den aktuellsten Viewer installiert haben und besuchen Sie unsere Knowledgebase, um mehr über Regionen mit dieser Altereinstufung zu erfahren. + Die Region, die Sie besuchen möchten, enthält Inhalte, die Ihre aktuellen Einstellungen überschreiten. Sie können Ihre Einstellungen unter „Ich“ > „Einstellungen“ > „Allgemein“ ändern. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - Sie dürfen diese Region aufgrund Ihrer Alterseinstufung nicht betreten. - -Möchten Sie unsere Knowledgebase besuchen, um mehr Informationen über Altereinstufung zu erhalten? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/de </url> - <usetemplate ignoretext="Ich kann diese Region aufgrund der Alterseinstufung nicht betreten" name="okcancelignore" notext="Schließen" yestext="Zur Knowledgbase"/> + <usetemplate ignoretext="Regionswechsel: Die Region, die Sie besuchen möchten, enthält Inhalte, die nur für Erwachsene zugänglich sind." name="okcancelignore" notext="Schließen" yestext="Zur Knowledge Base gehen"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - Aufgrund Ihrer Alterseinstufung dürfen Sie diese Region nicht betreten. + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind. </notification> <notification name="RegionEntryAccessBlocked_Change"> - Sie dürfen diese Region aufgrund der Einstellung Ihrer Inhaltseinstufung nicht betreten. - -Bitte ändern Sie Ihre Einstellungen bezüglich der Inhaltseinstufung, um die gewünschte Region zu betreten. Danach können Sie nach [REGIONMATURITY]-Inhalt suchen und auf diesen zugreifen. Um die Veränderungen rückgängig zu machen, gehen Sie zu Ich > Einstellungen > Allgemein. + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern oder diesen Vorgang abbrechen. Nachdem Sie Ihre Einstellungen geändert haben, können Sie erneut versuchen, die Region zu betreten. <form name="form"> - <button name="OK" text="Einstellung ändern"/> - <button name="Cancel" text="Schließen"/> - <ignore name="ignore" text="Meine Alterseinstufung lässt nicht zu, dass ich eine Region betrete."/> + <button name="OK" text="Einstellungen ändern"/> + <button name="Cancel" text="Abbrechen"/> + <ignore name="ignore" text="Regionswechsel: Die Region, die Sie besuchen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/> + </form> + </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + Wir haben technische Probleme mit Ihrem Teleport, da Ihre Einstellungen nicht mit dem Server synchronisiert sind. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + Die Region, die Sie besuchen möchten, enthält Inhalte, die Ihre aktuellen Einstellungen überschreiten. Sie können Ihre Einstellungen unter „Ich“ > „Einstellungen“ > „Allgemein“ ändern. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind. + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/de + </url> + <usetemplate ignoretext="Teleport: Die Region, die Sie besuchen möchten, enthält Inhalte, die nur für Erwachsene zugänglich sind." name="okcancelignore" notext="Schließen" yestext="Zur Knowledge Base gehen"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern und den Teleport fortsetzen oder Sie können den Teleport abbrechen. + <form name="form"> + <button name="OK" text="Ändern und fortfahren"/> + <button name="Cancel" text="Abbrechen"/> + <ignore name="ignore" text="Teleport (kann neu gestartet werden): Die Region, die Sie besuchen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern oder den Teleport abbrechen. Nachdem Sie Ihre Einstellungen geändert haben, können Sie den Teleport erneut versuchen. + <form name="form"> + <button name="OK" text="Einstellungen ändern"/> + <button name="Cancel" text="Abbrechen"/> + <ignore name="ignore" text="Teleport (kann nicht neu gestartet werden): Die Region, die Sie besuchen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/> </form> </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + Wir haben technische Probleme mit Ihrem Teleport, da Ihre Einstellungen nicht mit dem Server synchronisiert sind. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - Ihre Inhaltseinstufung ist jetzt [RATING]. + Sie erhalten keine Benachrichtigungen mehr, wenn Sie eine Region der Inhaltseinstufung „[RATING]“ besuchen. Sie können Ihre Inhaltseinstellungen von der Menüleiste aus ändern („Ich“ > „Einstellungen“ > „Allgemein“). + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + Wir konnten Ihre Einstellungen zur Anzeige von [PREFERRED_MATURITY]-Inhalten leider nicht ändern. Ihre Einstellungen wurden auf [ACTUAL_MATURITY]-Inhalte zurückgesetzt. Sie können erneut versuchen, Ihre Inhaltseinstellungen von der Menüleiste aus zu ändern („Ich“ > „Einstellungen“ > „Allgemein“). + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - Sie haben aufgrund Ihrer Alterseinstufung keinen Anspruch auf dieses Land. Der Grund hierfür ist möglicherweise, dass Sie nicht altersüberprüft sind. - -Bitte vergewissern Sie sich, dass Sie den aktuellsten Viewer installiert haben und besuchen Sie unsere Knowledgebase, um mehr über Regionen mit dieser Altereinstufung zu erfahren. + Die Inhaltseinstufung des Landes, das Sie in Besitz nehmen möchten, überschreitet Ihre aktuellen Einstellungen. Sie können Ihre Einstellungen unter „Ich“ > „Einstellungen“ > „Allgemein“ ändern. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - Sie haben aufgrund Ihrer Alterseinstufung keinen Anspruch auf dieses Land. - -Möchten Sie unsere Knowledgebase besuchen, um mehr Informationen über Altereinstufung zu erhalten? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + Nur Erwachsene können dieses Land in Besitz nehmen. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/de </url> - <usetemplate ignoretext="Ich habe aufgrund der Alterseinstufung keinen Anspruch auf dieses Land" name="okcancelignore" notext="Schließen" yestext="Zur Knowledgbase"/> + <usetemplate ignoretext="Nur Erwachsene können dieses Land in Besitz nehmen." name="okcancelignore" notext="Schließen" yestext="Zur Knowledge Base gehen"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - Sie haben aufgrund Ihrer Alterseinstufung keinen Anspruch auf dieses Land. + Das Land, das Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + Das Land, das Sie in Besitz nehmen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind. </notification> <notification name="LandClaimAccessBlocked_Change"> - Sie haben aufgrund der Einstellung Ihrer Alterseinstufung keinen Anspruch auf dieses Land. - -Klicken Sie auf „Einstellung ändern“, um Ihre Einstellung für Altereinstufung sofort zu ändern und Zugang zu erhalten. Sie können ab sofort [REGIONMATURITY]-Inhalt suchen und auf diesen zugreifen. Falls Sie diese Einstellung später rückgängig machen möchten, gehen Sie zu Bearbeiten > Einstellungen > Allgemein. - <usetemplate ignoretext="Meine Alterseinstufung lässt nicht zu, dass ich auf Land Anspruch erhebe" name="okcancelignore" notext="Schließen" yestext="Einstellung ändern"/> + Das Land, das Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern und anschließend erneut versuchen, das Land in Besitz zu nehmen. + <form name="form"> + <button name="OK" text="Einstellungen ändern"/> + <button name="Cancel" text="Abbrechen"/> + <ignore name="ignore" text="Das Land, das Sie in Besitz nehmen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - Sie können aufgrund Ihrer Alterseinstufung dieses Land nicht kaufen. Der Grund hierfür ist möglicherweise, dass Sie nicht altersüberprüft sind. - -Bitte vergewissern Sie sich, dass Sie den aktuellsten Viewer installiert haben und besuchen Sie unsere Knowledgebase, um mehr über Regionen mit dieser Altereinstufung zu erfahren. + Die Inhaltseinstufung des Landes, das Sie kaufen möchten, überschreitet Ihre aktuellen Einstellungen. Sie können Ihre Einstellungen unter „Ich“ > „Einstellungen“ > „Allgemein“ ändern. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - Sie können aufgrund Ihrer Alterseinstufung dieses Land nicht kaufen. - -Möchten Sie unsere Knowledgebase besuchen, um mehr Informationen über Altereinstufung zu erhalten? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Nur Erwachsene können dieses Land kaufen. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/de </url> - <usetemplate ignoretext="Ich kann aufgrund der Alterseinstufung dieses Land nicht kaufen" name="okcancelignore" notext="Schließen" yestext="Zur Knowledgbase"/> + <usetemplate ignoretext="Nur Erwachsene können dieses Land kaufen." name="okcancelignore" notext="Schließen" yestext="Zur Knowledge Base gehen"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - Sie können aufgrund Ihrer Alterseinstufung dieses Land nicht kaufen. + Das Land, das Sie kaufen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + Das Land, das Sie kaufen möchten, enthält Inhalte der Einstufung „[REGIONMATURITY]“, die nur für Erwachsene zugänglich sind. </notification> <notification name="LandBuyAccessBlocked_Change"> - Sie können aufgrund Ihrer Einstellung für Alterseinstufung dieses Land nicht kaufen. - -Klicken Sie auf „Einstellung ändern“, um Ihre Einstellung für Altereinstufung sofort zu ändern und Zugang zu erhalten. Sie können ab sofort [REGIONMATURITY]-Inhalt suchen und auf diesen zugreifen. Falls Sie diese Einstellung später rückgängig machen möchten, gehen Sie zu Bearbeiten > Einstellungen > Allgemein. - <usetemplate ignoretext="Meine Alterseinstufung lässt nicht zu, dass ich Land kaufe" name="okcancelignore" notext="Schließen" yestext="Einstellung ändern"/> + Das Land, das Sie kaufen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern und anschließend erneut versuchen, das Land zu kaufen. + <form name="form"> + <button name="OK" text="Einstellungen ändern"/> + <button name="Cancel" text="Abbrechen"/> + <ignore name="ignore" text="Das Land, das Sie kaufen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Zu viele Prims wurden ausgewählt. Bitte wählen Sie höchstens [MAX_PRIM_COUNT] Prims aus und versuchen Sie es erneut. @@ -1804,10 +1933,9 @@ Anzeige für [AMOUNT] L$ veröffentlichen? </form> </notification> <notification label="Alterseinstufung der Region ändern" name="RegionMaturityChange"> - Die Alterseinstufung dieser Region wurde aktualisiert. + Die Inhaltseinstufung dieser Region wurde geändert. Es kann eine Weile dauern, bis diese Änderung auf der Karte angezeigt wird. - -Um Regionen der Alterseinstufung „Adult" zu betreten, müssen Einwohner altersüberprüft sein. Dies kann entweder über die Alterverifizierung oder Zahlungsverifizierung geschehen. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="Falsche Voice-Version" name="VoiceVersionMismatch"> Diese Version von [APP_NAME] ist mit der Voice-Chat-Funktion in dieser Region nicht kompatibel. Damit Voice-Chat funktioniert, müssen Sie [APP_NAME] aktualisieren. @@ -1926,7 +2054,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"/> @@ -2091,14 +2225,11 @@ Von einer Webseite zu diesem Formular linken, um anderen leichten Zugang zu dies <usetemplate ignoretext="Die Kleidung, die während dem Bearbeiten meines Aussehens erstellt wird, sofort anziehen" name="okcancelignore" notext="Nein" yestext="Ja"/> </notification> <notification name="NotAgeVerified"> - Um auf Adult-Inhalte und –Bereiche in Second Life zuzugreifen, müssen Sie mindestens 18 Jahre alt sein. Bitte besuchen Sie die Altersüberprüfungsseite, um zu bestätigen, dass Sie mindestens 18 Jahre alt sind. -Hierzu wird Ihr Webbrowser geöffnet. - -[_URL] - <url name="url" option="0"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="Ich habe mein Alter nicht verifizieren lassen" name="okcancelignore" notext="Abbrechen" yestext="Zur Altersüberprüfung"/> + Der Ort, den Sie besuchen möchten, ist nur für Bewohner zugänglich, die mindestens 18 Jahre alt sind. + <usetemplate ignoretext="Ich bin nicht alt genug, um beschränkte Bereiche zu besuchen." name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + Ort auf Einwohner beschränkt, die mindestens 18 Jahre alt sind. </notification> <notification name="Cannot enter parcel: no payment info on file"> Um diesen Bereich besuchen zu können, müssen Ihre Zahlungsinformationen gespeichert sein. Möchten Sie diese Einstellung auf der [SECOND_LIFE]-Webseite einrichten? @@ -2134,10 +2265,10 @@ Hierzu wird Ihr Webbrowser geöffnet. Betreff: [SUBJECT], Nachricht: [MESSAGE] </notification> <notification name="FriendOnline"> - [NAME] ist online + <nolink>[NAME]</nolink> ist online </notification> <notification name="FriendOffline"> - [NAME] ist offline + <nolink>[NAME]</nolink> ist offline </notification> <notification name="AddSelfFriend"> Obwohl Sie ein sehr netter Mensch sind, können Sie sich nicht selbst als Freund hinzufügen. @@ -2159,7 +2290,7 @@ Hierzu wird Ihr Webbrowser geöffnet. Terrain.raw heruntergeladen </notification> <notification name="GestureMissing"> - Hmm. Geste [NAME] fehlt in Datenbank. + Geste [NAME] fehlt in Datenbank. </notification> <notification name="UnableToLoadGesture"> Geste [NAME] konnte nicht geladen werden. @@ -2250,14 +2381,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 +2411,9 @@ Wählen Sie eine kleinere Landfläche. <notification name="PaymentSent"> [MESSAGE] </notification> + <notification name="PaymentFailure"> + [MESSAGE] + </notification> <notification name="EventNotification"> Event-Benachrichtigung: @@ -2354,6 +2490,23 @@ Fliegen ist hier nicht möglich. <notification name="NoBuild"> In diesem Bereich ist das Bauen deaktiviert. Sie können keine Objekte bauen oder rezzen. </notification> + <notification name="PathfindingDirty"> + Diese Region weist ausstehende Pathfinding-Änderungen auf. Wenn Sie Baurechte besitzen, können Sie die Region durch Klicken auf die Schaltfläche „Region neu formen“ neu formen. + </notification> + <notification name="DynamicPathfindingDisabled"> + Dynamisches Pathfinding ist in dieser Region nicht aktiviert. Geskriptete Objekte, die Pathfinding-LSL-Aufrufe verwenden, funktionieren in dieser Region u. U. nicht wie erwartet. + </notification> + <notification name="PathfindingRebakeNavmesh"> + Wenn Sie bestimmte Objekte in dieser Region ändern, verhalten sich andere bewegliche Objekte u. U. inkorrekt. Um dieses Problem zu beheben, klicken Sie auf die Schaltfläche „Region neu formen“. Um weitere Informationen zu erhalten, klicken Sie auf „Hilfe“. + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Hilfe" ignoretext="Wenn Sie bestimmte Objekte in dieser Region ändern, verhalten sich andere bewegliche Objekte u. U. inkorrekt." name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Fehler aufgetreten. Möglicherweise ist ein Netzwerk- oder Serverproblem aufgetreten oder Sie haben nicht die erforderlichen Baurechte. Dieses Problem lässt sich manchmal durch Ab- und Anmelden lösen. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> Diese Parzelle verbirgt Avatare und Text-Chat vor einer anderen Parzelle. Sie können Einwohner außerhalb dieser Parzelle weder sehen noch von ihnen gesehen werden. Regulärer Text-Chat auf Kanal 0 ist ebenfalls blockiert. </notification> @@ -2372,9 +2525,7 @@ Hier funktionieren nur Skripts, die dem Landeigentümer gehören. Öffentliches Land kann nur in der Region in Besitz genommen werden, in der Sie sich befinden. </notification> <notification name="RegionTPAccessBlocked"> - Sie dürfen diese Region aufgrund Ihrer Alterseinstufung nicht betreten. Sie müssen eventuell eine Altersüberprüfung vornehmen und/oder den aktuellsten Viewer installieren. - -Bitte besuchen Sie unsere Knowledgebase, um mehr Details über Zugang zu Regionen mit dieser Alterseinstufung zu erhalten. + Die Region, die Sie besuchen möchten, enthält Inhalte, die Ihre aktuellen Einstellungen überschreiten. Sie können Ihre Einstellungen unter „Ich“ > „Einstellungen“ > „Allgemein“ ändern. </notification> <notification name="URBannedFromRegion"> Sie dürfen diese Region nicht betreten. @@ -2385,11 +2536,11 @@ Bitte besuchen Sie unsere Knowledgebase, um mehr Details über Zugang zu Regione <notification name="ImproperPaymentStatus"> Die für den Zutritt zu dieser Region erforderlichen Zahlungsinformationen liegen nicht vor. </notification> - <notification name="MustGetAgeRgion"> - Sie müssen altersüberprüft sein, um diese Region betreten zu können. + <notification name="MustGetAgeRegion"> + Sie müssen mindestens 18 Jahre alt sein, um diese Region betreten zu können. </notification> <notification name="MustGetAgeParcel"> - Sie müssen altersüberprüft sein, um diese Parzelle betreten zu können. + Sie müssen mindestens 18 Jahre alt sein, um diese Parzelle betreten zu können. </notification> <notification name="NoDestRegion"> Keine Zielregion gefunden. @@ -2489,14 +2640,35 @@ Versuchen Sie es in einigen Minuten erneut. </form> </notification> <notification name="TeleportOffered"> - [NAME_SLURL] hat Ihnen einen Teleport an seine/ihre Position angeboten: + [NAME_SLURL] hat Ihnen den Teleport an seinen/ihren Standort angeboten: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +„[MESSAGE]“ +<icon>[MATURITY_ICON]</icon> – [MATURITY_STR] <form name="form"> <button name="Teleport" text="Teleportieren"/> <button name="Cancel" text="Abbrechen"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] hat Ihnen den Teleport an seinen/ihren Standort angeboten: + +„[MESSAGE]“ +<icon>[MATURITY_ICON]</icon> – [MATURITY_STR] + +Diese Region enthält [REGION_CONTENT_MATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGION_CONTENT_MATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern und den Teleport fortsetzen oder Sie können den Teleport abbrechen. + <form name="form"> + <button name="Teleport" text="Ändern und fortfahren"/> + <button name="Cancel" text="Abbrechen"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] hat Ihnen den Teleport an seinen/ihren Standort angeboten: + +„[MESSAGE]“ +<icon>[MATURITY_ICON]</icon> – [MATURITY_STR] + +Diese Region enthält jedoch Inhalte, die nur für Erwachsene zugänglich sind. + </notification> <notification name="TeleportOfferSent"> Ein Teleportangebot wurde an [TO_NAME] geschickt </notification> @@ -2532,10 +2704,10 @@ Versuchen Sie es in einigen Minuten erneut. </form> </notification> <notification name="FriendshipAccepted"> - [NAME] hat Ihr Freundschaftsangebot akzeptiert. + <nolink>[NAME]</nolink> hat Ihr Freundschaftsangebot akzeptiert. </notification> <notification name="FriendshipDeclined"> - [NAME] hat Ihr Freundschaftsangebot abgelehnt. + <nolink>[NAME]</nolink> hat Ihr Freundschaftsangebot abgelehnt. </notification> <notification name="FriendshipAcceptedByMe"> Ihr Freundschaftsangebot wurde angeommen. @@ -2591,32 +2763,28 @@ Ist das OK? </form> </notification> <notification name="ScriptQuestionCaution"> - Das Objekt „<nolink>[OBJECTNAME]</nolink>“, das „[NAME]“ gehört, stellt folgende Anfrage: - -[QUESTIONS] -Wenn Sie diesem Objekt und seinem Ersteller nicht vertrauen, sollten Sie diese Anfrage ablehnen. - -Anfrage gestatten? + Achtung: Das Objekt „<nolink>[OBJECTNAME]</nolink>“ fordert uneingeschränkten Zugriff auf Ihr Linden-Dollar-Konto an. Wenn Sie Zugriff gewähren, kann dieses Objekt jederzeit und ohne weitere Warnung Ihr Konto belasten bzw. ganz leeren. + +Eine solche Anforderung ist nur in seltenen Fällen legitim. Gewähren Sie dem Objekt nur dann Zugriff, wenn Sie genau verstehen, wieso ein solcher Zugriff auf Ihr Konto erforderlich ist. <form name="form"> - <button name="Grant" text="Gewähren"/> + <button name="Grant" text="Uneingeschränkten Zugriff gewähren"/> <button name="Deny" text="Verweigern"/> - <button name="Details" text="Info..."/> </form> </notification> <notification name="ScriptDialog"> „<nolink>[TITLE]</nolink>“ von [NAME] [MESSAGE] <form name="form"> - <button name="Mute" text="Blockieren"/> - <button name="Ignore" text="Ignorieren"/> + <button name="Client_Side_Mute" text="Blockieren"/> + <button name="Client_Side_Ignore" text="Ignorieren"/> </form> </notification> <notification name="ScriptDialogGroup"> „<nolink>[TITLE]</nolink>“ von [GROUPNAME] [MESSAGE] <form name="form"> - <button name="Mute" text="Blockieren"/> - <button name="Ignore" text="Ignorieren"/> + <button name="Client_Side_Mute" text="Blockieren"/> + <button name="Client_Side_Ignore" text="Ignorieren"/> </form> </notification> <notification name="BuyLindenDollarSuccess"> @@ -2815,6 +2983,18 @@ für folgende Einwohner freigeben: [RESIDENTS] <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> </notification> + <notification name="ShareFolderConfirmation"> + Es kann nur jeweils ein Ordner geteilt werden. + +Möchten Sie wirklich die folgenden Artikel: + +<nolink>[ITEMS]</nolink> + +mit den folgenden Einwohnern teilen: + +[RESIDENTS] + <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> + </notification> <notification name="ItemsShared"> Objekte wurden erfolgreich freigegeben. </notification> @@ -2893,6 +3073,10 @@ Sie haben eine [RESOLUTION]-gebackene Textur für „[BODYREGION]“ nach [TIME] ( [EXISTENCE] Sekunden am Leben) Sie haben lokal eine [RESOLUTION]-gebackene Textur für „[BODYREGION]“ nach [TIME] Sekunden aktualisiert. </notification> + <notification name="LivePreviewUnavailable"> + Wir können keine Vorschau dieser Textur anzeigen, da sie nicht kopier- und/oder übertragungsfähig ist. + <usetemplate ignoretext="Hinweis anzeigen, wenn bei nicht kopier- und/oder übertragungsfähigen Texturen keine Live-Vorschau möglich ist" name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> Möchten Sie dieses Gespräch wirklich verlassen ? <usetemplate ignoretext="Bestätigen, bevor ich den Anruf verlasse." name="okcancelignore" notext="Nein" yestext="Ja"/> @@ -3062,6 +3246,62 @@ Durch Ausblenden der Schaltfläche „Sprechen“ wird die Sprechfunktion deakti Durch diese Aktion werden alle Menüelemente und Schaltflächen ausgeblendet. Um sie wieder anzuzeigen, klicken Sie erneut auf [SHORTCUT]. <usetemplate ignoretext="Vor Ausblenden der UI bestätigen" name="okcancelignore" notext="Abbrechen" yestext="OK"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht auf „[REQUESTED_TYPE]“ gesetzt werden. Diese Linksets werden stattdessen auf „[RESTRICTED_TYPE]“ gesetzt. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht gesetzt werden." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Einige der ausgewählten Linksets können nicht auf „[REQUESTED_TYPE]“ gesetzt werden, da die Form nicht konvex ist. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Einige der ausgewählten Linksets können nicht gesetzt werden, da die Form nicht konvex ist." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet. + +Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht auf „[REQUESTED_TYPE]“ gesetzt werden. Diese Linksets werden stattdessen auf „[RESTRICTED_TYPE]“ gesetzt. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet und andere können aufgrund von Berechtigungseinschränkungen nicht gesetzt werden." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet. + +Einige der ausgewählten Linksets können nicht auf „[REQUESTED_TYPE]“ gesetzt werden, da die Form nicht konvex ist. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet und andere können nicht gesetzt werden, da die Form nicht konvex ist." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht auf „[REQUESTED_TYPE]“ gesetzt werden. Diese Linksets werden stattdessen auf „[RESTRICTED_TYPE]“ gesetzt. + +Einige der ausgewählten Linksets können nicht auf „[REQUESTED_TYPE]“ gesetzt werden, da die Form nicht konvex ist. Die Nutzungsarten dieser Linksets bleiben unverändert. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Einige der ausgewählten Linksets können nicht gesetzt werden, da die Berechtigungen eingeschränkt sind und die Form nicht konvex ist." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet. + +Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht auf „[REQUESTED_TYPE]“ gesetzt werden. Diese Linksets werden stattdessen auf „[RESTRICTED_TYPE]“ gesetzt. + +Einige der ausgewählten Linksets können nicht auf „[REQUESTED_TYPE]“ gesetzt werden, da die Form nicht konvex ist. Die Nutzungsarten dieser Linksets bleiben unverändert. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet und andere können nicht gesetzt werden, da die Berechtigungen für das Linkset eingeschränkt sind und die Form nicht konvex ist." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + Das ausgewählte Objekt wirkt sich auf das Navmesh aus. Wenn Sie es in einen flexiblen Pfad ändern, wird es aus dem Navmesh entfernt. + <usetemplate ignoretext="Das ausgewählte Objekt wirkt sich auf das Navmesh aus. Wenn Sie es in einen flexiblen Pfad ändern, wird es aus dem Navmesh entfernt." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> <global name="UnsupportedGLRequirements"> Ihr Computer entspricht nicht den Hardwareanforderungen von [APP_NAME]. [APP_NAME] setzt eine OpenGL-Grafikkarte mit Multitextur-Unterstützung voraus. Falls Ihre Grafikkarte diese Funktion unterstützt, installieren Sie die neuesten Treiber sowie die aktuellen Service Packs und Patches für Ihr Betriebssystem. @@ -3086,4 +3326,24 @@ Ansonsten können Sie auf der Karte nachsehen und dort Ort suchen, die als „In <global name="You died and have been teleported to your home location"> Sie sind gestorben und wurden zu Ihrem Zuhause teleportiert. </global> + <notification name="LocalBitmapsUpdateFileNotFound"> + [FNAME] wurde nicht gefunden und konnte deshalb nicht aktualisiert werden. +Zukünftige Aktualisierungen dieser Datei werden deaktiviert. + </notification> + <notification name="LocalBitmapsUpdateFailedFinal"> + [FNAME] konnte auch nach [NRETRIES] Versuchen nicht geöffnet oder decodiert werden und gilt als beschädigt. +Zukünftige Aktualisierungen dieser Datei werden deaktiviert. + </notification> + <notification name="LocalBitmapsVerifyFail"> + Versuch, eine ungültige oder nicht lesbare Bilddatei ([FNAME]) hinzuzufügen, die nicht geöffnet oder decodiert werden konnte. +Versuch abgebrochen. + </notification> + <notification name="PathfindingReturnMultipleItems"> + Sie sind dabei, [NUM_ITEMS] Objekte zurückzugeben. Möchten Sie diesen Vorgang wirklich fortsetzen? + <usetemplate ignoretext="Möchten Sie wirklich mehrere Objekte zurückgeben?" name="okcancelignore" notext="Nein" yestext="Ja"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + Sie sind dabei, [NUM_ITEMS] Objekte zu löschen. Möchten Sie diesen Vorgang wirklich fortsetzen? + <usetemplate ignoretext="Möchten Sie wirklich mehrere Objekte löschen?" name="okcancelignore" notext="Nein" yestext="Ja"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/de/panel_bottomtray.xml b/indra/newview/skins/default/xui/de/panel_bottomtray.xml deleted file mode 100644 index afe9836401..0000000000 --- a/indra/newview/skins/default/xui/de/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Schaltet Mikrofon ein/aus"/> - <string name="VoiceControlBtnToolTip" value="Voice-Chat-Steuerung anzeigen/ausblenden"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Sprechen" label_selected="Sprechen" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="Gesten" name="Gesture" tool_tip="Gesten anzeigen/ausblenden"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Bewegen" name="movement_btn" tool_tip="Bewegungssteuerung anzeigen/ausblenden"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Ansicht" name="camera_btn" tool_tip="Kamerasteuerung anzeigen/ausblenden"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button label="" name="snapshots" tool_tip="Foto machen"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="Bauen" name="build_btn" tool_tip="Bauwerkzeuge ein-/ausblenden"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="Suche" name="search_btn" tool_tip="Suche anzeigen/ausblenden"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Karte" name="world_map_btn" tool_tip="Karte ein-/ausblenden"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Minikarte" name="mini_map_btn" tool_tip="Minikarte ein-/ausblenden"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="IMs"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="Benachrichtigungen"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> 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_group_invite.xml b/indra/newview/skins/default/xui/de/panel_group_invite.xml index 5f323d80dd..c32d2fe4bf 100644 --- a/indra/newview/skins/default/xui/de/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/de/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> Einige der ausgewählten Einwohner sind bereits Gruppenmitglieder und haben aus diesem Grund keine Einladung erhalten. </panel.string> + <panel.string name="invite_selection_too_large"> + Gruppeneinladungen nicht gesendet: zu viele Einwohner ausgewählt. Gruppeneinladungen sind auf 100 Einwohner pro Anfrage beschränkt. + </panel.string> <text name="help_text"> Sie können mehrere Einwohner in Ihre Gruppe einladen. Klicken Sie hierzu auf „Einwohnerliste öffnen“. </text> diff --git a/indra/newview/skins/default/xui/de/panel_login.xml b/indra/newview/skins/default/xui/de/panel_login.xml index 553bd3e2ff..8cc467185c 100644 --- a/indra/newview/skins/default/xui/de/panel_login.xml +++ b/indra/newview/skins/default/xui/de/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://de.secondlife.com/registration/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php?lang=de </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + ANMELDEN + </text> <text name="username_text"> Benutzername: </text> @@ -15,17 +15,10 @@ <text name="password_text"> Kennwort: </text> - <check_box label="Kennwort merken" name="remember_check"/> - <button label="Anmelden" name="connect_btn"/> - <text name="mode_selection_text"> - Modus: - </text> - <combo_box name="mode_combo" tool_tip="Wählen Sie den gewünschten Modus aus. Basis: Second Life schnell und einfach erkunden und chatten. Erweitert: Zugriff auf zusätzliche Funktionen."> - <combo_box.item label="Basis" name="Basic"/> - <combo_box.item label="Erweitert" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> - Hier anfangen: + Hier starten: </text> <combo_box name="start_location_combo"> <combo_box.item label="Mein letzter Standort" name="MyLastLocation"/> @@ -33,16 +26,21 @@ <combo_box.item label="<Region eingeben>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Registrieren + <layout_panel name="links_login_panel"> + <text name="login_help"> + Brauchen Sie Hilfe beim Anmelden? </text> <text name="forgot_password_text"> Benutzernamen oder Kennwort vergessen? </text> - <text name="login_help"> - Sie brauchen Hilfe? + <button label="Anmelden" name="connect_btn"/> + <check_box label="Kennwort speichern" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + IHR KONTO ERSTELLEN </text> + <button label="Jetzt starten" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_my_profile.xml b/indra/newview/skins/default/xui/de/panel_my_profile.xml deleted file mode 100644 index 89a4dfdaba..0000000000 --- a/indra/newview/skins/default/xui/de/panel_my_profile.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Profil" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=de-DE - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=de - </string> - <string name="my_account_link_url" value="http://secondlife.com/my/account/index.php?lang=de-DE"/> - <string name="no_partner_text" value="Keiner"/> - <string name="no_group_text" value="Keiner"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="scroll_content_panel"> - <panel name="second_life_image_panel"> - <text name="display_name_descr_text"> - Benutzername - </text> - <text name="name_descr_text"> - Anzeigename - </text> - <button label="Profil" name="see_profile_btn" tool_tip="Profil zu diesem Avatar anzeigen"/> - </panel> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/de/panel_nearby_chat.xml b/indra/newview/skins/default/xui/de/panel_nearby_chat.xml index 2068c39024..07ad761791 100644 --- a/indra/newview/skins/default/xui/de/panel_nearby_chat.xml +++ b/indra/newview/skins/default/xui/de/panel_nearby_chat.xml @@ -1,4 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="nearby_chat"> - <check_box label="Chat übersetzen" name="translate_chat_checkbox"/> + <layout_stack name="stack"> + <layout_panel name="translate_chat_checkbox_lp"> + <check_box label="Chat übersetzen" name="translate_chat_checkbox"/> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml index 08cc0b0ec8..69cf6d98de 100644 --- a/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="chat_bar"> +<panel name="nearby_chat"> <line_editor label="Zum Chatten hier klicken." name="chat_box" tool_tip="Eingabe drücken, um zu sprechen, Strg-Eingabe drücken, um zu Rufen."/> <button name="show_nearby_chat" tool_tip="Protokoll des Chats in der Nähe anzeigen/ausblenden"/> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_notes.xml b/indra/newview/skins/default/xui/de/panel_notes.xml deleted file mode 100644 index ef1961b63d..0000000000 --- a/indra/newview/skins/default/xui/de/panel_notes.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Notizen & Privatsphäre" name="panel_notes"> - <layout_stack name="layout"> - <layout_panel name="notes_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <text name="status_message" value="Meine Notizen:"/> - <text name="status_message2" value="Diese Person kann:"/> - <check_box label="meinen Online-Status sehen." name="status_check"/> - <check_box label="mich auf der Karte sehen." name="map_check"/> - <check_box label="meine Objekte bearbeiten, löschen oder nehmen." name="objects_check"/> - </panel> - </scroll_container> - </layout_panel> - <layout_panel name="notes_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Freund hinzufügen" name="add_friend" tool_tip="Dem Einwohner die Freundschaft anbieten"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="Instant Messenger öffnen"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Anrufen" name="call" tool_tip="Diesen Einwohner anrufen"/> - </layout_panel> - <layout_panel name="show_on_map_btn_lp"> - <button label="Karte" name="show_on_map_btn" tool_tip="Einwohner auf Karte anzeigen"/> - </layout_panel> - <layout_panel name="teleport_btn_lp"> - <button label="Teleportieren" name="teleport" tool_tip="Teleport anbieten"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> 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..c9ae350147 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,7 @@ <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="Übersetzen..." name="ok_btn"/> + <button label="Automatisch ersetzen..." name="autoreplace_showgui"/> + <button label="Rechtschreibprüfung..." name="spellcheck_showgui"/> </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_profile.xml b/indra/newview/skins/default/xui/de/panel_profile.xml deleted file mode 100644 index b4c6e67108..0000000000 --- a/indra/newview/skins/default/xui/de/panel_profile.xml +++ /dev/null @@ -1,74 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Profil" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=de-DE - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=de - </string> - <string name="my_account_link_url" value="http://secondlife.com/my/account/index.php?lang=de-DE"/> - <string name="no_partner_text" value="Keiner"/> - <string name="no_group_text" value="Keiner"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <panel name="second_life_image_panel"> - <text name="title_sl_descr_text" value="[SECOND_LIFE]:"/> - </panel> - <panel name="first_life_image_panel"> - <text name="title_rw_descr_text" value="Echtes Leben:"/> - </panel> - <text name="title_member_text" value="Einwohner seit:"/> - <text name="title_acc_status_text" value="Kontostatus:"/> - <text_editor name="acc_status_text"> - Einwohner. Keine Zahlungsinfo archiviert. - Linden. - </text_editor> - <text name="title_partner_text" value="Partner:"/> - <panel name="partner_data_panel"> - <text initial_value="(wird in Datenbank gesucht)" name="partner_text"/> - </panel> - <text name="title_groups_text" value="Gruppen:"/> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> - <layout_stack name="layout_verb_buttons"> - <layout_panel name="profile_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Freund hinzufügen" name="add_friend" tool_tip="Dem Einwohner die Freundschaft anbieten"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="Instant Messenger öffnen"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Anrufen" name="call" tool_tip="Diesen Einwohner anrufen"/> - </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="Teleportieren" name="teleport" tool_tip="Teleport anbieten"/> - </layout_panel> - <layout_panel name="overflow_btn_lp"> - <menu_button label="â–¼" name="overflow_btn" tool_tip="Dem Einwohner Geld geben oder Inventar an den Einwohner schicken"/> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="profile_me_buttons_panel"> - <button label="Profil bearbeiten" name="edit_profile_btn" tool_tip="Ihre persönlichen Informationen bearbeiten"/> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/de/panel_profile_view.xml b/indra/newview/skins/default/xui/de/panel_profile_view.xml deleted file mode 100644 index 7e93bd1ede..0000000000 --- a/indra/newview/skins/default/xui/de/panel_profile_view.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_target_profile"> - <string name="status_online"> - Online - </string> - <string name="status_offline"> - Offline - </string> - <text name="display_name_label" value="Anzeigename:"/> - <text name="solo_username_label" value="Benutzername:"/> - <text name="status" value="Online"/> - <text name="user_name_small" value="Dieser Name ist ein ganz außerordentlich langer Name"/> - <button name="copy_to_clipboard" tool_tip="In Zwischenablage kopieren"/> - <text name="user_label" value="Benutzername:"/> - <tab_container name="tabs" tab_min_width="60"> - <panel label="PROFIL" name="panel_profile"/> - <panel label="AUSWAHL" name="panel_picks"/> - <panel label="NOTIZEN & PRIVATSPHÄRE" name="panel_notes"/> - </tab_container> -</panel> diff --git a/indra/newview/skins/default/xui/de/panel_region_debug.xml b/indra/newview/skins/default/xui/de/panel_region_debug.xml index d1b8f0d78a..a03a0b8b7b 100644 --- a/indra/newview/skins/default/xui/de/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/de/panel_region_debug.xml @@ -36,5 +36,5 @@ <button label="?" name="top_scripts_help"/> <button label="Region neu starten" name="restart_btn" tool_tip="2-Minuten-Countdown und Region neu starten"/> <button label="?" name="restart_help"/> - <button label="Neustart verzögern" name="cancel_restart_btn" tool_tip="Regionsneustart um eine Stunde verschieben"/> + <button label="Neustart abbrechen" name="cancel_restart_btn" tool_tip="Regionsneustart abbrechen"/> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_region_estate.xml b/indra/newview/skins/default/xui/de/panel_region_estate.xml index b93bd3e442..b087451391 100644 --- a/indra/newview/skins/default/xui/de/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/de/panel_region_estate.xml @@ -16,10 +16,10 @@ (unbekannt) </text> <text name="Only Allow"> - Zugang nur dann, wenn überprüft mit: + Zugang nur Einwohnern gestatten, die: </text> - <check_box label="Zahlungsinformation gespeichert" name="limit_payment" tool_tip="Einwohner ohne Zahlungsinformation nicht zulassen."/> - <check_box label="Altersüberprüfung" name="limit_age_verified" tool_tip="Einwohner ohne Altersüberprüfung verbannen. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/> + <check_box label="Zahlungsinformationen hinterlegt haben" name="limit_payment" tool_tip="Um diesen Grundbesitz besuchen zu können, müssen Einwohner Zahlungsinformationen hinterlegt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/> + <check_box label="Sind mindestens 18 Jahre alt" name="limit_age_verified" tool_tip="Nur Einwohner, die mindestens 18 Jahre alt sind, können diesen Grundbesitz betreten. Weitere Informationen finden Sie unter [SUPPORT_SITE]."/> <check_box label="Voice-Chat erlauben" name="voice_chat_check"/> <button label="?" name="voice_chat_help"/> <text name="abuse_email_text" width="222"> diff --git a/indra/newview/skins/default/xui/de/panel_region_texture.xml b/indra/newview/skins/default/xui/de/panel_region_texture.xml deleted file mode 100644 index 2f4904730b..0000000000 --- a/indra/newview/skins/default/xui/de/panel_region_texture.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Bodentexturen" name="Textures"> - <text name="region_text_lbl"> - Region: - </text> - <text name="region_text"> - unbekannt - </text> - <text name="detail_texture_text"> - Terraintexturen (erfordert 512x512, 24-Bit-.tga-Dateien) - </text> - <text name="height_text_lbl"> - 1 (niedrig) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (Hoch) - </text> - <text name="height_text_lbl5"> - Texturhöhenbereich - </text> - <text name="height_text_lbl6"> - Nordwest - </text> - <text name="height_text_lbl7"> - Nordost - </text> - <text name="height_text_lbl8"> - Südwest - </text> - <text name="height_text_lbl9"> - Südost - </text> - <spinner label="Niedrig" label_width="40" name="height_start_spin_0"/> - <spinner label="Niedrig" label_width="40" name="height_start_spin_1"/> - <spinner label="Niedrig" label_width="40" name="height_start_spin_2"/> - <spinner label="Niedrig" label_width="40" name="height_start_spin_3"/> - <spinner label="Hoch" label_width="40" name="height_range_spin_0"/> - <spinner label="Hoch" label_width="40" name="height_range_spin_1"/> - <spinner label="Hoch" label_width="40" name="height_range_spin_2"/> - <spinner label="Hoch" label_width="40" name="height_range_spin_3"/> - <text name="height_text_lbl10"> - Diese Werte geben den Mischungsgrad für die obigen Texturen an. - </text> - <text name="height_text_lbl11"> - In Metern gemessen. Der NIEDRIG-Wert ist die MAXIMALE Höhe der Textur #1, der HÖCHST-Wert ist die MINDEST-Höhe von Textur #4. - </text> - <text name="height_text_lbl12"> - und der OBERE WERT die MINIMALE Höhe von Textur 4. - </text> - <button label="Übernehmen" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/de/panel_script_ed.xml b/indra/newview/skins/default/xui/de/panel_script_ed.xml index adfe2a342b..7e03aeff15 100644 --- a/indra/newview/skins/default/xui/de/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/de/panel_script_ed.xml @@ -22,6 +22,8 @@ <menu label="Datei" name="File"> <menu_item_call label="Speichern" name="Save"/> <menu_item_call label="Alle Änderungen zurücksetzen" name="Revert All Changes"/> + <menu_item_call label="Aus Datei laden..." name="LoadFromFile"/> + <menu_item_call label="In Datei speichern..." name="SaveToFile"/> </menu> <menu label="Bearbeiten" name="Edit"> <menu_item_call label="Rückgängig" name="Undo"/> diff --git a/indra/newview/skins/default/xui/de/panel_script_question_toast.xml b/indra/newview/skins/default/xui/de/panel_script_question_toast.xml new file mode 100644 index 0000000000..a2d0237da0 --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_script_question_toast.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel label="script_question_panel" name="panel_script_question_toast"> + <panel label="buttons_panel" name="buttons_panel"/> +</panel> diff --git a/indra/newview/skins/default/xui/de/panel_side_tray.xml b/indra/newview/skins/default/xui/de/panel_side_tray.xml deleted file mode 100644 index 3c81636fa0..0000000000 --- a/indra/newview/skins/default/xui/de/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Seitenleiste auf-/zuklappen." name="sidebar_openclose" tab_title="Seitenleiste auf-/zuklappen"/> - <sidetray_tab description="Startseite." name="sidebar_home" tab_title="Startseite"> - <panel label="Startseite" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Ihr öffentliches Profil und Auswahl bearbeiten." name="sidebar_me" tab_title="Mein Profil"> - <panel_container name="panel_container"> - <panel label="Ich" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Freunde, Kontakte und Leute in Ihrer Nähe finden." name="sidebar_people" tab_title="Leute"> - <panel_container name="panel_container"> - <panel label="Gruppenprofil" name="panel_group_info_sidetray"/> - <panel label="Ignorierte Einwohner & Objekte" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Hier finden Sie neue Orte und Orte, die Sie bereits besucht haben." label="Orte" name="sidebar_places" tab_title="Orte"> - <panel label="Orte" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="Inventar durchsuchen." name="sidebar_inventory" tab_title="Mein Inventar"> - <panel label="Inventar bearbeiten" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Ändern Sie Ihr Aussehen und Ihren aktuellen Look." name="sidebar_appearance" tab_title="Mein Aussehen"> - <panel label="Aussehen bearbeiten" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> 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..14ace0ac3a 100644 --- a/indra/newview/skins/default/xui/de/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/de/panel_status_bar.xml @@ -15,10 +15,10 @@ <panel.string name="buycurrencylabel"> [AMT] L$ </panel.string> - <panel name="balance_bg"> + <panel left="-415" name="balance_bg" width="205"> <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/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/de/panel_volume_pulldown.xml new file mode 100644 index 0000000000..3d43200e48 --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_volume_pulldown.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater" width="240"> + <button left="217" name="prefs_btn"/> + <slider label="Master" label_width="80" name="System Volume" width="180"/> + <slider label="Schaltflächen" label_width="80" name="UI Volume" width="180"/> + <slider label="Umgebung" label_width="80" name="Wind Volume" width="180"/> + <slider label="Sounds" label_width="80" name="SFX Volume" width="180"/> + <check_box name="gesture_audio_play_btn" tool_tip="Sounds von Gesten aktivieren"/> + <slider label="Musik" label_width="80" name="Music Volume" width="180"/> + <check_box name="enable_music" tool_tip="Streaming-Musik aktivieren"/> + <slider label="Medien" label_width="80" name="Media Volume" width="180"/> + <check_box name="enable_media" tool_tip="Streaming-Medien aktivieren"/> + <slider label="Voice" label_width="80" name="Voice Volume" width="180"/> + <check_box name="enable_voice_check" tool_tip="Voice-Chat aktivieren"/> +</panel> diff --git a/indra/newview/skins/default/xui/de/sidepanel_inventory.xml b/indra/newview/skins/default/xui/de/sidepanel_inventory.xml index 674ea3376b..18aad64f96 100644 --- a/indra/newview/skins/default/xui/de/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/de/sidepanel_inventory.xml @@ -2,47 +2,24 @@ <panel label="Sonstiges" name="objects panel"> <panel label="" name="sidepanel__inventory_panel"> <layout_stack name="inventory_layout_stack"> - <layout_panel name="inbox_outbox_layout_panel"> - <layout_stack name="inbox_outbox_layout_stack"> - <layout_panel name="inbox_layout_panel"> - <panel label="" name="marketplace_inbox"> - <string name="InboxLabelWithArg"> - Erhaltene Artikel ([NUM]) - </string> - <string name="InboxLabelNoArg"> - Erhaltene Artikel - </string> - <button label="Erhaltene Artikel" name="inbox_btn"/> - <text name="inbox_fresh_new_count"> - [NUM] neu - </text> - <panel tool_tip="Drag and drop items to your inventory to manage and use them"> - <text name="inbox_inventory_placeholder"> - Einkäufe auf dem Marktplatz werden hierher geliefert. - </text> - </panel> - </panel> - </layout_panel> - <layout_panel name="outbox_layout_panel"> - <panel label="" name="marketplace_outbox"> - <string name="OutboxLabelWithArg"> - Händler-Outbox ([NUM]) - </string> - <string name="OutboxLabelNoArg"> - Händler-Outbox - </string> - <button label="Händler-Outbox" name="outbox_btn"/> - <button label="" name="outbox_sync_btn" tool_tip="In meinen Marktplatz-Laden verschieben"/> - <panel> - <panel name="outbox_inventory_placeholder_panel"> - <text name="outbox_inventory_placeholder_title"> - Laden... - </text> - </panel> - </panel> - </panel> - </layout_panel> - </layout_stack> + <layout_panel name="inbox_layout_panel"> + <panel label="" name="marketplace_inbox"> + <string name="InboxLabelWithArg"> + Erhaltene Artikel ([NUM]) + </string> + <string name="InboxLabelNoArg"> + Erhaltene Artikel + </string> + <button label="Erhaltene Artikel" name="inbox_btn"/> + <text name="inbox_fresh_new_count"> + [NUM] neu + </text> + <panel name="inbox_inventory_placeholder_panel" tool_tip="Artikel zur Verwendung in Ihr Inventar ziehen"> + <text name="inbox_inventory_placeholder"> + Einkäufe aus dem Marktplatz werden hierher geliefert. + </text> + </panel> + </panel> </layout_panel> </layout_stack> <panel name="button_panel"> diff --git a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml index 18241dea32..1b67eaf03b 100644 --- a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (unbekannt) </panel.string> + <panel.string name="unknown_multiple"> + (unbekannt/mehrere) + </panel.string> <panel.string name="public"> (öffentlich) </panel.string> diff --git a/indra/newview/skins/default/xui/de/sidepanel_task_info.xml b/indra/newview/skins/default/xui/de/sidepanel_task_info.xml index 7b46ee7c9b..4c8d77d336 100644 --- a/indra/newview/skins/default/xui/de/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/de/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> Sie können diese Objekte nicht bearbeiten. </panel.string> + <panel.string name="text modify info 5"> + Dieses Objekt kann nicht über eine Regionsgrenze hinweg geändert werden + </panel.string> + <panel.string name="text modify info 6"> + Diese Objekte können nicht über eine Regionsgrenze hinweg geändert werden + </panel.string> <panel.string name="text modify warning"> Diese Objekt verfügt über verknüpfte Teile </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Preis: L$" name="Edit Cost"/> <check_box label="In Suche anzeigen" name="search_check" tool_tip="Dieses Objekt in Suchergebnissen anzeigen"/> + <text name="pathfinding_attributes_label"> + Pathfinding-Attribute: + </text> <text name="B:"> B: </text> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 2929556d43..79cb73ecf9 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -137,7 +137,7 @@ Beenden </string> <string name="create_account_url"> - http://join.secondlife.com/index.php?lang=de-DE + http://join.secondlife.com/index.php?lang=de-DE&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> Mit dem von Ihnen verwendeten Viewer ist der Zugriff auf Second Life nicht mehr möglich. Laden Sie von den folgenden Seite einen neuen Viewer herunter: @@ -181,8 +181,8 @@ Aktuelle Informationen finden Sie unter www.secondlife.com/status. </string> <string name="LoginFailedPremiumOnly"> Die Anmeldung bei Second Life ist vorübergehend eingeschränkt, um sicherzustellen, dass Einwohner, die sich bereits inworld aufhalten, das bestmögliche Erlebnis haben. - -Benutzer mit kostenlosen Konten können sich während dieses Zeitraums nicht bei Second Life anmelden, damit die Kapazität den Benutzern zur Verfügung steht, die ein gebührenpflichtiges Premium-Konto besitzen. + +Benutzer mit kostenlosen Konten können sich während dieses Zeitraums nicht bei Second Life anmelden, damit die Kapazität Benutzern zur Verfügung steht, die ein gebührenpflichtiges Premium-Konto besitzen. </string> <string name="LoginFailedComputerProhibited"> Der Zugriff auf Second Life ist von diesem Computer aus nicht möglich. @@ -339,17 +339,35 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. Sie können nur ein einzelnes Objekt hierher ziehen </string> <string name="TooltipPrice" value="[AMOUNT] L$"/> + <string name="TooltipOutboxDragToWorld"> + Sie können Artikel nicht in Ihrer Händler-Outbox rezzen + </string> <string name="TooltipOutboxNoTransfer"> - Eines oder mehrere dieser Objekte können nicht verkauft oder an einen anderen Benutzer übertragen werden. + Einer oder mehrere dieser Artikel können nicht verkauft oder übertragen werden. + </string> + <string name="TooltipOutboxNotInInventory"> + Nur Artikel direkt aus Ihrem Inventar können in Ihre Händler-Outbox gelegt werden </string> <string name="TooltipOutboxWorn"> - Sie tragen eines oder mehrere dieser Objekte. Nehmen Sie es/sie von Ihrem Avatar ab und versuchen Sie dann erneut, es/sie zu verschieben. + Artikel, die Sie tragen, können nicht in Ihre Händler-Outbox gelegt werden. + </string> + <string name="TooltipOutboxCallingCard"> + Sie können keine Visitenkarten in Ihre Händler-Outbox legen </string> <string name="TooltipOutboxFolderLevels"> - Dieser Ordner hat zu viele Unterordnerebenen. Ordnen Sie die Unterordner so an, dass maximal vier Verschachtelungsebenen vorhanden sind (Stammordner enthält A enthält B enthält C). + Tiefe der verschachtelten Ordner überschreitet 3 + </string> + <string name="TooltipOutboxTooManyFolders"> + Anzahl von Unterordnern im obersten Ordner überschreitet 20 </string> <string name="TooltipOutboxTooManyObjects"> - Dieser Ordner enthält mehr als 200 Objekte. Verpacken Sie einige dieser Artikel in Behältern, um die Anzahl zu verringern. + Anzahl von Artikeln im obersten Ordner überschreitet 200 + </string> + <string name="TooltipDragOntoOwnChild"> + Sie können einen Ordner nicht in einen seiner untergeordneten Ordner verschieben + </string> + <string name="TooltipDragOntoSelf"> + Sie können einen Ordner nicht in sich selbst verschieben </string> <string name="TooltipHttpUrl"> Anklicken, um Webseite anzuzeigen @@ -817,6 +835,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="anim_yes_head"> Ja </string> + <string name="multiple_textures"> + Mehrfach + </string> <string name="texture_loading"> Wird geladen... </string> @@ -865,6 +886,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="ScriptQuestionCautionChatDenied"> Dem Objekt „[OBJECTNAME]“, ein Objekt von „[OWNERNAME]“, in [REGIONNAME] [REGIONPOS], wurde folgende Berechtigung verweigert: [PERMISSIONS]. </string> + <string name="AdditionalPermissionsRequestHeader"> + Wenn Sie dem Objekt Zugriff auf Ihr Konto gewähren, kann dieses außerdem: + </string> <string name="ScriptTakeMoney"> Linden-Dollar (L$) von Ihnen nehmen </string> @@ -898,6 +922,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="ControlYourCamera"> Kamerasteuerung </string> + <string name="TeleportYourAgent"> + Sie teleportieren + </string> <string name="NotConnected"> Nicht verbunden </string> @@ -976,6 +1003,12 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="choose_the_directory"> Verzeichnis auswählen </string> + <string name="script_files"> + Skripts + </string> + <string name="dictionary_files"> + Wörterbücher + </string> <string name="AvatarSetNotAway"> Nicht abwesend </string> @@ -1214,43 +1247,36 @@ 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. + Einkäufe aus dem Marktplatz erscheinen hier. Sie können diese dann zur Verwendung in Ihr Inventar ziehen. </string> <string name="MarketplaceURL"> - http://marketplace.[DOMAIN_NAME] + https://marketplace.[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 + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4 </string> - <string name="InventoryOutboxCreationErrorTitle"> - Ihre Händler-Outbox ist nicht richtig konfiguriert + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard </string> - <string name="InventoryOutboxCreationErrorTooltip"> - Konfigurationsfehler in Händler-Outbox + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports </string> - <string name="InventoryOutboxCreationError"> - Wenden Sie sich zur Behebung des Problems an den Kundendienst. + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more </string> <string name="InventoryOutboxNotMerchantTitle"> - Jeder kann Artikel im Marktplatz verkaufen - </string> - <string name="InventoryOutboxNotMerchantTooltip"> - Werden Sie Händler! + Jeder kann Artikel im Marktplatz verkaufen. </string> + <string name="InventoryOutboxNotMerchantTooltip"/> <string name="InventoryOutboxNotMerchant"> - [[MARKETPLACE_URL] Im Second Life Marktplatz] werden über eine Million virtuelle Produkte zum Verkauf angeboten, die alle von Einwohnern erstellt wurden. Auch Sie können selbst erstellte Artikel sowie bestimmte gekaufte Artikel verkaufen. Die Einrichtung eines Händlerkontos geht blitzschnell und ist kostenlos. [[LEARN_MORE_URL] Lesen Sie weitere Informationen] oder [[CREATE_STORE_URL] öffnen Sie einen Laden] im Marktplatz, um Ihre Objekte zu verkaufen. + Wenn Sie als Händler aktiv werden möchten, müssen Sie einen [[MARKETPLACE_CREATE_STORE_URL] Laden im Marktplatz erstellen]. </string> <string name="InventoryOutboxNoItemsTitle"> - Eine neue Methode, um Artikel in den Marktplatz zu übertragen - </string> - <string name="InventoryOutboxNoItemsTooltip"> - Legen Sie Artikel hier ab, um sie zum Verkauf im Marktplatz vorzubereiten + Ihre Outbox ist leer. </string> + <string name="InventoryOutboxNoItemsTooltip"/> <string name="InventoryOutboxNoItems"> - Ziehen Sie zu verkaufende Artikel oder Ordner in diesen Bereich. Es erscheinen Kopien der Artikel; Ihr Inventar bleibt unverändert, es sei denn, es handelt sich um einen nicht kopierbaren Artikel. Wenn die Artikel in den Marktplatz übertragen werden sollen, klicken Sie auf die Schaltfläche „Hochladen“. Nach Übertragung der Artikel in Ihr Marktplatz-Inventar verschwinden sie aus diesem Ordner. + Ziehen Sie Ordner in dien Bereich und klicken Sie auf „In Marktplatz übertragen“, um sie im [[MARKETPLACE_DASHBOARD_URL] Marktplatz] zum Verkauf anzubieten. </string> <string name="Marketplace Error None"> Keine Fehler @@ -1388,6 +1414,12 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="InvFolder favorite"> Meine Favoriten </string> + <string name="InvFolder Favorites"> + Meine Favoriten + </string> + <string name="InvFolder favorites"> + Meine Favoriten + </string> <string name="InvFolder Current Outfit"> Aktuelles Outfit </string> @@ -1403,6 +1435,12 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="InvFolder Meshes"> Netze </string> + <string name="InvFolder Received Items"> + Erhaltene Artikel + </string> + <string name="InvFolder Merchant Outbox"> + Händler-Outbox + </string> <string name="InvFolder Friends"> Freunde </string> @@ -1412,6 +1450,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 +1579,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> @@ -3832,6 +3879,12 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_ <string name="LocationCtrlSeeAVsTooltip"> Avatare sichtbar; Chat außerhalb dieser Parzelle gestattet </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Bewegliche Objekte verhalten sich in dieser Region u. U. erst dann korrekt, wenn die Region neu geformt wird. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + Dynamisches Pathfinding ist in dieser Region nicht aktiviert. + </string> <string name="UpdaterWindowTitle"> [APP_NAME] Aktualisierung </string> @@ -3898,6 +3951,9 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_ <string name="Saved_message"> (Gespeichert am [LONG_TIMESTAMP]) </string> + <string name="IM_unblock_only_groups_friends"> + Wenn Sie diese Meldung sehen, müssen Sie unter „Einstellungen“ > „Privatsphäre“ die Option „Nur IMs und Anrufe von Freunden oder Gruppen durchstellen“ deaktivieren. + </string> <string name="answered_call"> Ihr Anruf wurde entgegengenommen </string> @@ -4030,6 +4086,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> @@ -4082,8 +4150,8 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_ Online </string> <string name="uploading_abuse_report"> - Bericht wird hochgeladen... - + Hochladen... + Missbrauchsbericht </string> <string name="New Shape"> @@ -4351,8 +4419,8 @@ Missbrauchsbericht <string name="server_is_down"> Trotz all unserer Bemühungen ist ein unerwarteter Fehler aufgetreten. - Bitte überprüfen Sie status.secondlifegrid.net, um festzustellen, ob ein Problem besteht. - Falls Sie weiterhin Problem haben, überprüfen Sie bitte Ihre Netzwerk- und Firewalleinstellungen. + Bitte überprüfen Sie status.secondlifegrid.net, um herauszufinden, ob ein Problem besteht. + Falls Sie weiterhin Problem haben, überprüfen Sie bitte Ihre Netzwerk- und Firewalleinstellungen. </string> <string name="dateTimeWeekdaysNames"> Sonntag:Montag:Dienstag:Mittwoch:Donnerstag:Freitag:Samstag @@ -4440,6 +4508,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 +4884,10 @@ Setzen Sie den Editorpfad in Anführungszeichen Minikarte </string> <string name="Command_Move_Label"> - Bewegen + Gehen / Rennen / Fliegen + </string> + <string name="Command_Outbox_Label"> + Händler-Outbox </string> <string name="Command_People_Label"> Leute @@ -4837,10 +4914,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 @@ -4884,6 +4961,9 @@ Setzen Sie den Editorpfad in Anführungszeichen <string name="Command_Move_Tooltip"> Ihren Avatar bewegen </string> + <string name="Command_Outbox_Tooltip"> + Artikel zum Verkauf in den Marktplatz übertragen + </string> <string name="Command_People_Tooltip"> Freunde, Gruppen und Leute in der Nähe </string> @@ -4912,7 +4992,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 +5027,40 @@ Setzen Sie den Editorpfad in Anführungszeichen <string name="Normal"> Normal </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Keine + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Wirkt sich auf Navmesh aus + </string> + <string name="Pathfinding_Object_Attr_Character"> + Figur + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (mehrere) + </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> + <string name="TeleportMaturityExceeded"> + Der Einwohner kann diese Region nicht besuchen. + </string> + <string name="UserDictionary"> + [Benutzer] + </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..8062633df6 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. @@ -46,6 +46,9 @@ Ihre Teleport-Anfrage kann nicht sofort bearbeitet werden. Versuchen Sie es in e <message name="no_inventory_host"> Das Inventarsystem ist zurzeit nicht verfügbar. </message> + <message name="MustGetAgeRegion"> + Sie müssen mindestens 18 Jahre alt sein, um diese Region betreten zu können. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -81,5 +84,8 @@ Ihre Teleport-Anfrage kann nicht sofort bearbeitet werden. Versuchen Sie es in e <message name="requesting"> Teleport wird initialisiert... </message> + <message name="pending"> + Anstehender Teleport... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/en/floater_aaa.xml b/indra/newview/skins/default/xui/en/floater_aaa.xml index 930bbaa8cb..d11373ce1d 100644 --- a/indra/newview/skins/default/xui/en/floater_aaa.xml +++ b/indra/newview/skins/default/xui/en/floater_aaa.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - legacy_header_height="18" can_minimize="false" can_tear_off="false" can_resize="true" @@ -16,67 +15,98 @@ save_dock_state="true" save_visibility="true" single_instance="true" - width="320"> - <string name="nudge_parabuild" translate="false">Nudge 1</string> - <string name="test_the_vlt">This string CHANGE2 is extracted.</string> - <string name="testing_eli">Just a test. changes.</string> - <text_editor - parse_urls="true" - bg_readonly_color="ChatHistoryBgColor" - bg_writeable_color="ChatHistoryBgColor" - border_visible="false" - follows="all" - font="SansSerif" - left="1" - top="20" - layout="topleft" - height="260" - name="chat_history" - max_length="200000" - parse_highlights="true" - text_color="ChatHistoryTextColor" - text_readonly_color="ChatHistoryTextColor" - translate="false" - track_end="true" - wrap="true" - width="320"> - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - Really long line that is long enough to wrap once with jyg descenders. - </text_editor> + width="650"> + <text left="0" + follows="left|top|bottom" + top="5" + clip_partial="true" + bottom="-5" + width="100" + valign="top"> +this +is +some +text +that +is +top +aligned</text> + <text left_pad="5" + follows="left|top|bottom" + top="5" + bottom="-5" + clip_partial="true" + width="100" + valign="center"> +this +is +some +text +that +is +center +aligned</text> + <text left_pad="5" + follows="left|top|bottom" + top="5" + clip_partial="true" + bottom="-5" + width="100" + valign="bottom"> +this +is +some +text +that +is +bottom +aligned</text> + <text_editor left_pad="5" + follows="left|top|bottom" + top="5" + clip_partial="true" + bottom="-5" + width="100" + valign="top"> +this +is +some +text +that +is +top +aligned + </text_editor> + <text_editor left_pad="5" + follows="left|top|bottom" + top="5" + bottom="-5" + clip_partial="true" + width="100" + valign="center"> +this +is +some +text +that +is +center +aligned + </text_editor> + <text_editor left_pad="5" + follows="left|top|bottom" + top="5" + clip_partial="true" + bottom="-5" + width="100" + valign="bottom"> +this +is +some +text +that +is +bottom +aligned + </text_editor> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index c7e9ec781d..63eb87f27a 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="centered" + positioning="centered" legacy_header_height="18" height="440" layout="topleft" @@ -196,27 +196,26 @@ Dummy Name replaced at run time top="5" width="435" word_wrap="true"> - 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) + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion + APR Copyright (C) 2011 The Apache Software Foundation + Collada DOM Copyright 2006 Sony Computer Entertainment Inc. + cURL Copyright (C) 1996-2010, 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). + FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. 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 + ogg/vorbis Copyright (C) 2002, Xiphophorus + OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. + PCRE Copyright (c) 1997-2012 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. + zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. Second Life Viewer uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details. 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 1c7b354221..793a6e6fa1 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="cascading" + positioning="cascading" can_tear_off="false" height="420" layout="topleft" @@ -192,12 +192,12 @@ type="string" length="1" follows="left|top" - height="20" + height="18" layout="topleft" left_pad="2" valign="center" name="ContentRatingText" - top_delta="0" + top_delta="-2" width="250"> Adult </text> @@ -209,7 +209,7 @@ layout="topleft" left="10" name="Owner:" - top_pad="1" + top_pad="3" width="100"> Owner: </text> @@ -736,7 +736,7 @@ height="16" layout="topleft" left_pad="10" - top_delta="-3" + top_delta="-1" mouse_opaque="false" name="region_maturity_text" valign="center" @@ -1206,15 +1206,11 @@ 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"> - See and chat with residents on this parcel - </panel.string> <text type="string" length="1" follows="left|top" - text_color="white" + text_color="White" height="16" layout="topleft" left="10" @@ -1223,30 +1219,33 @@ Only large parcels can be listed in search. width="278"> Allow other Residents to: </text> - <check_box - height="16" - label="Edit Terrain" - layout="topleft" - left="14" - name="edit land check" - tool_tip="If checked, anyone can terraform your land. It is best to leave this unchecked, as you can always edit your own land." - top_pad="4" - width="147i" /> - <check_box + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="20" + name="allow_label0" + width="150"> + Fly: + </text> + + <check_box height="16" - label="Fly" + label="Everyone" layout="topleft" name="check fly" tool_tip="If checked, Residents can fly on your land. If unchecked, they can only fly into and over your land." - left_pad="4" - width="150" /> + left_pad="2" + width="130" /> <text type="string" length="1" follows="left|top" height="16" layout="topleft" - left="14" + left="20" name="allow_label2" width="150"> Build: @@ -1271,7 +1270,7 @@ Only large parcels can be listed in search. follows="left|top" height="16" layout="topleft" - left="14" + left="20" name="allow_label3" width="150"> Object Entry: @@ -1298,7 +1297,7 @@ Only large parcels can be listed in search. follows="left|top" height="16" layout="topleft" - left="14" + left="20" name="allow_label4" width="150"> Run Scripts: @@ -1319,116 +1318,49 @@ Only large parcels can be listed in search. name="check group scripts" top_delta="0" width="70" /> - <text - type="string" - text_color="white" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="land_options_label" - width="278"> - Land Options: - </text> - <check_box + <panel + bevel_style="none" + border="true" + top="146" + bottom="146" + follows="left|bottom|right" + left="20" + right="-20"/> + <check_box height="16" label="Safe (no damage)" layout="topleft" - left="14" + left="18" name="check safe" tool_tip="If checked, sets the land to Safe, disabling damage combat. If cleared, damage combat is enabled." - top_pad="5" + top="130" width="200" /> <check_box height="16" label="No Pushing" layout="topleft" - left_pad="5" + left_pad="35" name="PushRestrictCheck" tool_tip="Prevents scripts from pushing. Checking this option may be useful for preventing disruptive behavior on your land." - top_delta="0" + top="130" width="119" /> <check_box height="16" label="Show Place in Search (L$30/week)" layout="topleft" - left="14" + left="18" name="ShowDirectoryCheck" tool_tip="Let people see this parcel in search results" + top="150" width="430" /> <combo_box - enabled="false" - height="23" - layout="topleft" - left="30" - name="land category with adult" - visible="false" - width="140"> - <combo_box.item - label="Any Category" - name="item0" - value="any" /> - <combo_box.item - label="Linden Location" - name="item1" - value="linden" /> - <combo_box.item - label="Adult" - name="item2" - value="adult" /> - <combo_box.item - label="Arts & Culture" - name="item3" - value="arts" /> - <combo_box.item - label="Business" - name="item4" - value="store" /> - <combo_box.item - label="Educational" - name="item5" - value="educational" /> - <combo_box.item - label="Gaming" - name="item6" - value="game" /> - <combo_box.item - label="Hangout" - name="item7" - value="gather" /> - <combo_box.item - label="Newcomer Friendly" - name="item8" - value="newcomer" /> - <combo_box.item - label="Parks & Nature" - name="item9" - value="park" /> - <combo_box.item - label="Residential" - name="item10" - value="home" /> - <combo_box.item - label="Shopping" - name="item11" - value="shopping" /> - <combo_box.item - label="Rental" - name="item13" - value="rental" /> - <combo_box.item - label="Other" - name="item12" - value="other" /> - </combo_box> - <combo_box - enabled="false" + enabled="true" height="23" layout="topleft" - left="30" + left="20" + top="194" name="land category" - visible="false" + visible="true" width="140"> <combo_box.item label="Any Category" @@ -1487,11 +1419,11 @@ Only large parcels can be listed in search. height="16" label="Moderate Content" layout="topleft" - left="14" + left="18" name="MatureCheck" - top="177" + top="170" label_text.valign="center" - label_text.v_pad="-5" + label_text.v_pad="-1" tool_tip=" " width="200" /> <text @@ -1500,18 +1432,19 @@ Only large parcels can be listed in search. follows="left|top" height="16" layout="topleft" - left="10" + left="20" name="Snapshot:" - text_color="white" - top="220" + text_color="White" + top="225" width="200"> Snapshot: </text> <texture_picker follows="left|top" + top_pad="0" height="150" layout="topleft" - left="14" + left="20" name="snapshot_ctrl" fallback_image="default_land_picture.j2c" tool_tip="Click to choose a picture" @@ -1520,33 +1453,34 @@ Only large parcels can be listed in search. type="string" length="1" follows="left|top" - text_color="white" - height="16" + text_color="LtGray" + height="32" layout="topleft" - left="230" - top="174" + left="274" + top="150" name="allow_label5" - width="278"> - Allow Residents on other parcels to: + 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="230" + left="253" + top="150" name="SeeAvatarsCheck" - tool_tip="Allows residents on other parcels to see and chat with residents on this parcel, and you to see and chat with them." - width="120" /> + 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="10" /> <text type="string" length="1" follows="left|top" height="16" layout="topleft" - left="230" - top="230" - text_color="white" + left="255" + top="282" + text_color="White" name="landing_point" word_wrap="true" width="200"> @@ -1554,12 +1488,13 @@ Only large parcels can be listed in search. </text> <button follows="right|top" + top_pad="0" height="23" label="Set" label_selected="Set" layout="topleft" name="Set" - left="230" + left="255" tool_tip="Sets the landing point where visitors arrive. Sets to your avatar's location inside this parcel." width="50" /> <button @@ -1575,11 +1510,11 @@ Only large parcels can be listed in search. <text type="string" length="1" - text_color="white" + text_color="White" follows="left|top" height="16" layout="topleft" - left="230" + left="255" top_pad="10" name="Teleport Routing: " width="200"> @@ -1589,7 +1524,7 @@ Only large parcels can be listed in search. height="23" layout="topleft" name="landing type" - top_pad="3" + top_pad="0" tool_tip="Teleport Routing -- select how to handle teleports onto your land" width="120"> <combo_box.item @@ -1951,35 +1886,17 @@ Only large parcels can be listed in search. (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" @@ -1989,28 +1906,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="Are age 18 or older [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 18 or older to access this parcel. See the [SUPPORT_SITE] for more information." top_pad="4" width="278" /> <check_box @@ -2020,7 +1937,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" @@ -2102,7 +2019,7 @@ Only large parcels can be listed in search. column_padding="0" follows="top|bottom" heading_height="14" - height="120" + height="125" layout="topleft" left="0" multi_select="true" @@ -2151,7 +2068,7 @@ Only large parcels can be listed in search. column_padding="0" follows="top|bottom" heading_height="14" - height="120" + height="125" layout="topleft" left="0" multi_select="true" diff --git a/indra/newview/skins/default/xui/en/floater_activeim.xml b/indra/newview/skins/default/xui/en/floater_activeim.xml index 670c528f08..b79c5d9a19 100644 --- a/indra/newview/skins/default/xui/en/floater_activeim.xml +++ b/indra/newview/skins/default/xui/en/floater_activeim.xml @@ -6,7 +6,6 @@ title="ACTIVE IM" height="22" width="320" - follows="right|bottom" background_visible="true" can_close="true" can_dock="true" diff --git a/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml new file mode 100644 index 0000000000..b5538a511c --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + height="190" + layout="topleft" + name="Anim Preview" + help_topic="animation_anim_preview" + title="ANIMATION.ANIM" + width="300"> + <text + type="string" + length="1" + follows="left|top" + height="15" + layout="topleft" + left="10" + mouse_opaque="false" + name="name_label" + top="20" + width="275"> + Name: + </text> + <line_editor + border_style="line" + border_thickness="1" + follows="left|top|right" + height="19" + layout="topleft" + left_delta="0" + max_length_bytes="63" + name="name_form" + top_pad="0" + width="280" /> + <text + type="string" + length="1" + follows="left|top" + height="15" + layout="topleft" + left_delta="0" + mouse_opaque="false" + name="description_label" + top_pad="10" + width="270"> + Description: + </text> + <line_editor + border_style="line" + border_thickness="1" + follows="left|top|right" + height="19" + layout="topleft" + left_delta="0" + max_length_bytes="127" + name="description_form" + top_pad="0" + width="280" /> + <button + follows="left|bottom" + height="22" + label="Upload (L$[AMOUNT])" + layout="topleft" + left="45" + name="ok_btn" + top_pad="60" + width="150" /> + <button + follows="right|bottom" + height="22" + label="Cancel" + label_selected="Cancel" + layout="topleft" + name="cancel_btn" + left_pad="5" + width="90" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_animation_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml index cb6b2f6ebc..cb6b2f6ebc 100644 --- a/indra/newview/skins/default/xui/en/floater_animation_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml diff --git a/indra/newview/skins/default/xui/en/floater_autoreplace.xml b/indra/newview/skins/default/xui/en/floater_autoreplace.xml new file mode 100644 index 0000000000..0bfefc8abe --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_autoreplace.xml @@ -0,0 +1,289 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + border="true" + can_close="true" + can_minimize="true" + can_resize="false" + help_topic="autoreplace_settings" + save_rect="true" + height="455" + width="490" + name="autoreplace_floater" + title="Auto-Replace Settings"> + <check_box + bottom_delta="30" + left_delta="15" + height="16" + width="100" + follows="left|top" + label="Enable Auto-Replace" + name="autoreplace_enable" + tool_tip="As you enter chat text, replace any of the keywords entered with the corresponding replacement"/> + <view_border + top_pad="15" + left="2" + height="0" + width="491" + follows="left|top" + bevel_style="none" + border_thickness="1" + mouse_opaque="false" + name="divisor1"/> + <button + top_pad="10" + left="10" + height="22" + width="110" + enabled="true" + follows="left|top" + mouse_opaque="true" + halign="center" + scale_image="true" + name="autoreplace_import_list" + label="Import List..." + tool_tip="Load a previously exported list from a file."/> + <button + top_delta="0" + left_pad="10" + height="22" + width="110" + enabled="true" + follows="left|top" + mouse_opaque="true" + halign="center" + scale_image="true" + name="autoreplace_export_list" + label="Export List..." + tool_tip="Save the selected list to a file so you can share it."/> + <button + top_delta="0" + left_pad="10" + height="22" + width="110" + enabled="true" + follows="left|top" + mouse_opaque="true" + halign="center" + scale_image="true" + name="autoreplace_new_list" + label="New List..." + tool_tip="Create a new list."/> + <button + top_delta="0" + left_pad="10" + height="22" + width="110" + enabled="true" + follows="left|top" + mouse_opaque="true" + halign="center" + scale_image="true" + name="autoreplace_delete_list" + label="Delete List" + tool_tip="Delete the selected list."/> + <scroll_list + top_pad="10" + left="10" + height="100" + width="370" + follows="left|top" + column_padding="0" + draw_heading="false" + multi_select="false" + name="autoreplace_list_name" + search_column="0"> + </scroll_list> + <button + top_delta="23" + left_pad="10" + height="22" + width="90" + enabled="true" + follows="left|top" + mouse_opaque="true" + halign="center" + scale_image="true" + name="autoreplace_list_up" + image_overlay="Arrow_Up" + tool_tip="Move this list up in priority."/> + <button + top_pad="10" + left_delta="0" + height="22" + width="90" + enabled="true" + follows="left|top" + mouse_opaque="true" + halign="center" + scale_image="true" + name="autoreplace_list_down" + image_overlay="Arrow_Down" + tool_tip="Move this list down in priority."/> + <view_border + top_pad="36" + left="2" + height="0" + width="491" + follows="left|top" + bevel_style="none" + border_thickness="1" + mouse_opaque="false" + name="divisor2"/> + <scroll_list + top_pad="10" + left="10" + height="120" + width="370" + follows="left|top" + column_padding="0" + draw_heading="true" + multi_select="true" + name="autoreplace_list_replacements" + search_column="0"> + <scroll_list.columns + label="Keyword" + name="keyword" + relative_width="0.30" /> + <scroll_list.columns + label="Replacement" + name="replacement" + relative_width="0.70" /> + </scroll_list> + <button + top_delta="41" + left_pad="10" + height="22" + width="90" + enabled="true" + follows="left|top" + mouse_opaque="true" + halign="center" + scale_image="true" + name="autoreplace_add_entry" + label="Add..."/> + <button + top_pad="10" + left_delta="0" + height="22" + width="90" + enabled="true" + follows="left|top" + mouse_opaque="true" + halign="center" + scale_image="true" + name="autoreplace_delete_entry" + label="Remove"/> + <view_border + top_pad="38" + left="2" + height="0" + width="491" + follows="left|top" + bevel_style="none" + border_thickness="1" + mouse_opaque="false" + name="divisor3"/> + <text + type="string" + follows="left|top" + height="16" + layout="topleft" + left="10" + top_pad="13" + width="50"> + Keyword: + </text> + <line_editor + name="autoreplace_keyword" + follows="left|top" + height="23" + layout="topleft" + left="100" + max_length_bytes="255" + top_delta="-5" + width="150" + /> + <text + type="string" + follows="left|top" + height="16" + layout="topleft" + left="10" + right="90" + top_pad="10" + > + Replacement: + </text> + <line_editor + name="autoreplace_replacement" + follows="left|top" + height="23" + layout="topleft" + left="100" + max_length_bytes="255" + top_delta="-5" + width="280" + /> + <button + top_delta="0" + right="-10" + height="22" + width="90" + enabled="false" + follows="left|top" + mouse_opaque="true" + halign="center" + scale_image="true" + name="autoreplace_save_entry" + label="Save Entry" + tool_tip="Save this entry."/> + <view_border + top_pad="10" + left="2" + height="0" + width="491" + follows="left|top" + bevel_style="none" + border_thickness="1" + mouse_opaque="false" + name="divisor4"/> + <button + top_pad="10" + right="380" + height="22" + width="90" + enabled="true" + follows="left|top" + mouse_opaque="true" + halign="center" + scale_image="true" + name="autoreplace_save_changes" + label="Save Changes" + tool_tip="Save all changes."/> + <button + top_delta="0" + right="480" + height="22" + width="90" + enabled="true" + follows="left|top" + mouse_opaque="true" + halign="center" + scale_image="true" + name="autoreplace_cancel" + label="Cancel" + tool_tip="Discard all changes."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </text> +--> diff --git a/indra/newview/skins/default/xui/en/floater_avatar.xml b/indra/newview/skins/default/xui/en/floater_avatar.xml index 6009821f7f..cd5cca02bd 100644 --- a/indra/newview/skins/default/xui/en/floater_avatar.xml +++ b/indra/newview/skins/default/xui/en/floater_avatar.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="cascading" + positioning="cascading" ignore_ui_scale="false" legacy_header_height="225" can_minimize="true" can_close="true" can_resize="true" min_height="230" - min_width="450" + min_width="515" height="230" layout="topleft" name="Avatar" @@ -15,7 +15,7 @@ help_topic="avatar" save_rect="true" save_visibility="true" - title="AVATAR PICKER" + title="CHOOSE AN AVATAR" width="700"> <web_browser top="25" diff --git a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml index cbbbeb6094..1a55dc2e2c 100644 --- a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml +++ b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="cascading" + positioning="cascading" legacy_header_height="18" can_resize="true" height="350" diff --git a/indra/newview/skins/default/xui/en/floater_build_options.xml b/indra/newview/skins/default/xui/en/floater_build_options.xml index afb7917043..38428b36fc 100644 --- a/indra/newview/skins/default/xui/en/floater_build_options.xml +++ b/indra/newview/skins/default/xui/en/floater_build_options.xml @@ -1,71 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater legacy_header_height="18" - follows="right" - height="198" + height="170" layout="topleft" name="build options floater" help_topic="build_options_floater" save_rect="true" title="GRID OPTIONS" width="264"> - <floater.string - name="grid_screen_text"> - Screen - </floater.string> - <floater.string - name="grid_local_text"> - Local - </floater.string> - <floater.string - name="grid_world_text"> - World - </floater.string> - <floater.string - name="grid_reference_text"> - Reference - </floater.string> - <floater.string - name="grid_attachment_text"> - Attachment - </floater.string> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - tool_tip="Grid opacity" - name="grid_mode_label" - top_pad="30" - width="123"> - Mode - </text> - <combo_box - height="23" - layout="topleft" - left_pad="9" - follows="left|top" - name="combobox grid mode" - tool_tip="Choose the type of grid ruler for positioning the object" - top_delta="-3" - width="108"> - <combo_box.item - label="World grid" - name="World" - value="World" /> - <combo_box.item - label="Local grid" - name="Local" - value="Local" /> - <combo_box.item - label="Reference grid" - name="Reference" - value="Reference" /> - <combo_box.commit_callback - function="GridOptions.gridMode"/> - </combo_box> <spinner control_name="GridResolution" follows="left|top" @@ -78,7 +20,7 @@ max_val="5" min_val="0.01" name="GridResolution" - top_pad="4" + top_pad="30" width="200" /> <spinner control_name="GridDrawSize" diff --git a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml index 4e0cfb0cd4..e7ab3cacdc 100644 --- a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml +++ b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml @@ -6,7 +6,7 @@ layout="topleft" name="floaterbulkperms" help_topic="floaterbulkperms" - title="EDIT CONTENT PERMISSIONS" + title="ADJUST CONTENT PERMISSIONS" width="410"> <floater.string name="nothing_to_modify_text"> @@ -192,7 +192,7 @@ name="newperms" top="90" width="250"> - New Content Permissions + Adjust Content Permissions To </text> <text type="string" @@ -292,11 +292,22 @@ height="23" label="OK" layout="topleft" - left="205" - name="apply" + left="110" + name="ok" top_pad="10" width="90"> <button.commit_callback + function="BulkPermission.Ok"/> + </button> + <button + follows="left|top" + height="23" + label="Apply" + layout="topleft" + left_pad="5" + name="apply" + width="90"> + <button.commit_callback function="BulkPermission.Apply"/> </button> <button diff --git a/indra/newview/skins/default/xui/en/floater_buy_contents.xml b/indra/newview/skins/default/xui/en/floater_buy_contents.xml index 92001534e7..ac96a70805 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_contents.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_contents.xml @@ -62,7 +62,7 @@ layout="topleft" left="10" name="buy_text" - text_color="white" + text_color="White" top="220" use_ellipses="true" width="260"> diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml index 6afa24d04a..553c5d51d0 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml @@ -215,7 +215,7 @@ <text type="string" length="1" - text_color="0.7 0.7 0.7 0.5" + text_color="LtGray_50" follows="top|left" layout="topleft" halign="right" @@ -229,7 +229,7 @@ <text type="string" length="1" - text_color="0.7 0.7 0.7 0.5" + text_color="LtGray_50" follows="top|left" layout="topleft" halign="right" @@ -243,7 +243,7 @@ Re-enter amount to see the latest exchange rate. <text type="string" length="1" - text_color="0.7 0.7 0.7 0.5" + text_color="LtGray_50" follows="top|left" layout="topleft" halign="right" @@ -257,7 +257,7 @@ Re-enter amount to see the latest exchange rate. <text type="string" length="1" - text_color="0.7 0.7 0.7 0.5" + text_color="LtGray_50" follows="top|left" layout="topleft" halign="right" diff --git a/indra/newview/skins/default/xui/en/floater_buy_object.xml b/indra/newview/skins/default/xui/en/floater_buy_object.xml index 8dfb6ba00c..5fdd4aa49d 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_object.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_object.xml @@ -89,7 +89,7 @@ left_delta="0" line_spacing.pixels="7" name="buy_text" - text_color="white" + text_color="White" top_pad="5" use_ellipses="true" width="260" @@ -106,7 +106,7 @@ Buy for L$[AMOUNT] from: left_delta="0" line_spacing.pixels="7" name="buy_name_text" - text_color="white" + text_color="White" top_pad="5" use_ellipses="true" width="260"> diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml index e7f5207271..521389d7b3 100644 --- a/indra/newview/skins/default/xui/en/floater_camera.xml +++ b/indra/newview/skins/default/xui/en/floater_camera.xml @@ -1,19 +1,19 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="specified" - specified_left="320" - specified_bottom="80" + positioning="specified" + right="-460" + bottom="-50" + follows="left|bottom" legacy_header_height="18" can_minimize="true" can_close="true" - follows="bottom" height="164" layout="topleft" name="camera_floater" help_topic="camera_floater" save_visibility="true" single_instance="true" - title="VIEW" + title="CAMERA CONTROLS" chrome="true" save_rect="true" width="228"> @@ -30,18 +30,6 @@ Move Camera Up and Down, Left and Right </floater.string> <floater.string - name="camera_modes_title"> - Camera modes - </floater.string> - <floater.string - name="pan_mode_title"> - Orbit Zoom Pan - </floater.string> - <floater.string - name="presets_mode_title"> - Preset Views - </floater.string> - <floater.string name="free_mode_title"> View Object </floater.string> diff --git a/indra/newview/skins/default/xui/en/floater_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml deleted file mode 100644 index 87606c1a2a..0000000000 --- a/indra/newview/skins/default/xui/en/floater_chat_bar.xml +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - open_positioning="specified" - specified_left="320" - specified_bottom="10" - height="60" - layout="topleft" - legacy_header_height="25" - single_instance="true" - title="NEARBY CHAT" - save_rect="true" - can_close="true" - can_minimize="true" - help_topic="chat_bar" - min_height="60" - min_width="150" - can_resize="true" - default_tab_group="1" - name="chat_bar" - width="380"> - <panel - top="20" - class="panel_nearby_chat" - follow="all" - width="380" - height="0" - visible="false" - filename="panel_nearby_chat.xml" - name="nearby_chat" /> - <panel width="380" - height="31" - left="0" - bottom="-1" - follows="left|right|bottom" - tab_group="1"> - <line_editor - border_style="line" - border_thickness="1" - follows="left|right" - height="23" - label="Click here to chat." - layout="topleft" - left_delta="7" - left="0" - max_length_bytes="1023" - name="chat_box" - text_pad_left="5" - text_pad_right="25" - tool_tip="Press Enter to say, Ctrl+Enter to shout" - top="2" - width="335" /> - <output_monitor - auto_update="true" - follows="right" - draw_border="false" - height="16" - layout="topleft" - left_pad="-24" - mouse_opaque="true" - name="chat_zone_indicator" - top="6" - visible="true" - width="20" /> - <button - follows="right" - is_toggle="true" - width="20" - top="2" - layout="topleft" - left_pad="12" - image_disabled="ComboButton_UpOff" - image_unselected="ComboButton_UpOff" - image_selected="ComboButton_On" - image_pressed="ComboButton_UpSelected" - image_pressed_selected="ComboButton_Selected" - height="23" - chrome="true" - name="show_nearby_chat" - tool_tip="Shows/hides nearby chat log"> - </button> - </panel> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_choose_group.xml b/indra/newview/skins/default/xui/en/floater_choose_group.xml index dc1ee5f24e..2cf6e682fd 100644 --- a/indra/newview/skins/default/xui/en/floater_choose_group.xml +++ b/indra/newview/skins/default/xui/en/floater_choose_group.xml @@ -20,7 +20,7 @@ Choose a group: </text> <scroll_list - height="160" + height="165" layout="topleft" left_delta="0" name="group list" diff --git a/indra/newview/skins/default/xui/en/floater_color_picker.xml b/indra/newview/skins/default/xui/en/floater_color_picker.xml index 421f3a72c6..e06d10606a 100644 --- a/indra/newview/skins/default/xui/en/floater_color_picker.xml +++ b/indra/newview/skins/default/xui/en/floater_color_picker.xml @@ -2,7 +2,6 @@ <floater legacy_header_height="18" can_minimize="false" - follows="left|top" height="380" layout="topleft" name="ColorPicker" diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml new file mode 100644 index 0000000000..19a4cbc119 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> + +<floater + can_resize="true" + positioning="cascading" + help_topic="conversation_log" + height="200" + min_height="100" + min_width="230" + layout="topleft" + name="floater_conversation_log" + save_rect="true" + single_instance="true" + reuse_instance="true" + title="CONVERSATION LOG" + width="300"> + <panel + follows="left|top|right" + height="32" + left="0" + name="buttons_panel" + top="0"> + <filter_editor + follows="left|top|right" + height="23" + layout="topleft" + left="8" + label="Filter People" + max_length_chars="300" + name="people_filter_input" + text_color="Black" + text_pad_left="10" + top="4" + width="204" /> + <menu_button + follows="top|right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_sort" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="8" + menu_filename="menu_conversation_log_view.xml" + menu_position="bottomleft" + name="conversation_view_btn" + tool_tip="View/sort options" + top="3" + width="31" /> + <menu_button + follows="top|right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="8" + name="conversations_gear_btn" + tool_tip="Actions on selected person or group" + top="3" + width="31" /> + </panel> + <panel + bottom="-1" + follows="all" + left="0" + name="log_panel" + right="-1" + top="32"> + <conversation_log_list + allow_select="true" + bottom="-8" + opaque="true" + follows="all" + left="8" + keep_selection_visible_on_reshape="true" + item_pad="2" + multi_select="false" + name="conversation_log_list" + right="-8" + top="0" /> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml new file mode 100644 index 0000000000..764b9d8385 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + can_resize="true" + default_tab_group="1" + help_topic="conversation_preview" + height="391" + layout="topleft" + min_height="243" + min_width="234" + name="preview_conversation" + title="CONVERSATION:" + width="400"> + <floater.string + name="Title"> + CONVERSATION: [NAME] + </floater.string> + <chat_history + font="SansSerifSmall" + follows="all" + visible="true" + height="330" + name="chat_history" + notify_unread_msg="false" + parse_highlights="true" + parse_urls="true" + left="5" + top_pad="25" + width="390"> + </chat_history> + <text + follows="bottom|right" + font="SansSerif" + height="22" + layout="topleft" + name="page_label" + right="-110" + top_pad="7" + value="Page" + width="35"> + </text> + <spinner + allow_digits_only="true" + decimal_digits="0" + follows="bottom|right" + height="23" + increment="1" + label_width="40" + layout="topleft" + left_pad="0" + name="history_page_spin" + top_delta="-3" + width="50"/> + <text + follows="bottom|right" + font="SansSerif" + height="22" + layout="topleft" + name="page_num_label" + left_pad="5" + top_delta="4" + width="40"> + </text> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_critical.xml b/indra/newview/skins/default/xui/en/floater_critical.xml index 13b15bf724..143bcb4430 100644 --- a/indra/newview/skins/default/xui/en/floater_critical.xml +++ b/indra/newview/skins/default/xui/en/floater_critical.xml @@ -6,7 +6,7 @@ height="500" layout="topleft" name="modal container" - open_positioning="centered" + positioning="centered" width="600"> <button height="20" diff --git a/indra/newview/skins/default/xui/en/floater_destinations.xml b/indra/newview/skins/default/xui/en/floater_destinations.xml index 373114a1eb..94ebaa9cb2 100644 --- a/indra/newview/skins/default/xui/en/floater_destinations.xml +++ b/indra/newview/skins/default/xui/en/floater_destinations.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="cascading" + positioning="cascading" ignore_ui_scale="false" legacy_header_height="225" can_minimize="true" @@ -17,11 +17,11 @@ save_rect="true" save_visibility="true" title="DESTINATIONS" - width="840"> + width="550"> <web_browser top="25" height="200" - width="840" + width="550" follows="all" name="destination_guide_contents" trusted_content="true"/> diff --git a/indra/newview/skins/default/xui/en/floater_event.xml b/indra/newview/skins/default/xui/en/floater_event.xml index 7ed020f832..cf61b7d24d 100644 --- a/indra/newview/skins/default/xui/en/floater_event.xml +++ b/indra/newview/skins/default/xui/en/floater_event.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - follows="all" height="400" can_resize="true" help_topic="event_details" diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml index 49aa8f3840..77adb5524e 100644 --- a/indra/newview/skins/default/xui/en/floater_fast_timers.xml +++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml @@ -22,7 +22,6 @@ top="5" width="180" height="40" - pad_bottom="-5" label="Pause" font="SansSerifHuge"/> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml index a941734358..200e9b9537 100644 --- a/indra/newview/skins/default/xui/en/floater_gesture.xml +++ b/indra/newview/skins/default/xui/en/floater_gesture.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="cascading" + positioning="cascading" save_rect="true" legacy_header_height="18" can_resize="true" @@ -9,7 +9,6 @@ help_topic="gestures" title="GESTURES" background_visible="true" - follows="all" label="Places" layout="topleft" min_height="350" diff --git a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml index 66bb9d3cea..9deb0d2030 100644 --- a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml @@ -132,6 +132,28 @@ name="vbo" tool_tip="Enabling this on modern hardware gives a performance gain. However, older hardware often has poor implementations of VBOs and you may get crashes when this is enabled." width="315" /> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="10" + name="tc label" + top_pad="10" + width="188"> + Enable S3TC: + </text> + <check_box + control_name="RenderCompressTextures" + height="16" + initial_value="true" + label="Enable Texture Compression (requires restart)" + layout="topleft" + left_pad="10" + name="texture compression" + tool_tip="Compresses textures in video memory, allowing for higher resolution textures to be loaded at the cost of some color quality." + width="315" /> <slider control_name="TextureMemory" decimal_digits="0" 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..c06cb63f8a 100644 --- a/indra/newview/skins/default/xui/en/floater_help_browser.xml +++ b/indra/newview/skins/default/xui/en/floater_help_browser.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="cascading" + positioning="cascading" legacy_header_height="18" can_resize="true" height="600" @@ -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_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml index e123de46c2..12c1676127 100644 --- a/indra/newview/skins/default/xui/en/floater_im_container.xml +++ b/indra/newview/skins/default/xui/en/floater_im_container.xml @@ -1,49 +1,180 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <multi_floater - can_close="false" + can_close="true" can_minimize="true" can_resize="true" - height="390" + height="210" layout="topleft" name="floater_im_box" help_topic="floater_im_box" save_rect="true" save_visibility="true" single_instance="true" + reuse_instance="true" title="CONVERSATIONS" - width="396"> - <tab_container - follows="left|right|top|bottom" - height="390" + bottom="-50" + right="-5" + width="450" + min_width="38"> + <string + name="collapse_icon" + value="Conv_toolbar_collapse"/> + <string + name="expand_icon" + value="Conv_toolbar_expand"/> + <layout_stack + animate="true" + bottom="-1" + follows="all" layout="topleft" - left="1" - name="im_box_tab_container" - tab_position="bottom" - tab_width="64" - tab_max_width = "134" - tab_height="16" - use_custom_icon_ctrl="true" - tab_icon_ctrl_pad="2" - halign="left" - use_ellipses="true" - top="0" - width="394"> - <first_tab - tab_bottom_image_flash="Toolbar_Left_Flash"/> - <middle_tab - tab_bottom_image_flash="Toolbar_Middle_Flash"/> - <last_tab - tab_bottom_image_flash="Toolbar_Right_Flash"/> - </tab_container> - <icon - color="DefaultShadowLight" - enabled="false" - follows="left|right|bottom" - height="17" - image_name="tabarea.tga" - layout="bottomleft" - left="1" - name="im_box_tab_container_icon" - bottom="10" - width="394" /> + left="0" + name="conversations_stack" + orientation="horizontal" + right="-1" + top="0"> + <layout_panel + auto_resize="false" + user_resize="true" + name="conversations_layout_panel" + min_dim="38" + expanded_min_dim="156"> + <layout_stack + animate="false" + follows="left|top|right" + height="35" + layout="topleft" + left="0" + name="conversations_pane_buttons_stack" + orientation="horizontal" + right="-1" + top="0"> + <layout_panel + auto_resize="true" + height="35" + name="conversations_pane_buttons_expanded"> + <menu_button + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_sort" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + menu_filename="menu_participant_view.xml" + layout="topleft" + left="10" + name="sort_btn" + tool_tip="View/sort options" + top="5" + width="31" /> + <button + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_plus" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left_pad="4" + name="add_btn" + tool_tip="Start a new conversation" + width="31"/> + <button + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Command_Speak_Icon" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left_pad="4" + name="speak_btn" + tool_tip="Speak with people using your microphone" + width="31"/> + </layout_panel> + <layout_panel + auto_resize="false" + height="35" + name="conversations_pane_buttons_collapsed" + width="41"> + <button + follows="right|top" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_collapse" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left="1" + name="expand_collapse_btn" + tool_tip="Collapse/Expand this list" + width="31" /> + </layout_panel> + </layout_stack> + <panel + bottom="-5" + follows="all" + layout="topleft" + name="conversations_list_panel" + opaque="true" + top="35" + left="5" + right="-1"/> + </layout_panel> + <layout_panel + auto_resize="true" + user_resize="true" + name="messages_layout_panel" + expanded_min_dim="222"> + <panel_container + bottom="-5" + follows="all" + layout="topleft" + left="0" + name="im_box_tab_container" + right="-1" + top="0"> + <panel + bottom="-1" + follows="all" + layout="topleft" + name="stub_panel" + opaque="true" + top_pad="0" + left="0" + right="-1"> + <button + follows="right|top" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_collapse" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + right="-10" + name="stub_collapse_btn" + tool_tip="Collapse this pane" + width="31" /> + <text + type="string" + clip_partial="false" + follows="left|top|right" + layout="topleft" + left="15" + right="-15" + name="stub_textbox" + top="25" + height="40" + valign="center" + parse_urls="true" + wrap="true"> + This conversation is in a separate window. [secondlife:/// Bring it back.] + </text> + </panel> + </panel_container> + </layout_panel> + </layout_stack> </multi_floater> diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index cb7d91abb8..8f0574177f 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -1,92 +1,308 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - legacy_header_height="18" background_visible="true" default_tab_group="1" - follows="all" - height="350" + height="355" + help_topic="floater_im_box" layout="topleft" name="panel_im" can_dock="false" can_minimize="true" can_close="true" + save_rect="true" visible="false" width="394" can_resize="true" - min_width="250" - min_height="190"> + can_tear_off="false" + min_width="340" + min_height="190" + positioning="relative"> + <floater.string name="call_btn_start">Conv_toolbar_open_call</floater.string> + <floater.string name="call_btn_stop">Conv_toolbar_hang_up</floater.string> + <floater.string + name="collapse_icon" + value="Conv_toolbar_collapse"/> + <floater.string + name="expand_icon" + value="Conv_toolbar_expand"/> + <floater.string + name="tear_off_icon" + value="Conv_toolbar_arrow_ne"/> + <floater.string + name="return_icon" + value="Conv_toolbar_arrow_sw"/> + <floater.string + name="participant_added" + value="[NAME] was invited to the conversation."/> + <floater.string + name="multiple_participants_added" + value="[NAME] were invited to the conversation."/> + <floater.string + name="tooltip_to_separate_window" + value="Move this conversation to a separate window"/> + <floater.string + name="tooltip_to_main_window" + value="Move this conversation back to main window"/> + <floater.string + name="start_call_button_tooltip" + value="Open voice connection"/> + <floater.string + name="end_call_button_tooltip" + value="Close voice connection"/> + <floater.string + name="expcol_button_not_tearoff_tooltip" + value="Collapse this pane"/> + <floater.string + name="expcol_button_tearoff_and_expanded_tooltip" + value="Collapse participant list"/> + <floater.string + name="expcol_button_tearoff_and_collapsed_tooltip" + value="Expand participant list"/> + <view + follows="all" + layout="topleft" + name="contents_view" + top="0" + left="0" + height="355" + width="394"> + <panel + follows="left|top|right" + layout="topleft" + name="toolbar_panel" + top="0" + left="0" + height="35" + width="394"> + <menu_button + menu_filename="menu_im_session_showmodes.xml" + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_sort" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left="5" + name="view_options_btn" + tool_tip="View/sort options" + top="5" + width="31" /> + <menu_button + menu_filename="menu_im_conversation.xml" + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left_pad="4" + name="gear_btn" + visible="false" + tool_tip="Actions on selected person" + width="31"/> + <button + enabled="false" + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_add_person" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left_pad="4" + name="add_btn" + tool_tip="Add someone to this conversation" + width="31"/> + <button + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_open_call" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left_pad="4" + name="voice_call_btn" + tool_tip="Open voice connection" + width="31"/> + <output_monitor + auto_update="true" + follows="top|left" + draw_border="false" + height="16" + layout="topleft" + top="10" + left_pad="10" + mouse_opaque="true" + name="speaking_indicator" + visible="false" + width="20" /> + <button + follows="right|top" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_close" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left="283" + name="close_btn" + tool_tip="End this conversation" + width="31" /> + <button + follows="right|top" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_collapse" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left_pad="5" + name="expand_collapse_btn" + tool_tip="Collapse/Expand this pane" + width="31" /> + <button + follows="right|top" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_arrow_ne" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left_pad="5" + name="tear_off_btn" + width="31" /> + </panel> <layout_stack - animate="false" + animate="true" default_tab_group="2" follows="all" - height="320" + height="310" width="394" layout="topleft" orientation="horizontal" name="im_panels" tab_group="1" - top="20" + top_pad="0" left="0"> <layout_panel - name="im_control_panel_holder" + name="speakers_list_panel" + follows="all" min_width="115" width="150" - height="320" - auto_resize="false" - user_resize="false"> - <panel - name="panel_im_control_panel" - layout="topleft" - height="320" - width="150" - follows="all"/> + height="310" + user_resize="true" + auto_resize="true"> </layout_panel> <layout_panel default_tab_group="3" left="0" tab_group="2" + follows="all" top="0" - height="200" - width="254" - user_resize="true"> - <button - height="20" - follows="left|top" - top="0" - left="2" - image_overlay="TabIcon_Open_Off" + height="310" + width="244" + layout="topleft" + user_resize="true" + auto_resize="true" + visible="true" + name="left_part_holder" + min_width="221"> + <panel + name="trnsAndChat_panel" + follows="all" + layout="topleft" + visible="true" + height="275" + width="244"> + <layout_stack + animate="true" + default_tab_group="2" + follows="all" + height="275" + width="244" layout="topleft" - width="25" - name="slide_left_btn" /> - <button - height="20" - follows="left|top" + visible="true" + orientation="vertical" + name="translate_and_chat_stack" + tab_group="1" + left_pad="0" top="0" - left="2" - image_overlay="TabIcon_Close_Off" - width="25" - name="slide_right_btn" /> - <chat_history - font="SansSerifSmall" - follows="left|right|top|bottom" - height="150" - name="chat_history" - parse_highlights="true" - parse_urls="true" - left="1" - width="249"> - </chat_history> - <line_editor - bottom="0" - follows="left|right|bottom" - font="SansSerifSmall" - height="20" - label="To" - layout="bottomleft" - name="chat_editor" - tab_group="3" - width="249"> - </line_editor> + left="0"> + <layout_panel + auto_resize="false" + height="26" + layout="topleft" + left_delta="0" + name="translate_chat_checkbox_lp" + top_delta="0" + visible="true" + width="210"> + <check_box + top="10" + control_name="TranslateChat" + enabled="true" + height="16" + label="Translate chat" + layout="topleft" + left="5" + name="translate_chat_checkbox" + width="230" /> + </layout_panel> + <layout_panel + height="248" + width="210" + layout="topleft" + follows="all" + left_delta="0" + top_delta="0" + bottom="0" + visible="true" + user_resize="true" + auto_resize="true" + name="chat_holder"> + <chat_history + font="SansSerifSmall" + follows="all" + visible="true" + height="240" + name="chat_history" + parse_highlights="true" + parse_urls="true" + right="-5" + left="5"> + </chat_history> + </layout_panel> + </layout_stack> + </panel> + <chat_editor + bottom="0" + expand_lines_count="5" + follows="left|right|bottom" + font="SansSerifSmall" + visible="true" + height="20" + is_expandable="true" + label="To" + text_tentative_color="TextFgTentativeColor" + layout="bottomleft" + name="chat_editor" + max_length="1023" + spellcheck="true" + tab_group="3" + width="220" + left="10" + wrap="true"> + </chat_editor> </layout_panel> </layout_stack> + </view> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_image_preview.xml b/indra/newview/skins/default/xui/en/floater_image_preview.xml index 86232de1a4..44d2c14cc8 100644 --- a/indra/newview/skins/default/xui/en/floater_image_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_image_preview.xml @@ -2,7 +2,7 @@ <floater legacy_header_height="18" can_minimize="false" - height="440" + height="460" layout="topleft" name="Image Preview" help_topic="image_preview" @@ -108,7 +108,7 @@ <text type="string" length="1" - bottom="225" + bottom="250" height="45" word_wrap="true" follows="top|left" @@ -137,7 +137,7 @@ Try saving image as 24 bit Targa (.tga). layout="topleft" left="165" name="cancel_btn" - top="410" + top="430" width="125" /> <button follows="bottom|left" diff --git a/indra/newview/skins/default/xui/en/floater_incoming_call.xml b/indra/newview/skins/default/xui/en/floater_incoming_call.xml index 81194f61cf..a7864381a9 100644 --- a/indra/newview/skins/default/xui/en/floater_incoming_call.xml +++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml @@ -8,8 +8,8 @@ layout="topleft" name="incoming call" help_topic="incoming_call" - title="Incoming call" - width="410"> + sound_flags="0" + width="550"> <floater.string name="lifetime"> 5 @@ -24,7 +24,7 @@ </floater.string> <floater.string name="VoiceInviteP2P"> - is calling. + is calling you. </floater.string> <floater.string name="VoiceInviteAdHoc"> @@ -49,14 +49,14 @@ image_name="icon_avatar_online.tga" layout="topleft" left_delta="19" - top="35" + top="20" width="36" /> <group_icon enabled="false" follows="left|top" height="36" layout="topleft" - top="35" + top="20" width="36" /> <text clip_partial="true" @@ -67,43 +67,43 @@ name="caller name" top="20" use_ellipses="true" - width="315" + width="475" word_wrap="true" /> - <text - clip_partial="true" - font="SansSerif" - height="30" - layout="topleft" - left="77" - name="question" - top_pad="5" - use_ellipses="true" - width="315" - word_wrap="true"> - Do you want to leave [CURRENT_CHAT] and join this voice chat? - </text> - <button + <button height="24" - label="Accept" - label_selected="Accept" + label="Answer" + label_selected="Answer" layout="topleft" left="70" name="Accept" - top="92" - width="100" /> + top_pad="5" + width="120" /> <button height="24" - label="Reject" - label_selected="Reject" + label="Ignore" + label_selected="Ignore" layout="topleft" name="Reject" left_pad="10" - width="100" /> + width="120" /> <button height="24" - label="Start IM" + label="Open IM instead" layout="topleft" name="Start IM" left_pad="10" - width="100" /> + width="120" /> + <text + clip_partial="true" + font="SansSerif" + height="30" + layout="topleft" + left="77" + name="question" + top_pad="5" + use_ellipses="true" + width="475" + word_wrap="true"> + If you answer, you will be disconnected from your current voice conversation. + </text> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_joystick.xml b/indra/newview/skins/default/xui/en/floater_joystick.xml index 6e1bb8fcd0..59f6a9434c 100644 --- a/indra/newview/skins/default/xui/en/floater_joystick.xml +++ b/indra/newview/skins/default/xui/en/floater_joystick.xml @@ -13,6 +13,7 @@ </floater.string> <check_box bottom="38" + height="10" control_name="JoystickEnabled" halign="left" label="Enable Joystick:" @@ -28,6 +29,7 @@ width="380" /> <spinner bottom="48" + height="10" control_name="JoystickAxis1" decimal_digits="0" increment="1" @@ -41,6 +43,7 @@ width="140" /> <spinner bottom="48" + height="10" control_name="JoystickAxis2" decimal_digits="0" increment="1" @@ -54,6 +57,7 @@ width="140" /> <spinner bottom="48" + height="10" control_name="JoystickAxis0" decimal_digits="0" increment="1" @@ -67,6 +71,7 @@ width="140" /> <spinner bottom="68" + height="10" control_name="JoystickAxis4" decimal_digits="0" increment="1" @@ -80,6 +85,7 @@ width="140" /> <spinner bottom="68" + height="10" control_name="JoystickAxis5" decimal_digits="0" increment="1" @@ -93,6 +99,7 @@ width="140" /> <spinner bottom="68" + height="10" control_name="JoystickAxis3" decimal_digits="0" increment="1" @@ -106,6 +113,7 @@ width="140" /> <spinner bottom="88" + height="10" control_name="JoystickAxis6" decimal_digits="0" increment="1" @@ -119,6 +127,7 @@ width="140" /> <check_box bottom_delta="18" + height="10" control_name="ZoomDirect" label="Direct Zoom" layout="topleft" @@ -127,6 +136,7 @@ width="60" /> <check_box bottom_delta="0" + height="10" control_name="Cursor3D" label="3D Cursor" layout="topleft" @@ -135,6 +145,7 @@ width="60" /> <check_box bottom_delta="0" + height="10" control_name="AutoLeveling" label="Auto Level" layout="topleft" @@ -157,6 +168,7 @@ </text> <check_box bottom="127" + height="10" control_name="JoystickAvatarEnabled" halign="center" label="Avatar" @@ -166,6 +178,7 @@ width="60" /> <check_box bottom="127" + height="10" control_name="JoystickBuildEnabled" halign="center" label="Build" @@ -175,6 +188,7 @@ width="60" /> <check_box bottom="127" + height="10" control_name="JoystickFlycamEnabled" halign="center" label="Flycam" @@ -257,6 +271,7 @@ </text> <spinner bottom="144" + height="10" control_name="AvatarAxisScale1" decimal_digits="2" label_width="0" @@ -268,6 +283,7 @@ width="56" /> <spinner bottom="144" + height="10" control_name="BuildAxisScale1" decimal_digits="2" label_width="0" @@ -279,6 +295,7 @@ width="56" /> <spinner bottom="144" + height="10" control_name="FlycamAxisScale1" decimal_digits="2" label_width="0" @@ -301,6 +318,7 @@ </text> <spinner bottom="164" + height="10" control_name="AvatarAxisScale2" decimal_digits="2" label_width="0" @@ -312,6 +330,7 @@ width="56" /> <spinner bottom="164" + height="10" control_name="BuildAxisScale2" decimal_digits="2" label_width="0" @@ -323,6 +342,7 @@ width="56" /> <spinner bottom="164" + height="10" control_name="FlycamAxisScale2" decimal_digits="2" label_width="0" @@ -345,6 +365,7 @@ </text> <spinner bottom="184" + height="10" control_name="AvatarAxisScale0" decimal_digits="2" label_width="0" @@ -356,6 +377,7 @@ width="56" /> <spinner bottom="184" + height="10" control_name="BuildAxisScale0" decimal_digits="2" label_width="0" @@ -367,6 +389,7 @@ width="56" /> <spinner bottom="184" + height="10" control_name="FlycamAxisScale0" decimal_digits="2" label_width="0" @@ -389,6 +412,7 @@ </text> <spinner bottom="204" + height="10" control_name="AvatarAxisScale4" decimal_digits="2" label_width="0" @@ -400,6 +424,7 @@ width="56" /> <spinner bottom="204" + height="10" control_name="BuildAxisScale4" decimal_digits="2" label_width="0" @@ -411,6 +436,7 @@ width="56" /> <spinner bottom="204" + height="10" control_name="FlycamAxisScale4" decimal_digits="2" label_width="0" @@ -433,6 +459,7 @@ </text> <spinner bottom="224" + height="10" control_name="AvatarAxisScale5" decimal_digits="2" label_width="0" @@ -444,6 +471,7 @@ width="56" /> <spinner bottom="224" + height="10" control_name="BuildAxisScale5" decimal_digits="2" label_width="0" @@ -455,6 +483,7 @@ width="56" /> <spinner bottom="224" + height="10" control_name="FlycamAxisScale5" decimal_digits="2" label_width="0" @@ -477,6 +506,7 @@ </text> <spinner bottom="244" + height="10" control_name="BuildAxisScale3" decimal_digits="2" label_width="0" @@ -488,6 +518,7 @@ width="56" /> <spinner bottom="244" + height="10" control_name="FlycamAxisScale3" decimal_digits="2" label_width="0" @@ -510,6 +541,7 @@ </text> <spinner bottom="274" + height="10" control_name="AvatarAxisDeadZone1" decimal_digits="2" increment="0.01" @@ -520,6 +552,7 @@ width="56" /> <spinner bottom="274" + height="10" control_name="BuildAxisDeadZone1" decimal_digits="2" increment="0.01" @@ -530,6 +563,7 @@ width="56" /> <spinner bottom="274" + height="10" control_name="FlycamAxisDeadZone1" decimal_digits="2" increment="0.01" @@ -551,6 +585,7 @@ </text> <spinner bottom="294" + height="10" control_name="AvatarAxisDeadZone2" decimal_digits="2" increment="0.01" @@ -561,6 +596,7 @@ width="56" /> <spinner bottom="294" + height="10" control_name="BuildAxisDeadZone2" decimal_digits="2" increment="0.01" @@ -571,6 +607,7 @@ width="56" /> <spinner bottom="294" + height="10" control_name="FlycamAxisDeadZone2" decimal_digits="2" increment="0.01" @@ -592,6 +629,7 @@ </text> <spinner bottom="314" + height="10" control_name="AvatarAxisDeadZone0" decimal_digits="2" increment="0.01" @@ -602,6 +640,7 @@ width="56" /> <spinner bottom="314" + height="10" control_name="BuildAxisDeadZone0" decimal_digits="2" increment="0.01" @@ -612,6 +651,7 @@ width="56" /> <spinner bottom="314" + height="10" control_name="FlycamAxisDeadZone0" decimal_digits="2" increment="0.01" @@ -633,6 +673,7 @@ </text> <spinner bottom="334" + height="10" control_name="AvatarAxisDeadZone4" decimal_digits="2" increment="0.01" @@ -643,6 +684,7 @@ width="56" /> <spinner bottom="334" + height="10" control_name="BuildAxisDeadZone4" decimal_digits="2" increment="0.01" @@ -653,6 +695,7 @@ width="56" /> <spinner bottom="334" + height="10" control_name="FlycamAxisDeadZone4" decimal_digits="2" increment="0.01" @@ -674,6 +717,7 @@ </text> <spinner bottom="354" + height="10" control_name="AvatarAxisDeadZone5" decimal_digits="2" increment="0.01" @@ -684,6 +728,7 @@ width="56" /> <spinner bottom="354" + height="10" control_name="BuildAxisDeadZone5" decimal_digits="2" increment="0.01" @@ -694,6 +739,7 @@ width="56" /> <spinner bottom="354" + height="10" control_name="FlycamAxisDeadZone5" decimal_digits="2" increment="0.01" @@ -715,6 +761,7 @@ </text> <spinner bottom="374" + height="10" control_name="BuildAxisDeadZone3" decimal_digits="2" increment="0.01" @@ -725,6 +772,7 @@ width="56" /> <spinner bottom="374" + height="10" control_name="FlycamAxisDeadZone3" decimal_digits="2" increment="0.01" @@ -802,6 +850,7 @@ </text> <spinner bottom="430" + height="10" control_name="FlycamAxisScale6" decimal_digits="2" label_width="0" @@ -824,6 +873,7 @@ </text> <spinner bottom="450" + height="10" control_name="FlycamAxisDeadZone6" decimal_digits="2" increment="0.01" diff --git a/indra/newview/skins/default/xui/en/floater_land_holdings.xml b/indra/newview/skins/default/xui/en/floater_land_holdings.xml index 3737294ebe..390ec9ab7d 100644 --- a/indra/newview/skins/default/xui/en/floater_land_holdings.xml +++ b/indra/newview/skins/default/xui/en/floater_land_holdings.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="centered" + positioning="centered" legacy_header_height="18" height="430" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml index 1f192f9b28..5cd7cd196d 100644 --- a/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml +++ b/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml @@ -4,7 +4,6 @@ bevel_style="none" border_style="line" can_resize="true" - follows="left|top" height="580" layout="topleft" min_height="271" diff --git a/indra/newview/skins/default/xui/en/floater_lsl_guide.xml b/indra/newview/skins/default/xui/en/floater_lsl_guide.xml index c9d87f158f..e9676777f4 100644 --- a/indra/newview/skins/default/xui/en/floater_lsl_guide.xml +++ b/indra/newview/skins/default/xui/en/floater_lsl_guide.xml @@ -2,7 +2,6 @@ <floater legacy_header_height="18" can_resize="true" - follows="left|top" height="400" layout="topleft" min_height="271" diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml index 31972d4122..b8893e11d9 100644 --- a/indra/newview/skins/default/xui/en/floater_map.xml +++ b/indra/newview/skins/default/xui/en/floater_map.xml @@ -1,10 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="cascading" + positioning="cascading" can_minimize="true" can_resize="true" chrome="true" - follows="top|right" height="200" layout="topleft" min_height="128" 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_mem_leaking.xml b/indra/newview/skins/default/xui/en/floater_mem_leaking.xml index 28a29c42aa..fb7d09a21e 100644 --- a/indra/newview/skins/default/xui/en/floater_mem_leaking.xml +++ b/indra/newview/skins/default/xui/en/floater_mem_leaking.xml @@ -2,7 +2,6 @@ <floater legacy_header_height="18" can_minimize="false" - follows="left|top" height="175" layout="topleft" name="MemLeak" 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..b98f280b56 --- /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 + 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="top"> + 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="center" + 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="24" auto_resize="false"> + <layout_stack orientation="horizontal" left="0" height="24" top="0" width="333" follows="all"> + <layout_panel width="0" /> + <layout_panel width="24" auto_resize="false"> + <loading_indicator + height="24" + layout="topleft" + left="0" + top="0" + width="24" /> + </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_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index eebc5ddc72..5e92a12251 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1,8 +1,16 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater can_close="true" can_drag_on_left="false" can_minimize="false" - can_resize="false" height="480" min_height="480" min_width="940" - name="Model Preview" title="UPLOAD MODEL" width="940" - help_topic="upload_model" > +<floater + can_close="true" + can_drag_on_left="false" + can_minimize="false" + can_resize="false" + height="480" + min_height="480" + width="980" + min_width="980" + name="Model Preview" + title="UPLOAD MODEL" + help_topic="upload_model" > <string name="status_idle"></string> <string name="status_parse_error">Error: Dae parsing issue - see log for details.</string> @@ -98,7 +106,7 @@ top_pad="15" left="0" height="300" - width="625" + width="635" name="import_tab" tab_position="top"> <!-- LOD PANEL --> @@ -116,19 +124,19 @@ left="3" name="lod_tab_border" top_pad="0" - width="619" /> - <text - follows="left|top" - height="18" - initial_value="Source" - layout="topleft" - left="75" - name="source" - text_color="ModelUploaderLabels" - top="15" - valign="center" - value="Source" - width="335" /> + width="629" /> + <text + follows="left|top" + height="18" + initial_value="Source" + layout="topleft" + left="85" + name="source" + text_color="ModelUploaderLabels" + top="15" + valign="center" + value="Source" + width="335"/> <text follows="left|top" halign="right" @@ -163,9 +171,9 @@ name="high_label" text_color="ModelUploaderLabels" top_pad="10" - valign="center" + valign="top" value="High" - width="65" /> + width="75" /> <combo_box follows="top|left" height="20" @@ -175,10 +183,10 @@ top_delta="-3" width="135"> <item - id="Load from file" + name="Load from file" value="Load from file" /> <item - id="Generate" + name="Generate" value="Generate" /> </combo_box> <line_editor @@ -210,10 +218,10 @@ visible="false" width="135"> <item - id="Triangle Limit" + name="Triangle Limit" value="Triangle Limit" /> <item - id="Error Threshold" + name="Error Threshold" value="Error Threshold" /> </combo_box> <spinner @@ -240,34 +248,34 @@ <text follows="left|top" halign="right" - height="18" + height="15" initial_value="0" layout="topleft" left_pad="0" name="high_triangles" - valign="center" + valign="top" value="0" width="65" /> <text follows="left|top" halign="right" - height="18" + height="15" initial_value="0" layout="topleft" left_pad="0" name="high_vertices" - valign="center" + valign="top" value="0" width="65" /> <text follows="left|top" halign="center" - height="18" + height="15" initial_value="" layout="topleft" left_pad="0" name="high_status" - valign="center" + valign="top" value="" width="65" /> <icon @@ -277,7 +285,7 @@ left_delta="20" mouse_opaque="true" name="status_icon_high" - top_delta="0" + top_delta="-2" width="16" /> <text follows="left|top" @@ -288,9 +296,9 @@ name="medium_label" text_color="ModelUploaderLabels" top_pad="15" - valign="center" + valign="top" value="Medium" - width="65" /> + width="75" /> <combo_box follows="top|left" height="20" @@ -300,13 +308,13 @@ top_delta="-3" width="135"> <item - id="Load from file" + name="Load from file" value="Load from file" /> <item - id="Generate" + name="Generate" value="Generate" /> <item - id="Use LoD above" + name="Use LoD above" value="Use LoD above" /> </combo_box> <line_editor @@ -339,10 +347,10 @@ top_delta="0" width="135"> <item - id="Triangle Limit" + name="Triangle Limit" value="Triangle Limit" /> <item - id="Error Threshold" + name="Error Threshold" value="Error Threshold" /> </combo_box> <spinner @@ -368,34 +376,34 @@ <text follows="left|top" halign="right" - height="18" + height="15" initial_value="0" layout="topleft" left_pad="0" name="medium_triangles" - valign="center" + valign="top" value="0" width="65" /> <text follows="left|top" halign="right" - height="18" + height="15" initial_value="0" layout="topleft" left_pad="0" name="medium_vertices" - valign="center" + valign="top" value="0" width="65" /> <text follows="left|top" halign="center" - height="18" + height="15" initial_value="" layout="topleft" left_pad="0" name="medium_status" - valign="center" + valign="top" value="" width="65" /> <icon @@ -405,7 +413,7 @@ left_delta="20" mouse_opaque="true" name="status_icon_medium" - top_delta="0" + top_delta="-2" width="16" /> <text follows="left|top" @@ -416,9 +424,9 @@ name="low_label" text_color="ModelUploaderLabels" top_pad="15" - valign="center" + valign="top" value="Low" - width="65" /> + width="75" /> <combo_box follows="top|left" height="20" @@ -428,13 +436,13 @@ top_delta="-3" width="135"> <item - id="Load from file" + name="Load from file" value="Load from file" /> <item - id="Generate" + name="Generate" value="Generate" /> <item - id="Use LoD above" + name="Use LoD above" value="Use LoD above" /> </combo_box> <line_editor @@ -467,10 +475,10 @@ top_delta="0" width="135"> <item - id="Triangle Limit" + name="Triangle Limit" value="Triangle Limit" /> <item - id="Error Threshold" + name="Error Threshold" value="Error Threshold" /> </combo_box> <spinner @@ -496,34 +504,34 @@ <text follows="left|top" halign="right" - height="18" + height="15" initial_value="0" layout="topleft" left_pad="0" name="low_triangles" - valign="center" + valign="top" value="0" width="65" /> <text follows="left|top" halign="right" - height="18" + height="15" initial_value="0" layout="topleft" left_pad="0" name="low_vertices" - valign="center" + valign="top" value="0" width="65" /> <text follows="left|top" halign="center" - height="18" + height="15" initial_value="" layout="topleft" left_pad="0" name="low_status" - valign="center" + valign="top" value="" width="65" /> <icon @@ -533,7 +541,7 @@ left_delta="20" mouse_opaque="true" name="status_icon_low" - top_delta="0" + top_delta="-2" width="16" /> <text follows="left|top" @@ -544,9 +552,9 @@ name="lowest_label" text_color="ModelUploaderLabels" top_pad="15" - valign="center" + valign="top" value="Lowest" - width="65" /> + width="75" /> <combo_box follows="top|left" height="20" @@ -556,13 +564,13 @@ top_delta="-3" width="135"> <item - id="Load from file" + name="Load from file" value="Load from file" /> <item - id="Generate" + name="Generate" value="Generate" /> <item - id="Use LoD above" + name="Use LoD above" value="Use LoD above" /> </combo_box> <line_editor @@ -595,10 +603,10 @@ top_delta="0" width="135"> <item - id="Triangle Limit" + name="Triangle Limit" value="Triangle Limit" /> <item - id="Error Threshold" + name="Error Threshold" value="Error Threshold" /> </combo_box> <spinner @@ -624,34 +632,34 @@ <text follows="left|top" halign="right" - height="18" + height="15" initial_value="0" layout="topleft" left_pad="0" name="lowest_triangles" - valign="center" + valign="top" value="0" width="65" /> <text follows="left|top" halign="right" - height="18" + height="15" initial_value="0" layout="topleft" left_pad="0" name="lowest_vertices" - valign="center" + valign="top" value="0" width="65" /> <text follows="left|top" halign="center" - height="18" + height="15" initial_value="" layout="topleft" left_pad="0" name="lowest_status" - valign="center" + valign="top" value="" width="65" /> <icon @@ -1201,7 +1209,7 @@ name="calculate_btn" top="3" height="20" - width="150" + width="165" tool_tip="Calculate weights &fee"/> <button follows="top|left" @@ -1234,7 +1242,7 @@ right="-2" top="3" height="20" - width="155"/> + width="275"/> <!-- ========== WEIGHTS ==========--> <text follows="top|left" @@ -1343,7 +1351,7 @@ layout="topleft" name="right_panel" top_pad="5" - width="290"> + width="340"> <combo_box top_pad="3" follows="left|top" diff --git a/indra/newview/skins/default/xui/en/floater_model_wizard.xml b/indra/newview/skins/default/xui/en/floater_model_wizard.xml deleted file mode 100644 index 9c0af7d9ba..0000000000 --- a/indra/newview/skins/default/xui/en/floater_model_wizard.xml +++ /dev/null @@ -1,841 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - layout="topleft" - name="Model Wizard" - help_topic="model_wizard" - bg_opaque_image_overlay="0.5 0.5 0.5 1" - height="480" - save_rect="true" - title="UPLOAD MODEL WIZARD" - width="535"> - <button - top="32" - tab_stop="false" - left="410" - height="32" - name="upload_btn" - enabled="false" - label="5. Upload" - border="false" - image_unselected="BreadCrumbBtn_Right_Off" - image_selected="BreadCrumbBtn_Right_Press" - image_hover_unselected="BreadCrumbBtn_Right_Over" - image_disabled="BreadCrumbBtn_Right_Disabled" - image_disabled_selected="BreadCrumbBtn_Right_Disabled" - width="110"> - <button.commit_callback - function="Wizard.Upload"/> - </button> - <button - top="32" - left="310" - height="32" - tab_stop="false" - name="review_btn" - label="4. Review" - enabled="false" - border="false" - image_unselected="BreadCrumbBtn_Middle_Off" - image_selected="BreadCrumbBtn_Middle_Press" - image_hover_unselected="BreadCrumbBtn_Middle_Over" - image_disabled="BreadCrumbBtn_Middle_Disabled" - image_disabled_selected="BreadCrumbBtn_Middle_Disabled" - width="110"> - <button.commit_callback - function="Wizard.Review"/> - </button> - <button - top="32" - left="210" - height="32" - name="physics_btn" - label="3. Physics" - tab_stop="false" - enabled="false" - border="false" - image_unselected="BreadCrumbBtn_Middle_Off" - image_selected="BreadCrumbBtn_Middle_Press" - image_hover_unselected="BreadCrumbBtn_Middle_Over" - image_disabled="BreadCrumbBtn_Middle_Disabled" - image_disabled_selected="BreadCrumbBtn_Middle_Disabled" - width="110"> - <button.commit_callback - function="Wizard.Physics"/> - </button> - <button - top="32" - left="115" - name="optimize_btn" - label="2. Optimize" - tab_stop="false" - height="32" - border="false" - image_unselected="BreadCrumbBtn_Middle_Off" - image_selected="BreadCrumbBtn_Middle_Press" - image_hover_unselected="BreadCrumbBtn_Middle_Over" - image_disabled="BreadCrumbBtn_Middle_Disabled" - image_disabled_selected="BreadCrumbBtn_Middle_Disabled" - width="110"> - <button.commit_callback - function="Wizard.Optimize"/> - </button> - <button - top="32" - left="15" - name="choose_file_btn" - tab_stop="false" - enabled="false" - label="1. Choose File" - height="32" - image_unselected="BreadCrumbBtn_Left_Off" - image_selected="BreadCrumbBtn_Left_Press" - image_hover_unselected="BreadCrumbBtn_Left_Over" - image_disabled="BreadCrumbBtn_Left_Disabled" - image_disabled_selected="BreadCrumbBtn_Left_Disabled" - width="110"> - <button.commit_callback - function="Wizard.Choose"/> - </button> - <panel - height="388" - top_pad="0" - name="choose_file_panel" - visible="false" - width="535" - left="0"> - <panel - height="22" - top_pad="15" - width="505" - name="header_panel" - bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" - left="15"> - <text - width="200" - left="10" - top="3" - name="header_text" - text_color="White" - height="10" - font="SansSerifBig" - layout="topleft"> - Choose model file - </text> - </panel> - <panel - top_pad="14" - left="15" - height="310" - width="505" - name="content" - bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true"> - <text - height="32" - left="10" - name="advanced_users_text" - text_color="White" - top="15" - width="320" - word_wrap="true"> - Advanced users: If you are familiar with 3D content creation tools you may wish to use the Advanced Uploader. - </text> - <button - follows="left|top" - height="20" - label="Switch to Advanced" - layout="topleft" - left_delta="0" - name="switch_to_advanced" - top_pad="5" - width="130"> - </button> - <text - type="string" - length="1" - text_color="White" - follows="left|top" - top_pad="30" - height="10" - layout="topleft" - left_delta="0" - name="Cache location" - width="320"> - Choose model file to upload - </text> - <line_editor - border_style="line" - border_thickness="1" - follows="left|top" - font="SansSerifSmall" - height="20" - layout="topleft" - left_delta="0" - max_length="4096" - name="lod_file" - top_pad="5" - width="230" /> - <button - follows="left|top" - height="23" - label="Browse..." - label_selected="Browse..." - layout="topleft" - left_pad="5" - name="browse" - top_delta="-1" - width="85"> - </button> - <text - type="string" - length="1" - text_color="White" - follows="left|top" - top_pad="5" - height="10" - layout="topleft" - left="10" - name="Model types" - width="320"> - Second Life supports COLLADA (.dae) files - </text> - <!-- Placeholder panel for 3D preview render --> - <panel - top="30" - right="-10" - name="choose_file_preview_panel" - bevel_style="none" - highlight_light_color="0.09 0.09 0.09 1" - border="true" - border_style="line" - height="150" - follows="all" - width="150"> - </panel> - <text - top_pad="10" - width="130" - height="14" - left_delta="0" - text_color="White" - word_wrap="true"> - Dimensions (meters): - </text> - <text - top_pad="0" - width="160" - height="15" - font="SansSerifSmallBold" - text_color="White" - name="dimensions" - left_delta="0"> - X Y Z - </text> - <text - top_delta="0" - width="160" - height="15" - name="dimension_x" - left="356"/> - <text - top_delta="0" - width="160" - height="15" - name="dimension_y" - left="403"/> - <text - top_delta="0" - width="160" - height="15" - name="dimension_z" - left="450"/> - <text - height="16" - left="10" - name="warning_label" - text_color="Yellow" - top="200" - visible="false" - width="320"> - WARNING: - </text> - <text - height="50" - left="10" - name="warning_text" - top_pad="0" - visible="false" - width="320" - word_wrap="true"> - You will not be able to complete the final step of uploading this model to the Second Life servers. [secondlife:///app/floater/learn_more Find out how] to set up your account for mesh model uploads. - </text> - </panel> - </panel> - - - <panel - height="388" - top_delta="0" - name="optimize_panel" - visible="true" - width="535" - left="0"> - <panel - height="22" - top_pad="15" - name="header_panel" - width="505" - bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" - left="15"> - <text - width="200" - left="10" - name="header_text" - top="3" - text_color="White" - height="10" - font="SansSerifBig" - layout="topleft"> - Optimize model - </text> - </panel> - <text - top_pad="14" - width="460" - height="20" - font="SansSerifSmall" - layout="topleft" - name="description" - word_wrap="true" - left_delta="5"> - We have optimized the model for performance. Adjust it further if you wish. - </text> - <panel - top_delta="40" - visible="false" - left="15" - height="270" - width="505" - name="content" - bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true"> - <text - top="20" - width="300" - height="12" - font="SansSerifBold" - left="112">Generating Level of Detail</text> - <progress_bar - name="optimize_progress_bar" - image_fill="model_wizard\progress_light.png" - color_bg="1 1 1 1" - color_bar="1 1 1 0.96" - follows="left|right|top" - width="260" - height="16" - image_bar="model_wizard\progress_bar_bg.png" - top_pad="14" - left="110"/> - <icon - top_pad="10" - left_delta="0" - width="13" - height="12" - image_name="model_wizard\check_mark.png"/> - <text - top_delta="0" - left_delta="18" - name="high_detail_text" - width="200" - height="14">Generate Level of Detail: High</text> - <icon - top_pad="10" - left_delta="-18" - width="13" - height="12" - image_name="model_wizard\check_mark.png"/> - <text - top_delta="0" - left_delta="18" - name="medium_detail_text" - width="200" - height="14">Generate Level of Detail: Medium</text> - <icon - top_pad="10" - left_delta="-18" - width="13" - height="12" - image_name="model_wizard\check_mark.png"/> - <text - top_delta="0" - left_delta="18" - name="low_detail_text" - width="200" - height="14">Generate Level of Detail: Low</text> - <icon - top_pad="10" - left_delta="-18" - width="13" - height="12" - image_name="model_wizard\check_mark.png"/> - <text - top_delta="0" - left_delta="18" - name="lowest_detail_text" - width="200" - height="14">Generate Level of Detail: Lowest</text> - </panel> - <panel - top_delta="0" - left_delta="0" - height="270" - width="505" - name="content2" - bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true"> - <text top="69" left="10" text_color="White" font="SansSerifSmallBold" width="120" height="16" wrap="true">Performance</text> - <text top="85" left="10" width="120" word_wrap="true" font="SansSerifSmall" height="40">Faster rendering -Less detail -Lower prim weight</text> - <text top="69" left="184" text_color="White" font="SansSerifSmallBold" width="120" height="16" wrap="true">Accuracy</text> - <text top="85" left="184" width="120" word_wrap="true" font="SansSerifSmall" height="40">Slower rendering -More detail -Higher prim weight</text> - - <slider - follows="left|top" - height="20" - increment="1" - layout="topleft" - left="10" - max_val="2" - initial_value="1" - min_val="0" - name="accuracy_slider" - show_text="false" - top="130" - width="290" /> - <text - font="SansSerifSmall" - top_pad="0" - width="5" - left_delta="6" - height="4">' - </text> - <text - font="SansSerifSmall" - top_delta="0" - width="5" - left_delta="137" - height="4">' - </text> - <text - font="SansSerifSmall" - top_delta="0" - width="5" - left_delta="137" - height="4">' - </text> - <button - follows="left|top" - height="20" - label="Recalculate Geometry" - layout="topleft" - left="80" - name="recalculate_geometry_btn" - top_pad="15" - width="150"> - </button> - <text top="10" right="-10" width="185" text_color="White" follows="left|top" height="15" name="lod_label"> - Geometry preview - </text> - <panel - right="-10" - top="32" - name="optimize_preview_panel" - bevel_style="none" - highlight_light_color="0.09 0.09 0.09 1" - border_style="line" - border="true" - height="185" - follows="all" - width="185"> - </panel> - <combo_box left_delta="75" top_pad="10" follows="left|top" list_position="below" height="22" - name="preview_lod_combo" width="110" tool_tip="LOD to view in preview render"> - <combo_item name="high"> - High detail - </combo_item> - <combo_item name="medium"> - Medium detail - </combo_item> - <combo_item name="low"> - Low detail - </combo_item> - <combo_item name="lowest"> - Lowest detail - </combo_item> - </combo_box> - </panel> - </panel> - - <panel - height="388" - top_delta="0" - name="physics_panel" - visible="false" - width="535" - left="0"> - <panel - height="22" - top_pad="15" - name="header_panel" - width="505" - bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" - left="15"> - <text - width="200" - left="10" - name="header_text" - top="3" - height="10" - font="SansSerifBig" - text_color="White" - layout="topleft"> - Adjust physics - </text> - </panel> - <text - top_pad="10" - width="474" - height="50" - font="SansSerifSmall" - layout="topleft" - name="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. - </text> - <panel - top_delta="44" - left="15" - height="270" - width="505" - name="content" - bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true"> - <text top="10" left="10" text_color="White" font="SansSerifSmallBold" width="120" halign="right" height="16" wrap="true">Performance</text> - <text top="26" left="10" width="120" word_wrap="true" font="SansSerifSmall" halign="right" height="40">Faster rendering -Less detail -Lower prim weight</text> - <text top="174" left="10" text_color="White" font="SansSerifSmallBold" width="120" halign="right" height="16" wrap="true">Accuracy</text> - <text top="190" left="10" width="120" word_wrap="true" font="SansSerifSmall" halign="right" height="40">Slower rendering -More detail -Higher prim weight</text> - - <slider - follows="left|top" - height="190" - increment=".1" - layout="topleft" - left="140" - max_val="1" - initial_value="0.5" - min_val="0" - name="physics_slider" - orientation="vertical" - show_text="false" - top="25" - width="22" /> - <text top="10" width="120" word_wrap="true" left_pad="10" height="50">Examples: -Moving objects -Flying objects -Vehicles</text> - <text top="95" width="120" word_wrap="true" left_delta="0" height="50">Examples: -Small static objects -Less detailed objects -Simple furniture</text> - <text top="180" width="120" word_wrap="true" left_delta="0" height="50">Examples: -Static objects -Detailed objects -Buildings</text> - <button - follows="left|top" - height="20" - label="Recalculate physics" - layout="topleft" - left="80" - name="recalculate_physics_btn" - top_pad="10" - width="150"> - </button> - <button - enabled="false" - follows="left|top" - height="20" - label="Recalculating..." - layout="topleft" - left_delta="0" - name="recalculating_physics_btn" - top_delta="0" - visible="false" - width="150"> - </button> - <text top="10" right="-10" width="185" text_color="White" follows="left|top" height="15" name="lod_label"> - Physics preview - </text> - <panel - right="-10" - top="32" - name="physics_preview_panel" - bevel_style="none" - highlight_light_color="0.09 0.09 0.09 1" - border_style="line" - border="true" - height="185" - follows="all" - width="185"> - </panel> - <combo_box left_delta="75" top_pad="10" follows="left|top" list_position="below" height="22" - name="preview_lod_combo2" width="110" tool_tip="LOD to view in preview render"> - <combo_item name="high"> - High detail - </combo_item> - <combo_item name="medium"> - Medium detail - </combo_item> - <combo_item name="low"> - Low detail - </combo_item> - <combo_item name="lowest"> - Lowest detail - </combo_item> - </combo_box> - </panel> - </panel> - - <panel - height="388" - top_delta="0" - name="review_panel" - visible="false" - width="535" - left="0"> - <panel - height="22" - top_pad="15" - name="header_panel" - width="505" - bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" - left="15"> - <text - width="200" - left="10" - name="header_text" - text_color="White" - top="3" - height="10" - font="SansSerifBig" - layout="topleft"> - Review - </text> - </panel> - <panel - top_pad="14" - left="15" - height="310" - width="505" - name="content" - bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true"> - <text - top="20" - width="485" - font="SansSerifMedium" - text_color="White" - left="10" - name="review_prim_equiv" - height="16">Impact to parcel/region: [EQUIV] prim equivalents - </text> - <text - top_pad="20" - width="485" - font="SansSerifMedium" - text_color="White" - left="10" - name="review_fee" - height="16">Your account will be charged an upload fee of L$ [FEE]. - </text> - <text - top_pad="20" - width="485" - font="SansSerifMedium" - text_color="White" - left="10" - name="review_confirmation" - height="32" - word_wrap="true">By clicking the upload button, you confirm that you have the appropriate rights to the material contained in the model. - </text> - </panel> - </panel> - - - - - <panel - height="388" - top_delta="0" - name="upload_panel" - visible="false" - width="535" - left="0"> - <panel - height="22" - top_pad="15" - name="header_panel" - width="505" - bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" - left="15"> - <text - width="200" - left="10" - name="header_text" - top="3" - text_color="White" - height="10" - font="SansSerifBig" - layout="topleft"> - Upload complete - </text> - </panel> - <text - top_pad="14" - width="495" - height="16" - font="SansSerifMedium" - layout="topleft" - name="model_uploaded_text" - text_color="White" - word_wrap="true" - left="25"> - Your model has been uploaded. - </text> - <text - top_pad="5" - width="495" - height="16" - font="SansSerifMedium" - layout="topleft" - name="inventory_text" - text_color="White" - word_wrap="true" - left="25"> - You will find it in the Objects folder in your inventory. - </text> - <text - top_pad="20" - width="495" - font="SansSerifMedium" - text_color="White" - left="25" - name="charged_fee" - height="16">Your account has been charged L$ [FEE]. - </text> - </panel> - - - - <button - top="440" - right="-285" - width="90" - height="22" - name="back" - label="<< Back" /> - <button - top_delta="0" - right="-190" - width="90" - height="22" - name="next" - label="Next >> " /> - <button - top_delta="0" - left_delta="0" - width="160" - height="22" - name="calculate" - label="Calculate weights & fee >> " /> - <button - enabled="false" - visible="false" - top_delta="0" - left_delta="0" - width="160" - height="22" - name="calculating" - label="Calculating... " /> - <button - enabled="false" - top_delta="0" - right="-150" - width="90" - height="22" - visible="false" - name="upload" - tool_tip="Upload to simulator" - label="Upload" /> - <button - top_delta="0" - right="-15" - width="90" - height="22" - name="cancel" - label="Cancel" /> - <button - top_delta="0" - right="-15" - width="90" - height="22" - name="close" - visible="false" - label="Close" /> - <spinner visible="false" left="10" height="20" follows="top|left" width="80" top_pad="-50" value="1.0" min_val="0.01" max_val="64.0" name="import_scale"/> - - <string name="status_idle">Idle</string> - <string name="status_parse_error">Dae parsing issue - see log for details.</string> - <string name="status_reading_file">Loading...</string> - <string name="status_generating_meshes">Generating Meshes...</string> - <string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string> - <string name="bad_element">Error: element is invalid</string> - <string name="high">High</string> - <string name="medium">Medium</string> - <string name="low">Low</string> - <string name="lowest">Lowest</string> - <string name="mesh_status_good">Ship it!</string> - <string name="mesh_status_na">N/A</string> - <string name="mesh_status_none">None</string> - <string name="mesh_status_submesh_mismatch">Levels of detail have a different number of textureable faces.</string> - <string name="mesh_status_mesh_mismatch">Levels of detail have a different number of mesh instances.</string> - <string name="mesh_status_too_many_vertices">Level of detail has too many vertices.</string> - <string name="mesh_status_missing_lod">Missing required level of detail.</string> - <string name="layer_all">All</string> - <!-- Text to display in physics layer combo box for "all layers" --> - -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_moveview.xml b/indra/newview/skins/default/xui/en/floater_moveview.xml index e96039a3e1..5e84283ab0 100644 --- a/indra/newview/skins/default/xui/en/floater_moveview.xml +++ b/indra/newview/skins/default/xui/en/floater_moveview.xml @@ -1,13 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="specified" - specified_left="558" - specified_bottom="80" + positioning="specified" + right="-693" + bottom="-50" legacy_header_height="18" can_dock="false" can_minimize="true" can_close="true" - follows="bottom" height="110" layout="topleft" name="move_floater" @@ -16,7 +15,7 @@ save_visibility="true" single_instance="true" chrome="true" - title="MOVE" + title="WALK / RUN / FLY" width="133"> <string name="walk_forward_tooltip"> diff --git a/indra/newview/skins/default/xui/en/floater_my_appearance.xml b/indra/newview/skins/default/xui/en/floater_my_appearance.xml index a40393aed8..fdea7a821a 100644 --- a/indra/newview/skins/default/xui/en/floater_my_appearance.xml +++ b/indra/newview/skins/default/xui/en/floater_my_appearance.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <floater - open_positioning="cascading" + positioning="cascading" legacy_header_height="18" can_resize="true" height="588" @@ -12,7 +12,7 @@ single_instance="true" reuse_instance="true" title="APPEARANCE" - min_height="260" + min_height="440" min_width="333" width="333"> <panel diff --git a/indra/newview/skins/default/xui/en/floater_my_inventory.xml b/indra/newview/skins/default/xui/en/floater_my_inventory.xml index cd0b59dc51..178987962b 100644 --- a/indra/newview/skins/default/xui/en/floater_my_inventory.xml +++ b/indra/newview/skins/default/xui/en/floater_my_inventory.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <floater - open_positioning="cascading" + positioning="cascading" can_close="true" can_resize="true" height="570" help_topic="sidebar_inventory" min_width="333" - min_height="440" + min_height="570" name="floater_my_inventory" save_rect="true" save_visibility="true" diff --git a/indra/newview/skins/default/xui/en/floater_my_web_profile.xml b/indra/newview/skins/default/xui/en/floater_my_web_profile.xml new file mode 100644 index 0000000000..df46fc198f --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_my_web_profile.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater name="floater_my_web_profile" + help_topic="web_profile" + width="780" + height="775" + save_rect="true" + single_instance="true" + reuse_instance="false" + filename="floater_web_content.xml"/>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..46ee113b69 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_pathfinding_characters.xml @@ -0,0 +1,209 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + positioning="cascading" + can_resize="true" + can_tear_off="false" + height="273" + width="635" + min_height="273" + min_width="635" + layout="topleft" + name="floater_pathfinding_characters" + help_topic="floater_pathfinding_characters" + reuse_instance="true" + save_rect="false" + single_instance="true" + title="Pathfinding characters"> + <floater.string name="messaging_initial"></floater.string> + <floater.string name="messaging_get_inprogress">Querying for pathfinding characters ...</floater.string> + <floater.string name="messaging_get_error">Error detected while querying for pathfinding characters.</floater.string> + <floater.string name="messaging_set_inprogress"></floater.string> + <floater.string name="messaging_set_error"></floater.string> + <floater.string name="messaging_complete_none_found">No pathfinding characters.</floater.string> + <floater.string name="messaging_complete_available">[NUM_SELECTED] characters selected out of [NUM_TOTAL].</floater.string> + <floater.string name="messaging_not_enabled">This region is not enabled for pathfinding.</floater.string> + <floater.string name="character_cpu_time">[CPU_TIME] µs</floater.string> + <floater.string name="character_owner_loading">[Loading]</floater.string> + <floater.string name="character_owner_unknown">[Unknown]</floater.string> + <floater.string name="character_owner_group">[group]</floater.string> + <panel + border="false" + bevel_style="none" + follows="left|top|right|bottom" + layout="topleft" + height="191" + width="635"> + <scroll_list + column_padding="0" + draw_heading="true" + follows="all" + height="135" + layout="topleft" + left="18" + top_pad="10" + tab_stop="false" + multi_select="true" + name="objects_scroll_list" + width="600"> + <scroll_list.columns + label="Name" + name="name" + dynamic_width="true" /> + <scroll_list.columns + label="Description" + name="description" + width="172" /> + <scroll_list.columns + label="Owner" + name="owner" + width="141" /> + <scroll_list.columns + label="CPU" + name="cpu_time" + width="60" /> + <scroll_list.columns + label="Altitude" + name="altitude" + width="64" /> + </scroll_list> + <text + height="26" + word_wrap="true" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + length="1" + follows="left|bottom|right" + layout="topleft" + name="messaging_status" + top_pad="17" + width="238"> + Characters: + </text> + <button + follows="right|bottom" + height="21" + label="Refresh list" + layout="topleft" + name="refresh_objects_list" + top_pad="-29" + left_pad="0" + width="115"/> + <button + follows="right|bottom" + height="21" + label="Select all" + layout="topleft" + name="select_all_objects" + top_pad="-21" + left_pad="8" + width="115"/> + <button + follows="right|bottom" + height="21" + label="Select none" + layout="topleft" + name="select_none_objects" + top_pad="-21" + left_pad="8" + width="115"/> + </panel> + <view_border + bevel_style="none" + follows="left|right|bottom" + height="0" + layout="topleft" + name="horiz_separator" + top_pad="0" + left="18" + width="600"/> + <panel + border="false" + bevel_style="none" + follows="left|right|bottom" + layout="topleft" + left="0" + height="67" + width="635"> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + length="1" + follows="left|bottom|right" + layout="topleft" + name="actions_label" + left="18" + top_pad="8" + width="242"> + Actions on selected characters: + </text> + <check_box + height="19" + follows="left|bottom" + label="Show beacon" + layout="topleft" + name="show_beacon" + top_pad="-16" + left_pad="0" + width="150" /> + <check_box + height="19" + follows="left|bottom" + label="Show physics capsule" + layout="topleft" + name="show_physics_capsule" + top_pad="-19" + left_pad="0" + width="150" /> + <button + follows="left|bottom" + height="22" + label="Take" + layout="topleft" + name="take_objects" + top_pad="9" + left="18" + width="94"/> + <button + follows="left|bottom" + height="22" + label="Take copy" + layout="topleft" + name="take_copy_objects" + top_pad="-22" + left_pad="6" + width="94"/> + <button + follows="left|bottom" + height="22" + label="Teleport me to it" + layout="topleft" + name="teleport_me_to_object" + tool_tip="Enabled only when one character is selected." + top_pad="-22" + left_pad="26" + width="159"/> + <button + follows="right|bottom" + height="22" + label="Return" + layout="topleft" + name="return_objects" + top_pad="-22" + left_pad="26" + width="94"/> + <button + follows="right|bottom" + height="22" + label="Delete" + layout="topleft" + name="delete_objects" + top_pad="-22" + left_pad="6" + width="94"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml new file mode 100644 index 0000000000..79f2027c31 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml @@ -0,0 +1,419 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + positioning="cascading" + can_tear_off="false" + height="498" + layout="topleft" + name="floater_pathfinding_console" + help_topic="floater_pathfinding_console" + reuse_instance="true" + save_rect="true" + single_instance="true" + title="Pathfinding view / test" + width="240"> + <floater.string name="navmesh_viewer_status_unknown"></floater.string> + <floater.string name="navmesh_viewer_status_library_not_implemented">Cannot find pathing library implementation.</floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled">This region is not enabled for pathfinding.</floater.string> + <floater.string name="navmesh_viewer_status_region_loading">Waiting for the region to finish loading.</floater.string> + <floater.string name="navmesh_viewer_status_checking_version">Checking the status of the navmesh.</floater.string> + <floater.string name="navmesh_viewer_status_downloading">Downloading the navmesh.</floater.string> + <floater.string name="navmesh_viewer_status_updating">The navmesh has changed on the server. Downloading the latest navmesh.</floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh">Latest navmesh has been downloaded.</floater.string> + <floater.string name="navmesh_viewer_status_error">Unable to download navmesh successfully.</floater.string> + <floater.string name="navmesh_simulator_status_unknown"></floater.string> + <floater.string name="navmesh_simulator_status_pending">Navmesh has pending changes.</floater.string> + <floater.string name="navmesh_simulator_status_building">Navmesh is building.</floater.string> + <floater.string name="navmesh_simulator_status_some_pending">Some navmesh regions have pending changes.</floater.string> + <floater.string name="navmesh_simulator_status_some_building">Some navmesh regions are building.</floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building">Some navmesh regions have pending changes and others are building.</floater.string> + <floater.string name="navmesh_simulator_status_complete">Navmesh is up-to-date.</floater.string> + <floater.string name="pathing_unknown"></floater.string> + <floater.string name="pathing_library_not_implemented">Cannot find pathing library implementation.</floater.string> + <floater.string name="pathing_region_not_enabled">This region is not enabled for pathfinding.</floater.string> + <floater.string name="pathing_choose_start_and_end_points">Please choose start and end points.</floater.string> + <floater.string name="pathing_choose_start_point">Please choose start point.</floater.string> + <floater.string name="pathing_choose_end_point">Please choose end point.</floater.string> + <floater.string name="pathing_path_valid">Path is shown in orange.</floater.string> + <floater.string name="pathing_path_invalid">A path between the chosen points cannot be found.</floater.string> + <floater.string name="pathing_error">An error occurred during path generation.</floater.string> + <panel + border="false" + bevel_style="none" + follows="left|top" + layout="topleft" + left="12" + top_pad="10" + height="61" + width="214"> + <text + height="13" + word_wrap="true" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + length="1" + layout="topleft" + left="0" + top_pad="0" + width="214"> + Viewer status + </text> + <text + height="40" + word_wrap="true" + use_ellipses="false" + type="string" + text_color="PathfindingGoodColor" + length="1" + follows="left|top" + layout="topleft" + left="0" + name="pathfinding_viewer_status" + top_pad="8" + width="214"> + </text> + </panel> + <panel + border="false" + bevel_style="none" + follows="left|top" + layout="topleft" + left="12" + height="66" + width="214"> + <text + height="13" + word_wrap="true" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + length="1" + layout="topleft" + left="0" + top_pad="5" + width="214"> + Simulator status + </text> + <text + height="40" + word_wrap="true" + use_ellipses="false" + type="string" + text_color="PathfindingGoodColor" + length="1" + follows="left|top" + layout="topleft" + left="0" + name="pathfinding_simulator_status" + top_pad="8" + width="214"> + </text> + </panel> + <view_border + bevel_style="none" + follows="top|left" + layout="topleft" + left="12" + top="179" + height="305" + width="213" + visible="true" /> + <tab_container + follows="left|top" + layout="topleft" + tab_position="top" + name="view_test_tab_container" + left="12" + top="157" + height="328" + width="214"> + <panel + border="false" + bevel_style="none" + follows="left|top" + layout="topleft" + name="view_panel" + label="View"> + <text + height="13" + word_wrap="true" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="show_label" + length="1" + follows="left|top" + layout="topleft" + top_pad="20" + left="12" + width="200"> + Show: + </text> + <check_box + height="19" + label="Test" + layout="topleft" + name="show_world" + top_pad="4" + width="90" /> + <check_box + height="19" + label="Movables only" + layout="topleft" + left="32" + name="show_world_movables_only" + top_pad="4" + width="90" /> + <check_box + height="19" + label="Navmesh" + left="12" + layout="topleft" + name="show_navmesh" + top_pad="7" + width="90" /> + <text + height="13" + word_wrap="true" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="show_walkability_label" + length="1" + follows="left|top" + layout="topleft" + left="32" + width="180"> + Show walkability map: + </text> + <combo_box + height="19" + layout="topleft" + left="32" + name="show_heatmap_mode" + top_pad="8" + width="156"> + <combo_box.item + label="Do not show" + name="show_heatmap_mode_none" + value="0" /> + <combo_box.item + label="Character type A" + name="show_heatmap_mode_a" + value="1" /> + <combo_box.item + label="Character type B" + name="show_heatmap_mode_b" + value="2" /> + <combo_box.item + label="Character type C" + name="show_heatmap_mode_c" + value="3" /> + <combo_box.item + label="Character type D" + name="show_heatmap_mode_d" + value="4" /> + </combo_box> + <check_box + height="19" + label="Walkables" + layout="topleft" + left="12" + name="show_walkables" + top_pad="10" + width="90" /> + <check_box + height="19" + label="Material volumes" + layout="topleft" + name="show_material_volumes" + top_pad="4" + width="90" /> + <check_box + height="19" + label="Static obstacles" + layout="topleft" + name="show_static_obstacles" + top_pad="4" + width="90" /> + <check_box + height="19" + label="Exclusion volumes" + layout="topleft" + name="show_exclusion_volumes" + top_pad="4" + width="90" /> + <check_box + height="19" + label="Water plane" + layout="topleft" + name="show_water_plane" + top_pad="4" + width="90" /> + <check_box + height="19" + label="With X-ray vision" + layout="topleft" + name="show_xray" + top_pad="4" + width="90" /> + </panel> + <panel + border="false" + bevel_style="none" + follows="left|top" + layout="topleft" + name="test_panel" + label="Test path"> + <text + height="14" + word_wrap="true" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="ctrl_click_label" + length="1" + left="12" + follows="left|top" + layout="topleft" + top_pad="20" + width="202"> + Ctrl-click to select start point. + </text> + <text + height="14" + word_wrap="true" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="shift_click_label" + length="1" + follows="left|top" + layout="topleft" + top_pad="5" + width="202"> + Shift-click to select end point. + </text> + <view_border + bevel_style="none" + follows="top|left" + layout="topleft" + height="0" + width="185" + top_pad="13" + visible="true" /> + <text + height="14" + word_wrap="true" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="character_width_label" + length="1" + follows="left|top" + layout="topleft" + top_pad="14" + width="202"> + Character width + </text> + <slider + decimal_digits="1" + height="14" + increment="0.1" + layout="topleft" + follows="left|top" + max_val="2" + min_val="0.2" + name="character_width" + top_pad="5" + value="1" + width="145" /> + <text + height="14" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="character_width_unit_label" + length="1" + follows="left|top" + layout="topleft" + top_pad="-14" + left_pad="0" + width="20"> + m + </text> + <text + height="14" + word_wrap="true" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="character_type_label" + length="1" + follows="left|top" + layout="topleft" + left_pad="-165" + top_pad="13" + width="202"> + Character type + </text> + <combo_box + follows="top|left" + layout="topleft" + height="19" + width="156" + top_pad="5" + name="path_character_type"> + <combo_box.item + label="None" + name="path_character_type_none" + value="0" /> + <combo_box.item + label="A" + name="path_character_type_a" + value="1" /> + <combo_box.item + label="B" + name="path_character_type_b" + value="2" /> + <combo_box.item + label="C" + name="path_character_type_c" + value="3" /> + <combo_box.item + label="D" + name="path_character_type_d" + value="4" /> + </combo_box> + <text + height="14" + word_wrap="true" + use_ellipses="false" + type="string" + text_color="PathfindingGoodColor" + length="1" + follows="left|top" + layout="topleft" + name="path_test_status" + top_pad="11" + width="202"> + </text> + <button + follows="left|top" + height="22" + label="Clear path" + layout="topleft" + name="clear_path" + top_pad="27" + width="96"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..4a457fb929 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml @@ -0,0 +1,597 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + positioning="cascading" + can_resize="true" + can_tear_off="false" + height="395" + width="1075" + min_height="395" + min_width="990" + layout="topleft" + name="floater_pathfinding_linksets" + help_topic="floater_pathfinding_linksets" + reuse_instance="true" + save_rect="false" + single_instance="true" + title="Pathfinding linksets"> + <floater.string name="messaging_initial"></floater.string> + <floater.string name="messaging_get_inprogress">Querying for pathfinding linksets ...</floater.string> + <floater.string name="messaging_get_error">Error detected while querying for pathfinding linksets.</floater.string> + <floater.string name="messaging_set_inprogress">Modifying selected pathfinding linksets ...</floater.string> + <floater.string name="messaging_set_error">Error detected while modifying selected pathfinding linksets.</floater.string> + <floater.string name="messaging_complete_none_found">No pathfinding linksets.</floater.string> + <floater.string name="messaging_complete_available">[NUM_SELECTED] linksets selected out of [NUM_TOTAL].</floater.string> + <floater.string name="messaging_not_enabled">This region is not enabled for pathfinding.</floater.string> + <floater.string name="linkset_terrain_name">[Terrain]</floater.string> + <floater.string name="linkset_terrain_description">--</floater.string> + <floater.string name="linkset_terrain_owner">--</floater.string> + <floater.string name="linkset_terrain_scripted">--</floater.string> + <floater.string name="linkset_terrain_land_impact">--</floater.string> + <floater.string name="linkset_terrain_dist_from_you">--</floater.string> + <floater.string name="linkset_owner_loading">[Loading]</floater.string> + <floater.string name="linkset_owner_unknown">[Unknown]</floater.string> + <floater.string name="linkset_owner_group">[group]</floater.string> + <floater.string name="linkset_is_scripted">Yes</floater.string> + <floater.string name="linkset_is_not_scripted">No</floater.string> + <floater.string name="linkset_is_unknown_scripted">Unknown</floater.string> + <floater.string name="linkset_use_walkable">Walkable</floater.string> + <floater.string name="linkset_use_static_obstacle">Static obstacle</floater.string> + <floater.string name="linkset_use_dynamic_obstacle">Movable obstacle</floater.string> + <floater.string name="linkset_use_material_volume">Material volume</floater.string> + <floater.string name="linkset_use_exclusion_volume">Exclusion volume</floater.string> + <floater.string name="linkset_use_dynamic_phantom">Movable phantom</floater.string> + <floater.string name="linkset_is_terrain">[unmodifiable]</floater.string> + <floater.string name="linkset_is_restricted_state">[restricted]</floater.string> + <floater.string name="linkset_is_non_volume_state">[concave]</floater.string> + <floater.string name="linkset_is_restricted_non_volume_state">[restricted,concave]</floater.string> + <floater.string name="linkset_choose_use">Choose linkset use...</floater.string> + <panel + border="false" + bevel_style="none" + follows="left|top|right|bottom" + layout="topleft" + height="226" + width="1059"> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + length="1" + follows="left|top" + layout="topleft" + left="20" + top_pad="14" + width="67"> + Filter by: + </text> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + length="1" + follows="left|top" + layout="topleft" + left_pad="0" + width="62"> + Name + </text> + <line_editor + border_style="line" + border_thickness="1" + follows="left|top" + height="20" + layout="topleft" + left_pad="0" + top_pad="-18" + max_length_chars="255" + name="filter_by_name" + width="161" /> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + length="1" + follows="left|top" + layout="topleft" + left_pad="22" + top_pad="-15" + width="88"> + Description + </text> + <line_editor + border_style="line" + border_thickness="1" + follows="left|top" + height="20" + layout="topleft" + left_pad="0" + top_pad="-17" + max_length_chars="255" + name="filter_by_description" + width="162" /> + <combo_box + height="20" + layout="topleft" + follows="left|top" + name="filter_by_linkset_use" + left_pad="32" + top_pad="-20" + width="199"> + <combo_box.item + label="Filter by linkset use..." + name="filter_by_linkset_use_none" + value="0" /> + <combo_box.item + label="Walkable" + name="filter_by_linkset_use_walkable" + value="1" /> + <combo_box.item + label="Static obstacle" + name="filter_by_linkset_use_static_obstacle" + value="2" /> + <combo_box.item + label="Movable obstacle" + name="filter_by_linkset_use_dynamic_obstacle" + value="3" /> + <combo_box.item + label="Material volume" + name="filter_by_linkset_use_material_volume" + value="4" /> + <combo_box.item + label="Exclusion volume" + name="filter_by_linkset_use_exclusion_volume" + value="5" /> + <combo_box.item + label="Movable phantom" + name="filter_by_linkset_use_dynamic_phantom" + value="6" /> + </combo_box> + <button + follows="right|top" + height="21" + label="Apply" + layout="topleft" + name="apply_filters" + top_pad="-21" + left_pad="91" + width="73"/> + <button + follows="right|top" + height="21" + label="Clear" + layout="topleft" + name="clear_filters" + top_pad="-21" + left_pad="8" + width="73"/> + <scroll_list + column_padding="0" + draw_heading="true" + follows="all" + height="135" + layout="topleft" + left="18" + top_pad="15" + tab_stop="false" + multi_select="true" + name="objects_scroll_list" + width="1040"> + <scroll_list.columns + label="Name (root prim)" + name="name" + dynamic_width="true" /> + <scroll_list.columns + label="Description (root prim)" + name="description" + width="158" /> + <scroll_list.columns + label="Owner" + name="owner" + width="141" /> + <scroll_list.columns + label="Scripted" + name="scripted" + width="60" /> + <scroll_list.columns + label="Impact" + name="land_impact" + width="55" /> + <scroll_list.columns + label="Distance" + name="dist_from_you" + width="65" /> + <scroll_list.columns + label="Linkset use" + name="linkset_use" + width="236" /> + <scroll_list.columns + label="A %" + name="a_percent" + width="41" /> + <scroll_list.columns + label="B %" + name="b_percent" + width="41" /> + <scroll_list.columns + label="C %" + name="c_percent" + width="41" /> + <scroll_list.columns + label="D %" + name="d_percent" + width="41" /> + </scroll_list> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + length="1" + follows="left|bottom|right" + layout="topleft" + name="messaging_status" + top_pad="17" + width="679"> + Linksets: + </text> + <button + follows="right|bottom" + height="21" + label="Refresh list" + layout="topleft" + name="refresh_objects_list" + top_pad="-16" + left_pad="0" + width="115"/> + <button + follows="right|bottom" + height="21" + label="Select all" + layout="topleft" + name="select_all_objects" + top_pad="-21" + left_pad="8" + width="115"/> + <button + follows="right|bottom" + height="21" + label="Select none" + layout="topleft" + name="select_none_objects" + top_pad="-21" + left_pad="8" + width="115"/> + </panel> + <view_border + bevel_style="none" + follows="left|bottom|right" + height="0" + layout="topleft" + name="horiz_separator" + top_pad="0" + left="18" + width="1039"/> + <panel + border="false" + bevel_style="none" + follows="left|right|bottom" + layout="topleft" + left="0" + height="67" + width="1010"> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + length="1" + left="18" + follows="left|bottom|right" + layout="topleft" + top_pad="8" + width="580"> + Actions on selected linksets (If a linkset is removed from the world, its attributes may be lost): + </text> + <check_box + height="19" + follows="left|bottom" + label="Show beacon" + layout="topleft" + name="show_beacon" + left_pad="0" + top_pad="-16" + width="90" /> + <button + follows="left|bottom" + height="21" + label="Take" + layout="topleft" + name="take_objects" + top_pad="9" + left="18" + width="95"/> + <button + follows="left|bottom" + height="21" + label="Take copy" + layout="topleft" + name="take_copy_objects" + top_pad="-21" + left_pad="6" + width="95"/> + <button + follows="left|bottom" + height="21" + label="Teleport me to it" + layout="topleft" + name="teleport_me_to_object" + top_pad="-21" + left_pad="239" + width="160"/> + <button + follows="right|bottom" + height="21" + label="Return" + layout="topleft" + name="return_objects" + top_pad="-21" + left_pad="252" + width="95"/> + <button + follows="right|bottom" + height="21" + label="Delete" + layout="topleft" + name="delete_objects" + top_pad="-21" + left_pad="6" + width="95"/> + </panel> + <view_border + bevel_style="none" + follows="left|bottom|right" + height="0" + layout="topleft" + name="horiz_separator" + top_pad="0" + left="18" + width="1039"/> + <panel + border="false" + bevel_style="none" + follows="left|right|bottom" + layout="topleft" + left="0" + height="75" + width="1010"> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + length="1" + follows="left|bottom" + layout="topleft" + left="18" + top_pad="8" + width="972"> + Edit attributes of selected linksets and press the button to apply changes + </text> + <combo_box + height="20" + layout="topleft" + follows="left|top" + name="edit_linkset_use" + left="18" + top_pad="17" + width="199"> + </combo_box> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="walkability_coefficients_label" + length="1" + follows="left|bottom" + layout="topleft" + left_pad="36" + top_pad="-17" + width="110"> + Walkability: + </text> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="edit_a_label" + length="1" + follows="left|bottom" + layout="topleft" + left_pad="0" + width="18"> + A + </text> + <line_editor + border_style="line" + border_thickness="1" + follows="left|bottom" + height="21" + layout="topleft" + left_pad="0" + top_pad="-19" + max_length_chars="3" + name="edit_a_value" + tool_tip="Walkability for characters of type A. Example character type is humanoid." + width="45" /> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="edit_b_label" + length="1" + follows="left|bottom" + layout="topleft" + left_pad="44" + top_pad="-15" + width="18"> + B + </text> + <line_editor + border_style="line" + border_thickness="1" + follows="left|bottom" + height="21" + layout="topleft" + left_pad="0" + top_pad="-19" + max_length_chars="3" + name="edit_b_value" + tool_tip="Walkability for characters of type B. Example character type is creature." + width="45" /> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="edit_c_label" + length="1" + follows="left|bottom" + layout="topleft" + left_pad="44" + top_pad="-15" + width="18"> + C + </text> + <line_editor + border_style="line" + border_thickness="1" + follows="left|bottom" + height="21" + layout="topleft" + left_pad="0" + top_pad="-19" + max_length_chars="3" + name="edit_c_value" + tool_tip="Walkability for characters of type C. Example character type is mechanical." + width="45" /> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="edit_d_label" + length="1" + follows="left|bottom" + layout="topleft" + left_pad="44" + top_pad="-15" + width="18"> + D + </text> + <line_editor + border_style="line" + border_thickness="1" + follows="left|bottom" + height="21" + layout="topleft" + left_pad="0" + top_pad="-19" + max_length_chars="3" + name="edit_d_value" + tool_tip="Walkability for characters of type D. Example character type is other." + width="45" /> + <button + follows="left|bottom" + height="21" + label="Apply changes" + layout="topleft" + name="apply_edit_values" + top_pad="-21" + left_pad="40" + width="140"/> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="suggested_use_a_label" + length="1" + follows="left|bottom" + layout="topleft" + left="363" + top_pad="5" + width="107"> + (Humanoid) + </text> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="suggested_use_b_label" + length="1" + follows="left|bottom" + layout="topleft" + left_pad="0" + width="107"> + (Creature) + </text> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="suggested_use_c_label" + length="1" + follows="left|bottom" + layout="topleft" + left_pad="0" + width="107"> + (Mechanical) + </text> + <text + height="13" + word_wrap="false" + use_ellipses="false" + type="string" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor" + name="suggested_use_d_label" + length="1" + follows="left|bottom" + layout="topleft" + left_pad="0" + width="107"> + (Other) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_people.xml b/indra/newview/skins/default/xui/en/floater_people.xml index 32dda1b694..701233ba4a 100644 --- a/indra/newview/skins/default/xui/en/floater_people.xml +++ b/indra/newview/skins/default/xui/en/floater_people.xml @@ -1,45 +1,35 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <floater - open_positioning="cascading" + positioning="cascading" can_close="true" can_resize="true" height="570" help_topic="sidebar_people" - min_height="440" - min_width="333" + min_height="220" + min_width="260" layout="topleft" name="floater_people" save_rect="true" single_instance="true" reuse_instance="true" title="PEOPLE" - width="333"> + width="370"> <panel_container default_panel_name="panel_people" follows="all" height="570" name="main_panel" - width="333"> + width="370"> <panel class="panel_people" name="panel_people" filename="panel_people.xml"/> <panel - class="panel_profile_view" - name="panel_profile_view" - filename="panel_profile_view.xml"/> - <panel class="panel_group_info_sidetray" name="panel_group_info_sidetray" filename="panel_group_info_sidetray.xml" label="Group Profile" font="SansSerifBold"/> - <panel - class="panel_block_list_sidetray" - name="panel_block_list_sidetray" - filename="panel_block_list_sidetray.xml" - label="Blocked Residents & Objects" - font="SansSerifBold"/> </panel_container> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_picks.xml b/indra/newview/skins/default/xui/en/floater_picks.xml index 7882116662..984894b016 100644 --- a/indra/newview/skins/default/xui/en/floater_picks.xml +++ b/indra/newview/skins/default/xui/en/floater_picks.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <floater - open_positioning="cascading" + positioning="cascading" can_close="true" can_resize="true" height="572" diff --git a/indra/newview/skins/default/xui/en/floater_places.xml b/indra/newview/skins/default/xui/en/floater_places.xml index 6484b54360..b241e265a9 100644 --- a/indra/newview/skins/default/xui/en/floater_places.xml +++ b/indra/newview/skins/default/xui/en/floater_places.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <floater - open_positioning="cascading" + positioning="cascading" legacy_header_height="18" can_resize="true" height="588" @@ -11,7 +11,7 @@ save_rect="true" reuse_instance="true" title="PLACES" - min_height="230" + min_height="440" min_width="333" width="333"> <panel diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml index 402868bb97..bd6faf4ed8 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater legacy_header_height="18" - open_positioning="centered" + positioning="centered" default_tab_group="1" height="460" layout="topleft" @@ -100,7 +100,7 @@ help_topic="preferences_colors_tab" name="colors" /> <panel - class="panel_preference" + class="panel_preference_privacy" filename="panel_preferences_privacy.xml" label="Privacy" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_preview_animation.xml b/indra/newview/skins/default/xui/en/floater_preview_animation.xml index 8427c7b06f..3ea5f54f2c 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_animation.xml @@ -41,18 +41,26 @@ label_selected="Stop" layout="topleft" left="10" - name="Anim play btn" + name="Inworld" tool_tip="Play this animation so that others can see it" top="47" - width="125" /> + width="125"> + <button.commit_callback + function="PreviewAnim.Play" + parameter="Inworld" /> + </button> <button height="20" label="Play Locally" label_selected="Stop" layout="topleft" left_pad="5" - name="Anim audition btn" + name="Locally" tool_tip="Play this animation so that only you can see it" top_delta="0" - width="125" /> + width="125"> + <button.commit_callback + function="PreviewAnim.Play" + parameter="Locally" /> + </button> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml index f35628f8e5..2e1c8ce670 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml @@ -3,7 +3,6 @@ legacy_header_height="18" can_resize="true" default_tab_group="1" - follows="left|top" height="361" layout="topleft" min_height="243" @@ -71,6 +70,7 @@ max_length="65536" name="Notecard Editor" parse_urls="false" + spellcheck="true" tab_group="1" top="46" width="392" diff --git a/indra/newview/skins/default/xui/en/floater_preview_texture.xml b/indra/newview/skins/default/xui/en/floater_preview_texture.xml index 92d3a6702c..137e278ddc 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_texture.xml @@ -2,7 +2,6 @@ <floater legacy_header_height="18" can_resize="true" - follows="left|top" height="350" layout="topleft" min_height="200" diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml index e6d749a3f0..9561f67941 100644 --- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml @@ -155,6 +155,7 @@ name="object_name" top_delta="0" translate="false" + parse_urls="false" use_ellipses="true" width="185"> Consetetur Sadipscing diff --git a/indra/newview/skins/default/xui/en/floater_script.xml b/indra/newview/skins/default/xui/en/floater_script.xml index 73e6d6147a..bd4edb81c8 100644 --- a/indra/newview/skins/default/xui/en/floater_script.xml +++ b/indra/newview/skins/default/xui/en/floater_script.xml @@ -2,7 +2,6 @@ <floater legacy_header_height="18" background_visible="true" - follows="left|top|right|bottom" height="250" layout="topleft" name="script_floater" diff --git a/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml index ce96ea232e..b5dd2f97b9 100644 --- a/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml +++ b/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml @@ -2,7 +2,6 @@ <floater legacy_header_height="18" can_resize="true" - follows="left|top|right|bottom" height="200" layout="topleft" name="script" diff --git a/indra/newview/skins/default/xui/en/floater_search.xml b/indra/newview/skins/default/xui/en/floater_search.xml index dd818e2e06..c3e7028dc5 100644 --- a/indra/newview/skins/default/xui/en/floater_search.xml +++ b/indra/newview/skins/default/xui/en/floater_search.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="cascading" + positioning="cascading" legacy_header_height="18" can_resize="true" height="775" diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml index 61f2e7e72d..49d64767cc 100644 --- a/indra/newview/skins/default/xui/en/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml @@ -1,10 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="cascading" + positioning="cascading" legacy_header_height="18" can_minimize="true" can_close="true" - follows="left|top" height="500" layout="topleft" name="Snapshot" @@ -35,7 +34,7 @@ </string> <string name="profile_succeeded_str"> - Profile feed updated! + Image uploaded </string> <string name="postcard_succeeded_str"> @@ -51,7 +50,7 @@ </string> <string name="profile_failed_str"> - Failed to update your Profile Feed. + Failed to upload image to your Profile Feed. </string> <string name="postcard_failed_str"> diff --git a/indra/newview/skins/default/xui/en/floater_spellcheck.xml b/indra/newview/skins/default/xui/en/floater_spellcheck.xml new file mode 100644 index 0000000000..76a350dd29 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_spellcheck.xml @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + border="true" + can_close="true" + can_minimize="true" + save_rect="true" + help_topic="spelling_settings" + can_resize="false" + height="315" + width="490" + name="spellcheck_floater" + title="Spell Checker Settings"> + <check_box + bottom_delta="30" + control_name="SpellCheck" + left_delta="15" + height="16" + width="100" + follows="left|top" + label="Enable spell checker" + name="spellcheck_enable" /> + <view_border + top_pad="10" + left="2" + height="0" + width="491" + follows="left|top" + bevel_style="none" + border_thickness="1" + mouse_opaque="false" + name="divisor1"/> + <text + enabled_control="SpellCheck" + follows="top|left" + height="10" + layout="topleft" + left="38" + mouse_opaque="false" + name="spellcheck_main" + top_pad="15" + type="string" + width="90" + > + Main dictionary : + </text> + <combo_box + enabled_control="SpellCheck" + follows="top|left" + height="23" + layout="topleft" + left_pad="10" + name="spellcheck_main_combo" + top_pad="-15" + width="175" + /> + <text + enabled_control="SpellCheck" + follows="top|left" + height="10" + label="Logs:" + layout="topleft" + left="38" + mouse_opaque="false" + name="spellcheck_additional" + top_pad="15" + type="string" + width="190" + > + Additional dictionaries : + </text> + <text + follows="top|left" + height="12" + layout="topleft" + left="55" + length="1" + name="spellcheck_available" + top_pad="10" + type="string" + width="175"> + Available + </text> + <text + follows="top|left" + height="12" + type="string" + left_pad="45" + length="1" + layout="topleft" + name="spellcheck_active" + width="175"> + Active + </text> + <scroll_list + enabled_control="SpellCheck" + follows="top|left" + height="155" + layout="topleft" + left="55" + multi_select="true" + name="spellcheck_available_list" + sort_column="0" + sort_ascending="true" + width="175" /> + <button + enabled_control="SpellCheck" + follows="top|left" + height="26" + image_overlay="Arrow_Right" + hover_glow_amount="0.15" + layout="topleft" + left_pad="10" + name="spellcheck_moveright_btn" + top_delta="50" + width="25"> + </button> + <button + enabled_control="SpellCheck" + follows="top|left" + height="26" + image_overlay="Arrow_Left" + hover_glow_amount="0.15" + layout="topleft" + name="spellcheck_moveleft_btn" + top_delta="30" + width="25"> + </button> + <scroll_list + enabled_control="SpellCheck" + follows="top|left" + height="155" + layout="topleft" + left_pad="10" + multi_select="true" + name="spellcheck_active_list" + sort_column="0" + sort_ascending="true" + top_pad="-105" + width="175" + /> + <button + enabled="false" + follows="left|top" + height="23" + label="Remove" + layout="topleft" + left="55" + name="spellcheck_remove_btn" + top_pad="5" + width="80" /> + <button + follows="left|top" + height="23" + label="Import..." + layout="topleft" + left_pad="15" + name="spellcheck_import_btn" + top_delta="0" + width="80" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/en/floater_spellcheck_import.xml new file mode 100644 index 0000000000..b54090015d --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_spellcheck_import.xml @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + border="true" + can_close="true" + can_minimize="true" + bottom="275" + left="300" + can_resize="false" + height="140" + width="400" + name="spellcheck_import" + title="Import Dictionary"> + <text + follows="top|left" + height="16" + layout="topleft" + left="25" + top="15" + type="string" + width="65"> + Dictionary: + </text> + <line_editor + enabled="false" + follows="left|top" + height="23" + layout="topleft" + left_pad="10" + max_length_bytes="255" + name="dictionary_path" + top_delta="-5" + width="200" /> + <button + follows="left|top" + height="23" + label="Browse" + label_selected="Browse" + layout="topleft" + left_pad="5" + name="dictionary_path_browse" + top_delta="0" + width="75" /> + <text + follows="top|left" + height="16" + layout="topleft" + left="25" + top_pad="8" + type="string" + width="65"> + Name: + </text> + <line_editor + enabled="false" + follows="left|top" + height="23" + layout="topleft" + left_pad="10" + max_length_bytes="255" + name="dictionary_name" + top_delta="-5" + width="200" /> + <text + follows="top|left" + height="16" + layout="topleft" + left="25" + top_pad="8" + type="string" + width="65"> + Language: + </text> + <line_editor + follows="left|top" + height="23" + layout="topleft" + left_pad="10" + max_length_bytes="255" + name="dictionary_language" + top_delta="-5" + width="200" /> + <view_border + top_pad="10" + left="2" + height="0" + width="396" + follows="left|top" + bevel_style="none" + border_thickness="1" + mouse_opaque="false" + name="divisor"/> + <button + top_pad="10" + right="280" + height="22" + width="90" + enabled="true" + follows="left|top" + mouse_opaque="true" + halign="center" + scale_image="true" + name="ok_btn" + label="Import" /> + <button + top_delta="0" + right="380" + height="22" + width="90" + enabled="true" + follows="left|top" + mouse_opaque="true" + halign="center" + scale_image="true" + name="cancel_btn" + label="Cancel" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml index 406114294d..f9eb16d224 100644 --- a/indra/newview/skins/default/xui/en/floater_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_stats.xml @@ -2,7 +2,6 @@ <floater legacy_header_height="18" can_resize="true" - follows="top|right" height="400" layout="topleft" name="Statistics" @@ -150,6 +149,19 @@ show_per_sec="true" show_bar="false"> </stat_bar> + <stat_bar + name="object_cache_hits" + label="Object Cache Hit Rate" + stat="object_cache_hits" + bar_min="0" + bar_max="100" + unit_label="%" + tick_spacing="20" + label_spacing="20" + show_history="true" + show_per_sec="false" + show_bar="false"> + </stat_bar> </stat_view> <!--Texture Stats--> <stat_view @@ -157,6 +169,32 @@ label="Texture" show_label="true"> <stat_bar + name="texture_cache_hits" + label="Cache Hit Rate" + stat="texture_cache_hits" + bar_min="0.f" + bar_max="100.f" + unit_label="%" + tick_spacing="20" + label_spacing="20" + show_history="true" + show_per_sec="false" + show_bar="false"> + </stat_bar> + <stat_bar + name="texture_cache_read_latency" + label="Cache Read Latency" + unit_label="msec" + stat="texture_cache_read_latency" + bar_min="0.f" + bar_max="1000.f" + tick_spacing="100" + label_spacing="200" + show_history="true" + show_per_sec="false" + show_bar="false"> + </stat_bar> + <stat_bar name="numimagesstat" label="Count" stat="numimagesstat" @@ -533,6 +571,20 @@ show_bar="false" show_mean="false" > </stat_bar> + <stat_bar + name="simpctscriptsrun" + label="Scripts Run" + unit_label=" %" + stat="simpctscriptsrun" + bar_min="0" + bar_max="100" + tick_spacing="10" + label_spacing="20" + precision="3" + show_per_sec="false" + show_bar="false" + show_mean="true"> + </stat_bar> <stat_bar name="simscripteps" @@ -549,6 +601,53 @@ show_mean="false" > </stat_bar> + <stat_view + name="simpathfinding" + label="Pathfinding" + show_label="true"> + <stat_bar + name="simsimaistepmsec" + label=" AI Step Time" + stat="simsimaistepmsec" + unit_label="ms" + precision="3" + bar_min="0.f" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_per_sec="false" + show_bar="false" + show_mean="false" > + </stat_bar> + <stat_bar + name="simsimskippedsilhouettesteps" + label=" Skipped Silhouette Steps" + stat="simsimskippedsilhouettesteps" + unit_label="/sec" + precision="0" + bar_min="0" + bar_max="45" + tick_spacing="4" + label_spacing="8" + show_per_sec="false" + show_bar="false"> + </stat_bar> + <stat_bar + name="simsimpctsteppedcharacters" + label=" Characters Updated" + unit_label=" %" + stat="simsimpctsteppedcharacters" + bar_min="0" + bar_max="100" + tick_spacing="10" + label_spacing="20" + precision="1" + show_per_sec="false" + show_bar="false" + show_mean="true"> + </stat_bar> + </stat_view> + <stat_bar name="siminpps" label="Packets In" diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml index 9b96a5badc..ecedb27438 100644 --- a/indra/newview/skins/default/xui/en/floater_sys_well.xml +++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml @@ -2,7 +2,6 @@ <floater legacy_header_height="18" bevel_style="in" - follows="right|bottom" layout="topleft" name="sys_well_window" help_topic="notification_chiclet" 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..a04050e7eb --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml @@ -0,0 +1,226 @@ +<?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" + visible="false" + 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" + visible="true" + 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_test_text_editor.xml b/indra/newview/skins/default/xui/en/floater_test_text_editor.xml index 548e24efba..e1fefc3631 100644 --- a/indra/newview/skins/default/xui/en/floater_test_text_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_test_text_editor.xml @@ -3,6 +3,7 @@ legacy_header_height="18" can_resize="true" height="600" + single_instance="false" layout="topleft" name="floater_test_text_editor" translate="false" diff --git a/indra/newview/skins/default/xui/en/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/en/floater_test_text_vertical_aligment.xml new file mode 100644 index 0000000000..d11373ce1d --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_test_text_vertical_aligment.xml @@ -0,0 +1,112 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_minimize="false" + can_tear_off="false" + can_resize="true" + can_drag_on_left="false" + can_close="true" + can_dock="true" + bevel_style="in" + height="300" + layout="topleft" + name="Test Floater" + save_rect="true" + title="TEST FLOATER" + save_dock_state="true" + save_visibility="true" + single_instance="true" + width="650"> + <text left="0" + follows="left|top|bottom" + top="5" + clip_partial="true" + bottom="-5" + width="100" + valign="top"> +this +is +some +text +that +is +top +aligned</text> + <text left_pad="5" + follows="left|top|bottom" + top="5" + bottom="-5" + clip_partial="true" + width="100" + valign="center"> +this +is +some +text +that +is +center +aligned</text> + <text left_pad="5" + follows="left|top|bottom" + top="5" + clip_partial="true" + bottom="-5" + width="100" + valign="bottom"> +this +is +some +text +that +is +bottom +aligned</text> + <text_editor left_pad="5" + follows="left|top|bottom" + top="5" + clip_partial="true" + bottom="-5" + width="100" + valign="top"> +this +is +some +text +that +is +top +aligned + </text_editor> + <text_editor left_pad="5" + follows="left|top|bottom" + top="5" + bottom="-5" + clip_partial="true" + width="100" + valign="center"> +this +is +some +text +that +is +center +aligned + </text_editor> + <text_editor left_pad="5" + follows="left|top|bottom" + top="5" + clip_partial="true" + bottom="-5" + width="100" + valign="bottom"> +this +is +some +text +that +is +bottom +aligned + </text_editor> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_test_textbox.xml b/indra/newview/skins/default/xui/en/floater_test_textbox.xml index 2df9bb35fe..1d31fbd6dc 100644 --- a/indra/newview/skins/default/xui/en/floater_test_textbox.xml +++ b/indra/newview/skins/default/xui/en/floater_test_textbox.xml @@ -8,21 +8,7 @@ help_topic="floater_test_textbox" translate="false" width="800"> - <text - type="string" - length="1" - height="90" - layout="topleft" - left="10" - top_pad="30" - width="300"> - First line of multiple lines -Second line of multiple lines -Third line of multiple lines -Fourth line of multiple lines -Fifth line of multiple lines - </text> - <text + <text clip_partial="true" top_pad="10" left="10" diff --git a/indra/newview/skins/default/xui/en/floater_test_widgets.xml b/indra/newview/skins/default/xui/en/floater_test_widgets.xml index 13c850c86c..10854f5a49 100644 --- a/indra/newview/skins/default/xui/en/floater_test_widgets.xml +++ b/indra/newview/skins/default/xui/en/floater_test_widgets.xml @@ -115,6 +115,7 @@ </flyout_button> <check_box bottom_delta="35" + height="10" label="Checkbox" layout="topleft" tool_tip="checkbox" @@ -275,6 +276,7 @@ <!-- "spinner" is a numerical input widget with an up and down arrow to change the value. --> <spinner + height="10" bottom_delta="35" follows="top|left" label="Spinner" diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml index cad7d72ed7..6021ba0a5a 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml @@ -3,15 +3,17 @@ legacy_header_height="18" can_minimize="false" can_resize="true" - height="290" + height="330" layout="topleft" - min_height="290" + min_height="330" min_width="410" name="texture picker" help_topic="texture_picker" title="PICK: TEXTURE" width="410"> - <floater.string + +<!-- top static --> + <floater.string name="choose_picture"> Click to choose a picture </floater.string> @@ -19,6 +21,16 @@ name="pick title"> Pick: </floater.string> + + <view + left="4" + top="20" + name="preview_widget" + height="165" + width="165" + follows="left|top" + /> + <text type="string" length="1" @@ -34,69 +46,103 @@ width="163"> Multiple textures </text> + + <!-- mode selector --> + <radio_group + control_name="mode_selection" + height="20" + layout="topleft" + left="18" + top_pad="80" + name="mode_selection" + follows="left|top"> + <radio_item + label="Inventory" + name="inventory" + top_delta="20" + layout="topleft" + height="16" + left="0" + value="0" + width="80" /> + <radio_item + label="Local" + left_pad="0" + layout="topleft" + top_delta="0" + height="16" + name="local" + value="1" + width="75" /> + </radio_group> + <!-- --> + <text type="string" length="1" follows="left|top" height="14" layout="topleft" - left_delta="0" + left_delta="-12" name="unknown" - top_pad="80" - width="163"> + top_pad="4" + width=""> Size: [DIMENSIONS] </text> + +<!-- middle: inventory mode --> + <button enabled="false" - follows="left|bottom" - height="20" + follows="left|top" + height="18" label="Default" label_selected="Default" layout="topleft" - left_delta="0" name="Default" - top_pad="4" - width="80" /> + width="73" + left="94" + top="215"/> <button + follows="left|top" + height="20" + label="Blank" + label_selected="Blank" + layout="topleft" + left_delta="0" + name="Blank" + top_pad="5" + width="73" /> + <button enabled="false" - follows="left|bottom" + follows="left|top" height="20" label="None" label_selected="None" layout="topleft" - left_pad="4" + left_delta="0" name="None" - top_delta="0" - width="80" /> - <button - follows="left|bottom" - height="20" - label="Blank" - label_selected="Blank" - layout="topleft" - left="4" - name="Blank" top_pad="5" - width="80" /> - <button - follows="left|bottom" + width="73" /> + <button + follows="left|top" height="28" image_selected="eye_button_active.tga" image_unselected="eye_button_inactive.tga" layout="topleft" - left_pad="50" - top_delta="3" + left_delta="-80" + top_delta="-25" name="Pipette" width="28" /> - <check_box + <text follows="left|bottom" height="20" - initial_value="true" - label="Apply now" layout="topleft" - left="4" - name="apply_immediate_check" - top="262" + left="8" + name="preview_disabled" + top="266" + value="Preview Disabled" + visible="false" width="120" /> <filter_editor follows="left|top|right" @@ -113,7 +159,7 @@ bg_alpha_color="DkGray2" border="false" follows="all" - height="200" + height="233" layout="topleft" left_delta="0" name="inventory panel" @@ -128,23 +174,89 @@ top_pad="0" left_delta="-3" width="200" /> - <button - follows="right|bottom" + +<!-- middle: local mode --> + <button + follows="left|top" + height="18" + label="Add" + label_selected="Add" + layout="topleft" + left="94" + top="215" + name="l_add_btn" + width="73" + visible="false"/> + <button + enabled="false" + follows="left|top" + height="20" + label="Remove" + label_selected="Remove" + layout="topleft" + left_delta="0" + name="l_rem_btn" + top_pad="5" + width="73" + visible="false"/> + <button + enabled="false" + follows="left|top" + height="20" + label="Upload" + label_selected="Upload" + layout="topleft" + left_delta="0" + name="l_upl_btn" + top_pad="5" + width="73" + visible="false"/> + <scroll_list + name="l_name_list" + left="170" + top="22" + width="235" + height="260" + follows="left|top|right|bottom" + column_padding="0" + can_resize="false" + draw_heading="true" + multi_select="true" + search_column="1" + visible="false"> + <column name="unit_name" label="Name" dynamicwidth="true" /> + <column name="unit_id_HIDDEN" label="ID" width="0" /> + </scroll_list> + +<!-- bottom static --> + <button + follows="bottom" height="20" label="OK" label_selected="OK" layout="topleft" - right="-120" + left="95" + top="-30" name="Select" width="100" /> <button - follows="right|bottom" + follows="bottom" height="20" label="Cancel" label_selected="Cancel" layout="topleft" - right="-10" - left_pad="5" + left_delta="120" + top_delta="0" name="Cancel" width="100" /> + <check_box + follows="left|bottom" + height="20" + initial_value="true" + label="Apply now" + layout="topleft" + left="6" + name="apply_immediate_check" + top_delta="0" + width="120" /> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml new file mode 100644 index 0000000000..1ea256b8b3 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml @@ -0,0 +1,428 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + can_minimize="false" + height="600" + layout="topleft" + name="TexFetchDebugger" + help_topic="texfetchdebugger" + title="Texture Fetching Debugger" + width="540"> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left="10" + name="total_num_fetched_label" + top="30" + width="400"> + 1, Total number of fetched textures: [NUM] + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_num_fetching_requests_label" + top_delta="25" + width="400"> + 2, Total number of fetching requests: [NUM] + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_num_cache_hits_label" + top_delta="25" + width="400"> + 3, Total number of cache hits: [NUM] + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_num_visible_tex_label" + top_delta="25" + width="400"> + 4, Total number of visible textures: [NUM] + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_num_visible_tex_fetch_req_label" + top_delta="25" + width="450"> + 5, Total number of visible texture fetching requests: [NUM] + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_fetched_data_label" + top_delta="25" + width="530"> + 6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_fetched_vis_data_label" + top_delta="25" + width="480"> + 7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_fetched_rendered_data_label" + top_delta="25" + width="530"> + 8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_time_cache_read_label" + top_delta="25" + width="400"> + 9, Total time on cache readings: [TIME] seconds + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_time_cache_write_label" + top_delta="25" + width="400"> + 10, Total time on cache writings: [TIME] seconds + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_time_decode_label" + top_delta="25" + width="400"> + 11, Total time on decodings: [TIME] seconds + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_time_gl_label" + top_delta="25" + width="400"> + 12, Total time on gl texture creation: [TIME] seconds + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_time_http_label" + top_delta="25" + width="400"> + 13, Total time on HTTP fetching: [TIME] seconds + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_time_fetch_label" + top_delta="25" + width="400"> + 14, Total time on entire fetching: [TIME] seconds + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_time_refetch_vis_cache_label" + top_delta="25" + width="540"> + 15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_time_refetch_all_cache_label" + top_delta="25" + width="540"> + 16, Refetching all textures from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_time_refetch_vis_http_label" + top_delta="25" + width="540"> + 17, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_time_refetch_all_http_label" + top_delta="25" + width="540"> + 18, Refetching all textures from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels + </text> + <spinner + decimal_digits="2" + follows="left|top" + height="20" + increment="0.01" + initial_value="1.0" + label="19, Ratio of Texel/Pixel:" + label_width="130" + layout="topleft" + left_delta="0" + max_val="10.0" + min_val="0.01" + name="texel_pixel_ratio" + top_delta="30" + width="200"> + <spinner.commit_callback + function="TexFetchDebugger.ChangeTexelPixelRatio" /> + </spinner> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="texture_source_label" + top_delta="30" + width="110"> + 20, Texture Source: + </text> + <radio_group + control_name="TextureFetchSource" + follows="top|left" + draw_border="false" + height="25" + layout="topleft" + left_pad="0" + name="texture_source" + top_delta="0" + width="264"> + <radio_item + height="16" + label="Cache + HTTP" + layout="topleft" + left="3" + name="0" + top="0" + width="100" /> + <radio_item + height="16" + label="HTTP Only" + layout="topleft" + left_delta="100" + name="1" + top_delta="0" + width="200" /> + </radio_group> + <button + follows="left|top" + height="20" + label="Start" + layout="topleft" + left="10" + name="start_btn" + top_delta="20" + width="70"> + <button.commit_callback + function="TexFetchDebugger.Start" /> + </button> + <button + follows="left|top" + height="20" + label="Reset" + layout="topleft" + left_pad="7" + name="clear_btn" + top_delta="0" + width="70"> + <button.commit_callback + function="TexFetchDebugger.Clear" /> + </button> + <button + follows="left|top" + height="20" + label="Close" + layout="topleft" + left_pad="7" + name="close_btn" + top_delta="0" + width="70"> + <button.commit_callback + function="TexFetchDebugger.Close" /> + </button> + <button + follows="left|top" + height="20" + label="Cache Read" + layout="topleft" + left="10" + name="cacheread_btn" + top_delta="20" + width="80"> + <button.commit_callback + function="TexFetchDebugger.CacheRead" /> + </button> + <button + follows="left|top" + height="20" + label="Cache Write" + layout="topleft" + left_pad="7" + name="cachewrite_btn" + top_delta="0" + width="80"> + <button.commit_callback + function="TexFetchDebugger.CacheWrite" /> + </button> + <button + follows="left|top" + height="20" + label="HTTP" + layout="topleft" + left_pad="7" + name="http_btn" + top_delta="0" + width="70"> + <button.commit_callback + function="TexFetchDebugger.HTTPLoad" /> + </button> + <button + follows="left|top" + height="20" + label="Decode" + layout="topleft" + left_pad="7" + name="decode_btn" + top_delta="0" + width="70"> + <button.commit_callback + function="TexFetchDebugger.Decode" /> + </button> + <button + follows="left|top" + height="20" + label="GL Texture" + layout="topleft" + left_pad="7" + name="gl_btn" + top_delta="0" + width="70"> + <button.commit_callback + function="TexFetchDebugger.GLTexture" /> + </button> + <button + follows="left|top" + height="20" + label="Refetch Vis Cache" + layout="topleft" + left="10" + name="refetchviscache_btn" + top_delta="20" + width="120"> + <button.commit_callback + function="TexFetchDebugger.RefetchVisCache" /> + </button> + <button + follows="left|top" + height="20" + label="Refetch All Cache" + layout="topleft" + left_pad="7" + name="refetchallcache_btn" + top_delta="0" + width="120"> + <button.commit_callback + function="TexFetchDebugger.RefetchAllCache" /> + </button> + <button + follows="left|top" + height="20" + label="Refetch Vis HTTP" + layout="topleft" + left_pad="7" + name="refetchvishttp_btn" + top_delta="0" + width="120"> + <button.commit_callback + function="TexFetchDebugger.RefetchVisHTTP" /> + </button> + <button + follows="left|top" + height="20" + label="Refetch All HTTP" + layout="topleft" + left_pad="7" + name="refetchallhttp_btn" + top_delta="0" + width="120"> + <button.commit_callback + function="TexFetchDebugger.RefetchAllHTTP" /> + </button> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 1808cab2a5..436e9f8fed 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -1,9 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - open_positioning="cascading" + positioning="cascading" legacy_header_height="18" - follows="left|top|right" - height="580" + height="590" layout="topleft" bg_opaque_image="Window_NoTitle_Foreground" bg_alpha_image="Window_NoTitle_Background" @@ -15,7 +14,27 @@ save_visibility="true" sound_flags="0" width="295"> - <floater.string + <floater.string + name="grid_screen_text"> + Screen + </floater.string> + <floater.string + name="grid_local_text"> + Local + </floater.string> + <floater.string + name="grid_world_text"> + World + </floater.string> + <floater.string + name="grid_reference_text"> + Reference + </floater.string> + <floater.string + name="grid_attachment_text"> + Attachment + </floater.string> + <floater.string name="status_rotate"> Drag colored bands to rotate object </floater.string> @@ -313,20 +332,48 @@ top_pad="0" name="checkbox snap to grid" width="134" /> - <button - left_pad="0" - label="Options..." + <combo_box + height="20" + layout="topleft" + follows="left|top" + name="combobox grid mode" + tool_tip="Choose the type of grid ruler for positioning the object" + top="83" + left="195" + top_pad="0" + width="60"> + <combo_box.item + label="World" + name="World" + value="World" /> + <combo_box.item + label="Local" + name="Local" + value="Local" /> + <combo_box.item + label="Reference" + name="Reference" + value="Reference" /> + <combo_box.commit_callback + function="BuildTool.gridMode"/> + </combo_box> + + <button + left="259" + label="" + image_selected="ForwardArrow_Press" + image_unselected="ForwardArrow_Off" layout="topleft" follows="top|left" name="Options..." tool_tip="See more grid options" top="83" - right="-35" - width="65" - height="21" > + width="25" + height="20" > <button.commit_callback function="BuildTool.gridOptions"/> </button> + <button follows="left|top" height="20" @@ -791,6 +838,7 @@ tab_min_width="40" tab_position="top" tab_height="25" + open_tabs_on_drag_and_drop="true" top="173" width="295"> @@ -829,6 +877,14 @@ You can't modify these objects </panel.string> <panel.string + name="text modify info 5"> + You can't modify this object across a region boundary + </panel.string> + <panel.string + name="text modify info 6"> + You can't modify these objects across a region boundary + </panel.string> + <panel.string name="text modify warning"> You must select entire object to set permissions </panel.string> @@ -893,7 +949,7 @@ left="10" length="1" follows="left|top" - height="19" + height="29" layout="topleft" name="Creator:" top_pad="7" @@ -906,7 +962,7 @@ length="1" follows="left|top" left_pad="0" - height="20" + height="29" layout="topleft" name="Creator Name" top_delta="0" @@ -921,10 +977,10 @@ length="1" left="10" follows="left|top" - height="19" + height="29" layout="topleft" name="Owner:" - top_pad="13" + top_pad="3" width="90"> Owner: </text> @@ -933,7 +989,7 @@ type="string" length="1" follows="left|top" - height="20" + height="29" layout="topleft" name="Owner Name" left_pad="0" @@ -952,7 +1008,7 @@ left="10" height="18" name="Group:" - top_pad="17" + top_pad="3" width="75"> Group: </text> @@ -981,7 +1037,7 @@ layout="topleft" name="checkbox share with group" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions." - top_pad="10" + top_pad="5" left="100" width="87" /> <button @@ -1003,7 +1059,7 @@ top_pad="10" left="10" name="label click action" - width="118"> + width="82"> Click to: </text> <combo_box @@ -1011,7 +1067,7 @@ height="23" layout="topleft" name="clickaction" - width="148" + width="130" left_pad="10"> <combo_box.item label="Touch (default)" @@ -1044,19 +1100,39 @@ layout="topleft" name="checkbox for sale" left="7" - width="100" /> -<!-- NEW SALE TYPE COMBO BOX --> + width="97" /> + <!-- NEW PRICE SPINNER +Objects are allowed to be for sale for L$0 to invoke buy UI behavior +even though the user gets a free copy. +--> + <spinner + follows="left|top" + decimal_digits="0" + increment="1" + left_pad="0" + control_name="Edit Cost" + name="Edit Cost" + label="L$" + label_width="15" + label_text.valign="center" + valign="center" + width="85" + min_val="0" + height="20" + max_val="999999999" /> + <!-- NEW SALE TYPE COMBO BOX --> <combo_box - left_pad="10" + left_pad="8" layout="topleft" follows="left|top" allow_text_entry="false" height="23" + top_pad="-23" initial_value="2" max_chars="20" mouse_opaque="true" name="sale type" - width="168"> + width="89"> <combo_box.item name="Copy" label="Copy" @@ -1070,31 +1146,13 @@ label="Original" value="1" /> </combo_box> -<!-- NEW PRICE SPINNER -Objects are allowed to be for sale for L$0 to invoke buy UI behavior -even though the user gets a free copy. ---> - <spinner - follows="left|top" - decimal_digits="0" - increment="1" - top_pad="8" - left="118" - control_name="Edit Cost" - name="Edit Cost" - label="Price: L$" - label_width="65" - width="165" - min_val="0" - height="20" - max_val="999999999" /> <check_box height="15" width="110" top_pad="5" label="Show in search" layout="topleft" - left="100" + left="7" name="search_check" tool_tip="Let people see this object in search results" /> <panel @@ -1107,15 +1165,16 @@ even though the user gets a free copy. name="perms_build" left="0" top_pad="4" - height="105" + height="121" width="290"> <text type="string" length="1" left="10" + word_wrap="true" top_pad="9" text_color="EmphasisColor" - height="16" + height="32" follows="left|top|right" layout="topleft" name="perm_modify" @@ -1158,6 +1217,7 @@ even though the user gets a free copy. label="Modify" layout="topleft" left="10" + height="10" name="checkbox next owner can modify" width="85" /> <check_box @@ -1184,7 +1244,7 @@ even though the user gets a free copy. type="string" text_color="EmphasisColor" length="1" - top="9" + top="23" follows="left|top" layout="topleft" left="230" @@ -1259,7 +1319,36 @@ even though the user gets a free copy. F: </text> </panel> - </panel> + <panel + border="false" + follows="left|top" + layout="topleft" + mouse_opaque="false" + name="pathfinding_attrs_panel" + left="0" + top_pad="0" + height="25" + width="290"> + <text + type="string" + follows="left|top" + name="pathfinding_attributes_label" + top_pad="4" + width="150" + left="10"> + Pathfinding attributes: + </text> + <text + type="string" + follows="left|top" + text_color="EmphasisColor" + name="pathfinding_attributes_value" + width="130" + word_wrap="false" + left_pad="0"> + </text> + </panel> + </panel> <!-- Object tab --> <panel border="false" @@ -1306,8 +1395,7 @@ even though the user gets a free copy. tool_tip="Causes object to not collide with other objects or avatars" top_pad="0" width="123" /> - - <text + <text type="string" length="1" follows="left|top" @@ -2906,7 +2994,7 @@ even though the user gets a free copy. use_ellipses="true" read_only="true" name="media_info" - width="280" /> + width="180" /> <web_browser visible="false" enabled="false" diff --git a/indra/newview/skins/default/xui/en/floater_top_objects.xml b/indra/newview/skins/default/xui/en/floater_top_objects.xml index 4dfdcd15c7..0b71177345 100644 --- a/indra/newview/skins/default/xui/en/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/en/floater_top_objects.xml @@ -2,7 +2,7 @@ <floater legacy_header_height="18" can_resize="true" - height="350" + height="372" layout="topleft" min_height="300" min_width="450" @@ -23,10 +23,6 @@ Time </floater.string> <floater.string - name="scripts_mono_time_label"> - Mono Time - </floater.string> - <floater.string name="top_colliders_title"> Top Colliders </floater.string> @@ -68,31 +64,35 @@ <scroll_list.columns label="Score" name="score" - width="55" /> + width="45" /> <scroll_list.columns label="Name" name="name" - width="140" /> + width="130" /> <scroll_list.columns label="Owner" name="owner" - width="105" /> + width="100" /> <scroll_list.columns label="Location" name="location" - width="130" /> + width="120" /> + <scroll_list.columns + label="Parcel" + name="parcel" + width="120" /> <scroll_list.columns label="Time" name="time" - width="150" /> - <scroll_list.columns - label="Mono Time" - name="mono_time" - width="100" /> + width="130" /> <scroll_list.columns label="URLs" name="URLs" - width="100" /> + width="40" /> + <scroll_list.columns + label="Memory (KB)" + name="memory" + width="40" /> <scroll_list.commit_callback function="TopObjects.CommitObjectsList" /> </scroll_list> @@ -193,6 +193,38 @@ <button.commit_callback function="TopObjects.GetByOwnerName" /> </button> + <text + type="string" + length="1" + follows="left|bottom" + height="20" + layout="topleft" + left="10" + top_pad="5" + name="parcel_name_text" + width="107"> + Parcel: + </text> + <line_editor + follows="left|bottom|right" + height="20" + layout="topleft" + left_pad="3" + name="parcel_name_editor" + top_delta="-3" + width="568" /> + <button + follows="bottom|right" + height="23" + label="Filter" + layout="topleft" + left_pad="5" + name="filter_parcel_btn" + top_delta="0" + width="100"> + <button.commit_callback + function="TopObjects.GetByParcelName" /> + </button> <button follows="bottom|right" height="22" diff --git a/indra/newview/skins/default/xui/en/floater_toybox.xml b/indra/newview/skins/default/xui/en/floater_toybox.xml index 493d44a9cf..d8211c24a7 100644 --- a/indra/newview/skins/default/xui/en/floater_toybox.xml +++ b/indra/newview/skins/default/xui/en/floater_toybox.xml @@ -5,12 +5,12 @@ can_minimize="false" can_resize="false" default_tab_group="1" - height="330" + height="375" help_topic="toybox" layout="topleft" legacy_header_height="18" name="Toybox" - open_positioning="centered" + positioning="centered" save_rect="true" single_instance="true" title="TOOLBAR BUTTONS" @@ -18,7 +18,7 @@ <text follows="left|top" font="SansSerifMedium" - valign="bottom" + valign="top" halign="left" height="20" layout="topleft" @@ -33,7 +33,7 @@ <text follows="left|top" font="SansSerifMedium" - valign="bottom" + valign="top" halign="left" height="20" layout="topleft" @@ -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..eb01294831 100644 --- a/indra/newview/skins/default/xui/en/floater_ui_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_ui_preview.xml @@ -5,7 +5,7 @@ height="640" layout="topleft" min_height="230" - min_width="650" + min_width="750" name="gui_preview_tool" help_topic="gui_preview_tool" single_instance="true" @@ -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_chat_volume.xml b/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml new file mode 100644 index 0000000000..5c71fd3bc6 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + +<floater + legacy_header_height="25" + bevel_style="in" + bg_opaque_image="Inspector_Background" + can_close="false" + can_minimize="false" + height="90" + layout="topleft" + name="floater_voice_volume" + single_instance="true" + sound_flags="0" + title="VOICE CHAT VOLUME" + visible="true" + width="245"> + <slider + control_name="AudioLevelVoice" + disabled_control="MuteAudio" + follows="left|top" + height="16" + increment="0.025" + initial_value="0.5" + label="Voice Chat" + label_width="50" + layout="topleft" + left="15" + top="50" + name="chat_voice_volume" + show_text="false" + slider_label.halign="right" + volume="true" + width="200"> + </slider> + <button + control_name="MuteVoice" + disabled_control="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16" /> +</floater>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml deleted file mode 100644 index 6807b01fa3..0000000000 --- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml +++ /dev/null @@ -1,158 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - open_positioning="cascading" - can_resize="true" - can_minimize="true" - can_close="true" - chrome="true" - height="205" - layout="topleft" - min_height="124" - min_width="190" - name="floater_voice_controls" - help_topic="floater_voice_controls" - title="VOICE CONTROLS" - save_dock_state="true" - save_visibility="true" - save_rect="true" - single_instance="true" - width="282"> - <string - name="title_nearby"> - VOICE SETTINGS - </string> - <string - name="title_group"> - GROUP CALL WITH [GROUP] - </string> - <string - name="title_adhoc"> - CONFERENCE CALL - </string> - <string - name="title_peer_2_peer"> - CALL WITH [NAME] - </string> - <string - name="no_one_near"> - No one near has voice enabled - </string> - <layout_stack - clip="false" - follows="all" - height="189" - layout="topleft" - left="10" - mouse_opaque="false" - name="my_call_stack" - orientation="vertical" - width="263"> - <layout_panel - follows="top|left|right" - user_resize="false" - auto_resize="false" - layout="topleft" - min_height="20" - height="20" - name="my_panel"> - <avatar_icon - enabled="false" - follows="left|top" - height="18" - default_icon_name="Generic_Person" - layout="topleft" - left="5" - name="user_icon" - top="0" - width="18" /> - <text - follows="top|left|right" - font="SansSerifSmallBold" - height="16" - layout="topleft" - left_pad="10" - name="user_text" - text_color="white" - top="4" - use_ellipses="true" - value="My Avatar:" - width="210" /> - <output_monitor - auto_update="true" - draw_border="false" - follows="top|right" - height="16" - layout="topleft" - right="-3" - name="speaking_indicator" - left_pad="5" - visible="true" - width="20" /> - </layout_panel> - <layout_panel name="leave_call_panel" height="26" min_height="26" user_resize="false" auto_resize="false"> - <layout_stack - clip="true" - follows="left|top|right" - height="26" - layout="topleft" - mouse_opaque="false" - name="voice_effect_and_leave_call_stack" - orientation="horizontal" - width="262"> - <layout_panel - height="26" - width="200"> - <panel - class="panel_voice_effect" - name="panel_voice_effect" - visiblity_control="VoiceMorphingEnabled" - filename="panel_voice_effect.xml" /> - </layout_panel> - <layout_panel - auto_resize="false" - user_resize="false" - follows="top|right" - height="23" - visible="true" - layout="topleft" - name="leave_call_btn_panel" - width="100"> - <button - follows="right|top" - height="23" - label="Leave Call" - name="leave_call_btn" - width="100" /> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel - follows="all" - layout="topleft" - left="2" - top_pad="0" - height="132" - name="callers_panel" - user_resize="false" - auto_resize="true" - width="280"> - <avatar_list - follows="all" - height="132" - ignore_online_status="true" - layout="topleft" - multi_select="true" - name="speakers_list" - width="280" /> - <panel - filename="panel_avatar_list_item.xml" - follows="left|right|top" - height="24" - layout="topleft" - left="0" - name="non_avatar_caller" - top="10" - width="276" /> - </layout_panel> - </layout_stack> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_voice_effect.xml b/indra/newview/skins/default/xui/en/floater_voice_effect.xml index 2c754cd8d0..146c3d7e30 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml @@ -5,13 +5,13 @@ height="500" name="voice_effects" help_topic="voice_effects" - title="VOICE MORPHING" + title="VOICE MORPHING PREVIEW" background_visible="true" - follows="all" label="Places" layout="topleft" min_height="360" min_width="200" + save_rect="true" width="300"> <string name="no_voice_effect"> (No Voice Morph) @@ -37,15 +37,20 @@ <string name="effect_Cyber">Cyber</string> <string name="effect_DeepBot">DeepBot</string> <string name="effect_Demon">Demon</string> + <string name="effect_Female Elf">Female Elf</string> <string name="effect_Flirty">Flirty</string> <string name="effect_Foxy">Foxy</string> - <string name="effect_Halloween_2010_Bonus">Halloween_2010_Bonus</string> + <string name="effect_Halloween 2010 Bonus">Halloween_2010_Bonus</string> <string name="effect_Helium">Helium</string> <string name="effect_Husky">Husky</string> + <string name="effect_Husky Whisper">Husky Whisper</string> <string name="effect_Intercom">Intercom</string> + <string name="effect_Julia">Julia</string> + <string name="effect_Lo Lilt">Lo Lilt</string> <string name="effect_Macho">Macho</string> <string name="effect_Micro">Micro</string> <string name="effect_Mini">Mini</string> + <string name="effect_Model">Model</string> <string name="effect_Nano">Nano</string> <string name="effect_Nightmare">Nightmare</string> <string name="effect_PopBot">PopBot</string> @@ -53,10 +58,12 @@ <string name="effect_Radio">Radio</string> <string name="effect_Robot">Robot</string> <string name="effect_Roxanne">Roxanne</string> + <string name="effect_Rumble">Rumble</string> <string name="effect_Sabrina">Sabrina</string> <string name="effect_Samantha">Samantha</string> <string name="effect_Sexy">Sexy</string> <string name="effect_Shorty">Shorty</string> + <string name="effect_Smaller">Smaller</string> <string name="effect_Sneaky">Sneaky</string> <string name="effect_Stallion">Stallion</string> <string name="effect_Sultry">Sultry</string> diff --git a/indra/newview/skins/default/xui/en/floater_voice_volume.xml b/indra/newview/skins/default/xui/en/floater_voice_volume.xml new file mode 100644 index 0000000000..9346295d5b --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_voice_volume.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<!-- + Not can_close / no title to avoid window chrome + Single instance - only have one at a time, recycle it each spawn +--> +<floater + legacy_header_height="25" + bevel_style="in" + bg_opaque_image="Inspector_Background" + can_close="false" + can_minimize="false" + height="90" + layout="topleft" + name="floater_voice_volume" + single_instance="true" + sound_flags="0" + title="VOICE VOLUME" + visible="true" + width="245"> + <text + follows="top|left|right" + font="SansSerifSmall" + height="21" + left="10" + name="avatar_name" + parse_urls="false" + top="35" + text_color="White" + translate="false" + use_ellipses="true" + value="TestString PleaseIgnore" + width="225" /> + <slider + follows="top|left" + height="23" + increment="0.01" + left="1" + max_val="0.95" + min_val="0.05" + name="volume_slider" + show_text="false" + tool_tip="Voice volume" + top_pad="0" + value="0.5" + width="200" /> + <button + follows="top|left" + height="16" + image_disabled="Audio_Off" + image_disabled_selected="AudioMute_Off" + image_hover_selected="AudioMute_Over" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + left_pad="0" + top_delta="4" + name="mute_btn" + width="16" /> +</floater> 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/floater_window_size.xml b/indra/newview/skins/default/xui/en/floater_window_size.xml index 355d257785..115fe413f3 100644 --- a/indra/newview/skins/default/xui/en/floater_window_size.xml +++ b/indra/newview/skins/default/xui/en/floater_window_size.xml @@ -28,22 +28,50 @@ tool_tip="width x height" top_pad="5" width="179"> - <combo_box.item - label="1000 x 700 (default)" - name="item0" - value="1000 x 700" /> - <combo_box.item - label="1024 x 768" - name="item1" - value="1024 x 768" /> - <combo_box.item - label="1280 x 720 (720p)" - name="item2" - value="1280 x 720" /> - <combo_box.item - label="1920 x 1080 (1080p)" - name="item3" - value="1920 x 1080" /> + <combo_box.item + label="1000 x 700 (default)" + name="item1" + value="1000 x 700" /> + <combo_box.item + label="1024 x 768 (4:3 XGA)" + name="item2" + value="1024 x 768" /> + <combo_box.item + label="1280 x 720 (16:9 HDTV)" + name="item3" + value="1280 x 720" /> + <combo_box.item + label="1280 x 800 (5:8 WXGA)" + name="item4" + value="1280 x 800" /> + <combo_box.item + label="1280 x 1024 (5:4 SXGA)" + name="item5" + value="1280 x 1024" /> + <combo_box.item + label="1440 x 900 (8:5 WSXGA)" + name="item7" + value="1440 x 900" /> + <combo_box.item + label="1600 x 900 (16:9 HD+)" + name="item8" + value="1600 x 900" /> + <combo_box.item + label="1600 x 1200 (4:3 UXGA)" + name="item9" + value="1600 x 1200" /> + <combo_box.item + label="1680 x 1050 (8:5 WSXGA+)" + name="item10" + value="1680 x 1050" /> + <combo_box.item + label="1920 x 1080 (16:9 HDTV)" + name="item11" + value="1920 x 1080" /> + <combo_box.item + label="1920 x 1200 (8:5 WUXGA)" + name="item12" + value="1920 x 1200" /> </combo_box> <button follows="right|bottom" diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index 56d79f62c7..83407069d2 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -2,7 +2,7 @@ <floater legacy_header_height="18" can_resize="true" - open_positioning="centered" + positioning="centered" height="600" layout="topleft" min_height="520" diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml index bc3bcd331b..ef4f19cd4c 100644 --- a/indra/newview/skins/default/xui/en/inspect_avatar.xml +++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml @@ -2,14 +2,14 @@ <!-- Not can_close / no title to avoid window chrome Single instance - only have one at a time, recycle it each spawn ---> +--> <floater legacy_header_height="25" bevel_style="in" bg_opaque_image="Inspector_Background" can_close="false" can_minimize="false" - height="164" + height="160" layout="topleft" name="inspect_avatar" single_instance="true" @@ -98,13 +98,13 @@ follows="top|left" height="23" increment="0.01" - left="1" + left="10" max_val="0.95" min_val="0.05" name="volume_slider" show_text="false" tool_tip="Voice volume" - top_pad="0" + top_pad="5" value="0.5" width="200" /> <button @@ -116,10 +116,21 @@ image_selected="AudioMute_Off" image_unselected="Audio_Off" is_toggle="true" - left_pad="0" + left_pad="5" top_delta="4" name="mute_btn" width="16" /> + <text + follows="top|left" + height="16" + left="8" + name="avatar_profile_link" + font="SansSerifSmall" + text_color="White" + top_pad="5" + translate="false" + value="[[LINK] View full profile]" + width="175" /> <avatar_icon follows="top|left" height="38" @@ -130,83 +141,4 @@ name="avatar_icon" top="10" width="38" /> -<!-- Overlapping buttons for default actions - llinspectavatar.cpp makes visible the most likely default action ---> - <button - follows="top|left" - height="20" - label="Add Friend" - left="8" - top="135" - name="add_friend_btn" - width="90" /> - <button - follows="top|left" - height="20" - label="IM" - left_delta="0" - top_delta="0" - name="im_btn" - width="80" - commit_callback.function="InspectAvatar.IM"/> - <button - follows="top|left" - height="20" - label="Profile" - layout="topleft" - name="view_profile_btn" - left_delta="96" - top_delta="0" - tab_stop="false" - width="80" /> - <!-- gear buttons here --> - <menu_button - follows="top|left" - height="20" - layout="topleft" - image_overlay="OptionsMenu_Off" - menu_filename="menu_inspect_avatar_gear.xml" - name="gear_btn" - right="-5" - top_delta="0" - width="35" /> - <menu_button - follows="top|left" - height="20" - image_overlay="OptionsMenu_Off" - menu_filename="menu_inspect_self_gear.xml" - name="gear_self_btn" - right="-5" - top_delta="0" - width="35" /> - <panel - follows="top|left" - top="164" - left="0" - height="60" - width="228" - visible="false" - background_visible="true" - name="moderator_panel" - background_opaque="true" - bg_opaque_color="MouseGray"> - <button - name="disable_voice" - label="Disable Voice" - top="20" - width="95" - height="20" - left="10" - commit_callback.function="InspectAvatar.DisableVoice"/> - <button - name="enable_voice" - label="Enable Voice" - top="20" - width="95" - height="20" - left="10" - visible="false" - commit_callback.function="InspectAvatar.EnableVoice"/> - </panel> </floater> diff --git a/indra/newview/skins/default/xui/en/inspect_object.xml b/indra/newview/skins/default/xui/en/inspect_object.xml index 8d14c974b4..bfeb8fc470 100644 --- a/indra/newview/skins/default/xui/en/inspect_object.xml +++ b/indra/newview/skins/default/xui/en/inspect_object.xml @@ -56,7 +56,7 @@ owner secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about halign="right" right="-5" name="price_text" - text_color="white" + text_color="White" top="60" font_shadow="none" width="60"> @@ -90,6 +90,7 @@ L$30,000 follows="all" font="SansSerifSmall" height="13" + clip="false" name="object_media_url" width="207" left_pad="2" 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_cof_gear.xml b/indra/newview/skins/default/xui/en/menu_cof_gear.xml index a6e9a40e31..45cf780557 100644 --- a/indra/newview/skins/default/xui/en/menu_cof_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_cof_gear.xml @@ -9,5 +9,5 @@ <menu label="New Body Parts" layout="topleft" - name="COF.Geear.New_Body_Parts" /> + name="COF.Gear.New_Body_Parts" /> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml new file mode 100644 index 0000000000..fd5c86b3ca --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_conversation.xml @@ -0,0 +1,196 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + bottom="806" + layout="topleft" + left="0" + mouse_opaque="false" + name="menu_conversation_participant" + visible="false"> + <menu_item_call + label="Close conversation" + layout="topleft" + name="close_conversation"> + <on_click function="Avatar.DoToSelected" parameter="close_conversation"/> + </menu_item_call> + <menu_item_call + label="Open voice conversation" + layout="topleft" + name="open_voice_conversation"> + <on_click function="Avatar.DoToSelected" parameter="open_voice_conversation"/> + </menu_item_call> + <menu_item_call + label="Disconnect from voice" + layout="topleft" + name="disconnect_from_voice"> + <on_click function="Avatar.DoToSelected" parameter="disconnect_from_voice"/> + </menu_item_call> + <menu_item_separator layout="topleft" name="separator_disconnect_from_voice"/> + <menu_item_call + label="View Profile" + layout="topleft" + name="view_profile"> + <on_click function="Avatar.DoToSelected" parameter="view_profile"/> + <on_enable function="Avatar.EnableItem" parameter="can_view_profile"/> + </menu_item_call> + <menu_item_call + label="IM" + layout="topleft" + name="im"> + <on_click function="Avatar.DoToSelected" parameter="im"/> + <on_enable function="Avatar.EnableItem" parameter="can_im"/> + </menu_item_call> + <menu_item_call + label="Offer teleport" + layout="topleft" + name="offer_teleport"> + <on_click function="Avatar.DoToSelected" parameter="offer_teleport"/> + <on_enable function="Avatar.EnableItem" parameter="can_offer_teleport"/> + </menu_item_call> + <menu_item_call + label="Voice call" + layout="topleft" + name="voice_call"> + <on_click function="Avatar.DoToSelected" parameter="voice_call"/> + <on_enable function="Avatar.EnableItem" parameter="can_call" /> + </menu_item_call> + <menu_item_call + label="Chat history..." + layout="topleft" + name="chat_history"> + <on_click function="Avatar.DoToSelected" parameter="chat_history"/> + <on_enable function="Avatar.EnableItem" parameter="can_chat_history"/> + </menu_item_call> + <menu_item_separator layout="topleft" name="separator_chat_history"/> + <menu_item_call + label="Add friend" + layout="topleft" + name="add_friend"> + <on_click function="Avatar.DoToSelected" parameter="add_friend"/> + <on_enable function="Avatar.EnableItem" parameter="can_add" /> + </menu_item_call> + <menu_item_call + label="Remove friend" + layout="topleft" + name="remove_friend"> + <on_click function="Avatar.DoToSelected" parameter="remove_friend" /> + <on_enable function="Avatar.EnableItem" parameter="can_delete" /> + </menu_item_call> + <menu_item_call + label="Remove friends" + layout="topleft" + name="remove_friends"> + <on_click function="Avatar.DoToSelected" parameter="remove_friend" /> + <on_enable function="Avatar.EnableItem" parameter="can_delete" /> + </menu_item_call> + <menu_item_call + label="Invite to group..." + layout="topleft" + name="invite_to_group"> + <on_click function="Avatar.DoToSelected" parameter="invite_to_group" /> + <on_enable function="Avatar.EnableItem" parameter="can_invite" /> + </menu_item_call> + <menu_item_separator layout="topleft" name="separator_invite_to_group"/> + <menu_item_call + label="Map" + layout="topleft" + name="map"> + <on_click function="Avatar.DoToSelected" parameter="map" /> + <on_enable function="Avatar.EnableItem" parameter="can_show_on_map" /> + </menu_item_call> + <menu_item_call + label="Share" + layout="topleft" + name="share"> + <on_click function="Avatar.DoToSelected" parameter="share" /> + <on_enable function="Avatar.EnableItem" parameter="can_share" /> + </menu_item_call> + <menu_item_call + label="Pay" + layout="topleft" + name="pay"> + <on_click function="Avatar.DoToSelected" parameter="pay" /> + <on_enable function="Avatar.EnableItem" parameter="can_pay" /> + </menu_item_call> + <menu_item_check + label="Block Voice" + layout="topleft" + name="block_unblock"> + <on_click function="Avatar.DoToSelected" parameter="block_unblock" /> + <on_check function="Avatar.CheckItem" parameter="is_blocked" /> + <on_enable function="Avatar.EnableItem" parameter="can_block" /> + </menu_item_check> + <menu_item_check + label="Block Text" + layout="topleft" + name="MuteText"> + <on_click function="Avatar.DoToSelected" parameter="mute_unmute" /> + <on_check function="Avatar.CheckItem" parameter="is_muted" /> + <on_enable function="Avatar.EnableItem" parameter="can_block" /> + </menu_item_check> + <menu_item_call + label="Group Profile" + layout="topleft" + name="group_profile"> + <on_click function="Group.DoToSelected" parameter="group_profile"/> + <on_enable function="Avatar.EnableItem" parameter="can_group_profile" /> + </menu_item_call> + <menu_item_call + label="Activate Group" + layout="topleft" + name="activate_group"> + <on_click function="Group.DoToSelected" parameter="activate_group"/> + <on_enable function="Avatar.EnableItem" parameter="can_activate_group" /> + </menu_item_call> + <menu_item_call + label="Leave Group" + layout="topleft" + name="leave_group"> + <on_click function="Group.DoToSelected" parameter="leave_group"/> + <on_enable function="Avatar.EnableItem" parameter="can_leave_group" /> + </menu_item_call> + <menu_item_separator layout="topleft" name="Moderator Options Separator"/> + <context_menu + label="Moderator Options" + layout="topleft" + name="Moderator Options"> + <menu_item_check + label="Allow text chat" + layout="topleft" + name="AllowTextChat"> + <on_check function="Avatar.CheckItem" parameter="is_allowed_text_chat" /> + <on_click function="Avatar.DoToSelected" parameter="toggle_allow_text_chat" /> + <on_enable function="Avatar.EnableItem" parameter="can_allow_text_chat" /> + </menu_item_check> + <menu_item_separator layout="topleft" name="moderate_voice_separator" /> + <menu_item_call + label="Mute this participant" + layout="topleft" + name="ModerateVoiceMuteSelected"> + <on_click function="Avatar.DoToSelected" parameter="selected" /> + <on_enable function="Avatar.EnableItem" parameter="can_mute" /> + <on_visible function="Avatar.VisibleItem" parameter="show_mute" /> + </menu_item_call> + <menu_item_call + label="Unmute this participant" + layout="topleft" + name="ModerateVoiceUnMuteSelected"> + <on_click function="Avatar.DoToSelected" parameter="selected" /> + <on_enable function="Avatar.EnableItem" parameter="can_unmute" /> + <on_visible function="Avatar.VisibleItem" parameter="show_unmute" /> + </menu_item_call> + <menu_item_call + label="Mute everyone" + layout="topleft" + name="ModerateVoiceMute"> + <on_click function="Avatar.DoToSelected" parameter="mute_all" /> + <on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" /> + </menu_item_call> + <menu_item_call + label="Unmute everyone" + layout="topleft" + name="ModerateVoiceUnmute"> + <on_click function="Avatar.DoToSelected" parameter="unmute_all" /> + <on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" /> + </menu_item_call> + </context_menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml new file mode 100644 index 0000000000..8796b87955 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml @@ -0,0 +1,142 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Conversation Context Menu"> + <menu_item_call + label="IM..." + layout="topleft" + name="IM"> + <on_click + function="Calllog.Action" + parameter="im" /> + <on_enable + function="Calllog.Enable" + parameter="can_im" /> + </menu_item_call> + <menu_item_call + label="Voice call..." + layout="topleft" + name="Call"> + <on_click + function="Calllog.Action" + parameter="call" /> + <on_enable + function="Calllog.Enable" + parameter="can_call" /> + </menu_item_call> + <menu_item_call + label="Open chat history..." + layout="topleft" + name="Chat history"> + <on_click + function="Calllog.Action" + parameter="chat_history" /> + <on_enable + function="Calllog.Enable" + parameter="can_view_chat_history" /> + </menu_item_call> + <menu_item_call + label="View Profile" + layout="topleft" + name="View Profile"> + <on_click + function="Calllog.Action" + parameter="view_profile" /> + <on_enable + function="Calllog.Enable" + parameter="can_view_profile" /> + </menu_item_call> + <menu_item_call + label="Offer Teleport" + name="teleport"> + <on_click + function="Calllog.Action" + parameter="offer_teleport"/> + <on_enable + function="Calllog.Enable" + parameter="can_offer_teleport"/> + </menu_item_call> + <menu_item_separator /> + <menu_item_call + label="Add Friend" + layout="topleft" + name="add_friend"> + <on_click + function="Calllog.Action" + parameter="add_friend"/> + <on_visible + function="Calllog.Check" + parameter="is_not_friend" /> + </menu_item_call> + <menu_item_call + label="Remove Friend" + layout="topleft" + name="remove_friend"> + <on_click + function="Calllog.Action" + parameter="remove_friend"/> + <on_visible + function="Calllog.Check" + parameter="is_friend" /> + </menu_item_call> + <menu_item_call + label="Invite to group..." + layout="topleft" + name="Invite"> + <on_click + function="Calllog.Action" + parameter="invite_to_group"/> + <on_enable + function="Calllog.Enable" + parameter="can_invite_to_group" /> + </menu_item_call> + <menu_item_separator /> + <menu_item_call + label="Map" + layout="topleft" + name="Map"> + <on_click + function="Calllog.Action" + parameter="show_on_map" /> + <on_enable + function="Calllog.Enable" + parameter="can_show_on_map" /> + </menu_item_call> + <menu_item_call + label="Share" + layout="topleft" + name="Share"> + <on_click + function="Calllog.Action" + parameter="share" /> + <on_enable + function="Calllog.Enable" + parameter="can_share" /> + </menu_item_call> + <menu_item_call + label="Pay" + layout="topleft" + name="Pay"> + <on_click + function="Calllog.Action" + parameter="pay" /> + <on_enable + function="Calllog.Enable" + parameter="can_pay" /> + </menu_item_call> + <menu_item_check + label="Block/Unblock" + layout="topleft" + name="Block/Unblock"> + <menu_item_check.on_click + function="Calllog.Action" + parameter="block"/> + <menu_item_check.on_check + function="Calllog.Check" + parameter="is_blocked" /> + <menu_item_check.on_enable + function="Calllog.Enable" + parameter="can_block" /> + </menu_item_check> + +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml new file mode 100644 index 0000000000..ce65b23971 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + name="menu_conversation_view" + left="0" bottom="0" visible="false" + mouse_opaque="false"> + <menu_item_check + label="Sort by name" + name="sort_by_name"> + <on_click + function="CallLog.Action" + parameter="sort_by_name"/> + <on_check + function="CallLog.Check" + parameter="sort_by_name"/> + </menu_item_check> + <menu_item_check + label="Sort by date" + name="sort_by_date"> + <on_click + function="CallLog.Action" + parameter="sort_by_date" /> + <on_check + function="CallLog.Check" + parameter="sort_by_date" /> + </menu_item_check> + <menu_item_separator /> + <menu_item_check + label="Sort friends on top" + name="sort_by_friends"> + <on_click + function="CallLog.Action" + parameter="sort_friends_on_top" /> + <on_check + function="CallLog.Check" + parameter="sort_friends_on_top" /> + </menu_item_check> + <menu_item_separator /> + <menu_item_call + label="View Nearby chat history..." + name="view_nearby_chat_history"> + <on_click + function="CallLog.Action" + parameter="view_nearby_chat_history" /> + </menu_item_call> +</toggleable_menu> 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_group_plus.xml b/indra/newview/skins/default/xui/en/menu_group_plus.xml index fce7414d80..eca9e7f3c9 100644 --- a/indra/newview/skins/default/xui/en/menu_group_plus.xml +++ b/indra/newview/skins/default/xui/en/menu_group_plus.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu name="menu_group_plus" +<toggleable_menu name="menu_group_plus" left="0" bottom="0" visible="false" mouse_opaque="false"> <menu_item_call name="item_join" label="Join Group..."> @@ -8,4 +8,4 @@ <menu_item_call name="item_new" label="New Group..."> <menu_item_call.on_click function="People.Group.Plus.Action" userdata="new_group" /> </menu_item_call> -</menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml new file mode 100644 index 0000000000..8882d0a7d8 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Conversation Gear Menu"> + <menu_item_call + label="View Profile" + layout="topleft" + name="View Profile"> + <on_click function="Avatar.GearDoToSelected" parameter="view_profile" /> + <on_enable function="Avatar.EnableGearItem" parameter="can_view_profile" /> + </menu_item_call> + <menu_item_call + label="Add Friend" + layout="topleft" + name="Add Friend"> + <on_click function="Avatar.GearDoToSelected" parameter="add_friend" /> + <on_enable function="Avatar.EnableGearItem" parameter="can_add" /> + </menu_item_call> + <menu_item_call + label="Remove friend" + layout="topleft" + name="remove_friend"> + <on_click function="Avatar.GearDoToSelected" parameter="remove_friend" /> + <on_enable function="Avatar.EnableGearItem" parameter="can_delete" /> + </menu_item_call> + <menu_item_call + label="Offer teleport" + layout="topleft" + name="offer_teleport"> + <on_click function="Avatar.GearDoToSelected" parameter="offer_teleport"/> + <on_enable function="Avatar.EnableGearItem" parameter="can_offer_teleport"/> + </menu_item_call> + <menu_item_call + label="Invite to group..." + layout="topleft" + name="invite_to_group"> + <on_click function="Avatar.GearDoToSelected" parameter="invite_to_group" /> + <on_enable function="Avatar.EnableGearItem" parameter="can_invite" /> + </menu_item_call> + <menu_item_separator + layout="topleft" + name="View Icons Separator" /> + <menu_item_call + label="Chat history..." + layout="topleft" + name="chat_history"> + <on_click function="Avatar.GearDoToSelected" parameter="chat_history"/> + <on_enable function="Avatar.EnableGearItem" parameter="can_chat_history"/> + </menu_item_call> + <menu_item_separator + layout="topleft"/> + <menu_item_call + label="Map" + layout="topleft" + name="map"> + <on_click function="Avatar.GearDoToSelected" parameter="map" /> + <on_enable function="Avatar.EnableGearItem" parameter="can_show_on_map" /> + </menu_item_call> + <menu_item_call + label="Share" + layout="topleft" + name="Share"> + <on_click function="Avatar.GearDoToSelected" parameter="share" /> + <on_enable function="Avatar.EnableGearItem" parameter="can_share" /> + </menu_item_call> + <menu_item_call + label="Pay" + layout="topleft" + name="Pay"> + <on_click function="Avatar.GearDoToSelected" parameter="pay" /> + <on_enable function="Avatar.EnableGearItem" parameter="can_pay" /> + </menu_item_call> + <menu_item_separator + layout="topleft"/> + <menu_item_check + label="Block Voice" + layout="topleft" + name="Block/Unblock"> + <on_check function="Avatar.CheckGearItem" parameter="is_blocked" /> + <on_click function="Avatar.GearDoToSelected" parameter="block_unblock" /> + <on_enable function="Avatar.EnableGearItem" parameter="can_block" /> + </menu_item_check> + <menu_item_check + label="Block Text" + layout="topleft" + name="MuteText"> + <on_check function="Avatar.CheckGearItem" parameter="is_muted" /> + <on_click function="Avatar.GearDoToSelected" parameter="mute_unmute" /> + <on_enable function="Avatar.EnableGearItem" parameter="can_block" /> + </menu_item_check> + <menu_item_separator + layout="topleft"/> +</toggleable_menu> + diff --git a/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml new file mode 100644 index 0000000000..b0adca0e0e --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + name="menu_modes" + left="0" bottom="0" visible="false" + mouse_opaque="false"> + <menu_item_check + label="Compact view" + name="compact_view"> + <menu_item_check.on_click + function="IMSession.Menu.Action" + parameter="compact_view"/> + <menu_item_check.on_check + function="IMSession.Menu.CompactExpandedModes.CheckItem" + parameter="compact_view"/> + </menu_item_check> + <menu_item_check + label="Expanded view" + name="expanded_view"> + <menu_item_check.on_click + function="IMSession.Menu.Action" + parameter="expanded_view"/> + <menu_item_check.on_check + function="IMSession.Menu.CompactExpandedModes.CheckItem" + parameter="expanded_view"/> + </menu_item_check> + <menu_item_separator layout="topleft" /> + <menu_item_check name="IMShowTime" label="Show time"> + <menu_item_check.on_click + function="IMSession.Menu.Action" + parameter="IMShowTime" /> + <menu_item_check.on_check + function="IMSession.Menu.ShowModes.CheckItem" + parameter="IMShowTime" /> + <menu_item_check.on_enable + function="IMSession.Menu.ShowModes.Enable" + parameter="IMShowTime" /> + </menu_item_check> + <menu_item_check name="IMShowNamesForP2PConv" label="Show names in one-to-one conversations"> + <menu_item_check.on_click + function="IMSession.Menu.Action" + parameter="IMShowNamesForP2PConv" /> + <menu_item_check.on_check + function="IMSession.Menu.ShowModes.CheckItem" + parameter="IMShowNamesForP2PConv" /> + <menu_item_check.on_enable + function="IMSession.Menu.ShowModes.Enable" + parameter="IMShowNamesForP2PConv" /> + </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_im_well_button.xml b/indra/newview/skins/default/xui/en/menu_im_well_button.xml deleted file mode 100644 index f8dfba91ff..0000000000 --- a/indra/newview/skins/default/xui/en/menu_im_well_button.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<context_menu - layout="topleft" - name="IM Well Button Context Menu"> - <menu_item_call - label="Close All" - layout="topleft" - name="Close All"> - <menu_item_call.on_click - function="IMWellChicletMenu.Action" - parameter="close all" /> - <menu_item_call.on_enable - function="IMWellChicletMenu.EnableItem" - parameter="can close all" /> - </menu_item_call> -</context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml deleted file mode 100644 index 76b188220d..0000000000 --- a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml +++ /dev/null @@ -1,143 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<toggleable_menu - create_jump_keys="true" - layout="topleft" - mouse_opaque="false" - visible="false" - name="Gear Menu"> - <menu_item_call - label="View Profile" - enabled="true" - name="view_profile"> - <menu_item_call.on_click - function="InspectAvatar.ViewProfile"/> - </menu_item_call> - <menu_item_call - label="Add Friend" - name="add_friend"> - <menu_item_call.on_click - function="InspectAvatar.AddFriend"/> - <menu_item_call.on_enable - function="InspectAvatar.Gear.Enable"/> - </menu_item_call> - <menu_item_call - label="IM" - name="im"> - <menu_item_call.on_click - function="InspectAvatar.IM"/> - </menu_item_call> - <menu_item_call - label="Call" - enabled="true" - name="call"> - <menu_item_call.on_click - function="InspectAvatar.Call"/> - <menu_item_call.on_enable - function="InspectAvatar.Gear.EnableCall"/> - </menu_item_call> - <menu_item_call - label="Teleport" - name="teleport"> - <menu_item_call.on_click - function="InspectAvatar.Teleport"/> - <menu_item_call.on_enable - function="InspectAvatar.Gear.EnableTeleportOffer"/> - </menu_item_call> - <menu_item_call - label="Invite to Group" - name="invite_to_group"> - <menu_item_call.on_click - function="InspectAvatar.InviteToGroup"/> - </menu_item_call> - <menu_item_separator /> - <menu_item_call - label="Block" - name="block"> - <menu_item_call.on_click - function="InspectAvatar.ToggleMute"/> - <menu_item_call.on_visible - function="InspectAvatar.EnableMute" /> - </menu_item_call> - <menu_item_call - label="Unblock" - name="unblock"> - <menu_item_call.on_click - function="InspectAvatar.ToggleMute"/> - <menu_item_call.on_visible - function="InspectAvatar.EnableUnmute" /> - </menu_item_call> - <menu_item_call - label="Report" - name="report"> - <menu_item_call.on_click - function="InspectAvatar.Report"/> - </menu_item_call> - <menu_item_call - label="Freeze" - name="freeze"> - <menu_item_call.on_click - function="InspectAvatar.Freeze"/> - <menu_item_call.on_visible - function="InspectAvatar.VisibleFreeze"/> - </menu_item_call> - <menu_item_call - label="Eject" - name="eject"> - <menu_item_call.on_click - function="InspectAvatar.Eject"/> - <menu_item_call.on_visible - function="InspectAvatar.VisibleEject"/> - </menu_item_call> - <menu_item_call - label="Kick" - name="kick"> - <menu_item_call.on_click - function="InspectAvatar.Kick"/> - <menu_item_call.on_visible - function="InspectAvatar.EnableGod"/> - </menu_item_call> - <menu_item_call - label="CSR" - name="csr"> - <menu_item_call.on_click - function="InspectAvatar.CSR" /> - <menu_item_call.on_visible - function="InspectAvatar.EnableGod" /> - </menu_item_call> - <menu_item_call - label="Debug Textures" - name="debug"> - <menu_item_call.on_click - function="Avatar.Debug"/> - <menu_item_call.on_visible - function="IsGodCustomerService"/> - </menu_item_call> - <menu_item_call - label="Find On Map" - name="find_on_map"> - <menu_item_call.on_click - function="InspectAvatar.FindOnMap"/> - <menu_item_call.on_visible - function="InspectAvatar.VisibleFindOnMap"/> - </menu_item_call> - <menu_item_call - label="Zoom In" - name="zoom_in"> - <menu_item_call.on_click - function="InspectAvatar.ZoomIn"/> - <menu_item_call.on_visible - function="InspectAvatar.VisibleZoomIn"/> - </menu_item_call> - <menu_item_call - label="Pay" - name="pay"> - <menu_item_call.on_click - function="InspectAvatar.Pay"/> - </menu_item_call> - <menu_item_call - label="Share" - name="share"> - <menu_item_call.on_click - function="InspectAvatar.Share"/> - </menu_item_call> -</toggleable_menu> 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..2c420aa1e3 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 @@ -57,7 +57,7 @@ layout="topleft" name="take_copy"> <menu_item_call.on_click - function="InspectObject.TakeFreeCopy"/> + function="Tools.TakeCopy"/> <menu_item_call.on_visible function="Tools.EnableTakeCopy"/> </menu_item_call> @@ -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_inspect_self_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml deleted file mode 100644 index 5e7b16ed4a..0000000000 --- a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml +++ /dev/null @@ -1,252 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<toggleable_menu - layout="topleft" - name="Self Pie"> - <menu_item_call - label="Sit Down" - layout="topleft" - name="Sit Down Here"> - <menu_item_call.on_click - function="Self.SitDown" - parameter="" /> - <menu_item_call.on_enable - function="Self.EnableSitDown" /> - </menu_item_call> - <menu_item_call - label="Stand Up" - layout="topleft" - name="Stand Up"> - <menu_item_call.on_click - function="Self.StandUp" - parameter="" /> - <menu_item_call.on_enable - function="Self.EnableStandUp" /> - </menu_item_call> - <context_menu - label="Take Off" - layout="topleft" - name="Take Off >"> - <context_menu - label="Clothes" - layout="topleft" - name="Clothes >"> - <menu_item_call - enabled="false" - label="Shirt" - layout="topleft" - name="Shirt"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="shirt" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="shirt" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Pants" - layout="topleft" - name="Pants"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="pants" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="pants" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Skirt" - layout="topleft" - name="Skirt"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="skirt" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="skirt" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Shoes" - layout="topleft" - name="Shoes"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="shoes" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="shoes" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Socks" - layout="topleft" - name="Socks"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="socks" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="socks" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Jacket" - layout="topleft" - name="Jacket"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="jacket" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="jacket" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Gloves" - layout="topleft" - name="Gloves"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="gloves" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="gloves" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Undershirt" - layout="topleft" - name="Self Undershirt"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="undershirt" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="undershirt" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Underpants" - layout="topleft" - name="Self Underpants"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="underpants" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="underpants" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Tattoo" - layout="topleft" - name="Self Tattoo"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="tattoo" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="tattoo" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Alpha" - layout="topleft" - name="Self Alpha"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="alpha" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="alpha" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="All Clothes" - layout="topleft" - name="All Clothes"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="all" /> - </menu_item_call> - </context_menu> - <context_menu - label="HUD" - layout="topleft" - name="Object Detach HUD" /> - <context_menu - label="Detach" - layout="topleft" - name="Object Detach" /> - <menu_item_call - label="Detach All" - layout="topleft" - name="Detach All"> - <menu_item_call.on_click - function="Self.RemoveAllAttachments" - parameter="" /> - <menu_item_call.on_enable - function="Self.EnableRemoveAllAttachments" /> - </menu_item_call> - </context_menu> - <menu_item_call - label="Change Outfit" - layout="topleft" - name="Chenge Outfit"> - <menu_item_call.on_click - function="CustomizeAvatar" /> - <menu_item_call.on_enable - function="Edit.EnableCustomizeAvatar" /> - </menu_item_call> - <menu_item_call label="Edit My Outfit" - layout="topleft" - name="Edit Outfit"> - <menu_item_call.on_click - function="EditOutfit" /> - <menu_item_call.on_enable - function="Edit.EnableCustomizeAvatar" /> - </menu_item_call> - <menu_item_call label="Edit My Shape" - layout="topleft" - name="Edit My Shape"> - <menu_item_call.on_click - function="EditShape" /> - <menu_item_call.on_enable - function="Edit.EnableEditShape" /> - </menu_item_call> - <menu_item_call - label="My Friends" - layout="topleft" - name="Friends..."> - <menu_item_call.on_click - function="SideTray.PanelPeopleTab" - parameter="friends_panel" /> - </menu_item_call> - <menu_item_call - label="My Groups" - layout="topleft" - name="Groups..."> - <menu_item_call.on_click - function="SideTray.PanelPeopleTab" - parameter="groups_panel" /> - </menu_item_call> - <menu_item_call - label="My Profile" - layout="topleft" - name="Profile..."> - <menu_item_call.on_click - function="ShowAgentProfile" - parameter="agent" /> - </menu_item_call> - <menu_item_call - label="Debug Textures" - name="Debug..."> - <menu_item_call.on_click - function="Avatar.Debug" /> - <menu_item_call.on_visible - function="IsGodCustomerService"/> - </menu_item_call> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index fb85e5278a..13dc0b941a 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -453,6 +453,14 @@ layout="topleft" name="Copy Separator" /> <menu_item_call + label="Cut" + layout="topleft" + name="Cut"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="cut" /> + </menu_item_call> + <menu_item_call label="Copy" layout="topleft" name="Copy"> @@ -529,6 +537,14 @@ layout="topleft" name="Landmark Separator" /> <menu_item_call + label="Copy SLurl" + layout="topleft" + name="url_copy"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="copy_slurl" /> + </menu_item_call> + <menu_item_call label="About Landmark" layout="topleft" name="About Landmark"> @@ -686,12 +702,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..29720a680b 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="false" 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_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml index 719509301b..f6004621a6 100644 --- a/indra/newview/skins/default/xui/en/menu_object.xml +++ b/indra/newview/skins/default/xui/en/menu_object.xml @@ -1,179 +1,199 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <context_menu - layout="topleft" - name="Object Pie"> - <menu_item_call - enabled="false" - label="Touch" - name="Object Touch"> - <menu_item_call.on_click - function="Object.Touch" /> - <menu_item_call.on_enable - function="Object.EnableTouch" - name="EnableTouch" - parameter="Touch" /> - </menu_item_call> - <menu_item_call - label="Edit" - name="Edit..."> - <menu_item_call.on_click - function="Object.Edit" /> + layout="topleft" + name="Object Pie"> + <menu_item_call + enabled="false" + label="Touch" + name="Object Touch"> + <menu_item_call.on_click + function="Object.Touch" /> <menu_item_call.on_enable - function="EnableEdit"/> - </menu_item_call> - <menu_item_call + function="Object.EnableTouch" + name="EnableTouch" + parameter="Touch" /> + </menu_item_call> + <menu_item_call + label="Edit" + name="Edit..."> + <menu_item_call.on_click + function="Object.Edit" /> + <menu_item_call.on_enable + function="EnableEdit"/> + </menu_item_call> + <menu_item_call label="Build" name="Build"> - <menu_item_call.on_click + <menu_item_call.on_click function="Object.Build" /> - <menu_item_call.on_enable - function="EnableEdit"/> - </menu_item_call> - <menu_item_call - enabled="false" - label="Open" - name="Open"> - <menu_item_call.on_click - function="Object.Open" /> - <menu_item_call.on_enable - function="Object.EnableOpen" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Sit Here" - name="Object Sit"> - <menu_item_call.on_click - function="Object.SitOrStand" /> - <menu_item_call.on_enable - function="Object.EnableSit" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Stand Up" - name="Object Stand Up"> - <menu_item_call.on_click - function="Object.SitOrStand" /> - <menu_item_call.on_enable - function="Object.EnableStandUp" /> - </menu_item_call> - <menu_item_call - label="Object Profile" - name="Object Inspect"> - <menu_item_call.on_click - function="Object.Inspect" /> - <menu_item_call.on_enable - function="Object.EnableInspect" /> - </menu_item_call> + <menu_item_call.on_enable + function="EnableEdit"/> + </menu_item_call> <menu_item_call - label="Zoom In" - name="Zoom In"> + enabled="false" + label="Open" + name="Open"> <menu_item_call.on_click - function="Object.ZoomIn" /> + function="Object.Open" /> + <menu_item_call.on_enable + function="Object.EnableOpen" /> </menu_item_call> -<menu_item_separator layout="topleft" /> - <context_menu - label="Put On" - name="Put On" > - <menu_item_call - enabled="false" - label="Wear" - name="Wear"> - <menu_item_call.on_click - function="Object.AttachToAvatar" /> - <menu_item_call.on_enable - function="Object.EnableWear" /> - </menu_item_call> - <menu_item_call + <menu_item_call enabled="false" - label="Add" - name="Add"> - <menu_item_call.on_click - function="Object.AttachAddToAvatar" /> - <menu_item_call.on_enable - function="Object.EnableWear" /> - </menu_item_call> - <context_menu - label="Attach" - name="Object Attach" /> - <context_menu - label="Attach HUD" - name="Object Attach HUD" /> - </context_menu> - <context_menu - label="Manage" - name="Remove"> - <menu_item_call - enabled="false" - label="Report Abuse" - name="Report Abuse..."> - <menu_item_call.on_click - function="Object.ReportAbuse" /> - <menu_item_call.on_enable - function="Object.EnableReportAbuse" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Block" - name="Object Mute"> - <menu_item_call.on_click - function="Object.Mute" /> - <menu_item_call.on_enable - function="Object.EnableMute" /> - </menu_item_call> - <menu_item_call + label="Sit Here" + name="Object Sit"> + <menu_item_call.on_click + function="Object.SitOrStand" /> + <menu_item_call.on_enable + function="Object.EnableSit" /> + </menu_item_call> + <menu_item_call enabled="false" - label="Return" - name="Return..."> - <menu_item_call.on_click - function="Object.Return" /> - <menu_item_call.on_enable - function="Object.EnableReturn" /> - </menu_item_call> - </context_menu> - <menu_item_separator layout="topleft" /> - <menu_item_call - label="Take" - layout="topleft" - name="Pie Object Take"> + label="Stand Up" + name="Object Stand Up"> + <menu_item_call.on_click + function="Object.SitOrStand" /> + <menu_item_call.on_enable + function="Object.EnableStandUp" /> + </menu_item_call> + <menu_item_call + label="Object Profile" + name="Object Inspect"> + <menu_item_call.on_click + function="Object.Inspect" /> + <menu_item_call.on_enable + function="Object.EnableInspect" /> + </menu_item_call> + <menu_item_call + label="Zoom In" + name="Zoom In"> + <menu_item_call.on_click + function="Object.ZoomIn" /> + </menu_item_call> + <menu_item_call + label="Show in linksets" + name="show_in_linksets"> + <menu_item_call.on_click + function="Pathfinding.Linksets.Select" /> + <menu_item_call.on_enable + function="EnableSelectInPathfindingLinksets"/> + <menu_item_call.on_visible + function="EnableSelectInPathfindingLinksets"/> + </menu_item_call> + <menu_item_call + label="Show in characters" + name="show_in_characters"> + <menu_item_call.on_click + function="Pathfinding.Characters.Select" /> + <menu_item_call.on_enable + function="EnableSelectInPathfindingCharacters"/> + <menu_item_call.on_visible + function="EnableSelectInPathfindingCharacters"/> + </menu_item_call> + <menu_item_separator layout="topleft" /> + <context_menu + label="Put On" + name="Put On" > + <menu_item_call + enabled="false" + label="Wear" + name="Wear"> <menu_item_call.on_click - function="Object.Take"/> + function="Object.AttachToAvatar" /> <menu_item_call.on_enable - function="Object.VisibleTake"/> - </menu_item_call> - <menu_item_call - enabled="false" - label="Take Copy" - name="Take Copy"> + function="Object.EnableWear" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Add" + name="Add"> <menu_item_call.on_click - function="Tools.TakeCopy" /> + function="Object.AttachAddToAvatar" /> <menu_item_call.on_enable - function="Tools.EnableTakeCopy" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Pay" - name="Pay..."> - <menu_item_call.on_click - function="PayObject" /> - <menu_item_call.on_enable - function="EnablePayObject" /> -</menu_item_call> - <menu_item_call - enabled="false" - label="Buy" - name="Buy..."> + function="Object.EnableWear" /> + </menu_item_call> + <context_menu + label="Attach" + name="Object Attach" /> + <context_menu + label="Attach HUD" + name="Object Attach HUD" /> + </context_menu> + <context_menu + label="Manage" + name="Remove"> + <menu_item_call + enabled="false" + label="Report Abuse" + name="Report Abuse..."> <menu_item_call.on_click - function="Object.Buy" /> + function="Object.ReportAbuse" /> <menu_item_call.on_enable - function="Object.EnableBuy" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Delete" - name="Delete"> + function="Object.EnableReportAbuse" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Block" + name="Object Mute"> <menu_item_call.on_click - function="Object.Delete" /> + function="Object.Mute" /> <menu_item_call.on_enable - function="Object.EnableDelete" /> + function="Object.EnableMute" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Return" + name="Return..."> + <menu_item_call.on_click + function="Object.Return" /> + <menu_item_call.on_enable + function="Object.EnableReturn" /> + </menu_item_call> + </context_menu> + <menu_item_separator layout="topleft" /> + <menu_item_call + label="Take" + layout="topleft" + name="Pie Object Take"> + <menu_item_call.on_click + function="Object.Take"/> + <menu_item_call.on_enable + function="Object.VisibleTake"/> + </menu_item_call> + <menu_item_call + enabled="false" + label="Take Copy" + name="Take Copy"> + <menu_item_call.on_click + function="Tools.TakeCopy" /> + <menu_item_call.on_enable + function="Tools.EnableTakeCopy" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Pay" + name="Pay..."> + <menu_item_call.on_click + function="PayObject" /> + <menu_item_call.on_enable + function="EnablePayObject" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Buy" + name="Buy..."> + <menu_item_call.on_click + function="Object.Buy" /> + <menu_item_call.on_enable + function="Object.EnableBuy" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Delete" + name="Delete"> + <menu_item_call.on_click + function="Object.Delete" /> + <menu_item_call.on_enable + function="Object.EnableDelete" /> </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_object_icon.xml b/indra/newview/skins/default/xui/en/menu_object_icon.xml index 0c8a2af002..2d4f1792c2 100644 --- a/indra/newview/skins/default/xui/en/menu_object_icon.xml +++ b/indra/newview/skins/default/xui/en/menu_object_icon.xml @@ -24,4 +24,22 @@ function="ObjectIcon.Action" parameter="block" /> </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Show on Map" + layout="topleft" + name="show_on_map"> + <menu_item_call.on_click + function="ObjectIcon.Action" + parameter="map" /> + </menu_item_call> + <menu_item_call + label="Teleport to Object Location" + layout="topleft" + name="teleport_to_object"> + <menu_item_call.on_click + function="ObjectIcon.Action" + parameter="teleport" /> + </menu_item_call> </menu> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml index fc7272b904..3b8ace6308 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml @@ -195,6 +195,20 @@ <menu_item_separator name="sepatator2" /> <menu_item_call + label="Expand all folders" + layout="topleft" + name="expand"> + <on_click + function="Gear.Expand" /> + </menu_item_call> + <menu_item_call + label="Collapse all folders" + layout="topleft" + name="collapse"> + <on_click + function="Gear.Collapse" /> + </menu_item_call> + <menu_item_call label="Rename Outfit" layout="topleft" name="rename"> diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml new file mode 100644 index 0000000000..7ea87ee05c --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml @@ -0,0 +1,112 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="participant_manu_view"> + <menu_item_check + label="Sort conversations by type" + layout="topleft" + name="sort_sessions_by_type"> + <on_click + function="IMFloaterContainer.Action" + parameter="sort_sessions_by_type" /> + <on_check + function="IMFloaterContainer.Check" + parameter="sort_sessions_by_type" /> + </menu_item_check> + <menu_item_check + label="Sort conversations by name" + layout="topleft" + name="sort_sessions_by_name"> + <on_click + function="IMFloaterContainer.Action" + parameter="sort_sessions_by_name" /> + <on_check + function="IMFloaterContainer.Check" + parameter="sort_sessions_by_name" /> + </menu_item_check> + <menu_item_check + label="Sort conversations by recent activity" + layout="topleft" + name="sort_sessions_by_recent"> + <on_click + function="IMFloaterContainer.Action" + parameter="sort_sessions_by_recent" /> + <on_check + function="IMFloaterContainer.Check" + parameter="sort_sessions_by_recent" /> + </menu_item_check> + <menu_item_separator + layout="topleft" /> + <menu_item_check + label="Sort participants by name" + layout="topleft" + name="sort_participants_by_name"> + <on_click + function="IMFloaterContainer.Action" + parameter="sort_participants_by_name" /> + <on_check + function="IMFloaterContainer.Check" + parameter="sort_participants_by_name" /> + </menu_item_check> + <menu_item_check + label="Sort participants by recent activity" + layout="topleft" + name="sort_participants_by_recent"> + <on_click + function="IMFloaterContainer.Action" + parameter="sort_participants_by_recent" /> + <on_check + function="IMFloaterContainer.Check" + parameter="sort_participants_by_recent" /> + </menu_item_check> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Chat preferences..." + name="chat_preferences"> + <on_click + function="IMFloaterContainer.Action" + parameter="chat_preferences" /> + </menu_item_call> + <menu_item_call + label="Privacy preferences..." + name="privacy_preferences"> + <on_click + function="IMFloaterContainer.Action" + parameter="privacy_preferences" /> + </menu_item_call> + <menu_item_check + label="Conversation log..." + name="Conversation" + visible="true"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="conversation" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="conversation" /> + <menu_item_check.on_enable + function="Avatar.EnableItem" + parameter="conversation_log" /> + </menu_item_check> + <menu_item_separator layout="topleft" /> + <menu_item_check name="Translate_chat" label="Translate Nearby chat"> + <menu_item_check.on_click + function="IMFloaterContainer.Action" + parameter="Translating.Toggle" /> + <menu_item_check.on_check + function="IMFloaterContainer.Check" + parameter="Translating.On" /> + <menu_item_check.on_enable + function="IMFloaterContainer.Check" + parameter="Translating.Enabled" /> + </menu_item_check> + <menu_item_check name="Translation_settings" label="Translation settings..."> + <menu_item_check.on_check + function="Floater.Visible" + parameter="prefs_translation" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="prefs_translation" /> + </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml new file mode 100644 index 0000000000..63295ea27b --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + name="menu_blocked_gear" + left="0" bottom="0" visible="false" + mouse_opaque="false"> + <menu_item_call + label="Unblock" + name="unblock"> + <on_click + function="Block.Action" + parameter="unblock_item" /> + <on_enable + function="Block.Enable" + parameter="unblock_item" /> + </menu_item_call> + <menu_item_call + label="Profile..." + name="profile"> + <on_click + function="Block.Action" + parameter="profile_item"/> + <on_enable + function="Block.Enable" + parameter="profile_item" /> + </menu_item_call> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_plus.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_plus.xml new file mode 100644 index 0000000000..0c7155667e --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_people_blocked_plus.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + name="menu_blocked_plus" + left="0" bottom="0" visible="false" + mouse_opaque="false"> + <menu_item_call + label="Block Resident by name..." + name="block_resident_by_name"> + <on_click + function="Block.Action" + parameter="block_res_by_name"/> + </menu_item_call> + <menu_item_call + label="Block object by name" + name="block_object_by_name"> + <on_click + function="Block.Action" + parameter="block_obj_by_name"/> + </menu_item_call> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_view.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_view.xml new file mode 100644 index 0000000000..2efb70ee37 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_people_blocked_view.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + name="menu_blocked_view" + left="0" bottom="0" visible="false" + mouse_opaque="false"> + <menu_item_check + label="Sort by name" + name="sort_by_name"> + <on_click + function="Block.Action" + parameter="sort_by_name"/> + <on_check + function="Block.Check" + parameter="sort_by_name"/> + </menu_item_check> + <menu_item_check + label="Sort by type" + name="sort_by_type"> + <on_click + function="Block.Action" + parameter="sort_by_type" /> + <on_check + function="Block.Check" + parameter="sort_by_type" /> + </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml index b452f96e7a..dde9432867 100644 --- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml @@ -40,8 +40,12 @@ function="CheckControl" parameter="FriendsListShowPermissions" /> </menu_item_check> - <menu_item_separator layout="topleft" /> - <menu_item_call name="show_blocked_list" label="Show Blocked Residents & Objects"> - <menu_item_call.on_click function="People.Friends.ViewSort.Action" parameter="panel_block_list_sidetray" /> - </menu_item_call> + <menu_item_check name="view_conversation" label="View Conversation Log..."> + <menu_item_check.on_check + function="Floater.Visible" + parameter="conversation" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="conversation" /> + </menu_item_check> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_groups.xml b/indra/newview/skins/default/xui/en/menu_people_groups.xml index 8f89d37dbb..1e0364b84e 100644 --- a/indra/newview/skins/default/xui/en/menu_people_groups.xml +++ b/indra/newview/skins/default/xui/en/menu_people_groups.xml @@ -1,8 +1,18 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu name="menu_group_plus" +<toggleable_menu name="menu_group_plus" left="0" bottom="0" visible="false" mouse_opaque="false" opaque="true" color="MenuDefaultBgColor"> <menu_item_call + label="Activate" + name="Activate"> + <menu_item_call.on_click + function="People.Groups.Action" + parameter="activate" /> + <menu_item_call.on_enable + function="People.Groups.Enable" + parameter="activate" /> + </menu_item_call> + <menu_item_call label="View Info" name="View Info"> <menu_item_call.on_click @@ -23,7 +33,7 @@ parameter="chat" /> </menu_item_call> <menu_item_call - label="Call" + label="Voice call" name="Call"> <menu_item_call.on_click function="People.Groups.Action" @@ -34,17 +44,6 @@ </menu_item_call> <menu_item_separator /> <menu_item_call - label="Activate" - name="Activate"> - <menu_item_call.on_click - function="People.Groups.Action" - parameter="activate" /> - <menu_item_call.on_enable - function="People.Groups.Enable" - parameter="activate" /> - </menu_item_call> - <menu_item_separator /> - <menu_item_call label="Leave" name="Leave"> <menu_item_call.on_click @@ -54,4 +53,4 @@ function="People.Groups.Enable" parameter="leave" /> </menu_item_call> -</menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_groups_view.xml index c710fe3b9b..73f79f1e70 100644 --- a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_groups_view.xml @@ -14,13 +14,4 @@ function="CheckControl" parameter="GroupListShowIcons" /> </menu_item_check> - <menu_item_call - label="Leave Selected Group" - layout="topleft" - name="Leave Selected Group"> - <menu_item_call.on_click - function="People.Group.Minus.Action"/> - <menu_item_call.on_enable - function="People.Group.Minus.Enable"/> - </menu_item_call> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby.xml b/indra/newview/skins/default/xui/en/menu_people_nearby.xml index d2e35e4cc0..60a6c98514 100644 --- a/indra/newview/skins/default/xui/en/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/en/menu_people_nearby.xml @@ -10,12 +10,53 @@ function="Avatar.Profile" /> </menu_item_call> <menu_item_call + label="IM" + layout="topleft" + name="IM"> + <menu_item_call.on_click + function="Avatar.IM" /> + <menu_item_call.on_enable + function="Avatar.EnableItem" + parameter="can_im"/> + </menu_item_call> + <menu_item_call + label="Offer Teleport" + name="teleport"> + <menu_item_call.on_click + function="Avatar.OfferTeleport"/> + <menu_item_call.on_enable + function="Avatar.EnableItem" + parameter="can_offer_teleport"/> + </menu_item_call> + <menu_item_call + label="Voice call" + layout="topleft" + name="Call"> + <menu_item_call.on_click + function="Avatar.Call" /> + <menu_item_call.on_enable + function="Avatar.EnableItem" + parameter="can_call" /> + </menu_item_call> + <menu_item_separator /> + <menu_item_call + label="View chat history..." + layout="topleft" + name="Chat history"> + <menu_item_call.on_click + function="Avatar.Calllog" /> + <menu_item_call.on_enable + function="Avatar.EnableItem" + parameter="can_callog"/> + </menu_item_call> + <menu_item_separator /> + <menu_item_call label="Add Friend" layout="topleft" name="Add Friend"> <menu_item_call.on_click function="Avatar.AddFriend" /> - <menu_item_call.on_enable + <menu_item_call.on_visible function="Avatar.EnableItem" parameter="can_add" /> </menu_item_call> @@ -30,22 +71,16 @@ parameter="can_delete" /> </menu_item_call> <menu_item_call - label="IM" - layout="topleft" - name="IM"> - <menu_item_call.on_click - function="Avatar.IM" /> - </menu_item_call> - <menu_item_call - label="Call" + label="Invite to group..." layout="topleft" - name="Call"> + name="Invite"> <menu_item_call.on_click - function="Avatar.Call" /> + function="Avatar.InviteToGroup" /> <menu_item_call.on_enable - function="Avatar.EnableItem" - parameter="can_call" /> + function="Avatar.EnableItem" + parameter="can_invite"/> </menu_item_call> + <menu_item_separator /> <menu_item_call label="Map" layout="topleft" @@ -62,6 +97,9 @@ name="Share"> <menu_item_call.on_click function="Avatar.Share" /> + <menu_item_call.on_enable + function="Avatar.EnableItem" + parameter="can_share"/> </menu_item_call> <menu_item_call label="Pay" @@ -69,6 +107,9 @@ name="Pay"> <menu_item_call.on_click function="Avatar.Pay" /> + <menu_item_call.on_enable + function="Avatar.EnableItem" + parameter="can_pay"/> </menu_item_call> <menu_item_check label="Block/Unblock" @@ -83,13 +124,5 @@ function="Avatar.EnableItem" parameter="can_block" /> </menu_item_check> - <menu_item_call - label="Offer Teleport" - name="teleport"> - <menu_item_call.on_click - function="Avatar.OfferTeleport"/> - <menu_item_call.on_enable - function="Avatar.EnableItem" - parameter="can_offer_teleport"/> - </menu_item_call> + <menu_item_separator /> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml new file mode 100644 index 0000000000..da88ca9f4d --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + name="menu_group_plus" + left="0" bottom="0" visible="false" + mouse_opaque="false"> + <menu_item_check + label="Sort by Recent Speakers" + name="sort_by_recent_speakers"> + <menu_item_check.on_click + function="People.Nearby.ViewSort.Action" + parameter="sort_by_recent_speakers"/> + <menu_item_check.on_check + function="People.Nearby.ViewSort.CheckItem" + parameter="sort_by_recent_speakers"/> + </menu_item_check> + <menu_item_check + label="Sort by Name" + name="sort_name"> + <menu_item_check.on_click + function="People.Nearby.ViewSort.Action" + parameter="sort_name"/> + <menu_item_check.on_check + function="People.Nearby.ViewSort.CheckItem" + parameter="sort_name"/> + </menu_item_check> + <menu_item_check + label="Sort by Distance" + name="sort_distance"> + <menu_item_check.on_click + function="People.Nearby.ViewSort.Action" + parameter="sort_distance"/> + <menu_item_check.on_check + function="People.Nearby.ViewSort.CheckItem" + parameter="sort_distance"/> + </menu_item_check> + <menu_item_separator layout="topleft" /> + <menu_item_check name="view_icons" label="View People Icons"> + <menu_item_check.on_click + function="People.Nearby.ViewSort.Action" + parameter="view_icons" /> + <menu_item_check.on_check + function="CheckControl" + parameter="NearbyListShowIcons" /> + </menu_item_check> + <menu_item_check name ="view_map" label="View Map"> + <menu_item_check.on_check + function="CheckControl" + parameter="NearbyListShowMap" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="NearbyListShowMap" /> + </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml deleted file mode 100644 index 614dd693c5..0000000000 --- a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<toggleable_menu - name="menu_group_plus" - left="0" bottom="0" visible="false" - mouse_opaque="false"> - <menu_item_check - label="Sort by Recent Speakers" - name="sort_by_recent_speakers"> - <menu_item_check.on_click - function="People.Nearby.ViewSort.Action" - parameter="sort_by_recent_speakers"/> - <menu_item_check.on_check - function="People.Nearby.ViewSort.CheckItem" - parameter="sort_by_recent_speakers"/> - </menu_item_check> - <menu_item_check - label="Sort by Name" - name="sort_name"> - <menu_item_check.on_click - function="People.Nearby.ViewSort.Action" - parameter="sort_name"/> - <menu_item_check.on_check - function="People.Nearby.ViewSort.CheckItem" - parameter="sort_name"/> - </menu_item_check> - <menu_item_check - label="Sort by Distance" - name="sort_distance"> - <menu_item_check.on_click - function="People.Nearby.ViewSort.Action" - parameter="sort_distance"/> - <menu_item_check.on_check - function="People.Nearby.ViewSort.CheckItem" - parameter="sort_distance"/> - </menu_item_check> - <menu_item_separator layout="topleft" /> - <menu_item_check name="view_icons" label="View People Icons"> - <menu_item_check.on_click - function="People.Nearby.ViewSort.Action" - parameter="view_icons" /> - <menu_item_check.on_check - function="CheckControl" - parameter="NearbyListShowIcons" /> - </menu_item_check> - <menu_item_check name ="view_map" label="View Map"> - <menu_item_check.on_check - function="CheckControl" - parameter="NearbyListShowMap" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="NearbyListShowMap" /> - </menu_item_check> - <menu_item_separator layout="topleft" /> - <menu_item_call name="show_blocked_list" label="Show Blocked Residents & Objects"> - <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="panel_block_list_sidetray" /> - </menu_item_call> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml index 485a5a658c..1dbc90dd2b 100644 --- a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml @@ -32,8 +32,4 @@ function="CheckControl" parameter="RecentListShowIcons" /> </menu_item_check> - <menu_item_separator layout="topleft" /> - <menu_item_call name="show_blocked_list" label="Show Blocked Residents & Objects"> - <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="panel_block_list_sidetray" /> - </menu_item_call> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_text_editor.xml b/indra/newview/skins/default/xui/en/menu_text_editor.xml index fe8489166b..70b40dd89b 100644 --- a/indra/newview/skins/default/xui/en/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/en/menu_text_editor.xml @@ -2,6 +2,85 @@ <context_menu name="Text editor context menu"> <menu_item_call + label="(unknown)" + layout="topleft" + name="Suggestion 1"> + <menu_item_call.on_click + function="SpellCheck.ReplaceWithSuggestion" + parameter="0" /> + <menu_item_call.on_visible + function="SpellCheck.VisibleSuggestion" + parameter="0" /> + </menu_item_call> + <menu_item_call + label="(unknown)" + layout="topleft" + name="Suggestion 2"> + <menu_item_call.on_click + function="SpellCheck.ReplaceWithSuggestion" + parameter="1" /> + <menu_item_call.on_visible + function="SpellCheck.VisibleSuggestion" + parameter="1" /> + </menu_item_call> + <menu_item_call + label="(unknown)" + layout="topleft" + name="Suggestion 3"> + <menu_item_call.on_click + function="SpellCheck.ReplaceWithSuggestion" + parameter="2" /> + <menu_item_call.on_visible + function="SpellCheck.VisibleSuggestion" + parameter="2" /> + </menu_item_call> + <menu_item_call + label="(unknown)" + layout="topleft" + name="Suggestion 4"> + <menu_item_call.on_click + function="SpellCheck.ReplaceWithSuggestion" + parameter="3" /> + <menu_item_call.on_visible + function="SpellCheck.VisibleSuggestion" + parameter="3" /> + </menu_item_call> + <menu_item_call + label="(unknown)" + layout="topleft" + name="Suggestion 5"> + <menu_item_call.on_click + function="SpellCheck.ReplaceWithSuggestion" + parameter="4" /> + <menu_item_call.on_visible + function="SpellCheck.VisibleSuggestion" + parameter="4" /> + </menu_item_call> + <menu_item_separator + layout="topleft" + name="Suggestion Separator" /> + <menu_item_call + label="Add to Dictionary" + layout="topleft" + name="Add to Dictionary"> + <menu_item_call.on_click + function="SpellCheck.AddToDictionary" /> + <menu_item_call.on_enable + function="SpellCheck.EnableAddToDictionary" /> + </menu_item_call> + <menu_item_call + label="Add to Ignore" + layout="topleft" + name="Add to Ignore"> + <menu_item_call.on_click + function="SpellCheck.AddToIgnore" /> + <menu_item_call.on_enable + function="SpellCheck.EnableAddToIgnore" /> + </menu_item_call> + <menu_item_separator + layout="topleft" + name="Spellcheck Separator" /> + <menu_item_call label="Cut" layout="topleft" name="Cut"> diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml index 73f0fa7979..7cd56f257a 100644 --- a/indra/newview/skins/default/xui/en/menu_url_agent.xml +++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml @@ -1,13 +1,27 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <context_menu layout="topleft" - name="Url Popup"> + name="Url Popup"> <menu_item_call - label="Show Resident Profile" + label="View Profile" layout="topleft" name="show_agent"> <menu_item_call.on_click - function="Url.ShowProfile" /> + function="Url.ShowProfile" /> + </menu_item_call> + <menu_item_call + label="Send IM..." + layout="topleft" + name="send_im"> + <menu_item_call.on_click + function="Url.SendIM" /> + </menu_item_call> + <menu_item_call + label="Add Friend..." + layout="topleft" + name="add_friend"> + <menu_item_call.on_click + function="Url.AddFriend" /> </menu_item_call> <menu_item_separator layout="topleft" /> diff --git a/indra/newview/skins/default/xui/en/menu_url_objectim.xml b/indra/newview/skins/default/xui/en/menu_url_objectim.xml index 35c2269b0d..87ab58e622 100644 --- a/indra/newview/skins/default/xui/en/menu_url_objectim.xml +++ b/indra/newview/skins/default/xui/en/menu_url_objectim.xml @@ -3,7 +3,7 @@ layout="topleft" name="Url Popup"> <menu_item_call - label="Show Object Information" + label="Object Profile..." layout="topleft" name="show_object"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index c8c1922bf6..544f06ac0c 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -9,14 +9,6 @@ name="Me" tear_off="true"> <menu_item_call - label="Dashboard..." - name="Manage My Account"> - <menu_item_call.on_click - function="PromptShowURL" - name="ManageMyAccount_url" - parameter="WebLaunchJoinNow,http://secondlife.com/account/" /> - </menu_item_call> - <menu_item_call label="Profile..." name="Profile"> <menu_item_call.on_click @@ -31,6 +23,14 @@ <menu_item_call.on_enable function="Edit.EnableCustomizeAvatar" /> </menu_item_call> + <menu_item_call + label="Choose an avatar..." + name="Avatar Picker"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="avatar" /> + </menu_item_call> + <menu_item_separator/> <menu_item_check label="Inventory..." name="Inventory" @@ -52,29 +52,28 @@ function="Inventory.NewWindow" parameter="" /> </menu_item_call> - <menu_item_check - label="Gestures..." - name="Gestures" - shortcut="control|G"> - <menu_item_check.on_check - function="Floater.Visible" - parameter="gestures" /> - <menu_item_check.on_click - function="Floater.Toggle" - parameter="gestures" /> - </menu_item_check> - <menu_item_check - label="Voice..." - name="ShowVoice" - visibility_control="VoiceMorphingEnabled"> - <menu_item_check.on_check - function="Floater.Visible" - Parameter="voice_effect" /> - <menu_item_check.on_click - function="Floater.Toggle" - parameter="voice_effect" /> - </menu_item_check> - + <menu_item_call + label="Places..." + name="Places"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="places" /> + </menu_item_call> + <menu_item_call + label="Picks..." + name="Picks"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="picks" /> + </menu_item_call> + <menu_item_separator/> + <menu_item_call + label="Camera Controls..." + name="Camera Controls"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="camera" /> + </menu_item_call> <menu create_jump_keys="true" label="Movement" @@ -117,6 +116,13 @@ <menu_item_call.on_click function="Tools.StopAllAnimations" /> </menu_item_call> + <menu_item_call + label="Walk / run / fly..." + name="Walk / run / fly"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="moveview" /> + </menu_item_call> </menu> <menu @@ -124,44 +130,45 @@ label="Status" name="Status" tear_off="true"> - <menu_item_call - label="Away" - name="Set Away"> - <menu_item_call.on_click + <menu_item_check + label="Away"> + <menu_item_check.on_check + function="View.Status.CheckAway" /> + <menu_item_check.on_click function="World.SetAway" /> - </menu_item_call> - <menu_item_call - label="Busy" - name="Set Busy"> - <menu_item_call.on_click - function="World.SetBusy"/> - </menu_item_call> - </menu> + </menu_item_check> + <menu_item_check + label="Do Not Disturb"> + <menu_item_check.on_check + function="View.Status.CheckDoNotDisturb" /> + <menu_item_check.on_click + function="World.SetDoNotDisturb"/> + </menu_item_check> + + </menu> + + <menu_item_separator/> <menu_item_call - label="Request Admin Status" - name="Request Admin Options" - shortcut="control|alt|G" - visible="false"> + label="Buy L$..." + name="Buy and Sell L$"> <menu_item_call.on_click - function="Advanced.RequestAdminStatus" /> + function="BuyCurrency" /> </menu_item_call> <menu_item_call - label="Leave Admin Status" - name="Leave Admin Options" - shortcut="control|alt|shift|G" - visible="false"> + label="Merchant Outbox..." + name="MerchantOutbox"> <menu_item_call.on_click - function="Advanced.LeaveAdminStatus" /> + function="Floater.ToggleOrBringToFront" + parameter="outbox" /> </menu_item_call> - - <menu_item_separator/> - <menu_item_call - label="Buy L$" - name="Buy and Sell L$"> + label="Account dashboard..." + name="Manage My Account"> <menu_item_call.on_click - function="BuyCurrency" /> + function="PromptShowURL" + name="ManageMyAccount_url" + parameter="WebLaunchJoinNow,http://secondlife.com/account/" /> </menu_item_call> <menu_item_separator/> @@ -176,8 +183,7 @@ </menu_item_call> <menu_item_call label="Toolbar buttons..." - name="Toolbars" - shortcut="control|T"> + name="Toolbars"> <menu_item_call.on_click function="Floater.Toggle" parameter="toybox" /> @@ -189,6 +195,15 @@ <menu_item_call.on_click function="View.ToggleUI" /> </menu_item_call> + <menu_item_check + label="Show HUD Attachments" + name="Show HUD Attachments" + shortcut="alt|shift|H"> + <menu_item_check.on_check + function="View.CheckHUDAttachments" /> + <menu_item_check.on_click + function="View.ShowHUDAttachments" /> + </menu_item_check> <menu_item_separator/> @@ -205,67 +220,178 @@ label="Communicate" name="Communicate" tear_off="true"> - <menu_item_call - label="My Friends" - name="My Friends" - shortcut="control|shift|F"> - <menu_item_call.on_click - function="SideTray.PanelPeopleTab" - parameter="friends_panel" /> - </menu_item_call> - <menu_item_call - label="My Groups" - name="My Groups" - shortcut="control|shift|G"> - <menu_item_call.on_click - function="SideTray.PanelPeopleTab" - parameter="groups_panel" /> - </menu_item_call> - - <menu_item_separator/> - - <!--menu_item_call - label="Chat" - name="Chat"> - <menu_item_call.on_click - function="World.Chat" /> - </menu_item_call--> - <menu_item_check - label="Nearby Chat" + <menu_item_check + label="Conversations..." + name="Conversations" + shortcut="control|T"> + <menu_item_check.on_check + function="Floater.IsOpen" + parameter="im_container" /> + <menu_item_check.on_click + function="Floater.ToggleOrBringToFront" + parameter="im_container" /> + </menu_item_check> + <menu_item_check + label="Nearby Chat..." name="Nearby Chat" shortcut="control|H" use_mac_ctrl="true"> <menu_item_check.on_check function="Floater.Visible" - parameter="chat_bar" /> + parameter="nearby_chat" /> + <menu_item_check.on_click + function="Floater.ToggleOrBringToFront" + parameter="nearby_chat" /> + </menu_item_check> + <menu_item_check + label="Speak" + name="Speak"> + <menu_item_check.on_check + function="Agent.IsMicrophoneOn" + parameter="speak" /> + <menu_item_check.on_enable + function="Agent.IsActionAllowed" + parameter="speak" /> + <menu_item_check.on_click + function="Agent.ToggleMicrophone" + parameter="speak" /> + </menu_item_check> + <menu_item_check + label="Conversation Log..."> + <menu_item_check.on_check + function="Floater.Visible" + parameter="conversation" /> + <menu_item_check.on_enable + function="Conversation.IsConversationLoggingAllowed" /> <menu_item_check.on_click function="Floater.Toggle" - parameter="chat_bar" /> + parameter="conversation" /> </menu_item_check> - <menu_item_call - label="Nearby People" - name="Active Speakers" - shortcut="control|shift|A"> - <menu_item_call.on_click - function="SideTray.PanelPeopleTab" - parameter="nearby_panel" /> + <menu_item_separator/> + <menu + label="Voice morphing" + name="VoiceMorphing" + visibility_control="VoiceMorphingEnabled"> + <menu_item_check + label="No voice morphing" + name="NoVoiceMorphing"> + <menu_item_check.on_check + function="Communicate.VoiceMorphing.NoVoiceMorphing.Check" /> + <menu_item_check.on_click + function="Communicate.VoiceMorphing.NoVoiceMorphing.Click" /> + </menu_item_check> + <menu_item_separator/> + <menu_item_check + label="Preview..." + name="Preview"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="voice_effect" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="voice_effect" /> + </menu_item_check> + <menu_item_call + label="Subscribe..." + name="Subscribe"> + <menu_item_call.on_click + function="Communicate.VoiceMorphing.Subscribe" /> </menu_item_call> + </menu> <menu_item_check - label="Nearby Voice" - name="Nearby Voice"> + label="Gestures..." + name="Gestures" + shortcut="control|G"> <menu_item_check.on_check function="Floater.Visible" - parameter="voice_controls" /> + parameter="gestures" /> <menu_item_check.on_click function="Floater.Toggle" - parameter="voice_controls" /> + parameter="gestures" /> + </menu_item_check> + <menu_item_separator/> + <menu_item_check + label="Friends" + name="My Friends" + shortcut="control|shift|F"> + <menu_item_check.on_check + function="SideTray.CheckPanelPeopleTab" + parameter="friends_panel" /> + <menu_item_check.on_click + function="SideTray.PanelPeopleTab" + parameter="friends_panel" /> + </menu_item_check> + <menu_item_check + label="Groups" + name="My Groups" + shortcut="control|shift|G"> + <menu_item_check.on_check + function="SideTray.CheckPanelPeopleTab" + parameter="groups_panel" /> + <menu_item_check.on_click + function="SideTray.PanelPeopleTab" + parameter="groups_panel" /> + </menu_item_check> + <menu_item_check + label="Nearby people" + name="Active Speakers" + shortcut="control|shift|A"> + <menu_item_check.on_check + function="SideTray.CheckPanelPeopleTab" + parameter="nearby_panel" /> + <menu_item_check.on_click + function="SideTray.PanelPeopleTab" + parameter="nearby_panel" /> </menu_item_check> + <menu_item_call + label="Block List" + name="Block List"> + <menu_item_call.on_click + function="SideTray.PanelPeopleTab" + parameter="blocked_panel" /> + </menu_item_call> + <menu_item_separator/> + <menu_item_check + label="Do Not Disturb"> + <menu_item_check.on_check + function="View.Status.CheckDoNotDisturb" /> + <menu_item_check.on_click + function="World.SetDoNotDisturb"/> + </menu_item_check> + </menu> <menu create_jump_keys="true" label="World" name="World" tear_off="true"> + <menu_item_call + label="Landmark This Place" + name="Create Landmark Here"> + <menu_item_call.on_click + function="World.CreateLandmark" /> + <menu_item_call.on_enable + function="World.EnableCreateLandmark" /> + </menu_item_call> + <menu_item_call + label="Destinations..." + name="Destinations"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="destinations" /> + </menu_item_call> + <menu_item_check + label="World map" + name="World Map" + shortcut="control|M" + use_mac_ctrl="true"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="world_map" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="world_map" /> + </menu_item_check> <menu_item_check label="Mini-map" name="Mini-Map" @@ -277,18 +403,6 @@ function="Floater.Toggle" parameter="mini_map" /> </menu_item_check> - <menu_item_check - label="World Map" - name="World Map" - shortcut="control|M" - use_mac_ctrl="true"> - <menu_item_check.on_check - function="Floater.Visible" - parameter="world_map" /> - <menu_item_check.on_click - function="Floater.Toggle" - parameter="world_map" /> - </menu_item_check> <menu_item_check label="Search" name="Search" @@ -300,6 +414,25 @@ function="Floater.Toggle" parameter="search" /> </menu_item_check> + <menu_item_separator/> + <menu_item_call + label="Teleport home" + name="Teleport Home" + shortcut="control|shift|H"> + <menu_item_call.on_click + function="World.TeleportHome" /> + <menu_item_call.on_enable + function="World.EnableTeleportHome" /> + </menu_item_call> + <menu_item_call + label="Set home to here" + name="Set Home to Here"> + <menu_item_call.on_click + function="World.SetHomeLocation" /> + <menu_item_call.on_enable + function="World.EnableSetHomeLocation" /> + </menu_item_call> + <menu_item_separator/> <menu_item_call label="Snapshot" name="Take Snapshot" @@ -308,82 +441,51 @@ function="Floater.Show" parameter="snapshot" /> </menu_item_call> - <menu_item_call - label="Landmark This Place" - name="Create Landmark Here"> - <menu_item_call.on_click - function="World.CreateLandmark" /> - <menu_item_call.on_enable - function="World.EnableCreateLandmark" /> - </menu_item_call> - <menu - create_jump_keys="true" - label="Place Profile" - name="Land" - tear_off="true"> + <menu_item_separator/> <menu_item_call - label="Place Profile" + label="Place profile" layout="topleft" name="Place Profile"> <menu_item_call.on_click function="World.PlaceProfile" /> </menu_item_call> <menu_item_call - label="About Land" + label="About land" name="About Land"> <menu_item_call.on_click function="Floater.Show" parameter="about_land" /> </menu_item_call> <menu_item_call - label="Region/Estate" + label="Region / Estate" name="Region/Estate"> <menu_item_call.on_click function="Floater.Show" parameter="region_info" /> </menu_item_call> - </menu> + <menu_item_call + label="My land holdings..." + name="My Land"> + <menu_item_call.on_click + function="Floater.Show" + parameter="land_holdings" /> + </menu_item_call> + <menu_item_call + label="Buy this land" + name="Buy Land"> + <menu_item_call.on_click + function="Land.Buy" /> + <menu_item_call.on_enable + function="World.EnableBuyLand" /> + </menu_item_call> <menu_item_separator/> - <menu_item_call - label="Buy This Land" - name="Buy Land"> - <menu_item_call.on_click - function="Land.Buy" /> - <menu_item_call.on_enable - function="World.EnableBuyLand" /> - </menu_item_call> - <menu_item_call - label="My Land" - name="My Land"> - <menu_item_call.on_click - function="Floater.Show" - parameter="land_holdings" /> - </menu_item_call> <menu create_jump_keys="true" label="Show" name="LandShow" tear_off="true"> - <menu_item_check - label="Move Controls" - name="Movement Controls"> - <menu_item_check.on_check - function="Floater.Visible" - parameter="moveview" /> - <menu_item_check.on_click - function="World.Toggle.MovementControls" /> - </menu_item_check> - <menu_item_check - label="View Controls" - name="Camera Controls"> - <menu_item_check.on_check - function="Floater.Visible" - parameter="camera" /> - <menu_item_check.on_click - function="World.Toggle.CameraControls" /> - </menu_item_check> <menu_item_check label="Ban Lines" name="Ban Lines"> @@ -456,24 +558,6 @@ </menu> <menu_item_separator/> - - <menu_item_call - label="Teleport Home" - name="Teleport Home" - shortcut="control|shift|H"> - <menu_item_call.on_click - function="World.TeleportHome" /> - <menu_item_call.on_enable - function="World.EnableTeleportHome" /> - </menu_item_call> - <menu_item_call - label="Set Home to Here" - name="Set Home to Here"> - <menu_item_call.on_click - function="World.SetHomeLocation" /> - <menu_item_call.on_enable - function="World.EnableSetHomeLocation" /> - </menu_item_call> <!-- <menu_item_check label="Show Navigation Bar" name="ShowNavbarNavigationPanel"> @@ -496,12 +580,10 @@ </menu_item_check> <menu_item_separator/>--> - <menu_item_separator/> - <menu create_jump_keys="true" label="Sun" - name="Environment Settings" + name="Sun" tear_off="true"> <menu_item_call label="Sunrise" @@ -847,14 +929,6 @@ function="Tools.EnableTakeCopy" /> </menu_item_call> <menu_item_call - label="Save Back to My Inventory" - name="Save Object Back to My Inventory"> - <menu_item_call.on_click - function="Tools.SaveToInventory" /> - <menu_item_call.on_enable - function="Tools.EnableSaveToInventory" /> - </menu_item_call> - <menu_item_call label="Save Back to Object Contents" name="Save Object Back to Object Contents"> <menu_item_call.on_click @@ -923,7 +997,50 @@ </menu_item_call> </menu> - <menu_item_separator/> + <menu + create_jump_keys="true" + label="Pathfinding" + name="Pathfinding" + tear_off="true"> + <menu_item_call + label="Linksets..." + name="pathfinding_linksets_menu_item"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="pathfinding_linksets" /> + <menu_item_call.on_enable + function="Tools.EnablePathfinding" /> + </menu_item_call> + <menu_item_call + label="Characters..." + name="pathfinding_characters_menu_item"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="pathfinding_characters" /> + <menu_item_call.on_enable + function="Tools.EnablePathfinding" /> + </menu_item_call> + <menu_item_call + label="View / test..." + name="pathfinding_console_menu_item"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="pathfinding_console" /> + <menu_item_call.on_enable + function="Tools.EnablePathfindingView" /> + </menu_item_call> + <menu_item_call + label="Rebake region" + name="pathfinding_rebake_navmesh_item"> + <menu_item_call.on_click + function="Tools.DoPathfindingRebakeRegion"/> + <menu_item_call.on_enable + function="Tools.EnablePathfindingRebakeRegion" /> + </menu_item_call> + </menu> + + + <menu_item_separator/> <menu create_jump_keys="true" @@ -1130,6 +1247,7 @@ enabled="false" label="Undo" name="Undo" + allow_key_repeat="true" shortcut="control|Z"> <on_click function="Edit.Undo" @@ -1141,6 +1259,7 @@ enabled="false" label="Redo" name="Redo" + allow_key_repeat="true" shortcut="control|Y"> <on_click function="Edit.Redo" @@ -1155,6 +1274,13 @@ name="Help" tear_off="true"> <menu_item_call + label="How to..." + name="How To"> + <menu_item_call.on_click + function="Help.ToggleHowTo" + parameter="" /> + </menu_item_call> + <menu_item_call label="[SECOND_LIFE] Help" name="Second Life Help" shortcut="F1"> @@ -1169,7 +1295,58 @@ function="Floater.Show" parameter="hud" /> </menu_item_call>--> - + <menu_item_separator/> + + <menu_item_call + label="User’s guide" + name="User’s guide"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-User-s-Guide/ta-p/1244857"/> + </menu_item_call> + <menu_item_call + label="Knowledge Base" + name="Knowledge Base"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="http://community.secondlife.com/t5/tkb/communitypage"/> + </menu_item_call> + <menu_item_call + label="Wiki" + name="Wiki"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="http://wiki.secondlife.com"/> + </menu_item_call> + <menu_item_call + label="Community Forums" + name="Community Forums"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="http://community.secondlife.com/t5/Forums/ct-p/Forums"/> + </menu_item_call> + <menu_item_call + label="Support portal" + name="Support portal"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="https://support.secondlife.com/"/> + </menu_item_call> + <menu_item_separator/> + <menu_item_call + label="[SECOND_LIFE] News" + name="Second Life News"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/> + </menu_item_call> + <menu_item_call + label="[SECOND_LIFE] Blogs" + name="Second Life Blogs"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/> + </menu_item_call> <menu_item_separator/> <menu_item_call @@ -1351,15 +1528,6 @@ function="View.HighlightTransparent" /> </menu_item_check> <menu_item_check - label="Show HUD Attachments" - name="Show HUD Attachments" - shortcut="alt|shift|H"> - <menu_item_check.on_check - function="View.CheckHUDAttachments" /> - <menu_item_check.on_click - function="View.ShowHUDAttachments" /> - </menu_item_check> - <menu_item_check label="Show Mouselook Crosshairs" name="ShowCrosshairs"> <menu_item_check.on_check @@ -1419,7 +1587,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" @@ -1430,7 +1598,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" @@ -1441,7 +1609,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" @@ -1452,7 +1620,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" @@ -1463,7 +1631,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" @@ -1474,7 +1642,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" @@ -1485,7 +1653,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" @@ -1496,7 +1664,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" @@ -1507,7 +1675,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" @@ -1518,7 +1686,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" @@ -1529,7 +1697,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" @@ -1540,7 +1708,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" @@ -1551,7 +1719,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" @@ -1568,7 +1736,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" @@ -1682,36 +1850,6 @@ function="ToggleControl" parameter="MouseSmooth" /> </menu_item_check> - - <menu_item_separator/> - - <menu - create_jump_keys="true" - label="Shortcuts" - 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> <menu_item_call enabled="false" label="Release Keys" @@ -1723,12 +1861,14 @@ function="Tools.EnableReleaseKeys" parameter="" /> </menu_item_call> - <menu_item_call - label="Set UI Size to Default" - name="Set UI Size to Default"> - <menu_item_call.on_click - function="View.DefaultUISize" /> - </menu_item_call> + <menu_item_separator/> + + <menu + create_jump_keys="true" + label="Shortcuts" + name="Shortcuts" + tear_off="true" + visible="false"> <!-- 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" @@ -1815,55 +1955,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" @@ -1930,7 +2021,7 @@ <menu_item_check.on_click function="Advanced.ToggleConsole" parameter="texture" /> - </menu_item_check> + </menu_item_check> <menu_item_check label="Debug Console" name="Debug Console" @@ -1952,28 +2043,6 @@ parameter="notifications_console" /> </menu_item_call> <menu_item_check - label="Texture Size Console" - name="Texture Size" - shortcut="control|shift|6"> - <menu_item_check.on_check - function="Advanced.CheckConsole" - parameter="texture size" /> - <menu_item_check.on_click - function="Advanced.ToggleConsole" - parameter="texture size" /> - </menu_item_check> - <menu_item_check - label="Texture Category Console" - name="Texture Category" - shortcut="control|shift|7"> - <menu_item_check.on_check - function="Advanced.CheckConsole" - parameter="texture category" /> - <menu_item_check.on_click - function="Advanced.ToggleConsole" - parameter="texture category" /> - </menu_item_check> - <menu_item_check label="Fast Timers" name="Fast Timers" shortcut="control|shift|9" @@ -2007,7 +2076,20 @@ function="Advanced.ToggleConsole" parameter="scene view" /> </menu_item_check> - + <menu_item_call + enabled="false" + visible="false" + label="Texture Fetch Debug Console" + name="Texture Fetch Debug Console"> + <menu_item_call.on_click + function="Floater.Show" + parameter="tex_fetch_debugger" /> + <on_enable + function="Develop.SetTexFetchDebugger" /> + <on_visible + function="Develop.SetTexFetchDebugger" /> + </menu_item_call> + <menu_item_separator/> <menu_item_call @@ -2473,6 +2555,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"> @@ -2483,6 +2575,52 @@ function="Advanced.ToggleInfoDisplay" parameter="sculpt" /> </menu_item_check> + <menu + create_jump_keys="true" + label="Texture Density" + name="Texture Density" + tear_off="true"> + <menu_item_check + label="None" + name="None"> + <menu_item_check.on_check + function="Advanced.CheckDisplayTextureDensity" + parameter="none" /> + <menu_item_check.on_click + function="Advanced.SetDisplayTextureDensity" + parameter="none" /> + </menu_item_check> + <menu_item_check + label="Current" + name="Current"> + <menu_item_check.on_check + function="Advanced.CheckDisplayTextureDensity" + parameter="current" /> + <menu_item_check.on_click + function="Advanced.SetDisplayTextureDensity" + parameter="current" /> + </menu_item_check> + <menu_item_check + label="Desired" + name="Desired"> + <menu_item_check.on_check + function="Advanced.CheckDisplayTextureDensity" + parameter="desired" /> + <menu_item_check.on_click + function="Advanced.SetDisplayTextureDensity" + parameter="desired" /> + </menu_item_check> + <menu_item_check + label="Full" + name="Full"> + <menu_item_check.on_check + function="Advanced.CheckDisplayTextureDensity" + parameter="full" /> + <menu_item_check.on_click + function="Advanced.SetDisplayTextureDensity" + parameter="full" /> + </menu_item_check> + </menu> </menu> <menu create_jump_keys="true" @@ -2650,16 +2788,6 @@ parameter="TextureLoadFullRes" /> </menu_item_check> <menu_item_check - label="Audit Textures" - name="Audit Textures"> - <menu_item_check.on_check - function="CheckControl" - parameter="AuditTexture" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="AuditTexture" /> - </menu_item_check> - <menu_item_check label="Texture Atlas (experimental)" name="Texture Atlas"> <menu_item_check.on_check @@ -2826,7 +2954,7 @@ <menu create_jump_keys="true" label="World" - name="World" + name="DevelopWorld" tear_off="true"> <menu_item_check label="Sim Sun Override" @@ -2839,16 +2967,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 @@ -3072,7 +3190,7 @@ tear_off="true"> <menu_item_call label="Iris" - name="Iris"> + name="Grab Iris"> <menu_item_call.on_click function="Advanced.GrabBakedTexture" parameter="iris" /> @@ -3082,7 +3200,7 @@ </menu_item_call> <menu_item_call label="Head" - name="Head"> + name="Grab Head"> <menu_item_call.on_click function="Advanced.GrabBakedTexture" parameter="head" /> @@ -3092,7 +3210,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" /> @@ -3102,7 +3220,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" /> @@ -3112,7 +3230,7 @@ </menu_item_call> <menu_item_call label="Skirt" - name="Skirt"> + name="Grab Skirt"> <menu_item_call.on_click function="Advanced.GrabBakedTexture" parameter="skirt" /> @@ -3152,12 +3270,6 @@ <menu_item_call.on_click function="Advanced.TestFemale" /> </menu_item_call> - <menu_item_call - label="Toggle PG" - name="Toggle PG"> - <menu_item_call.on_click - function="Advanced.TogglePG" /> - </menu_item_call> <menu_item_check label="Allow Select Avatar" name="Allow Select Avatar"> @@ -3169,6 +3281,40 @@ parameter="AllowSelectAvatar" /> </menu_item_check> </menu> + <menu + create_jump_keys="true" + label="Animation Speed" + name="Animation Speed" + tear_off="true"> + <menu_item_call + label="All Animations 10% Faster" + name="All Animations 10 Faster"> + <menu_item_call.on_click + function="Advanced.AnimTenFaster" /> + </menu_item_call> + <menu_item_call + label="All Animations 10% Slower" + name="All Animations 10 Slower"> + <menu_item_call.on_click + function="Advanced.AnimTenSlower" /> + </menu_item_call> + <menu_item_call + label="Reset All Animation Speed" + name="Reset All Animation Speed"> + <menu_item_call.on_click + function="Advanced.AnimResetAll" /> + </menu_item_call> + <menu_item_check + label="Slow Motion Animations" + name="Slow Motion Animations"> + <menu_item_check.on_check + function="CheckControl" + parameter="SlowMotionAnimation" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="SlowMotionAnimation" /> + </menu_item_check> + </menu> <menu_item_call label="Force Params to Default" name="Force Params to Default"> @@ -3186,16 +3332,6 @@ parameter="" /> </menu_item_check> <menu_item_check - label="Slow Motion Animations" - name="Slow Motion Animations"> - <menu_item_check.on_check - function="CheckControl" - parameter="SlowMotionAnimation" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="SlowMotionAnimation" /> - </menu_item_check> - <menu_item_check label="Show Look At" name="Show Look At"> <menu_item_check.on_check @@ -3322,6 +3458,14 @@ <menu_item_call.on_click function="Advanced.CompressImage" /> </menu_item_call> + + <menu_item_call + label="Enable Visual Leak Detector" + name="Enable Visual Leak Detector"> + <menu_item_call.on_click + function="Advanced.ToggleVisualLeakDetector" /> + </menu_item_call> + <menu_item_check label="Output Debug Minidump" name="Output Debug Minidump"> @@ -3342,6 +3486,62 @@ 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 + name="Debug" + 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 + name="Info" + 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 + name="Warning" + 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 + name="Error" + 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 + name="None" + 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/> @@ -3380,10 +3580,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" /> @@ -3652,7 +3853,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 e4458f33b1..c681e39002 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -77,6 +77,21 @@ </form> </template> + <template name="okhelpignore"> + <form> + <button + default="true" + index="0" + name="OK_okhelpignore" + text="$yestext"/> + <button + index="1" + name="Help_okhelpignore" + text="$helptext"/> + <ignore text="$ignoretext"/> + </form> + </template> + <template name="yesnocancelbuttons"> <form> <button @@ -203,34 +218,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 @@ -835,8 +896,7 @@ You need an account to enter [SECOND_LIFE]. Would you like to create one now? option="0" name="url" target = "_external"> - - http://join.secondlife.com/ + [create_account_url] </url> <usetemplate name="okcancelbuttons" @@ -852,7 +912,22 @@ You need an account to enter [SECOND_LIFE]. Would you like to create one now? You need to enter either the Username or both the First and Last name of your avatar into the Username field, then login again. </notification> - + <notification + icon="alertmodal.tga" + name="InvalidGrid" + type="alertmodal"> + <tag>fail</tag> +'[GRID]' is not a valid grid identifier. + </notification> + + <notification + icon="alertmodal.tga" + name="InvalidLocationSLURL" + type="alertmodal"> + <tag>fail</tag> +Your start location did not specify a valid grid. + </notification> + <notification icon="alertmodal.tga" name="DeleteClassified" @@ -1144,7 +1219,7 @@ There was a problem saving a compiled script due to the following reason: [REASO icon="alertmodal.tga" name="StartRegionEmpty" type="alertmodal"> -Oops, Your Start Region is not defined. +Your Start Region is not defined. Please type the Region name in Start Location box or choose My Last Location or My Home as your Start Location. <tag>fail</tag> <usetemplate @@ -1199,6 +1274,64 @@ Visit [_URL] for more information? <notification icon="alertmodal.tga" + name="IntelOldDriver" + type="alertmodal"> + There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance. + + Visit [_URL] to check for driver updates? + <tag>confirm</tag> + <url option="0" name="url"> + http://www.intel.com/p/en_US/support/detect/graphics + </url> + <usetemplate + ignoretext="My graphics driver is out of date" + name="okcancelignore" + notext="No" + yestext="Yes"/> + <tag>fail</tag> + </notification> + + <notification + icon="alertmodal.tga" + name="AMDOldDriver" + type="alertmodal"> + There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance. + + Visit [_URL] to check for driver updates? + <tag>confirm</tag> + <url option="0" name="url"> + http://support.amd.com/us/Pages/AMDSupportHub.aspx + </url> + <usetemplate + ignoretext="My graphics driver is out of date" + name="okcancelignore" + notext="No" + yestext="Yes"/> + <tag>fail</tag> + </notification> + + <notification + icon="alertmodal.tga" + name="NVIDIAOldDriver" + type="alertmodal"> + There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance. + + Visit [_URL] to check for driver updates? + <tag>confirm</tag> + <url option="0" name="url"> + http://www.nvidia.com/Download/index.aspx?lang=en-us + </url> + <usetemplate + ignoretext="My graphics driver is out of date" + name="okcancelignore" + notext="No" + yestext="Yes"/> + <tag>fail</tag> + </notification> + + + <notification + icon="alertmodal.tga" name="UnknownGPU" type="alertmodal"> Your system contains a graphics card that [APP_NAME] doesn't recognize. @@ -1436,6 +1569,14 @@ Please make sure none are locked, and that you own all of them. <notification icon="alertmodal.tga" + name="CannotLinkPermanent" + type="alertmodal"> + Objects cannot be linked across region boundaries. + <tag>fail</tag> + </notification> + + <notification + icon="alertmodal.tga" name="CannotLinkDifferentOwners" type="alertmodal"> Unable to link because not all of the objects have the same owner. @@ -1621,7 +1762,7 @@ Unable to create output file: [FILE] icon="alertmodal.tga" name="DoNotSupportBulkAnimationUpload" type="alertmodal"> -[APP_NAME] does not currently support bulk upload of animation files. +[APP_NAME] does not currently support bulk upload of BVH format animation files. <tag>fail</tag> </notification> @@ -2294,6 +2435,93 @@ Would you be my friend? </notification> <notification + icon="alertmodal.tga" + label="Add Auto-Replace List" + name="AddAutoReplaceList" + type="alertmodal"> + <tag>addlist</tag> + Name for the new list: + <tag>confirm</tag> + <form name="form"> + <input name="listname" type="text"/> + <button + default="true" + index="0" + name="SetName" + text="OK"/> + </form> + </notification> + + <notification + icon="alertmodal.tga" + label="Rename Auto-Replace List" + name="RenameAutoReplaceList" + type="alertmodal"> + The name '[DUPNAME]' is in use + Enter a new unique name: + <tag>confirm</tag> + <form name="form"> + <input name="listname" type="text"/> + <button + default="false" + index="0" + name="ReplaceList" + text="Replace Current List"/> + <button + default="true" + index="1" + name="SetName" + text="Use New Name"/> + </form> + </notification> + + <notification + icon="alertmodal.tga" + name="InvalidAutoReplaceEntry" + type="alertmodal"> + The keyword must be a single word, and the replacement may not be empty. + <tag>fail</tag> + </notification> + + <notification + icon="alertmodal.tga" + name="InvalidAutoReplaceList" + type="alertmodal"> + That replacement list is not valid. + <tag>fail</tag> + </notification> + + <notification + icon="alertmodal.tga" + name="SpellingDictImportRequired" + type="alertmodal"> + You must specify a file, a name, and a language. + <tag>fail</tag> + </notification> + + <notification + icon="alertmodal.tga" + name="SpellingDictIsSecondary" + type="alertmodal"> +The dictionary [DIC_NAME] does not appear to have an "aff" file; this means that it is a "secondary" dictionary. +It can be used as an additional dictionary, but not as your Main dictionary. + +See https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + <tag>confirm</tag> + </notification> + + <notification + icon="alertmodal.tga" + name="SpellingDictImportFailed" + type="alertmodal"> + Unable to copy + [FROM_NAME] + to + [TO_NAME] + <tag>fail</tag> + </notification> + + <notification icon="alertmodal.tga" label="Save Outfit" name="SaveOutfitAs" @@ -2369,7 +2597,7 @@ Would you be my friend? name="RemoveFromFriends" type="alertmodal"> <tag>friendship</tag> -Do you want to remove [NAME] from your Friends List? +Do you want to remove <nolink>[NAME]</nolink> from your Friends List? <tag>confirm</tag> <usetemplate name="okcancelbuttons" @@ -2704,7 +2932,7 @@ You have been moved into a nearby region. name="AvatarMovedLast" type="alertmodal"> <tag>fail</tag> -Your last location is not currently available. +Your requested location is not currently available. You have been moved into a nearby region. </notification> @@ -2739,12 +2967,11 @@ You can use [SECOND_LIFE] normally and other people will see you correctly. [APP_NAME] installation is complete. If this is your first time using [SECOND_LIFE], you will need to create an account before you can log in. -Return to [http://join.secondlife.com secondlife.com] to create a new account? <tag>confirm</tag> <usetemplate name="okcancelbuttons" notext="Continue" - yestext="New Account..."/> + yestext="Create Account..."/> </notification> <notification @@ -2858,6 +3085,7 @@ Would you like to trust this authority? icon="alertmodal.tga" name="GrantedModifyRights" persist="true" + log_to_im="true" type="notify"> [NAME] has given you permission to edit their objects. </notification> @@ -2866,6 +3094,7 @@ Would you like to trust this authority? icon="alertmodal.tga" name="RevokedModifyRights" persist="true" + log_to_im="true" type="notify"> Your privilege to modify [NAME]'s objects has been revoked </notification> @@ -3409,7 +3638,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 <nolink>[GROUP]</nolink>. Leave Group? <tag>group</tag> <tag>confirm</tag> @@ -3499,12 +3728,15 @@ Cannot offer friendship at this time. Please try again in a moment. <notification icon="alert.tga" - name="BusyModeSet" + name="DoNotDisturbModeSet" type="alert"> -Busy mode is set. -Chat and instant messages will be hidden. Instant messages will get your Busy mode response. All teleportation offers will be declined. All inventory offers will go to your Trash. +Do Not Disturb is on. You will not be notified of incoming communications. + +- Other residents will receive your Do Not Disturb response (set in Preferences > General). +- Teleportation offers will be declined. +- Voice calls will be rejected. <usetemplate - ignoretext="I change my status to Busy mode" + ignoretext="I change my status to Do Not Disturb mode" name="okignore" yestext="OK"/> </notification> @@ -4024,9 +4256,7 @@ Are you sure you want to change the Estate Covenant? name="RegionEntryAccessBlocked" type="alertmodal"> <tag>fail</tag> -You are not allowed in that Region due to your maturity Rating. This may be a result of a lack of information validating your age. - -Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. + The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me > Preferences > General. <usetemplate name="okbutton" yestext="OK"/> @@ -4034,13 +4264,11 @@ Please verify you have the latest Viewer installed, and go to the Knowledge Base <notification icon="alertmodal.tga" - name="RegionEntryAccessBlocked_KB" + name="RegionEntryAccessBlocked_AdultsOnlyContent" type="alertmodal"> <tag>fail</tag> <tag>confirm</tag> -You are not allowed in that region due to your maturity Rating. - -Go to the Knowledge Base for more information about maturity Ratings? + The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only. <url option="0" name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> @@ -4048,55 +4276,172 @@ Go to the Knowledge Base for more information about maturity Ratings? name="okcancelignore" yestext="Go to Knowledge Base" notext="Close" - ignoretext="I can't enter this Region, due to restrictions of the maturity Rating"/> + ignoretext="Region crossing: The region you're trying to visit contains content which is accessible to adults only."/> </notification> <notification icon="notifytip.tga" name="RegionEntryAccessBlocked_Notify" + log_to_im="false" + log_to_chat="true" type="notifytip"> <tag>fail</tag> -You are not allowed in that region due to your maturity Rating. +The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. + </notification> + + <notification + icon="notifytip.tga" + name="RegionEntryAccessBlocked_NotifyAdultsOnly" + log_to_im="false" + log_to_chat="true" + type="notifytip"> + <tag>fail</tag> + The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only. </notification> <notification icon="alertmodal.tga" name="RegionEntryAccessBlocked_Change" type="alertmodal"> - <tag>fail</tag> + <tag>fail</tag> <tag>confirm</tag> -You are not allowed in that Region due to your maturity Rating preference. - -To enter the desired region, please change your maturity Rating preference. This will allow you to search for and access [REGIONMATURITY] content. To undo any changes, go to Me > Preferences > General. - <form name="form"> +The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, or you can cancel. After your preferences are changed, you may attempt to enter the region again. + <form name="form"> <button index="0" name="OK" - text="Change Preference"/> - <button + text="Change preferences"/> + <button default="true" index="1" name="Cancel" - text="Close"/> - <ignore name="ignore" text="My chosen Rating preference prevents me from entering a Region"/> + text="Cancel"/> + <ignore name="ignore" text="Region crossing: The region you're trying to visit contains content excluded by your preferences."/> </form> </notification> <notification + icon="alertmodal.tga" + name="RegionEntryAccessBlocked_PreferencesOutOfSync" + type="alertmodal"> + <tag>fail</tag> + We are having technical difficulties with your teleport because your preferences are out of sync with the server. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="TeleportEntryAccessBlocked" + type="alertmodal"> + <tag>fail</tag> + The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me > Preferences > General. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="TeleportEntryAccessBlocked_AdultsOnlyContent" + type="alertmodal"> + <unique> + <context>REGIONMATURITY</context> + </unique> + <tag>fail</tag> + <tag>confirm</tag> + The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only. + <url option="0" name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate + name="okcancelignore" + yestext="Go to Knowledge Base" + notext="Close" + ignoretext="Teleport: The region you're trying to visit contains content which is accessible to adults only."/> + </notification> + + <notification icon="notifytip.tga" - name="PreferredMaturityChanged" + name="TeleportEntryAccessBlocked_Notify" + log_to_im="false" + log_to_chat="true" type="notifytip"> -Your maturity Rating preference is now [RATING]. + <unique> + <context>REGIONMATURITY</context> + </unique> + <tag>fail</tag> + The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. + </notification> + + <notification + icon="notifytip.tga" + name="TeleportEntryAccessBlocked_NotifyAdultsOnly" + log_to_im="false" + log_to_chat="true" + type="notifytip"> + <unique> + <context>REGIONMATURITY</context> + </unique> + <tag>fail</tag> + The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only. </notification> <notification icon="alertmodal.tga" - name="LandClaimAccessBlocked" + name="TeleportEntryAccessBlocked_ChangeAndReTeleport" type="alertmodal"> -You cannot claim this land due to your maturity Rating. This may be a result of a lack of information validating your age. + <unique> + <context>REGIONMATURITY</context> + </unique> + <tag>fail</tag> + <tag>confirm</tag> + The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences and continue with the teleport, or you can cancel this teleport. + <form name="form"> + <button + index="0" + name="OK" + text="Change and continue"/> + <button + default="true" + index="1" + name="Cancel" + text="Cancel"/> + <ignore name="ignore" text="Teleport (restartable): The region you're trying to visit contains content excluded by your preferences."/> + </form> + </notification> -Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. - <tag>fail</tag> + <notification + icon="alertmodal.tga" + name="TeleportEntryAccessBlocked_Change" + type="alertmodal"> + <unique> + <context>REGIONMATURITY</context> + </unique> + <tag>fail</tag> + <tag>confirm</tag> + The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, or you can cancel the teleport. After your preferences are changed, you will need to attempt the teleport again. + <form name="form"> + <button + index="0" + name="OK" + text="Change preferences"/> + <button + default="true" + index="1" + name="Cancel" + text="Cancel"/> + <ignore name="ignore" text="Teleport (non-restartable): The region you're trying to visit contains content excluded by your preferences."/> + </form> + </notification> + + <notification + icon="alertmodal.tga" + name="TeleportEntryAccessBlocked_PreferencesOutOfSync" + type="alertmodal"> + <tag>fail</tag> + We are having technical difficulties with your teleport because your preferences are out of sync with the server. <usetemplate name="okbutton" yestext="OK"/> @@ -4104,12 +4449,43 @@ Please verify you have the latest Viewer installed, and go to the Knowledge Base <notification icon="alertmodal.tga" - name="LandClaimAccessBlocked_KB" + name="PreferredMaturityChanged" type="alertmodal"> -You cannot claim this land due to your maturity Rating. +You won't receive any more notifications that you're about to visit a region with [RATING] content. You may change your content preferences in the future by using Me > Preferences > General from the menu bar. + <tag>confirm</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> -Go to the Knowledge Base for more information about maturity Ratings? - <tag>fail</tag> + <notification + icon="alertmodal.tga" + name="MaturityChangeError" + type="alertmodal"> + We were unable to change your preferences to view [PREFERRED_MATURITY] content at this time. Your preferences have been reset to view [ACTUAL_MATURITY] content. You may attempt to change your preferences again by using Me > Preferences > General from the menu bar. + <tag>confirm</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="LandClaimAccessBlocked" + type="alertmodal"> + The land you're trying to claim has a maturity rating exceeding your current preferences. You can change your preferences using Me > Preferences > General. + <tag>fail</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="LandClaimAccessBlocked_AdultsOnlyContent" + type="alertmodal"> + Only adults can claim this land. + <tag>fail</tag> <tag>confirm</tag> <url option="0" name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview @@ -4118,41 +4494,56 @@ Go to the Knowledge Base for more information about maturity Ratings? name="okcancelignore" yestext="Go to Knowledge Base" notext="Close" - ignoretext="I can't claim this Land, due to restrictions of the maturity Rating"/> + ignoretext="Only adults can claim this land."/> </notification> <notification icon="notifytip.tga" name="LandClaimAccessBlocked_Notify" + log_to_im="false" + log_to_chat="true" type="notifytip"> -You cannot claim this land due to your maturity Rating. - <tag>fail</tag> + The land you're trying to claim contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. + <tag>fail</tag> + </notification> + + <notification + icon="notifytip.tga" + name="LandClaimAccessBlocked_NotifyAdultsOnly" + log_to_im="false" + log_to_chat="true" + type="notifytip"> + <tag>fail</tag> + The land you're trying to claim contains [REGIONMATURITY] content, which is accessible to adults only. </notification> <notification icon="alertmodal.tga" name="LandClaimAccessBlocked_Change" type="alertmodal"> -You cannot claim this land due to your maturity Rating preference. - -You can click 'Change Preference' to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me > Preferences > General. + The land you're trying to claim contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, then you can try claiming the land again. <tag>fail</tag> <tag>confirm</tag> - <usetemplate - name="okcancelignore" - yestext="Change Preference" - notext="Close" - ignoretext="My chosen Rating preference prevents me from claiming Land"/> + <form name="form"> + <button + index="0" + name="OK" + text="Change preferences"/> + <button + default="true" + index="1" + name="Cancel" + text="Cancel"/> + <ignore name="ignore" text="The land you're trying to claim contains content excluded by your preferences."/> + </form> </notification> <notification icon="alertmodal.tga" name="LandBuyAccessBlocked" type="alertmodal"> -You cannot buy this land due to your maturity Rating. This may be a result of a lack of information validating your age. - -Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. - <tag>fail</tag> + The land you're trying to buy has a maturity rating exceeding your current preferences. You can change your preferences using Me > Preferences > General. + <tag>fail</tag> <usetemplate name="okbutton" yestext="OK"/> @@ -4160,11 +4551,9 @@ Please verify you have the latest Viewer installed, and go to the Knowledge Base <notification icon="alertmodal.tga" - name="LandBuyAccessBlocked_KB" + name="LandBuyAccessBlocked_AdultsOnlyContent" type="alertmodal"> -You cannot buy this land due to your maturity Rating. - -Go to the Knowledge Base for more information about maturity Ratings? + Only adults can buy this land. <tag>confirm</tag> <tag>fail</tag> <url option="0" name="url"> @@ -4174,31 +4563,48 @@ Go to the Knowledge Base for more information about maturity Ratings? name="okcancelignore" yestext="Go to Knowledge Base" notext="Close" - ignoretext="I can't buy this Land, due to restrictions of the maturity Rating"/> + ignoretext="Only adults can buy this land."/> </notification> <notification icon="notifytip.tga" name="LandBuyAccessBlocked_Notify" + log_to_im="false" + log_to_chat="true" type="notifytip"> -You cannot buy this land due to your maturity Rating. - <tag>fail</tag> + The land you're trying to buy contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. + <tag>fail</tag> + </notification> + + <notification + icon="notifytip.tga" + name="LandBuyAccessBlocked_NotifyAdultsOnly" + log_to_im="false" + log_to_chat="true" + type="notifytip"> + <tag>fail</tag> + The land you're trying to buy contains [REGIONMATURITY] content, which is accessible to adults only. </notification> <notification icon="alertmodal.tga" name="LandBuyAccessBlocked_Change" type="alertmodal"> -You cannot buy this land due to your maturity Rating preference. - -You can click 'Change Preference' to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me > Preferences > General. + The land you're trying to buy contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, then you can try buying the land again. <tag>confirm</tag> <tag>fail</tag> - <usetemplate - name="okcancelignore" - yestext="Change Preference" - notext="Close" - ignoretext="My chosen Rating preference prevents me from buying Land"/> + <form name="form"> + <button + index="0" + name="OK" + text="Change preferences"/> + <button + default="true" + index="1" + name="Cancel" + text="Cancel"/> + <ignore name="ignore" text="The land you're trying to buy contains content excluded by your preferences."/> + </form> </notification> <notification @@ -4353,10 +4759,11 @@ Type a short announcement which will be sent to everyone in this region. label="Changed Region Maturity" name="RegionMaturityChange" type="alertmodal"> -The maturity rating for this region has been updated. -It may take some time for the change to be reflected on the map. - -To enter Adult regions, Residents must be Account Verified, either by age-verification or payment-verification. +The maturity rating for this region has been changed. +It may take some time for this change to be reflected on the map. + <usetemplate + name="okbutton" + yestext="OK"/> </notification> <notification @@ -4619,6 +5026,20 @@ Go to your [http://secondlife.com/account/ Dashboard] to see your account histor <notification icon="alertmodal.tga" + name="ConfirmAddingChatParticipants" + type="alertmodal"> + <unique/> +When you add a person to an existing conversation, a new conversation will be created. All participants will receive new conversation notifications. + <tag>confirm</tag> + <usetemplate + ignoretext="Confirm adding chat paticipants" + name="okcancelignore" + notext="Cancel" + yestext="Ok"/> + </notification> + + <notification + icon="alertmodal.tga" name="ConfirmQuit" type="alertmodal"> <unique/> @@ -4786,25 +5207,25 @@ Do you want to replace it with the selected object? <notification icon="alert.tga" - label="Busy Mode Warning" - name="BusyModePay" + label="Do Not Disturb Mode Warning" + name="DoNotDisturbModePay" type="alert"> -You are in Busy Mode, which means you will not receive any items offered in exchange for this payment. +You have turned on Do Not Disturb. You will not receive any items offered in exchange for this payment. -Would you like to leave Busy Mode before completing this transaction? +Would you like to turn off Do Not Disturb before completing this transaction? <tag>confirm</tag> <form name="form"> <ignore name="ignore" save_option="true" - text="I am about to pay a person or object while I am in Busy mode"/> + text="I am about to pay a person or object while I am in Do Not Disturb mode"/> <button default="true" - ignore="Always leave Busy Mode" + ignore="Always leave Do Not Disturb Mode" index="0" name="Yes" text="OK"/> <button - ignore="Never leave Busy Mode" + ignore="Never leave Do Not Disturb Mode" index="1" name="No" text="Cancel"/> @@ -5062,20 +5483,20 @@ Would you like to automatically wear the clothing you are about to create? icon="alertmodal.tga" name="NotAgeVerified" type="alertmodal"> - <tag>fail</tag> -To access adult content and areas in Second Life you must be at least 18 years old. Please visit our age verification page to confirm you are over 18. -Note this will launch your web browser. - -[_URL] - <tag>confirm</tag> - <url option="0" name="url"> - https://secondlife.com/my/account/verification.php - </url> + The location you're trying to visit is restricted to residents age 18 and over. + <tag>fail</tag> <usetemplate - ignoretext="I have not verified my age" - name="okcancelignore" - notext="Cancel" - yestext="Go to Age Verification"/> + ignoretext="I am not old enough to visit age restricted areas." + name="okignore" + yestext="OK"/> + </notification> + + <notification + icon="notifytip.tga" + name="NotAgeVerified_Notify" + type="notifytip"> + Location restricted to age 18 and over. + <tag>fail</tag> </notification> <notification @@ -5115,6 +5536,8 @@ The string [STRING_NAME] is missing from strings.xml <notification icon="notifytip.tga" name="IMSystemMessageTip" + log_to_im="true" + log_to_chat="false" type="notifytip"> [MESSAGE] </notification> @@ -5158,18 +5581,14 @@ Topic: [SUBJECT], Message: [MESSAGE] <notification icon="notifytip.tga" - name="FriendOnline" - type="notifytip"> - <tag>friendship</tag> -[NAME] is Online - </notification> - - <notification - icon="notifytip.tga" - name="FriendOffline" + name="FriendOnlineOffline" + log_to_chat="false" type="notifytip"> <tag>friendship</tag> -[NAME] is Offline +<nolink>[NAME]</nolink> is [STATUS] + <unique combine="cancel_old"> + <context>NAME</context> + </unique> </notification> <notification @@ -5222,7 +5641,7 @@ Terrain.raw downloaded icon="notifytip.tga" name="GestureMissing" type="notifytip"> -Hmm. Gesture [NAME] is missing from the database. +Gesture [NAME] is missing from the database. <tag>fail</tag> </notification> @@ -5413,6 +5832,8 @@ You don't have permission to copy this. <notification icon="notifytip.tga" name="InventoryAccepted" + log_to_im="true" + log_to_chat="false" type="notifytip"> [NAME] received your inventory offer. </notification> @@ -5420,6 +5841,8 @@ You don't have permission to copy this. <notification icon="notifytip.tga" name="InventoryDeclined" + log_to_im="true" + log_to_chat="false" type="notifytip"> [NAME] declined your inventory offer. </notification> @@ -5501,6 +5924,7 @@ Please select at least one type of content to search (General, Moderate, or Adul <notification icon="notify.tga" name="PaymentReceived" + log_to_im="true" persist="true" type="notify"> <tag>funds</tag> @@ -5510,6 +5934,16 @@ Please select at least one type of content to search (General, Moderate, or Adul <notification icon="notify.tga" name="PaymentSent" + log_to_im="true" + persist="true" + type="notify"> + <tag>funds</tag> +[MESSAGE] + </notification> + + <notification + icon="notify.tga" + name="PaymentFailure" persist="true" type="notify"> <tag>funds</tag> @@ -5645,6 +6079,7 @@ The objects on the selected parcel that are NOT owned by you have been returned <notification icon="notify.tga" name="ServerObjectMessage" + log_to_im="true" persist="true" type="notify"> Message from [NAME]: @@ -5701,6 +6136,36 @@ This area has building disabled. You can't build or rez objects here. </notification> <notification + icon="notify.tga" + name="PathfindingDirty" + persist="true" + type="notify"> + <unique/> + The region has pending pathfinding changes. If you have build rights, you may rebake the region by clicking on the “Rebake region†button. + </notification> + + <notification + icon="notify.tga" + name="DynamicPathfindingDisabled" + persist="true" + type="notify"> + <unique/> + Dynamic pathfinding is not enabled on this region. Scripted objects using pathfinding LSL calls may not operate as expected on this region. + </notification> + + <notification + icon="alertmodal.tga" + name="PathfindingCannotRebakeNavmesh" + type="alertmodal"> + <unique/> + An error occurred. There may be a network or server problem, or you may not have build rights. Sometimes logging out and back in will solve this problem. + <usetemplate + name="okbutton" + yestext="OK" + /> + </notification> + + <notification icon="notify.tga" name="SeeAvatars" persist="true" @@ -5751,9 +6216,7 @@ You can only claim public land in the Region you're in. persist="true" type="notify"> <tag>fail</tag> -You aren't allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer. - -Please go to the Knowledge Base for details on accessing areas with this maturity Rating. + The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me > Preferences > General. </notification> <notification @@ -5785,11 +6248,11 @@ You do not have proper payment status to enter this region. <notification icon="notify.tga" - name="MustGetAgeRgion" + name="MustGetAgeRegion" persist="true" type="notify"> <tag>fail</tag> -You must be age-verified to enter this region. +You must be age 18 or over to enter this region. </notification> <notification @@ -5798,7 +6261,7 @@ You must be age-verified to enter this region. persist="true" type="notify"> <tag>fail</tag> -You must be age-verified to enter this parcel. + You must be age 18 or over to enter this parcel. </notification> <notification @@ -6015,7 +6478,9 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th <notification icon="notify.tga" name="UserGiveItem" - type="offer"> + log_to_im ="true" + type="offer" + sound="UISndNewIncomingIMSession"> [NAME_SLURL] has given you this [OBJECTTYPE]: [ITEM_SLURL] <form name="form"> @@ -6070,10 +6535,14 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th <notification icon="notify.tga" name="TeleportOffered" - type="offer"> + log_to_im="true" + log_to_chat="false" + type="offer" + sound="UISndNewIncomingIMSession"> [NAME_SLURL] has offered to teleport you to their location: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <tag>confirm</tag> <form name="form"> <button @@ -6089,8 +6558,51 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th <notification icon="notify.tga" - name="TeleportOfferSent" + name="TeleportOffered_MaturityExceeded" + log_to_im="true" + log_to_chat="false" type="offer"> +[NAME_SLURL] has offered to teleport you to their location: + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +This region contains [REGION_CONTENT_MATURITY] content, but your current preferences are set to exclude [REGION_CONTENT_MATURITY] content. We can change your preferences and continue with the teleport, or you can cancel this teleport. + <tag>confirm</tag> + <form name="form"> + <button + index="0" + name="Teleport" + text="Change and Continue"/> + <button + index="1" + name="Cancel" + text="Cancel"/> + </form> + </notification> + + <notification + icon="notify.tga" + name="TeleportOffered_MaturityBlocked" + log_to_im="true" + log_to_chat="false" + type="notifytip"> +[NAME_SLURL] has offered to teleport you to their location: + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +However, this region contains content accessible to adults only. + <tag>fail</tag> + </notification> + + <notification + icon="notify.tga" + name="TeleportOfferSent" + log_to_im="true" + log_to_chat="false" + show_toast="false" + type="notify"> Teleport offer sent to [TO_NAME] </notification> @@ -6117,6 +6629,7 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th <notification icon="notify.tga" name="OfferFriendship" + log_to_im="true" type="offer"> <tag>friendship</tag> <tag>confirm</tag> @@ -6140,7 +6653,9 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th <notification icon="notify.tga" name="FriendshipOffered" - type="offer"> + log_to_im="true" + show_toast="false" + type="notify"> <tag>friendship</tag> You have offered friendship to [TO_NAME] </notification> @@ -6169,24 +6684,28 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th <notification icon="notify.tga" name="FriendshipAccepted" - type="offer"> + log_to_im="true" + type="notify"> <tag>friendship</tag> -[NAME] accepted your friendship offer. +<nolink>[NAME]</nolink> accepted your friendship offer. </notification> <notification icon="notify.tga" name="FriendshipDeclined" + log_to_im="true" persist="true" type="notify"> <tag>friendship</tag> -[NAME] declined your friendship offer. +<nolink>[NAME]</nolink> declined your friendship offer. </notification> <notification icon="notify.tga" name="FriendshipAcceptedByMe" - type="offer"> + log_to_im="true" + show_toast="false" + type="notify"> <tag>friendship</tag> Friendship offer accepted. </notification> @@ -6194,7 +6713,9 @@ Friendship offer accepted. <notification icon="notify.tga" name="FriendshipDeclinedByMe" - type="offer"> + log_to_im="true" + show_toast="false" + type="notify"> <tag>friendship</tag> Friendship offer declined. </notification> @@ -6243,6 +6764,7 @@ If you stay in this region you will be logged out. <notification icon="notify.tga" name="LoadWebPage" + show_toast="false" type="notify"> Load web page [URL]? @@ -6318,47 +6840,45 @@ Is this OK? <notification icon="notify.tga" name="ScriptQuestionCaution" - priority="high" + priority="critical" persist="true" type="notify"> -An object named '<nolink>[OBJECTNAME]</nolink>', owned by '[NAME]' would like to: - -[QUESTIONS] -If you do not trust this object and its creator, you should deny the request. +Warning: The object '<nolink>[OBJECTNAME]</nolink>' wants total access to your Linden Dollars account. If you allow access, it can remove funds from your account at any time, or empty your account completely, on an ongoing basis with no additional warnings. + +Do not allow access if you do not fully understand why it wants access to your account. -Grant this request? <tag>confirm</tag> <form name="form"> <button index="0" name="Grant" - text="Grant"/> + text="Allow total access"/> <button default="true" index="1" name="Deny" text="Deny"/> - <button - index="2" - name="Details" - text="Details..."/> </form> + <footer> +[FOOTERTEXT] + </footer> </notification> <notification icon="notify.tga" name="ScriptDialog" + show_toast="false" type="notify"> [NAME]'s '<nolink>[TITLE]</nolink>' [MESSAGE] <form name="form"> <button index="-2" - name="Mute" + name="Client_Side_Mute" text="Block"/> <button index="-1" - name="Ignore" + name="Client_Side_Ignore" text="Ignore"/> </form> </notification> @@ -6366,6 +6886,7 @@ Grant this request? <notification icon="notify.tga" name="ScriptDialogGroup" + show_toast="false" type="notify"> <tag>group</tag> [GROUPNAME]'s '<nolink>[TITLE]</nolink>' @@ -6373,11 +6894,11 @@ Grant this request? <form name="form"> <button index="-2" - name="Mute" + name="Client_Side_Mute" text="Block"/> <button index="-1" - name="Ignore" + name="Client_Side_Ignore" text="Ignore"/> </form> </notification> @@ -6939,6 +7460,26 @@ With the following Residents: <usetemplate name="okcancelbuttons" notext="Cancel" + yestext="OK"/> + </notification> + + <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: + +<nolink>[ITEMS]</nolink> + +With the following Residents: + +[RESIDENTS] + <tag>confirm</tag> + <usetemplate + name="okcancelbuttons" + notext="Cancel" yestext="Ok"/> </notification> @@ -7106,6 +7647,18 @@ You locally updated a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] <notification icon="alertmodal.tga" + name="LivePreviewUnavailable" + type="alert"> + +We cannot display a preview of this texture because it is no-copy and/or no-transfer. + <usetemplate + ignoretext="Warn me that Live Preview mode is not available for no-copy and/or no-transfer textures" + name="okignore" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" name="ConfirmLeaveCall" type="alert"> Are you sure you want to leave this call? @@ -7135,7 +7688,7 @@ Mute everyone? <usetemplate ignoretext="Confirm before I mute all participants in a group call" name="okcancelignore" - yestext="Ok" + yestext="OK" notext="Cancel"> <unique/> </usetemplate> @@ -7588,7 +8141,135 @@ The site at '<nolink>[HOST_NAME]</nolink>' in realm ' notext="Cancel" ignoretext="Confirm before hiding UI"/> </notification> - + + <notification + icon="alertmodal.tga" + name="PathfindingLinksets_WarnOnPhantom" + type="alertmodal"> +Some selected linksets will have the Phantom flag toggled. + +Do you wish to continue? + <tag>confirm</tag> + <usetemplate + ignoretext="Some selected linksets phantom flag will be toggled." + name="okcancelignore" + notext="Cancel" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="PathfindingLinksets_MismatchOnRestricted" + type="alertmodal"> +Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because of permission restrictions on the linkset. These linksets will be set to be '[RESTRICTED_TYPE]' instead. + +Do you wish to continue? + <tag>confirm</tag> + <usetemplate + ignoretext="Some selected linksets cannot be set because of permission restrictions on the linkset." + name="okcancelignore" + notext="Cancel" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="PathfindingLinksets_MismatchOnVolume" + type="alertmodal"> +Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because the shape is non-convex. + +Do you wish to continue? + <tag>confirm</tag> + <usetemplate + ignoretext="Some selected linksets cannot be set because the shape is non-convex" + name="okcancelignore" + notext="Cancel" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted" + type="alertmodal"> +Some selected linksets will have the Phantom flag toggled. + +Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because of permission restrictions on the linkset. These linksets will be set to be '[RESTRICTED_TYPE]' instead. + +Do you wish to continue? + <tag>confirm</tag> + <usetemplate + ignoretext="Some selected linksets phantom flag will be toggled and others cannot be set because of permission restrictions on the linkset." + name="okcancelignore" + notext="Cancel" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume" + type="alertmodal"> +Some selected linksets will have the Phantom flag toggled. + +Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because the shape is non-convex. + +Do you wish to continue? + <tag>confirm</tag> + <usetemplate + ignoretext="Some selected linksets phantom flag will be toggled and others cannot be set because the shape is non-convex" + name="okcancelignore" + notext="Cancel" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume" + type="alertmodal"> +Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because of permission restrictions on the linkset. These linksets will be set to be '[RESTRICTED_TYPE]' instead. + +Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because the shape is non-convex. These linksets' use types will not change. + +Do you wish to continue? + <tag>confirm</tag> + <usetemplate + ignoretext="Some selected linksets cannot be set because of permission restrictions on the linkset and because the shape is non-convex." + name="okcancelignore" + notext="Cancel" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume" + type="alertmodal"> +Some selected linksets will have the Phantom flag toggled. + +Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because of permission restrictions on the linkset. These linksets will be set to be '[RESTRICTED_TYPE]' instead. + +Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because the shape is non-convex. These linksets' use types will not change. + +Do you wish to continue? + <tag>confirm</tag> + <usetemplate + ignoretext="Some selected linksets phantom flag will be toggled and others cannot be set because of permission restrictions on the linkset and because the shape is non-convex." + name="okcancelignore" + notext="Cancel" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="PathfindingLinksets_ChangeToFlexiblePath" + type="alertmodal"> + The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh. + <tag>confirm</tag> + <usetemplate + ignoretext="The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh." + name="okcancelignore" + notext="Cancel" + yestext="OK"/> + </notification> + <global name="UnsupportedGLRequirements"> You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_NAME] requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system. @@ -7621,4 +8302,1733 @@ Otherwise, you can look at the Map and find places marked "Infohub". You died and have been teleported to your home location. </global> + <notification + icon="alertmodal.tga" + name="LocalBitmapsUpdateFileNotFound" + persist="true" + type="notify"> +[FNAME] could not be updated because the file could no longer be found. +Disabling future updates for this file. + </notification> + + <notification + icon="alertmodal.tga" + name="LocalBitmapsUpdateFailedFinal" + persist="true" + type="notify"> +[FNAME] could not be opened or decoded for [NRETRIES] attempts, and is now considered broken. +Disabling future updates for this file. + </notification> + + <notification + icon="alertmodal.tga" + name="LocalBitmapsVerifyFail" + persist="true" + type="notify"> +Attempted to add an invalid or unreadable image file [FNAME] which could not be opened or decoded. +Attempt cancelled. + </notification> + + <notification + icon="alertmodal.tga" + name="PathfindingReturnMultipleItems" + type="alertmodal"> + You are returning [NUM_ITEMS] items. Are you sure you want to continue? + <tag>confirm</tag> + <usetemplate + ignoretext="Are you sure you want to return multiple items?" + name="okcancelignore" + notext="No" + yestext="Yes"/> + </notification> + + <notification + icon="alertmodal.tga" + name="PathfindingDeleteMultipleItems" + type="alertmodal"> + You are deleting [NUM_ITEMS] items. Are you sure you want to continue? + <tag>confirm</tag> + <usetemplate + ignoretext="Are you sure you want to delete multiple items?" + name="okcancelignore" + notext="No" + yestext="Yes"/> + </notification> + + + <notification + icon="alertmodal.tga" + name="AvatarFrozen" + type="notify"> + <tag>fail</tag> +[AV_FREEZER] has frozen you. You cannot move or interact with the world. + </notification> + + <notification + icon="alertmodal.tga" + name="AvatarFrozenDuration" + type="notify"> + <tag>fail</tag> +[AV_FREEZER] has frozen you for [AV_FREEZE_TIME] seconds. You cannot move or interact with the world. + </notification> + + <notification + icon="alertmodal.tga" + name="YouFrozeAvatar" + type="notify"> + <tag>fail</tag> +Avatar frozen. + </notification> + + <notification + icon="alertmodal.tga" + name="AvatarHasUnFrozenYou" + type="notify"> + <tag>fail</tag> +[AV_FREEZER] has unfrozen you. + </notification> + + <notification + icon="alertmodal.tga" + name="AvatarUnFrozen" + type="notify"> + <tag>fail</tag> +Avatar unfrozen. + </notification> + + <notification + icon="alertmodal.tga" + name="AvatarFreezeFailure" + type="notify"> + <tag>fail</tag> +Freeze failed because you don't have admin permission for that parcel. + </notification> + + <notification + icon="alertmodal.tga" + name="AvatarFreezeThaw" + type="notify"> + <tag>fail</tag> +Your freeze expired, go about your business. + </notification> + + <notification + icon="alertmodal.tga" + name="AvatarCantFreeze" + type="notify"> + <tag>fail</tag> +Sorry, can't freeze that user. + </notification> + + <notification + icon="alertmodal.tga" + name="NowOwnObject" + type="notify"> + <tag>fail</tag> +You are now the owner of object [OBJECT_NAME] + </notification> + + <notification + icon="alertmodal.tga" + name="CantRezOnLand" + type="notify"> + <tag>fail</tag> +Can't rez object at [OBJECT_POS] because the owner of this land does not allow it. Use the land tool to see land ownership. + </notification> + + <notification + icon="alertmodal.tga" + name="RezFailTooManyRequests" + type="notify"> + <tag>fail</tag> +Object can not be rezzed because there are too many requests. + </notification> + + <notification + icon="alertmodal.tga" + name="SitFailCantMove" + type="notify"> + <tag>fail</tag> +You cannot sit because you cannot move at this time. + </notification> + + <notification + icon="alertmodal.tga" + name="SitFailNotAllowedOnLand" + type="notify"> + <tag>fail</tag> +You cannot sit because you are not allowed on that land. + </notification> + + <notification + icon="alertmodal.tga" + name="SitFailNotSameRegion" + type="notify"> + <tag>fail</tag> +Try moving closer. Can't sit on object because +it is not in the same region as you. + </notification> + + <notification + icon="alertmodal.tga" + name="NoNewObjectRegionFull" + type="notify"> + <tag>fail</tag> +Unable to create new object. The region is full. + </notification> + + <notification + icon="alertmodal.tga" + name="FailedToPlaceObject" + type="notify"> + <tag>fail</tag> +Failed to place object at specified location. Please try again. + </notification> + + <notification + icon="alertmodal.tga" + name="NoOwnNoGardening" + type="notify"> + <tag>fail</tag> +You Can't create trees and grass on land you don't own. + </notification> + + <notification + icon="alertmodal.tga" + name="NoCopyPermsNoObject" + type="notify"> + <tag>fail</tag> +Copy failed because you lack permission to copy the object '[OBJ_NAME]'. + </notification> + + <notification + icon="alertmodal.tga" + name="NoTransPermsNoObject" + type="notify"> + <tag>fail</tag> +Copy failed because the object '[OBJ_NAME]' cannot be transferred to you. + </notification> + + <notification + icon="alertmodal.tga" + name="AddToNavMeshNoCopy" + type="notify"> + <tag>fail</tag> +Copy failed because the object '[OBJ_NAME]' contributes to navmesh. + </notification> + + <notification + icon="alertmodal.tga" + name="DupeWithNoRootsSelected" + type="notify"> + <tag>fail</tag> +Duplicate with no root objects selected. + </notification> + + <notification + icon="alertmodal.tga" + name="CantDupeCuzRegionIsFull" + type="notify"> + <tag>fail</tag> +Can't duplicate objects because the region is full. + </notification> + + <notification + icon="alertmodal.tga" + name="CantDupeCuzParcelNotFound" + type="notify"> + <tag>fail</tag> +Can't duplicate objects - Can't find the parcel they are on. + </notification> + + <notification + icon="alertmodal.tga" + name="CantCreateCuzParcelFull" + type="notify"> + <tag>fail</tag> +Can't create object because +the parcel is full. + </notification> + + <notification + icon="alertmodal.tga" + name="RezAttemptFailed" + type="notify"> + <tag>fail</tag> +Attempt to rez an object failed. + </notification> + + <notification + icon="alertmodal.tga" + name="ToxicInvRezAttemptFailed" + type="notify"> + <tag>fail</tag> +Unable to create item that has caused problems on this region. + </notification> + + <notification + icon="alertmodal.tga" + name="InvItemIsBlacklisted" + type="notify"> + <tag>fail</tag> +That inventory item has been blacklisted. + </notification> + + <notification + icon="alertmodal.tga" + name="NoCanRezObjects" + type="notify"> + <tag>fail</tag> +You are not currently allowed to create objects. + </notification> + + <notification + icon="alertmodal.tga" + name="LandSearchBlocked" + type="notify"> + <tag>fail</tag> +Land Search Blocked. +You have performed too many land searches too quickly. +Please try again in a minute. + </notification> + + <notification + icon="alertmodal.tga" + name="NotEnoughResourcesToAttach" + type="notify"> + <tag>fail</tag> +Not enough script resources available to attach object! + </notification> + + <notification + icon="alertmodal.tga" + name="YouDiedAndGotTPHome" + type="notify"> + <tag>fail</tag> +You died and have been teleported to your home location + </notification> + + <notification + icon="alertmodal.tga" + name="EjectComingSoon" + type="notify"> + <tag>fail</tag> +You are no longer allowed here and have [EJECT_TIME] seconds to leave. + </notification> + + <notification + icon="alertmodal.tga" + name="NoEnterServerFull" + type="notify"> + <tag>fail</tag> +You can't enter this region because +the server is full. + </notification> + + <notification + icon="alertmodal.tga" + name="SaveBackToInvDisabled" + type="notify"> + <tag>fail</tag> +Save Back To Inventory has been disabled. + </notification> + + <notification + icon="alertmodal.tga" + name="NoExistNoSaveToContents" + type="notify"> + <tag>fail</tag> +Cannot save '[OBJ_NAME]' to object contents because the object it was rezzed from no longer exists. + </notification> + + <notification + icon="alertmodal.tga" + name="NoModNoSaveToContents" + type="notify"> + <tag>fail</tag> +Cannot save '[OBJ_NAME]' to object contents because you do not have permission to modify the object '[DEST_NAME]'. + </notification> + + <notification + icon="alertmodal.tga" + name="NoSaveBackToInvDisabled" + type="notify"> + <tag>fail</tag> +Cannot save '[OBJ_NAME]' back to inventory -- this operation has been disabled. + </notification> + + <notification + icon="alertmodal.tga" + name="NoCopyNoSelCopy" + type="notify"> + <tag>fail</tag> +You cannot copy your selection because you do not have permission to copy the object '[OBJ_NAME]'. + </notification> + + <notification + icon="alertmodal.tga" + name="NoTransNoSelCopy" + type="notify"> + <tag>fail</tag> +You cannot copy your selection because the object '[OBJ_NAME]' is not transferrable. + </notification> + + <notification + icon="alertmodal.tga" + name="NoTransNoCopy" + type="notify"> + <tag>fail</tag> +You cannot copy your selection because the object '[OBJ_NAME]' is not transferrable. + </notification> + + <notification + icon="alertmodal.tga" + name="NoPermsNoRemoval" + type="notify"> + <tag>fail</tag> +Removal of the object '[OBJ_NAME]' from the simulator is disallowed by the permissions system. + </notification> + + <notification + icon="alertmodal.tga" + name="NoModNoSaveSelection" + type="notify"> + <tag>fail</tag> +Cannot save your selection because you do not have permission to modify the object '[OBJ_NAME]'. + </notification> + + <notification + icon="alertmodal.tga" + name="NoCopyNoSaveSelection" + type="notify"> + <tag>fail</tag> +Cannot save your selection because the object '[OBJ_NAME]' is not copyable. + </notification> + + <notification + icon="alertmodal.tga" + name="NoModNoTaking" + type="notify"> + <tag>fail</tag> +You cannot take your selection because you do not have permission to modify the object '[OBJ_NAME]'. + </notification> + + <notification + icon="alertmodal.tga" + name="RezDestInternalError" + type="notify"> + <tag>fail</tag> +Internal Error: Unknown destination type. + </notification> + + <notification + icon="alertmodal.tga" + name="DeleteFailObjNotFound" + type="notify"> + <tag>fail</tag> +Delete failed because object not found + </notification> + + <notification + icon="alertmodal.tga" + name="SorryCantEjectUser" + type="notify"> + <tag>fail</tag> +Sorry, can't eject that user. + </notification> + + <notification + icon="alertmodal.tga" + name="RegionSezNotAHome" + type="notify"> + <tag>fail</tag> +This region does not allow you to set your home location here. + </notification> + + <notification + icon="alertmodal.tga" + name="HomeLocationLimits" + type="notify"> + <tag>fail</tag> +You can only set your 'Home Location' on your land or at a mainland Infohub. + </notification> + + <notification + icon="alertmodal.tga" + name="HomePositionSet" + type="notify"> + <tag>fail</tag> +Home position set. + </notification> + + <notification + icon="alertmodal.tga" + name="AvatarEjected" + type="notify"> + <tag>fail</tag> +Avatar ejected. + </notification> + + <notification + icon="alertmodal.tga" + name="AvatarEjectFailed" + type="notify"> + <tag>fail</tag> +Eject failed because you don't have admin permission for that parcel. + </notification> + + <notification + icon="alertmodal.tga" + name="CantMoveObjectParcelFull" + type="notify"> + <tag>fail</tag> +Can't move object '[OBJECT_NAME]' to +[OBJ_POSITION] in region [REGION_NAME] because the parcel is full. + </notification> + + <notification + icon="alertmodal.tga" + name="CantMoveObjectParcelPerms" + type="notify"> + <tag>fail</tag> +Can't move object '[OBJECT_NAME]' to +[OBJ_POSITION] in region [REGION_NAME] because your objects are not allowed on this parcel. + </notification> + + <notification + icon="alertmodal.tga" + name="CantMoveObjectParcelResources" + type="notify"> + <tag>fail</tag> +Can't move object '[OBJECT_NAME]' to +[OBJ_POSITION] in region [REGION_NAME] because there are not enough resources for this object on this parcel. + </notification> + + <notification + icon="alertmodal.tga" + name="CantMoveObjectRegionVersion" + type="notify"> + <tag>fail</tag> +Can't move object '[OBJECT_NAME]' to +[OBJ_POSITION] in region [REGION_NAME] because the other region is running an older version which does not support receiving this object via region crossing. + </notification> + + <notification + icon="alertmodal.tga" + name="CantMoveObjectNavMesh" + type="notify"> + <tag>fail</tag> +Can't move object '[OBJECT_NAME]' to +[OBJ_POSITION] in region [REGION_NAME] because you cannot modify the navmesh across region boundaries. + </notification> + + <notification + icon="alertmodal.tga" + name="CantMoveObjectWTF" + type="notify"> + <tag>fail</tag> +Can't move object '[OBJECT_NAME]' to +[OBJ_POSITION] in region [REGION_NAME] because of an unknown reason. ([FAILURE_TYPE]) + </notification> + + <notification + icon="alertmodal.tga" + name="NoPermModifyObject" + type="notify"> + <tag>fail</tag> +You don't have permission to modify that object + </notification> + + <notification + icon="alertmodal.tga" + name="CantEnablePhysObjContributesToNav" + type="notify"> + <tag>fail</tag> +Can't enable physics for an object that contributes to the navmesh. + </notification> + + <notification + icon="alertmodal.tga" + name="CantEnablePhysKeyframedObj" + type="notify"> + <tag>fail</tag> +Can't enable physics for keyframed objects. + </notification> + + <notification + icon="alertmodal.tga" + name="CantEnablePhysNotEnoughLandResources" + type="notify"> + <tag>fail</tag> +Can't enable physics for object -- insufficient land resources. + </notification> + + <notification + icon="alertmodal.tga" + name="CantEnablePhysCostTooGreat" + persist="true" + type="notify"> + <tag>fail</tag> +Can't enable physics for object with physics resource cost greater than [MAX_OBJECTS] + </notification> + + <notification + icon="alertmodal.tga" + name="PhantomWithConcavePiece" + type="notify"> + <tag>fail</tag> +This object cannot have a concave piece because it is phantom and contributes to the navmesh. + </notification> + + <notification + icon="alertmodal.tga" + name="UnableAddItem" + type="notify"> + <tag>fail</tag> +Unable to add item! + </notification> + + <notification + icon="alertmodal.tga" + name="UnableEditItem" + type="notify"> + <tag>fail</tag> +Unable to edit this! + </notification> + + <notification + icon="alertmodal.tga" + name="NoPermToEdit" + type="notify"> + <tag>fail</tag> +Not permitted to edit this. + </notification> + + <notification + icon="alertmodal.tga" + name="NoPermToCopyInventory" + type="notify"> + <tag>fail</tag> +Not permitted to copy that inventory. + </notification> + + <notification + icon="alertmodal.tga" + name="CantSaveItemDoesntExist" + type="notify"> + <tag>fail</tag> +Cannot save to object contents: Item no longer exists. + </notification> + + <notification + icon="alertmodal.tga" + name="CantSaveItemAlreadyExists" + type="notify"> + <tag>fail</tag> +Cannot save to object contents: Item with that name already exists in inventory + </notification> + + <notification + icon="alertmodal.tga" + name="CantSaveModifyAttachment" + type="notify"> + <tag>fail</tag> +Cannot save to object contents: This would modify the attachment permissions. + </notification> + + <notification + icon="alertmodal.tga" + name="TooManyScripts" + type="notify"> + <tag>fail</tag> +Too many scripts. + </notification> + + <notification + icon="alertmodal.tga" + name="UnableAddScript" + type="notify"> + <tag>fail</tag> +Unable to add script! + </notification> + + <notification + icon="alertmodal.tga" + name="AssetServerTimeoutObjReturn" + type="notify"> + <tag>fail</tag> +Asset server didn't respond in a timely fashion. Object returned to sim. + </notification> + + <notification + icon="alertmodal.tga" + name="RegionDisablePhysicsShapes" + type="notify"> + <tag>fail</tag> +This region does not have physics shapes enabled. + </notification> + + <notification + icon="alertmodal.tga" + name="NoModNavmeshAcrossRegions" + type="notify"> + <tag>fail</tag> +You cannot modify the navmesh across region boundaries. + </notification> + + <notification + icon="alertmodal.tga" + name="NoSetPhysicsPropertiesOnObjectType" + type="notify"> + <tag>fail</tag> +Cannot set physics properties on that object type. + </notification> + + <notification + icon="alertmodal.tga" + name="NoSetRootPrimWithNoShape" + type="notify"> + <tag>fail</tag> +Cannot set root prim to have no shape. + </notification> + + <notification + icon="alertmodal.tga" + name="NoRegionSupportPhysMats" + type="notify"> + <tag>fail</tag> +This region does not have physics materials enabled. + </notification> + + <notification + icon="alertmodal.tga" + name="OnlyRootPrimPhysMats" + type="notify"> + <tag>fail</tag> +Only root prims may have their physics materials adjusted. + </notification> + + <notification + icon="alertmodal.tga" + name="NoSupportCharacterPhysMats" + type="notify"> + <tag>fail</tag> +Setting physics materials on characters is not yet supported. + </notification> + + <notification + icon="alertmodal.tga" + name="InvalidPhysMatProperty" + type="notify"> + <tag>fail</tag> +One or more of the specified physics material properties was invalid. + </notification> + + <notification + icon="alertmodal.tga" + name="NoPermsAlterStitchingMeshObj" + type="notify"> + <tag>fail</tag> +You may not alter the stitching type of a mesh object. + </notification> + + <notification + icon="alertmodal.tga" + name="NoPermsAlterShapeMeshObj" + type="notify"> + <tag>fail</tag> +You may not alter the shape of a mesh object + </notification> + + <notification + icon="alertmodal.tga" + name="FullRegionCantEnter" + type="notify"> + <tag>fail</tag> +You can't enter this region because \nthe region is full. + </notification> + + <notification + icon="alertmodal.tga" + name="LinkFailedOwnersDiffer" + type="notify"> + <tag>fail</tag> +Link failed -- owners differ + </notification> + + <notification + icon="alertmodal.tga" + name="LinkFailedNoModNavmeshAcrossRegions" + type="notify"> + <tag>fail</tag> +Link failed -- cannot modify the navmesh across region boundaries. + </notification> + + <notification + icon="alertmodal.tga" + name="LinkFailedNoPermToEdit" + type="notify"> + <tag>fail</tag> +Link failed because you do not have edit permission. + </notification> + + <notification + icon="alertmodal.tga" + name="LinkFailedTooManyPrims" + type="notify"> + <tag>fail</tag> +Link failed -- too many primitives + </notification> + + <notification + icon="alertmodal.tga" + name="LinkFailedCantLinkNoCopyNoTrans" + type="notify"> + <tag>fail</tag> +Link failed -- cannot link no-copy with no-transfer + </notification> + + <notification + icon="alertmodal.tga" + name="LinkFailedNothingLinkable" + type="notify"> + <tag>fail</tag> +Link failed -- nothing linkable. + </notification> + + <notification + icon="alertmodal.tga" + name="LinkFailedTooManyPathfindingChars" + type="notify"> + <tag>fail</tag> +Link failed -- too many pathfinding characters + </notification> + + <notification + icon="alertmodal.tga" + name="LinkFailedInsufficientLand" + type="notify"> + <tag>fail</tag> +Link failed -- insufficient land resources + </notification> + + <notification + icon="alertmodal.tga" + name="LinkFailedTooMuchPhysics" + type="notify"> + <tag>fail</tag> +Object uses too many physics resources -- its dynamics have been disabled. + </notification> + + <notification + icon="alertmodal.tga" + name="TeleportedHomeByObjectOnParcel" + persist="true" + type="notify"> + <tag>fail</tag> +You have been teleported home by the object '[OBJECT_NAME]' on the parcel '[PARCEL_NAME]' + </notification> + + <notification + icon="alertmodal.tga" + name="TeleportedHomeByObject" + persist="true" + type="notify"> + <tag>fail</tag> +You have been teleported home by the object '[OBJECT_NAME]' + </notification> + + <notification + icon="alertmodal.tga" + name="TeleportedByAttachment" + type="notify"> + <tag>fail</tag> +You have been teleported by an attachment on [ITEM_ID] + </notification> + + <notification + icon="alertmodal.tga" + name="TeleportedByObjectOnParcel" + type="notify"> + <tag>fail</tag> +You have been teleported by the object '[OBJECT_NAME]' on the parcel '[PARCEL_NAME]' + </notification> + + <notification + icon="alertmodal.tga" + name="TeleportedByObjectOwnedBy" + type="notify"> + <tag>fail</tag> +You have been teleported by the object '[OBJECT_NAME]' owned by [OWNER_ID] + </notification> + + <notification + icon="alertmodal.tga" + name="TeleportedByObjectUnknownUser" + type="notify"> + <tag>fail</tag> +You have been teleported by the object '[OBJECT_NAME]' owned by an unknown user. + </notification> + + <notification + icon="alertmodal.tga" + name="CantCreateObjectRegionFull" + type="notify"> + <tag>fail</tag> +Unable to create requested object. The region is full. + </notification> + + <notification + icon="alertmodal.tga" + name="CantAttackMultipleObjOneSpot" + type="notify"> + <tag>fail</tag> +You can't attach multiple objects to one spot. + </notification> + + <notification + icon="alertmodal.tga" + name="CantCreateMultipleObjAtLoc" + type="notify"> + <tag>fail</tag> +You can't create multiple objects here. + </notification> + + <notification + icon="alertmodal.tga" + name="UnableToCreateObjTimeOut" + type="notify"> + <tag>fail</tag> +Unable to create requested object. Object is missing from database. + </notification> + + <notification + icon="alertmodal.tga" + name="UnableToCreateObjUnknown" + type="notify"> + <tag>fail</tag> +Unable to create requested object. The request timed out. Please try again. + </notification> + + <notification + icon="alertmodal.tga" + name="UnableToCreateObjMissingFromDB" + type="notify"> + <tag>fail</tag> +Unable to create requested object. Please try again. + </notification> + + <notification + icon="alertmodal.tga" + name="RezFailureTookTooLong" + type="notify"> + <tag>fail</tag> +Rez failed, requested object took too long to load. + </notification> + + <notification + icon="alertmodal.tga" + name="FailedToPlaceObjAtLoc" + type="notify"> + <tag>fail</tag> +Failed to place object at specified location. Please try again. + </notification> + + <notification + icon="alertmodal.tga" + name="CantCreatePlantsOnLand" + type="notify"> + <tag>fail</tag> +You cannot create plants on this land. + </notification> + + <notification + icon="alertmodal.tga" + name="CantRestoreObjectNoWorldPos" + type="notify"> + <tag>fail</tag> +Cannot restore object. No world position found. + </notification> + + <notification + icon="alertmodal.tga" + name="CantRezObjectInvalidMeshData" + type="notify"> + <tag>fail</tag> +Unable to rez object because its mesh data is invalid. + </notification> + + <notification + icon="alertmodal.tga" + name="CantRezObjectTooManyScripts" + type="notify"> + <tag>fail</tag> +Unable to rez object because there are already too many scripts in this region. + </notification> + + <notification + icon="alertmodal.tga" + name="CantCreateObjectNoAccess" + type="notify"> + <tag>fail</tag> +Your access privileges don't allow you to create objects there. + </notification> + + <notification + icon="alertmodal.tga" + name="CantCreateObject" + type="notify"> + <tag>fail</tag> +You are not currently allowed to create objects. + </notification> + + <notification + icon="alertmodal.tga" + name="InvalidObjectParams" + type="notify"> + <tag>fail</tag> +Invalid object parameters + </notification> + + <notification + icon="alertmodal.tga" + name="CantDuplicateObjectNoAcess" + type="notify"> + <tag>fail</tag> +Your access privileges don't allow you to duplicate objects here. + </notification> + + <notification + icon="alertmodal.tga" + name="CantChangeShape" + type="notify"> + <tag>fail</tag> +You are not allowed to change this shape. + </notification> + + <notification + icon="alertmodal.tga" + name="NoAccessToClaimObjects" + type="notify"> + <tag>fail</tag> +Your access privileges don't allow you to claim objects here. + </notification> + + <notification + icon="alertmodal.tga" + name="DeedFailedNoPermToDeedForGroup" + type="notify"> + <tag>fail</tag> +Deed failed because you do not have permission to deed objects for your group. + </notification> + + <notification + icon="alertmodal.tga" + name="NoPrivsToBuyObject" + type="notify"> + <tag>fail</tag> +Your access privileges don't allow you to buy objects here. + </notification> + + <notification + icon="alertmodal.tga" + name="CantAttachObjectAvatarSittingOnIt" + type="notify"> + <tag>fail</tag> +Cannot attach object because an avatar is sitting on it. + </notification> + + <notification + icon="alertmodal.tga" + name="WhyAreYouTryingToWearShrubbery" + type="notify"> + <tag>fail</tag> +Trees and grasses cannot be worn as attachments. + </notification> + + <notification + icon="alertmodal.tga" + name="CantAttachGroupOwnedObjs" + type="notify"> + <tag>fail</tag> +Cannot attach group-owned objects. + </notification> + + <notification + icon="alertmodal.tga" + name="CantAttachObjectsNotOwned" + type="notify"> + <tag>fail</tag> +Cannot attach objects that you don't own. + </notification> + + <notification + icon="alertmodal.tga" + name="CantAttachNavmeshObjects" + type="notify"> + <tag>fail</tag> +Cannot attach objects that contribute to navmesh. + </notification> + + <notification + icon="alertmodal.tga" + name="CantAttachObjectNoMovePermissions" + type="notify"> + <tag>fail</tag> +Cannot attach object because you do not have permission to move it. + </notification> + + <notification + icon="alertmodal.tga" + name="CantAttachNotEnoughScriptResources" + type="notify"> + <tag>fail</tag> +Not enough script resources available to attach object! + </notification> + + <notification + icon="alertmodal.tga" + name="CantDropItemTrialUser" + type="notify"> + <tag>fail</tag> +You can't drop objects here; try the Free Trial area. + </notification> + + <notification + icon="alertmodal.tga" + name="CantDropMeshAttachment" + type="notify"> + <tag>fail</tag> +You can't drop mesh attachments. Detach to inventory and then rez in world. + </notification> + + <notification + icon="alertmodal.tga" + name="CantDropAttachmentNoPermission" + type="notify"> + <tag>fail</tag> +Failed to drop attachment: you don't have permission to drop there. + </notification> + + <notification + icon="alertmodal.tga" + name="CantDropAttachmentInsufficientLandResources" + type="notify"> + <tag>fail</tag> +Failed to drop attachment: insufficient available land resource. + </notification> + + <notification + icon="alertmodal.tga" + name="CantDropAttachmentInsufficientResources" + type="notify"> + <tag>fail</tag> +Failed to drop attachments: insufficient available resources. + </notification> + + <notification + icon="alertmodal.tga" + name="CantDropObjectFullParcel" + type="notify"> + <tag>fail</tag> +Cannot drop object here. Parcel is full. + </notification> + + <notification + icon="alertmodal.tga" + name="CantTouchObjectBannedFromParcel" + type="notify"> + <tag>fail</tag> +Can't touch/grab this object because you are banned from the land parcel. + </notification> + + <notification + icon="alertmodal.tga" + name="PlzNarrowDeleteParams" + type="notify"> + <tag>fail</tag> +Please narrow your delete parameters. + </notification> + + <notification + icon="alertmodal.tga" + name="UnableToUploadAsset" + type="notify"> + <tag>fail</tag> +Unable to upload asset. + </notification> + + <notification + icon="alertmodal.tga" + name="CantTeleportCouldNotFindUser" + type="notify"> + <tag>fail</tag> +Could not find user to teleport home + </notification> + + <notification + icon="alertmodal.tga" + name="GodlikeRequestFailed" + type="notify"> + <tag>fail</tag> +godlike request failed + </notification> + + <notification + icon="alertmodal.tga" + name="GenericRequestFailed" + type="notify"> + <tag>fail</tag> +generic request failed + </notification> + + <notification + icon="alertmodal.tga" + name="CantUploadPostcard" + type="notify"> + <tag>fail</tag> +Unable to upload postcard. Try again later. + </notification> + + <notification + icon="alertmodal.tga" + name="CantFetchInventoryForGroupNotice" + type="notify"> + <tag>fail</tag> +Unable to fetch inventory details for the group notice. + </notification> + + <notification + icon="alertmodal.tga" + name="CantSendGroupNoticeNotPermitted" + type="notify"> + <tag>fail</tag> +Unable to send group notice -- not permitted. + </notification> + + <notification + icon="alertmodal.tga" + name="CantSendGroupNoticeCantConstructInventory" + type="notify"> + <tag>fail</tag> +Unable to send group notice -- could not construct inventory. + </notification> + + <notification + icon="alertmodal.tga" + name="CantParceInventoryInNotice" + type="notify"> + <tag>fail</tag> +Unable to parse inventory in notice. + </notification> + + <notification + icon="alertmodal.tga" + name="TerrainUploadFailed" + type="notify"> + <tag>fail</tag> +Terrain upload failed. + </notification> + + <notification + icon="alertmodal.tga" + name="TerrainFileWritten" + type="notify"> + <tag>fail</tag> +Terrain file written. + </notification> + + <notification + icon="alertmodal.tga" + name="TerrainFileWrittenStartingDownload" + type="notify"> + <tag>fail</tag> +Terrain file written, starting download... + </notification> + + <notification + icon="alertmodal.tga" + name="TerrainBaked" + type="notify"> + <tag>fail</tag> +Terrain baked. + </notification> + + <notification + icon="alertmodal.tga" + name="TenObjectsDisabledPlzRefresh" + type="notify"> + <tag>fail</tag> +Only the first 10 selected objects have been disabled. Refresh and make additional selections if required. + </notification> + + <notification + icon="alertmodal.tga" + name="UpdateViewerBuyParcel" + type="notify"> + <tag>fail</tag> +You need to update your viewer to buy this parcel. + </notification> + + <notification + icon="alertmodal.tga" + name="LandBuyAccessBlocked" + type="notify"> + <tag>fail</tag> +You can't buy this land due to your maturity Rating. You may need to validate your age and/or install the latest Viewer. Please go to the Knowledge Base for details on accessing areas with this maturity Rating. + </notification> + + <notification + icon="alertmodal.tga" + name="CantBuyParcelNotForSale" + type="notify"> + <tag>fail</tag> +Unable to buy, this parcel is not for sale. + </notification> + + <notification + icon="alertmodal.tga" + name="CantBuySalePriceOrLandAreaChanged" + type="notify"> + <tag>fail</tag> +Unable to buy, the sale price or land area has changed. + </notification> + + <notification + icon="alertmodal.tga" + name="CantBuyParcelNotAuthorized" + type="notify"> + <tag>fail</tag> +You are not the authorized buyer for this parcel. + </notification> + + <notification + icon="alertmodal.tga" + name="CantBuyParcelAwaitingPurchaseAuth" + type="notify"> + <tag>fail</tag> +You cannot purchase this parcel because it is already awaiting purchase aut + </notification> + + <notification + icon="alertmodal.tga" + name="CantBuildOverflowParcel" + type="notify"> + <tag>fail</tag> +You cannot build objects here because doing so would overflow the parcel. + </notification> + + <notification + icon="alertmodal.tga" + name="SelectedMultipleOwnedLand" + type="notify"> + <tag>fail</tag> +You selected land with different owners. Please select a smaller area and try again. + </notification> + + <notification + icon="alertmodal.tga" + name="CantJoinTooFewLeasedParcels" + type="notify"> + <tag>fail</tag> +Not enough leased parcels in selection to join. + </notification> + + <notification + icon="alertmodal.tga" + name="CantDivideLandMultipleParcelsSelected" + type="notify"> + <tag>fail</tag> +Can't divide land.\nThere is more than one parcel selected.\nTry selecting a smaller piece of land. + </notification> + + <notification + icon="alertmodal.tga" + name="CantDivideLandCantFindParcel" + type="notify"> + <tag>fail</tag> +Can't divide land.\nCan't find the parcel.\nPlease report with Help -> Reprt Bug... + </notification> + + <notification + icon="alertmodal.tga" + name="CantDivideLandWholeParcelSelected" + type="notify"> + <tag>fail</tag> +Can't divide land. Whole parcel is selected.\nTry selecting a smaller piece of land. + </notification> + + <notification + icon="alertmodal.tga" + name="LandHasBeenDivided" + type="notify"> + <tag>fail</tag> +Land has been divided. + </notification> + + <notification + icon="alertmodal.tga" + name="PassPurchased" + type="notify"> + <tag>fail</tag> +You purchased a pass. + </notification> + + <notification + icon="alertmodal.tga" + name="RegionDisallowsClassifieds" + type="notify"> + <tag>fail</tag> +Region does not allow classified advertisements. + </notification> + + <notification + icon="alertmodal.tga" + name="LandPassExpireSoon" + type="notify"> + <tag>fail</tag> +Your pass to this land is about to expire. + </notification> + + <notification + icon="alertmodal.tga" + name="CantSitNoSuitableSurface" + type="notify"> + <tag>fail</tag> +There is no suitable surface to sit on, try another spot. + </notification> + + <notification + icon="alertmodal.tga" + name="CantSitNoRoom" + type="notify"> + <tag>fail</tag> +No room to sit here, try another spot. + </notification> + + <notification + icon="alertmodal.tga" + name="ClaimObjectFailedNoPermission" + type="notify"> + <tag>fail</tag> +Claim object failed because you don't have permission + </notification> + + <notification + icon="alertmodal.tga" + name="ClaimObjectFailedNoMoney" + type="notify"> + <tag>fail</tag> +Claim object failed because you don't have enough L$. + </notification> + + <notification + icon="alertmodal.tga" + name="CantDeedGroupLand" + type="notify"> + <tag>fail</tag> +Cannot deed group-owned land. + </notification> + + <notification + icon="alertmodal.tga" + name="BuyObjectFailedNoMoney" + type="notify"> + <tag>fail</tag> +Buy object failed because you don't have enough L$. + </notification> + + <notification + icon="alertmodal.tga" + name="BuyInventoryFailedNoMoney" + type="notify"> + <tag>fail</tag> +Buy inventory failed because you do not have enough L$ + </notification> + + <notification + icon="alertmodal.tga" + name="BuyPassFailedNoMoney" + type="notify"> + <tag>fail</tag> +You don't have enough L$ to buy a pass to this land. + </notification> + + <notification + icon="alertmodal.tga" + name="CantBuyPassTryAgain" + type="notify"> + <tag>fail</tag> +Unable to buy pass right now. Try again later. + </notification> + + <notification + icon="alertmodal.tga" + name="CantCreateObjectParcelFull" + type="notify"> + <tag>fail</tag> +Can't create object because \nthe parcel is full. + </notification> + + <notification + icon="alertmodal.tga" + name="FailedPlacingObject" + type="notify"> + <tag>fail</tag> +Failed to place object at specified location. Please try again. + </notification> + + <notification + icon="alertmodal.tga" + name="CantCreateLandmarkForEvent" + type="notify"> + <tag>fail</tag> +Unable to create landmark for event. + </notification> + + <notification + icon="alertmodal.tga" + name="GodBeatsFreeze" + type="notify"> + <tag>fail</tag> +Your godlike powers break the freeze! + </notification> + + <notification + icon="alertmodal.tga" + name="SpecialPowersRequestFailedLogged" + type="notify"> + <tag>fail</tag> +Request for special powers failed. This request has been logged. + </notification> + + <notification + icon="alertmodal.tga" + name="ExpireExplanation" + type="notify"> + <tag>fail</tag> +The system is currently unable to process your request. The request timed out. + </notification> + + <notification + icon="alertmodal.tga" + name="DieExplanation" + type="notify"> + <tag>fail</tag> +The system is unable to process your request. + </notification> + + <notification + icon="alertmodal.tga" + name="AddPrimitiveFailure" + type="notify"> + <tag>fail</tag> +Insufficient funds to create primitve. + </notification> + + <notification + icon="alertmodal.tga" + name="RezObjectFailure" + type="notify"> + <tag>fail</tag> +Insufficient funds to create object. + </notification> + + <notification + icon="alertmodal.tga" + name="ResetHomePositionNotLegal" + type="notify"> + <tag>fail</tag> +Reset Home position since Home wasn't legal. + </notification> + + <notification + icon="alertmodal.tga" + name="CantInviteRegionFull" + type="notify"> + <tag>fail</tag> +You cannot currently invite anyone to your location because the region is full. Try again later. + </notification> + + <notification + icon="alertmodal.tga" + name="CantSetHomeAtRegion" + type="notify"> + <tag>fail</tag> +This region does not allow you to set your home location here. + </notification> + + <notification + icon="alertmodal.tga" + name="ListValidHomeLocations" + type="notify"> + <tag>fail</tag> +You can only set your 'Home Location' on your land or at a mainland Infohub. + </notification> + + <notification + icon="alertmodal.tga" + name="SetHomePosition" + type="notify"> + <tag>fail</tag> +Home position set. + </notification> + + <notification + icon="alertmodal.tga" + name="CantDerezInventoryError" + type="notify"> + <tag>fail</tag> +Cannot derez object due to inventory fault. + </notification> + + <notification + icon="alertmodal.tga" + name="CantCreateRequestedInv" + type="notify"> + <tag>fail</tag> +Cannot create requested inventory. + </notification> + + <notification + icon="alertmodal.tga" + name="CantCreateRequestedInvFolder" + type="notify"> + <tag>fail</tag> +Cannot create requested inventory folder. + </notification> + + <notification + icon="alertmodal.tga" + name="CantCreateInventory" + type="notify"> + <tag>fail</tag> +Cannot create that inventory. + </notification> + + <notification + icon="alertmodal.tga" + name="CantCreateLandmark" + type="notify"> + <tag>fail</tag> +Cannot create landmark. + </notification> + + <notification + icon="alertmodal.tga" + name="CantCreateOutfit" + type="notify"> + <tag>fail</tag> +Cannot create outfit right now. Try again in a minute. + </notification> + + <notification + icon="alertmodal.tga" + name="InventoryNotForSale" + type="notify"> + <tag>fail</tag> +Inventory is not for sale. + </notification> + + <notification + icon="alertmodal.tga" + name="CantFindInvItem" + type="notify"> + <tag>fail</tag> +Unable to find inventory item. + </notification> + + <notification + icon="alertmodal.tga" + name="CantFindObject" + type="notify"> + <tag>fail</tag> +Unable to find object. + </notification> + + <notification + icon="alertmodal.tga" + name="CantTransfterMoneyRegionDisabled" + type="notify"> + <tag>fail</tag> +Money transfers to objects are currently disabled in this region. + </notification> + + <notification + icon="alertmodal.tga" + name="CantPayNoAgent" + type="notify"> + <tag>fail</tag> +Could not figure out who to pay. + </notification> + + <notification + icon="alertmodal.tga" + name="CantDonateToPublicObjects" + type="notify"> + <tag>fail</tag> +You cannot give L$ to public objects. + </notification> + + <notification + icon="alertmodal.tga" + name="InventoryCreationInWorldObjectFailed" + type="notify"> + <tag>fail</tag> +Inventory creation on in-world object failed. + </notification> + + <notification + icon="alertmodal.tga" + name="UserBalanceOrLandUsageError" + type="notify"> + <tag>fail</tag> +An internal error prevented us from properly updating your viewer. The L$ balance or parcel holdings displayed in your viewer may not reflect your actual balance on the servers. + </notification> + + <notification + icon="alertmodal.tga" + name="LargePrimAgentIntersect" + type="notify"> + <tag>fail</tag> +Cannot create large prims that intersect other players. Please re-try when other players have moved. + </notification> + + <notification + icon="alertmodal.tga" + name="PreferenceChatClearLog" + type="alertmodal"> + This will delete the logs of previous conversations, and any backups of that file. + <tag>confirm</tag> + <usetemplate + ignoretext="Confirm before I delete the log of previous conversations." + name="okcancelignore" + notext="Cancel" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="PreferenceChatDeleteTranscripts" + type="alertmodal"> + This will delete the transcripts for all previous conversations. The list of past conversations will not be affected. All files with the suffixes .txt and txt.backup in the folder [FOLDER] will be deleted. + <tag>confirm</tag> + <usetemplate + ignoretext="Confirm before I delete transcripts." + name="okcancelignore" + notext="Cancel" + yestext="OK"/> + </notification> + + <notification + icon="alert.tga" + name="PreferenceChatPathChanged" + type="alert"> + Unable to move files. Restored previous path. + <usetemplate + ignoretext="Unable to move files. Restored previous path." + name="okignore" + yestext="OK"/> + </notification> + </notifications> diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml deleted file mode 100644 index 9369d1b5cf..0000000000 --- a/indra/newview/skins/default/xui/en/panel_activeim_row.xml +++ /dev/null @@ -1,97 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - name="panel_activeim_row" - layout="topleft" - follows="left|right" - top="0" - left="0" - height="35" - width="318" - background_opaque="false" - background_visible="true" - bg_alpha_color="0.0 0.0 0.0 0.0" > - <chiclet_im_p2p - name="p2p_chiclet" - layout="topleft" - follows="left" - top="3" - left="5" - height="25" - width="25" - visible="false" - speaker.name="speaker_p2p" - speaker.width="20" - speaker.height="25" - speaker.left="25" - speaker.top="25" - speaker.auto_update="true" - speaker.draw_border="false" - speaker.visible="false"> - </chiclet_im_p2p> - <chiclet_im_group - name="group_chiclet" - layout="topleft" - follows="left" - top="3" - left="5" - height="25" - width="25" - visible="false" - speaker.name="speaker_grp" - speaker.width="20" - speaker.height="25" - speaker.left="25" - speaker.top="25" - speaker.auto_update="true" - speaker.draw_border="false" - speaker.visible="false"> - </chiclet_im_group> - <chiclet_im_adhoc - name="adhoc_chiclet" - layout="topleft" - follows="left" - top="3" - left="5" - height="25" - width="25" - visible="false" - speaker.name="speaker_hoc" - speaker.width="20" - speaker.height="25" - speaker.left="25" - speaker.top="25" - speaker.auto_update="true" - speaker.draw_border="false" - speaker.visible="false"> - </chiclet_im_adhoc> - <text - translate="false" - type="string" - name="contact_name" - layout="topleft" - top="10" - left_pad="10" - height="14" - width="250" - length="1" - follows="right|left" - parse_urls="false" - use_ellipses="true" - font="SansSerifBold"> - TestString PleaseIgnore - </text> - <button - top="10" - right="-5" - width="17" - height="17" - layout="topleft" - follows="right" - name="hide_btn" - mouse_opaque="true" - label="" - tab_stop="false" - image_unselected="Toast_CloseBtn" - image_selected="Toast_CloseBtn" - /> -</panel>
\ No newline at end of file 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 deleted file mode 100644 index e70abc0975..0000000000 --- a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml +++ /dev/null @@ -1,99 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - border="false" - follows="all" - height="215" - name="panel_im_control_panel" - width="150"> - <layout_stack - mouse_opaque="false" - border_size="0" - clip="false" - follows="all" - height="215" - layout="topleft" - left="3" - name="vertical_stack" - orientation="vertical" - top="0" - width="147"> - <layout_panel - auto_resize="true" - follows="top|left" - height="130" - layout="topleft" - left="0" - min_height="0" - mouse_opaque="false" - width="147" - top="0" - name="speakers_list_panel" - user_resize="false"> - <avatar_list - color="DkGray2" - follows="all" - height="130" - ignore_online_status="true" - layout="topleft" - name="speakers_list" - opaque="false" - show_info_btn="true" - show_profile_btn="false" - show_speaking_indicator="false" - width="147" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="130" - name="call_btn_panel" - user_resize="false" - visible="false"> - <button - follows="all" - height="20" - label="Call" - name="call_btn" - width="130" - top="5" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="130" - name="end_call_btn_panel" - user_resize="false" - visible="false"> - <button - follows="all" - height="20" - label="Leave Call" - name="end_call_btn" - top="5"/> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="130" - name="voice_ctrls_btn_panel" - user_resize="false" - visible="false"> - <button - follows="all" - height="20" - label="Voice Controls" - name="voice_ctrls_btn" - top="5" - use_ellipses="true" /> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml index b7c58eb6ab..aa1b929412 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml @@ -129,6 +129,7 @@ left_pad="3" right="-53" name="info_btn" + tool_tip="More info" tab_stop="false" top_delta="0" width="16" /> diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml index 1e6a31d388..53d0252215 100644 --- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml @@ -4,88 +4,99 @@ follows="left|top|right|bottom" height="305" layout="topleft" + left="0" name="block_list_panel" help_topic="blocked_list" min_height="350" min_width="240" - width="280"> - <button - follows="top|left" - height="24" - image_hover_unselected="BackButton_Over" - image_pressed="BackButton_Press" - image_unselected="BackButton_Off" - layout="topleft" - name="back" - left="4" - tab_stop="false" - top="1" - width="30"/> - <text - follows="top|left|right" - font="SansSerifLargeBold" - height="20" - layout="topleft" - left_pad="10" - name="title_text" - text_color="white" - top="5" - width="250"> - Block List - </text> - <scroll_list + width="323"> + <panel + follows="left|top|right" + height="27" + label="bottom_panel" + layout="topleft" + left="0" + name="blocked_buttons_panel" + right="-1" + top="0"> + <filter_editor + follows="left|top|right" + height="23" + layout="topleft" + left="6" + label="Filter" + max_length_chars="300" + name="blocked_filter_input" + text_color="Black" + text_pad_left="10" + top="4" + width="177" /> + <menu_button + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="8" + menu_filename="menu_people_blocked_gear.xml" + menu_position="bottomleft" + name="blocked_gear_btn" + tool_tip="Actions on selected person or object" + top="3" + width="31" /> + <menu_button + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_sort" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="2" + menu_filename="menu_people_blocked_view.xml" + menu_position="bottomleft" + name="view_btn" + tool_tip="Sort options" + top_delta="0" + width="31" /> + <menu_button + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="AddItem_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="2" + menu_filename="menu_people_blocked_plus.xml" + menu_position="bottomleft" + name="plus_btn" + tool_tip="Pick a Resident or an object to block" + top_delta="0" + width="31"/> + <button + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="TrashItem_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + left_pad="2" + layout="topleft" + name="unblock_btn" + tool_tip="Remove Resident or object from blocked list" + top_delta="0" + width="31"/> + </panel> + <block_list follows="all" - height="190" + height="273" layout="topleft" - left="5" + left="3" name="blocked" tool_tip="List of currently blocked Residents" - top="30" - width="270"> - <scroll_list.columns - name="item_name" /> - <scroll_list.columns - name="item_type" - width="96" /> - </scroll_list> - <button - follows="left|bottom" - height="23" - label="Block person" - layout="topleft" - left_delta="0" - name="Block resident..." - tool_tip="Pick a Resident to block" - top_pad="4" - width="210"> - <button.commit_callback - function="Block.ClickPick" /> - </button> - <button - follows="left|bottom" - height="23" - label="Block object by name" - layout="topleft" - left_delta="0" - name="Block object by name..." - tool_tip="Pick an object to block by name" - top_pad="4" - width="210" > - <button.commit_callback - function="Block.ClickBlockByName" /> - </button> - <button - enabled="false" - follows="left|bottom" - height="23" - label="Unblock" - layout="topleft" - left_delta="0" - name="Unblock" - tool_tip="Remove Resident or object from blocked list" - top_pad="4" - width="210" > - <button.commit_callback - function="Block.ClickRemove" /> - </button> + top="31" + right="-1"/> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml new file mode 100644 index 0000000000..752321b949 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + follows="top|right|left" + height="23" + layout="topleft" + left="0" + name="blocked_list_item" + top="0" + width="380"> + <icon + height="24" + follows="top|right|left" + image_name="ListItem_Select" + layout="topleft" + left="0" + name="selected_icon" + top="0" + visible="false" + width="380" /> + <icon + follows="top|right|left" + height="24" + image_name="ListItem_Over" + layout="topleft" + left="0" + name="hovered_icon" + top="0" + visible="false" + width="380" /> + <avatar_icon + default_icon_name="Generic_Person" + follows="top|left" + height="20" + layout="topleft" + left="5" + mouse_opaque="true" + top="2" + visible="false" + width="20" /> + <group_icon + default_icon_name="Generic_Group" + follows="top|left" + height="20" + layout="topleft" + left="5" + mouse_opaque="true" + top="2" + visible="false" + width="20" /> + <icon + follows="top|left" + height="16" + image_name="Inv_Object" + layout="topleft" + left="7" + name="object_icon" + top="4" + visible="false" + width="16" /> + <text + follows="left|right" + font="SansSerifSmall" + height="15" + layout="topleft" + left_pad="5" + name="item_name" + parse_urls="false" + top="6" + use_ellipses="true" + width="180" /> +</panel>
\ No newline at end of file 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..27a27473d8 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,15 +39,14 @@ height="28" layout="topleft" width="310" - min_width="188" - user_resize="false"> + min_width="188"> <panel left="0" filename="panel_nearby_chat_bar.xml" follows="left|right" top="4" width="310" - name="chat_bar" + name="nearby_chat" mouse_opaque="false"/> </layout_panel> <layout_panel @@ -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_chat_header.xml b/indra/newview/skins/default/xui/en/panel_chat_header.xml index 2645d472f9..5c5c718bdf 100644 --- a/indra/newview/skins/default/xui/en/panel_chat_header.xml +++ b/indra/newview/skins/default/xui/en/panel_chat_header.xml @@ -23,7 +23,7 @@ <text parse_urls="false" allow_scroll="false" - v_pad = "7" + v_pad = "6" read_only = "true" follows="left|right" font.style="BOLD" @@ -37,7 +37,7 @@ top="0" translate="false" use_ellipses="true" - valign="bottom" + valign="top" value="TestString PleaseIgnore" /> <text allow_scroll="false" @@ -49,7 +49,7 @@ left_pad="5" name="time_box" right="-5" - top="8" + top="7" value="23:30" width="110" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_chat_item.xml b/indra/newview/skins/default/xui/en/panel_chat_item.xml index 6af1105400..1ef99649e6 100644 --- a/indra/newview/skins/default/xui/en/panel_chat_item.xml +++ b/indra/newview/skins/default/xui/en/panel_chat_item.xml @@ -16,13 +16,14 @@ top="3" width="18" /> <text_chat - top="5" + top="3" left="30" + right="-10" height="120" text_color="white" word_wrap="true" mouse_opaque="true" - valign="bottom" + valign="top" name="msg_text"> </text_chat> </panel> 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..fc321fdd23 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 @@ -88,58 +87,8 @@ layout="topleft" min_height="28" min_width="37" - name="im_well_panel" - top="0" - user_resize="false" - width="37"> - <chiclet_im_well - follows="right" - height="28" - layout="topleft" - left="0" - max_displayed_count="99" - name="im_well" - top="0" - width="35"> - <!-- -Emulate 4 states of button by background images, see details in EXT-3147. The same should be for notification_well button -xml attribute Description -image_unselected "Unlit" - there are no new messages -image_selected "Unlit" + "Selected" - there are no new messages and the Well is open -image_pressed "Lit" - there are new messages -image_pressed_selected "Lit" + "Selected" - there are new messages and the Well is open - --> - <button - auto_resize="false" - follows="right" - halign="center" - height="23" - image_overlay="Unread_IM" - image_overlay_alignment="center" - image_pressed="WellButton_Lit" - image_pressed_selected="WellButton_Lit_Selected" - image_selected="PushButton_Press" - label_color="Black" - left="0" - name="Unread IM messages" - tool_tip="Conversations" - width="34"> - <init_callback - function="Button.SetDockableFloaterToggle" - parameter="im_well_window" /> - </button> - </chiclet_im_well> - </layout_panel> - <layout_panel - auto_resize="false" - follows="right" - height="28" - layout="topleft" - min_height="28" - 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_cof_wearables.xml b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml index beea53437a..aa8e3d07a6 100644 --- a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml +++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml @@ -37,6 +37,7 @@ top="0" width="311" /> </accordion_tab> + <!-- The Attachments title is overwritten by the definition of "Attachments remain" in strings.xml --> <accordion_tab layout="topleft" name="tab_attachments" diff --git a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml new file mode 100644 index 0000000000..a054e71e34 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + follows="left|top|right" + height="24" + layout="topleft" + name="conversation_list_item" + mouse_opaque="false" + width="120"> + <avatar_icon + follows="top|left" + height="20" + default_icon_name="Generic_Person" + layout="topleft" + left="5" + top="2" + visible="false" + width="20" /> + <group_icon + follows="top|left" + height="20" + default_icon_name="Generic_Group" + layout="topleft" + left="5" + top="2" + visible="false" + width="20" /> + <icon + follows="top|left" + height="20" + image_name="Nearby_chat_icon" + layout="topleft" + left="5" + name="nearby_chat_icon" + top="2" + visible="false" + width="20"/> + <layout_stack + animate="false" + follows="all" + height="24" + layout="topleft" + left="30" + mouse_opaque="false" + name="conversation_item_stack" + orientation="horizontal" + top="0" + width="90"> + <layout_panel + auto_resize="false" + user_resize="false" + height="24" + mouse_opaque="false" + name="call_icon_panel" + visible="false" + width="20"> + <icon + height="18" + follows="top|right|left" + image_name="Conv_toolbar_open_call" + layout="topleft" + left="0" + name="selected_icon" + top="3" + width="18" /> + </layout_panel> + <layout_panel + auto_resize="true" + user_resize="false" + height="24" + mouse_opaque="false" + name="conversation_title_panel" + width="70"> + <text + follows="left|top|right" + font="SansSerifSmall" + height="15" + layout="topleft" + left="5" + name="conversation_title" + parse_urls="false" + top="6" + use_ellipses="true" + value="(loading)" + width="35" /> + <output_monitor + auto_update="true" + follows="top|right" + draw_border="false" + height="16" + layout="topleft" + left_pad="5" + mouse_opaque="true" + name="speaking_indicator" + visible="false" + width="20" /> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml new file mode 100644 index 0000000000..78d4c174d2 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + follows="top|right|left" + height="23" + layout="topleft" + left="0" + name="conversation_log_list_item" + top="0" + width="380"> + <icon + height="24" + follows="top|right|left" + image_name="ListItem_Select" + layout="topleft" + left="0" + name="selected_icon" + top="0" + visible="false" + width="380" /> + <icon + follows="top|right|left" + height="24" + image_name="ListItem_Over" + layout="topleft" + left="0" + name="hovered_icon" + top="0" + visible="false" + width="380" /> + <icon + follows="top|left" + height="20" + layout="topleft" + left="5" + image_name="Conv_toolbar_open_call" + mouse_opaque="true" + name="voice_session_icon" + tool_tip="Included a voice conversation" + top="2" + visible="false" + width="20" /> + <icon + follows="top|left" + height="20" + layout="topleft" + left="5" + image_name="Conv_log_inbox" + mouse_opaque="false" + name="unread_ims_icon" + tool_tip="Messages arrived while you were logged out" + top="2" + visible="false" + width="20" /> + <avatar_icon + default_icon_name="Generic_Person" + follows="top|left" + height="20" + layout="topleft" + left_pad="5" + mouse_opaque="true" + top="2" + visible="false" + width="20" /> + <group_icon + default_icon_name="Generic_Group" + follows="top|left" + height="20" + layout="topleft" + mouse_opaque="true" + top="2" + visible="false" + width="20" /> + <text + follows="left|right" + font="SansSerifSmall" + height="15" + layout="topleft" + left_pad="5" + name="conversation_name" + parse_urls="false" + top="6" + use_ellipses="true" + width="180" /> + <text + follows="right" + font="SansSerifSmall" + height="15" + layout="topleft" + left_pad="5" + name="date_time" + parse_urls="false" + top="6" + use_ellipses="true" + width="110"/> + <button + name="delete_btn" + tool_tip="Remove this entry" + layout="topleft" + follows="top|right" + image_unselected="Conv_toolbar_close" + image_selected="Conv_toolbar_close" + top="5" + left_pad="0" + height="14" + width="14" + tab_stop="false"/> +</panel>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml index df459b4083..4b05ab27e4 100644 --- a/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml @@ -29,7 +29,7 @@ width="380" /> <icon height="16" - color="0.75 0.75 0.75 1" + color="LtGray" follows="top|left" image_name="Inv_Object" layout="topleft" 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..553c112e6f 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml @@ -134,6 +134,7 @@ top_pad="2" max_length="1023" name="pick_desc" + spellcheck="true" text_color="black" word_wrap="true" /> <text @@ -201,7 +202,6 @@ layout="topleft" left="0" name="layout_panel1" - user_resize="false" auto_resize="true" width="150"> <button @@ -221,7 +221,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_skin.xml b/indra/newview/skins/default/xui/en/panel_edit_skin.xml index 45591ba2ad..b61f65a3d1 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_skin.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_skin.xml @@ -27,10 +27,10 @@ default_image_name="Default" follows="left|top" height="80" - label="Head Tattoos" + label="Head" layout="topleft" left="25" - name="Head Tattoos" + name="Head" tool_tip="Click to choose a picture" top="10" width="74" > @@ -43,10 +43,10 @@ default_image_name="Default" follows="left|top" height="80" - label="Upper Tattoos" + label="Upper body" layout="topleft" left_pad="20" - name="Upper Tattoos" + name="Upper Body" tool_tip="Click to choose a picture" top="10" width="74" > @@ -59,10 +59,10 @@ default_image_name="Default" follows="left|top" height="80" - label="Lower Tattoos" + label="Lower body" layout="topleft" left_pad="20" - name="Lower Tattoos" + name="Lower Body" tool_tip="Click to choose a picture" top="10" width="74" > 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..f34b913218 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -164,7 +164,7 @@ layout="topleft" left_pad="8" name="edit_wearable_title" - text_color="white" + text_color="White" top="3" value="Editing Shape" use_ellipses="true" @@ -190,7 +190,7 @@ layout="topleft" left="10" name="description_text" - text_color="white" + text_color="White" top="10" value="Shape:" width="150" /> @@ -254,7 +254,7 @@ name="description" prevalidate_callback="ascii" select_on_focus="true" - text_color="black" + text_color="Black" top_pad="3" width="290" /> </panel> @@ -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 deleted file mode 100644 index c1dc2aaaf7..0000000000 --- a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml +++ /dev/null @@ -1,114 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - border="false" - follows="all" - height="238" - name="panel_im_control_panel" - width="150"> - <layout_stack - mouse_opaque="false" - border_size="0" - clip="false" - follows="all" - height="238" - layout="topleft" - left="5" - name="vertical_stack" - orientation="vertical" - top="0" - width="145"> - <layout_panel - auto_resize="true" - follows="top|left" - height="100" - layout="topleft" - min_height="0" - mouse_opaque="false" - width="145" - top="0" - name="speakers_list_panel" - user_resize="false"> - <avatar_list - color="DkGray2" - follows="all" - height="100" - ignore_online_status="true" - layout="topleft" - name="speakers_list" - opaque="false" - show_info_btn="true" - show_profile_btn="false" - show_speaking_indicator="false" - width="145" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="28" - layout="topleft" - min_height="28" - width="130" - name="group_info_btn_panel" - user_resize="false"> - <button - follows="left|right|bottom" - height="23" - label="Group Profile" - name="group_info_btn" - use_ellipses="true" - top="5" - width="130" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="28" - layout="topleft" - min_height="28" - width="130" - name="call_btn_panel" - user_resize="false"> - <button - follows="all" - height="23" - label="Call Group" - name="call_btn" - use_ellipses="true" - width="130" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="28" - layout="topleft" - min_height="28" - width="130" - name="end_call_btn_panel" - user_resize="false" - visible="false"> - <button - follows="all" - height="23" - label="Leave Call" - name="end_call_btn" - use_ellipses="true" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="28" - layout="topleft" - min_height="28" - width="130" - name="voice_ctrls_btn_panel" - user_resize="false" - visible="false"> - <button - follows="all" - height="23" - label="Open Voice Controls" - name="voice_ctrls_btn" - use_ellipses="true" /> - </layout_panel> - </layout_stack> -</panel> 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_group_invite.xml b/indra/newview/skins/default/xui/en/panel_group_invite.xml index cd834b61ce..124c0596c3 100644 --- a/indra/newview/skins/default/xui/en/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/en/panel_group_invite.xml @@ -19,6 +19,10 @@ name="already_in_group"> Some Residents you chose are already in the group, and so were not sent an invitation. </panel.string> + <panel.string + name="invite_selection_too_large"> + Group Invitations not sent: too many Residents selected. Group Invitations are limited to 100 per request. + </panel.string> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_group_list_item.xml index 12735026fa..cfe3aeb7c9 100644 --- a/indra/newview/skins/default/xui/en/panel_group_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_group_list_item.xml @@ -56,6 +56,7 @@ left_pad="3" right="-31" name="info_btn" + tool_tip="More info" tab_stop="false" top_delta="-2" width="16" /> diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml index 607e1bb213..c8ce5cdebf 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml @@ -141,6 +141,7 @@ Maximum 200 per group daily max_length_bytes="63" name="create_subject" prevalidate_callback="ascii" + spellcheck="true" width="218" /> <text follows="left|top" @@ -161,6 +162,7 @@ Maximum 200 per group daily left_pad="3" max_length="511" name="create_message" + spellcheck="true" top_delta="0" width="218" word_wrap="true" /> @@ -200,14 +202,14 @@ Maximum 200 per group daily Drag and drop item here to attach it: </text> <icon - height="72" + height="48" image_name="DropTarget" layout="topleft" left_pad="10" mouse_opaque="true" name="drop_icon" top_delta="-10" - width="72" /> + width="110" /> <button follows="left|top" layout="topleft" @@ -309,6 +311,7 @@ Maximum 200 per group daily left_pad="3" max_length_bytes="63" name="view_subject" + spellcheck="true" top_delta="-1" visible="false" width="200" /> @@ -333,6 +336,7 @@ Maximum 200 per group daily right="-1" max_length="511" name="view_message" + spellcheck="true" top_delta="-40" width="313" word_wrap="true" /> diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index a7178dc288..df91ad8b5e 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -172,7 +172,7 @@ including the Everyone and Owner Roles. draw_heading="true" draw_stripes="false" heading_height="23" - height="130" + height="132" layout="topleft" search_column="1" left="0" @@ -254,7 +254,7 @@ things in this group. There's a broad variety of Abilities. column_padding="0" draw_stripes="true" height="200" - follows="left|top" + follows="left|top|right" layout="topleft" left="0" right="-1" 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 deleted file mode 100644 index 9f73b7c540..0000000000 --- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml +++ /dev/null @@ -1,175 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - border="false" - height="300" - name="panel_im_control_panel" - width="150"> - <avatar_icon - follows="left|top" - height="105" - left_delta="20" - name="avatar_icon" - top="-5" - width="114"/> - <layout_stack - mouse_opaque="false" - border_size="0" - clip="false" - follows="all" - height="183" - layout="topleft" - left="5" - name="button_stack" - orientation="vertical" - top_pad="5" - width="145"> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="20" - layout="topleft" - left="2" - min_height="20" - width="140" - name="view_profile_btn_panel" - top="0" - user_resize="false"> - <button - follows="left|top|right" - height="23" - label="Profile" - name="view_profile_btn" - top="0" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="add_friend_btn_panel" - user_resize="false"> - <button - follows="left|top|right" - height="23" - label="Add Friend" - name="add_friend_btn" - top="5" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="teleport_btn_panel" - user_resize="false"> - <button - auto_resize="false" - follows="left|top|right" - height="23" - label="Teleport" - name="teleport_btn" - tool_tip = "Offer to teleport this person" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="share_btn_panel" - user_resize="false"> - <button - auto_resize="true" - follows="left|top|right" - height="23" - label="Share" - name="share_btn" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="pay_btn_panel" - user_resize="false"> - <button - auto_resize="true" - follows="left|top|right" - height="23" - label="Pay" - name="pay_btn" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="call_btn_panel" - user_resize="false"> - <button - follows="left|top|right" - height="23" - label="Call" - name="call_btn" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="end_call_btn_panel" - user_resize="false" - visible="false"> - <button - follows="left|top|right" - height="23" - label="End Call" - name="end_call_btn" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="voice_ctrls_btn_panel" - user_resize="false" - visible="false"> - <button - follows="left|top|right" - height="23" - label="Voice Controls" - name="voice_ctrls_btn" - width="140" /> - </layout_panel> - <layout_panel - mouse_opaque="false" - auto_resize="true" - follows="top|left" - height="0" - layout="topleft" - min_height="0" - width="140" - name="spacer" - user_resize="false" /> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml index 383e637ace..433a3181cd 100644 --- a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <inbox_inventory_panel + accepts_drag_and_drop="false" name="inventory_inbox" - start_folder="Received Items" + start_folder.type="inbox" follows="all" layout="topleft" top="0" left="0" height="165" width="308" top_pad="0" diff --git a/indra/newview/skins/default/xui/en/panel_instant_message.xml b/indra/newview/skins/default/xui/en/panel_instant_message.xml index 4251128714..2e5d650902 100644 --- a/indra/newview/skins/default/xui/en/panel_instant_message.xml +++ b/indra/newview/skins/default/xui/en/panel_instant_message.xml @@ -15,7 +15,7 @@ <panel background_visible="true" bevel_style="in" - bg_alpha_color="black" + bg_alpha_color="Black" follows="top" height="24" label="im_header" @@ -64,7 +64,7 @@ left_pad="5" name="user_name" parse_urls="false" - text_color="white" + text_color="White" top="8" translate="false" use_ellipses="true" @@ -90,7 +90,7 @@ layout="topleft" left="10" name="message" - text_color="white" + text_color="White" top="33" use_ellipses="true" value="" diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml index d2088594dd..fd6e96b9a7 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -271,7 +271,7 @@ <text_editor bg_readonly_color="DkGray2" follows="all" - height="70" + height="75" layout="topleft" left="0" max_length="127" @@ -288,7 +288,7 @@ layout="topleft" left="0" name="folder_label" - top_pad="15" + top_pad="10" value="Landmark location:" width="290" /> <combo_box diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml index 23d8cb11ca..67a09949ce 100644 --- a/indra/newview/skins/default/xui/en/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml @@ -35,7 +35,9 @@ left="0" mouse_opaque="true" name="favorites_list" - start_folder="Favorites" + scroll.hide_scrollbar="true" + folder_view.use_ellipses="true" + start_folder.name="Favorites" width="307"/> </accordion_tab> <accordion_tab @@ -51,7 +53,9 @@ left="0" mouse_opaque="true" name="landmarks_list" - start_folder="Landmarks" + scroll.hide_scrollbar="true" + folder_view.use_ellipses="true" + start_folder.name="Landmarks" width="307"/> </accordion_tab> <accordion_tab @@ -67,7 +71,9 @@ left="0" mouse_opaque="true" name="my_inventory_list" - start_folder="My Inventory" + scroll.hide_scrollbar="true" + folder_view.use_ellipses="true" + start_folder.name="My Inventory" width="307"/> </accordion_tab> <accordion_tab @@ -83,7 +89,9 @@ left="0" mouse_opaque="true" name="library_list" - start_folder="LIBRARY" + scroll.hide_scrollbar="true" + folder_view.use_ellipses="true" + start_folder.name="LIBRARY" width="313"/> </accordion_tab> </accordion> @@ -114,7 +122,6 @@ height="25" layout="topleft" name="options_gear_btn_panel" - user_resize="false" width="32"> <menu_button follows="bottom|left" @@ -135,7 +142,6 @@ height="25" layout="topleft" name="add_btn_panel" - user_resize="false" width="32"> <button follows="bottom|left" @@ -156,7 +162,6 @@ height="25" layout="topleft" name="dummy_panel" - user_resize="false" width="212"> <icon follows="bottom|left|right" @@ -173,7 +178,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..134ca75018 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -1,218 +1,265 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel -follows="all" -height="600" -layout="topleft" -left="0" -name="panel_login" -focus_root="true" -top="600" - width="996"> -<panel.string - name="create_account_url"> - http://join.secondlife.com/ -</panel.string> -<string name="reg_in_client_url" translate="false"> - http://secondlife.eniac15.lindenlab.com/reg-in-client/ -</string> -<panel.string - name="forgot_password_url"> - http://secondlife.com/account/request.php -</panel.string> -<!-- *NOTE: Custom resize logic for login_html in llpanellogin.cpp --> -<web_browser - tab_stop="false" - trusted_content="true" - bg_opaque_color="Black" - border_visible="false" - bottom="600" - follows="all" - left="0" - name="login_html" - start_url="" - top="0" - height="600" - width="980"/> -<layout_stack -follows="left|bottom|right" -name="login_widgets" -layout="topleft" -orientation="horizontal" -top="519" -width="996" -height="80"> -<layout_panel -auto_resize="false" -follows="left|bottom" -name="login" -layout="topleft" -width="705" -min_width="705" -user_resize="false" -height="80"> -<text -follows="left|bottom" -font="SansSerifSmall" -height="16" -name="username_text" -top="20" -left="20" -width="150"> -Username: -</text> -<combo_box -allow_text_entry="true" -follows="left|bottom" -height="22" -left_delta="0" -max_chars="128" -combo_editor.prevalidate_callback="ascii" -tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine" -top_pad="0" -name="username_combo" -width="178"> - <combo_box.combo_button - visible ="false"/> - <combo_box.drop_down_button - visible ="false"/> -</combo_box> -<text -follows="left|bottom" -font="SansSerifSmall" -height="15" -left_pad="-19" -name="password_text" -top="20" - width="150"> - Password: -</text> -<line_editor -follows="left|bottom" - height="22" - max_length_bytes="16" -name="password_edit" -is_password="true" -select_on_focus="true" - top_pad="0" - width="135" /> - <check_box -control_name="RememberPassword" -follows="left|bottom" -font="SansSerifSmall" -height="16" -label="Remember password" - top_pad="3" - name="remember_check" - width="135" /> -<button - follows="left|bottom" - height="23" - image_unselected="PushButton_On" - image_selected="PushButton_On_Selected" - label="Log In" - label_color="White" - layout="topleft" - left_pad="10" - name="connect_btn" - top="35" - width="90" /> - <text - follows="left|bottom" - font="SansSerifSmall" - height="15" - left_pad="8" - name="start_location_text" - top="20" - width="130"> - Start at: - </text> -<combo_box -allow_text_entry="true" -control_name="NextLoginLocation" - follows="left|bottom" - height="23" -max_chars="128" -top_pad="0" -name="start_location_combo" - width="165"> -<combo_box.item -label="My last location" -name="MyLastLocation" - value="last" /> -<combo_box.item -label="My home" -name="MyHome" - value="home" /> -<combo_box.item -label="<Type region name>" -name="Typeregionname" value="" /> -</combo_box> -<combo_box -allow_text_entry="true" -font="SansSerifSmall" - follows="left|right|bottom" - height="23" - max_chars="256" -layout="topleft" -top_pad="2" -name="server_combo" -width="135" - visible="false" /> -</layout_panel> -<layout_panel -tab_stop="false" -follows="right|bottom" -name="links" -width="205" -min_width="205" -user_resize="false" -height="80"> - <text -follows="right|bottom" -font="SansSerifSmall" -text_color="EmphasisColor" -halign="right" -height="16" -top="12" -right="-10" -name="create_new_account_text" - width="200"> - Sign up - </text> -<text -follows="right|bottom" -font="SansSerifSmall" -text_color="EmphasisColor" -halign="right" -height="16" -name="forgot_password_text" -top_pad="12" -right="-10" - width="200"> - Forgot your username or password? -</text> -<text -follows="right|bottom" -font="SansSerifSmall" -text_color="EmphasisColor" -halign="right" -height="16" -name="login_help" -top_pad="2" -right="-10" - width="200"> - Need help logging in? </text> -<!-- <text - follows="right|bottom" - font="SansSerifSmall" - halign="right" - height="28" - top_pad="2" - name="channel_text" - width="180" - word_wrap="true"> - [VERSION] - </text>--> - </layout_panel> -</layout_stack> + follows="all" + height="600" + layout="topleft" + left="0" + name="panel_login" + focus_root="true" + top="600" + width="1130"> + <string name="reg_in_client_url" translate="false"> + http://secondlife.eniac15.lindenlab.com/reg-in-client/ + </string> + <panel.string + name="forgot_password_url"> + http://secondlife.com/account/request.php + </panel.string> + <!-- *NOTE: Custom resize logic for login_html in llpanellogin.cpp --> + <web_browser + tab_stop="false" + trusted_content="true" + bg_opaque_color="Black" + border_visible="false" + bottom="600" + follows="all" + left="0" + name="login_html" + start_url="" + top="0" + height="600" + width="996"/> + <layout_stack + animate="false" + clip="false" + follows="left|bottom|right" + name="login_widgets" + layout="topleft" + orientation="horizontal" + top="519" + width="1130" + height="80"> + <layout_panel + auto_resize="false" + follows="left|bottom" + name="login" + layout="topleft" + width="310" + min_width="310" + height="80"> + <text + follows="left|bottom" + font="SansSerif" + font.style="BOLD" + font.size="Large" + height="16" + name="log_in_text" + top="8" + left="15" + width="150"> + LOG IN + </text> + <text + follows="left|bottom" + font="SansSerifSmall" + height="16" + name="username_text" + top="35" + left="15" + width="150"> + Username: + </text> + <!-- STEAM-14: Turn off commit_on_focus_lost so if user presses Enter + with focus in this combo_box, we can use commit action to initiate + login --> + <combo_box + allow_text_entry="true" + follows="left|bottom" + height="22" + left_delta="0" + max_chars="128" + commit_on_focus_lost="false" + combo_editor.prevalidate_callback="ascii" + tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine" + top_pad="0" + name="username_combo" + width="178"> +<!-- empirically, displayed width is 150 anyway?!? --> + <combo_box.combo_button + visible ="false"/> + <combo_box.drop_down_button + visible ="false"/> + </combo_box> +<!-- left="175" based on actual "username_combo" width of 150 vs. 178 --> + <text + follows="left|bottom" + font="SansSerifSmall" + height="16" + name="password_text" + top="35" + left="175" + width="150"> + Password: + </text> + <!-- STEAM-14: Turn off commit_on_focus_lost so if user presses Enter + with focus in this line_editor, we can use commit action to + initiate login --> + <line_editor + follows="left|bottom" + height="22" + max_length_bytes="16" + name="password_edit" + is_password="true" + select_on_focus="true" + commit_on_focus_lost="false" + top_pad="0" + width="135" /> + </layout_panel> + <layout_panel + auto_resize="false" + follows="left|bottom" + name="start_location_panel" + layout="topleft" + width="175" + min_width="175" + height="80"> + <text + follows="left|bottom" + font="SansSerifSmall" + height="16" + left="10" + name="start_location_text" + top="35" + width="130"> + Start at: + </text> + <combo_box + allow_text_entry="true" + control_name="NextLoginLocation" + follows="left|bottom" + height="22" + max_chars="128" + top_pad="0" + name="start_location_combo" + width="165"> + <combo_box.item + label="My last location" + name="MyLastLocation" + value="last" /> + <combo_box.item + label="My home" + name="MyHome" + value="home" /> + <combo_box.item + label="<Type region name>" + name="Typeregionname" value="" /> + </combo_box> + </layout_panel> + <layout_panel + auto_resize="false" + follows="left|bottom" + name="grid_panel" + layout="topleft" + width="145" + height="80" + visible="false"> + <combo_box + allow_text_entry="false" + font="SansSerifSmall" + follows="left|right|bottom" + height="23" + max_chars="256" + left="10" + top="51" + layout="topleft" + top_pad="2" + name="server_combo" + width="135" /> + </layout_panel> + <layout_panel + auto_resize="false" + follows="left|bottom" + name="links_login_panel" + layout="topleft" + width="290" + height="80"> + <text + follows="left|bottom" + font="SansSerifSmall" + text_color="EmphasisColor" + left="10" + height="16" + name="login_help" + top="19" + width="280"> + Need help logging in? + </text> + <text + follows="left|bottom" + font="SansSerifSmall" + text_color="EmphasisColor" + height="16" + name="forgot_password_text" + top="35" + width="280"> + Forgot your username or password? + </text> + <button + follows="left|bottom" + top_pad="0" + height="23" + image_unselected="PushButton_On" + image_selected="PushButton_On_Selected" + label="Log In" + label_color="White" + layout="topleft" + name="connect_btn" + width="90" /> + <check_box + control_name="RememberPassword" + follows="left|bottom" + font="SansSerifSmall" + left="110" + top="56" + height="16" + label="Remember password" + top_pad="3" + name="remember_check" + width="145" /> + </layout_panel> + <layout_panel + tab_stop="false" + follows="right|bottom" + name="links" + width="210" + min_width="100" + height="80"> + <text + follows="right|bottom" + font="SansSerif" + font.style="BOLD" + font.size="Large" + halign="right" + height="16" + name="create_account_text" + top="8" + right="-15" + width="200"> + CREATE YOUR ACCOUNT + </text> + <button + follows="right|bottom" + top="35" + right="-15" + height="23" + image_unselected="PushButton_On" + image_selected="PushButton_On_Selected" + label="Start now" + label_color="White" + layout="topleft" + left_pad="10" + name="create_new_account_btn" + width="90" /> + </layout_panel> + </layout_stack> </panel> 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..1c882bb099 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" @@ -86,11 +80,9 @@ top="16" width="288" /> <recent_inventory_panel - accepts_drag_and_drop="false" bg_opaque_color="DkGray2" bg_alpha_color="DkGray2" background_visible="true" - background_opaque="true" border="false" bevel_style="none" follows="all" @@ -119,7 +111,6 @@ height="25" layout="topleft" name="options_gear_btn_panel" - user_resize="false" width="32"> <menu_button follows="bottom|left" @@ -140,7 +131,6 @@ height="25" layout="topleft" name="add_btn_panel" - user_resize="false" width="32"> <button follows="bottom|left" @@ -161,7 +151,6 @@ height="25" layout="topleft" name="dummy_panel" - user_resize="false" width="212"> <icon follows="bottom|left|right" @@ -178,7 +167,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_media_settings_general.xml b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml index cdf14572fe..e844a15118 100644 --- a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml +++ b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml @@ -30,7 +30,7 @@ (This page does not pass the specified whitelist) </text> <line_editor - max_length="1024" + max_length_bytes="1024" bottom_delta="-24" enabled="true" follows="left|top" diff --git a/indra/newview/skins/default/xui/en/panel_my_profile.xml b/indra/newview/skins/default/xui/en/panel_my_profile.xml deleted file mode 100644 index 4bd2235cda..0000000000 --- a/indra/newview/skins/default/xui/en/panel_my_profile.xml +++ /dev/null @@ -1,146 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - follows="all" - height="535" - label="Profile" - layout="topleft" - left="0" - name="panel_profile" - top="0" - width="315"> - <string - name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string - name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=en - </string> - <string - name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=en - </string> - <string - name="my_account_link_url" - value="http://secondlife.com/account" /> - <string - name="no_partner_text" - value="None" /> - <string - name="no_group_text" - value="None" /> - <string - name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string - name="name_text_args"> - [NAME] - </string> - <string - name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack - name="layout" - orientation="vertical" - follows="all" - layout="topleft" - left="0" - top="0" - height="510" - width="315" - border_size="0"> - <layout_panel - name="profile_stack" - follows="all" - layout="topleft" - top="0" - left="0" - height="492" - user_resize="false" - width="315"> - <scroll_container - color="DkGray2" - follows="all" - layout="topleft" - left="0" - name="profile_scroll" - opaque="true" - height="488" - width="315" - top="0"> - <panel - layout="topleft" - follows="left|top|right" - height="488" - name="scroll_content_panel" - top="0" - left="0" - width="297"> - <panel - follows="left|top|right" - height="117" - layout="topleft" - left="10" - name="second_life_image_panel" - top="0" - width="297"> - - <texture_picker - allow_no_texture="true" - default_image_name="None" - enabled="false" - fallback_image="Generic_Person_Large" - follows="top|left" - height="124" - layout="topleft" - left="3" - name="2nd_life_pic" - top="10" - width="102" /> - - <text - follows="left|top|right" - font="SansSerifLarge" - font.style="BOLD" - height="15" - layout="topleft" - left_pad="10" - name="display_name_descr_text" - text_color="0.7 0.7 0.7 1.0" - top_delta="0" - width="280" > - User name - </text> - - <text - follows="left|top|right" - font.style="BOLD" - height="15" - layout="topleft" - left_delta="0" - name="name_descr_text" - text_color="0.4 0.4 0.4 1.0" - top_delta="20" - width="280"> - Display Name - </text> - - <button - follows="bottom" - height="23" - left_delta="0" - top_delta="20" - label="Profile" - name="see_profile_btn" - tool_tip="See profile for this avatar" - width="120" /> - - </panel> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml index 7a8e872dc9..3edeb9aa36 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" @@ -70,133 +70,134 @@ layout="topleft" auto_resize="true" user_resize="true" - min_width="480" + min_width="410" 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" + min_width="185" 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 ▼ - </more_button> - </favorites_bar> + width="320"> + <icon + follows="top|left" + height="25" + image_name="ChatBarHandle" + layout="topleft" + left="-323" + 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="320"> + <label + follows="left|top" + height="13" + 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="13" + valign="bottom" + 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 ▼ + </more_button> + </favorites_bar> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml index d492f9bd68..4de56b424e 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml @@ -1,35 +1,65 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - height="300" follows="all" + top="0" + bottom_delta="10" + help_topic="nearby_chat" layout="topleft" name="nearby_chat" - help_topic="nearby_chat" - width="320"> - <check_box - bottom_delta="36" - control_name="TranslateChat" - enabled="true" - height="16" - label="Translate chat" - layout="topleft" - left="5" - name="translate_chat_checkbox" - width="230" /> - <chat_history - parse_urls="true" - bg_readonly_color="ChatHistoryBgColor" - bg_writeable_color="ChatHistoryBgColor" - follows="all" - left="5" - top_delta="17" - layout="topleft" - height="260" - name="chat_history" - parse_highlights="true" - text_color="ChatHistoryTextColor" - text_readonly_color="ChatHistoryTextColor" - right_widget_pad="5" - left_widget_pad="0" - width="315" /> + width="242" + height="169"> + <layout_stack + follows="all" + height="164" + layout="topleft" + left="0" + name="stack" + top="5" + orientation="vertical" + width="242"> + <layout_panel + auto_resize="false" + height="26" + layout="topleft" + left_delta="0" + name="translate_chat_checkbox_lp" + top_delta="0" + visible="true" + width="230"> + <check_box + top="10" + control_name="TranslateChat" + enabled="true" + height="16" + label="Translate chat" + layout="topleft" + left="5" + name="translate_chat_checkbox" + width="230" /> + </layout_panel> + <layout_panel + auto_resize="true" + height="138" + left_delta="0" + layout="topleft" + name="chat_history_lp" + width="242"> + <chat_history + bg_readonly_color="ChatHistoryBgColor" + bg_writeable_color="ChatHistoryBgColor" + follows="all" + layout="topleft" + left="5" + left_widget_pad="0" + height="138" + name="chat_history" + parse_highlights="true" + parse_urls="true" + right_widget_pad="5" + text_color="ChatHistoryTextColor" + text_readonly_color="ChatHistoryTextColor" + top="0" + width="237" /> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml index 21c627cdfb..19143cef89 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml @@ -5,7 +5,7 @@ height="25" layout="topleft" left="0" - name="chat_bar" + name="nearby_chat" top="21" width="308"> <line_editor @@ -19,6 +19,7 @@ left="0" max_length_bytes="1023" name="chat_box" + spellcheck="true" text_pad_left="5" text_pad_right="25" tool_tip="Press Enter to say, Ctrl+Enter to shout" 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_notes.xml b/indra/newview/skins/default/xui/en/panel_notes.xml deleted file mode 100644 index 124b1cfc6b..0000000000 --- a/indra/newview/skins/default/xui/en/panel_notes.xml +++ /dev/null @@ -1,236 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - follows="all" - height="515" - label="Notes & Privacy" - layout="topleft" - left="0" - name="panel_notes" - top="0" - width="313" -> - <layout_stack - name="layout" - orientation="vertical" - follows="all" - layout="topleft" - left="0" - top="0" - height="517" - width="313" - border_size="0"> - <layout_panel - name="notes_stack" - follows="all" - layout="topleft" - top="0" - left="0" - height="450" - width="313"> - <scroll_container - color="DkGray2" - follows="all" - layout="topleft" - left="0" - name="profile_scroll" - opaque="true" - height="450" - width="313" - top="0"> - <panel - height="450" - layout="topleft" - name="profile_scroll_panel" - top="0" - left="0" - width="303"> - <text - follows="left|top" - font.style="BOLD" - height="16" - layout="topleft" - left="11" - name="status_message" - text_color="white" - top="10" - value="My private notes:" - width="293" /> - <text_editor - follows="left|top" - height="120" - layout="topleft" - left="12" - max_length="1000" - name="notes_edit" - text_color="DkGray" - top_pad="3" - width="288" - word_wrap="true" /> - <text - follows="left|top" - font.style="BOLD" - height="16" - layout="topleft" - left="11" - name="status_message2" - text_color="white" - top_pad="20" - value="Allow this person to:" - width="293" /> - <check_box - enabled="false" - height="16" - label="See my online status" - layout="topleft" - left="10" - name="status_check" - width="293" /> - <check_box - enabled="false" - height="16" - label="See me on the map" - layout="topleft" - left="10" - name="map_check" - width="293" /> - <check_box - enabled="false" - height="16" - label="Edit, delete or take my objects" - layout="topleft" - left="10" - name="objects_check" - width="293" /> - </panel> - </scroll_container> - </layout_panel> - <layout_panel - follows="bottom|left" - height="30" - layout="topleft" - left="0" - name="notes_buttons_panel" - auto_resize="false" - width="313"> - - <layout_stack - follows="bottom|left|right" - height="23" - layout="topleft" - name="bottom_bar_ls" - left="2" - orientation="horizontal" - top_pad="5" - width="309"> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left="0" - name="add_friend_btn_lp" - user_resize="false" - auto_resize="true" - width="118"> - <button - follows="bottom|left|right" - height="23" - label="Add Friend" - layout="topleft" - left="1" - mouse_opaque="false" - name="add_friend" - tool_tip="Offer friendship to the Resident" - top="0" - width="117" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="im_btn_lp" - user_resize="false" - auto_resize="true" - width="22"> - <button - follows="bottom|left|right" - height="23" - label="IM" - layout="topleft" - name="im" - tool_tip="Open instant message session" - top="0" - left="1" - width="21" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="call_btn_lp" - user_resize="false" - auto_resize="true" - width="52"> - <button - follows="bottom|left|right" - height="23" - label="Call" - layout="topleft" - name="call" - tool_tip="Call this Resident" - left="1" - top="0" - use_ellipses="true" - width="51" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="show_on_map_btn_lp" - user_resize="false" - auto_resize="true" - width="46"> - <button - enabled="false" - follows="bottom|left|right" - height="23" - label="Map" - layout="topleft" - name="show_on_map_btn" - tool_tip="Show the Resident on the map" - top="0" - left="1" - width="45" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="teleport_btn_lp" - user_resize="false" - auto_resize="true" - width="81"> - <button - follows="bottom|left|right" - height="23" - label="Teleport" - layout="topleft" - name="teleport" - tool_tip="Offer teleport" - left="1" - top="0" - width="80" /> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_notification.xml b/indra/newview/skins/default/xui/en/panel_notification.xml index f6f62ac54e..94c468e1bb 100644 --- a/indra/newview/skins/default/xui/en/panel_notification.xml +++ b/indra/newview/skins/default/xui/en/panel_notification.xml @@ -3,8 +3,8 @@ background_opaque="false" border_visible="false" background_visible="true" - bg_alpha_color="1 0.3 0.3 0" - bg_opaque_color="1 0.3 0.3 0" + bg_alpha_color="PanelNotificationBackground" + bg_opaque_color="PanelNotificationBackground" label="notification_panel" layout="topleft" left="0" @@ -20,8 +20,8 @@ border_visible="false" bevel_style="none" background_visible="true" - bg_alpha_color="0.3 0.3 0.3 0" - bg_opaque_color="0.3 0.3 0.3 0" + bg_alpha_color="ToastBackground" + bg_opaque_color="ToastBackground" follows="left|right|top" height="100" label="info_panel" @@ -39,7 +39,7 @@ left="10" name="text_box" read_only="true" - text_color="white" + text_color="White" top="10" visible="false" width="285" @@ -52,7 +52,7 @@ layout="topleft" left="10" name="caution_text_box" - text_color="1 0.82 0.46 1" + text_color="NotifyCautionBoxColor" top="10" visible="false" width="285" @@ -60,7 +60,7 @@ <text_editor h_pad="0" v_pad="0" - bg_readonly_color="0.0 0.0 0.0 0" + bg_readonly_color="Transparent" border_visible="false" embedded_items="false" enabled="false" @@ -73,8 +73,8 @@ name="text_editor_box" read_only="true" tab_stop="false" - text_color="white" - text_readonly_color="white" + text_color="White" + text_readonly_color="White" top="10" visible="false" width="285" diff --git a/indra/newview/skins/default/xui/en/panel_online_status_toast.xml b/indra/newview/skins/default/xui/en/panel_online_status_toast.xml index b1a7697e83..dadbd9c9ab 100644 --- a/indra/newview/skins/default/xui/en/panel_online_status_toast.xml +++ b/indra/newview/skins/default/xui/en/panel_online_status_toast.xml @@ -25,7 +25,7 @@ layout="topleft" left_pad="5" name="message" - text_color="white" + text_color="White" top="15" use_ellipses="true" value="" 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..c80e5b168a 100644 --- a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml @@ -1,18 +1,32 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<outbox_inventory_panel +<inventory_panel name="inventory_outbox" - start_folder="Outbox" + start_folder.name="Outbox" + show_empty_message="false" + show_load_status="false" + start_folder.type="outbox" follows="all" layout="topleft" top="0" left="0" height="165" width="308" top_pad="0" bg_opaque_color="DkGray2" bg_alpha_color="DkGray2" background_visible="true" - background_opaque="true" border="false" bevel_style="none" show_item_link_overlays="true" tool_tip="Drag and drop items here to prepare them for sale on your storefront" - > - <scroll reserve_scroll_corner="false" /> -</outbox_inventory_panel> + scroll.reserve_scroll_corner="false"> + <folder folder_arrow_image="Folder_Arrow" + folder_indentation="8" + item_height="20" + item_top_pad="4" + selection_image="Rounded_Square" + left_pad="5" + icon_pad="2" + icon_width="16" + text_pad="1" + text_pad_right="4" + arrow_size="12" + max_folder_item_overlap="2"/> + <item allow_open="false"/> +</inventory_panel> 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..ed274d0233 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -38,12 +38,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M name="no_filtered_friends_msg"> Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]. </string> - <string - name="people_filter_label" - value="Filter People" /> - <string - name="groups_filter_label" - value="Filter Groups" /> <!-- *WORKAROUND: for group_list.no_items_msg & group_list.no_filtered_items_msg attributes. They are not defined as translatable in VLT. See EXT-5931 @@ -60,21 +54,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M <string name="AltMiniMapToolTipMsg" value="[REGION](Double-click to teleport, shift-drag to pan)"/> - <filter_editor - follows="left|top|right" - height="23" - layout="topleft" - left="10" - label="Filter" - max_length_chars="300" - name="filter_input" - text_color="Black" - text_pad_left="10" - top="3" - width="303" /> <tab_container + bottom="-10" follows="all" - height="383" layout="topleft" left="3" name="tabs" @@ -82,31 +64,120 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M tab_min_width="70" tab_height="30" tab_position="top" - top_pad="10" + top="0" halign="center" - width="319"> - <panel + right="-5"> + +<!-- ================================= NEARBY tab =========================== --> + + <panel background_opaque="true" background_visible="true" bg_alpha_color="DkGray" bg_opaque_color="DkGray" + bottom="-1" follows="all" - height="383" label="NEARBY" layout="topleft" left="0" help_topic="people_nearby_tab" name="nearby_panel" - top="0" - width="313"> + right="-1" + top="0"> + <panel + follows="left|top|right" + height="27" + label="bottom_panel" + layout="topleft" + left="0" + name="nearby_buttons_panel" + right="-1" + top="0"> + <filter_editor + follows="left|top|right" + height="23" + layout="topleft" + left="6" + label="Filter People" + max_length_chars="300" + name="nearby_filter_input" + text_color="Black" + text_pad_left="10" + top="4" + width="178" /> + <button + commit_callback.function="People.Gear" + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="7" + name="gear_btn" + tool_tip="Actions on selected person" + top="3" + width="31" /> + <menu_button + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_sort" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="2" + menu_filename="menu_people_nearby_view.xml" + menu_position="bottomleft" + name="nearby_view_btn" + tool_tip="View/sort options" + top_delta="0" + width="31" /> + <button + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="AddItem_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="2" + name="add_friend_btn" + tool_tip="Offer friendship to a resident" + top_delta="0" + width="31"> + <commit_callback + function="People.AddFriend" /> + </button> + <dnd_button + enabled="false" + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="TrashItem_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + left_pad="2" + layout="topleft" + name="nearby_del_btn" + tool_tip="Remove selected person as a friend" + top_delta="0" + width="31"> + <commit_callback + function="People.DelFriend" /> + </dnd_button> + </panel> <layout_stack clip="false" follows="all" - height="355" + height="410" layout="topleft" + left="0" mouse_opaque="false" orientation="vertical" - width="313"> + right="-1" + top_pad="0"> <layout_panel height="142" layout="topleft" @@ -123,16 +194,16 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M left="3" mouse_opaque="false" name="Net Map" - top="4" - width="305"/> + right="-1" + top="4" /> </layout_panel> <layout_panel height="213" layout="topleft" min_dim="100" mouse_opaque="false" - user_resize="true" - width="313"> + right="-1" + user_resize="true"> <avatar_list allow_select="true" follows="all" @@ -143,84 +214,122 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M keep_one_selected="false" multi_select="true" name="avatar_list" - top="2" - width="306" /> + right="-1" + top="2" /> </layout_panel> </layout_stack> - <panel - background_visible="true" - follows="left|right|bottom" - height="27" - label="bottom_panel" - layout="topleft" - left="3" - name="bottom_panel" - top_pad="0" - width="313"> - <menu_button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Left_Over" - image_overlay="OptionsMenu_Off" - image_selected="Toolbar_Left_Selected" - image_unselected="Toolbar_Left_Off" - layout="topleft" - left="0" - name="nearby_view_sort_btn" - tool_tip="Options" - top="1" - width="31" /> - <button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Middle_Over" - image_overlay="AddItem_Off" - image_selected="Toolbar_Middle_Selected" - image_unselected="Toolbar_Middle_Off" - layout="topleft" - left_pad="1" - name="add_friend_btn" - tool_tip="Add selected Resident to your friends List" - width="31"> - <commit_callback - function="People.addFriend" /> - </button> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Right_Off" - layout="topleft" - left_pad="1" - name="dummy_icon" - width="243" - /> - </panel> </panel> + +<!-- ================================= FRIENDS tab ========================== --> + <panel background_opaque="true" background_visible="true" bg_alpha_color="DkGray" bg_opaque_color="DkGray" + bottom="-1" follows="all" - height="383" - label="MY FRIENDS" + label="FRIENDS" layout="topleft" left="0" help_topic="people_friends_tab" name="friends_panel" - top="0" - width="313"> + right="-1" + top="0"> + <panel + follows="left|top|right" + height="27" + label="bottom_panel" + layout="topleft" + left="0" + name="friends_buttons_panel" + right="-1" + top="0"> + <filter_editor + follows="left|top|right" + height="23" + layout="topleft" + left="6" + label="Filter People" + max_length_chars="300" + name="friends_filter_input" + text_color="Black" + text_pad_left="10" + top="4" + width="177" /> + <button + commit_callback.function="People.Gear" + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="8" + name="gear_btn" + tool_tip="Actions on selected person" + top="3" + width="31" /> + <menu_button + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_sort" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="2" + menu_filename="menu_people_friends_view.xml" + menu_position="bottomleft" + name="friends_view_btn" + tool_tip="View/sort options" + top_delta="0" + width="31" /> + <button + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="AddItem_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="2" + name="friends_add_btn" + tool_tip="Offer friendship to a resident" + top_delta="0" + width="31"> + <commit_callback + function="People.AddFriendWizard" /> + </button> + <dnd_button + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="TrashItem_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + left_pad="2" + layout="topleft" + name="friends_del_btn" + tool_tip="Remove selected person as a friend" + top_delta="0" + width="31"> + <commit_callback + function="People.DelFriend" /> + </dnd_button> + </panel> <accordion background_visible="true" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" follows="all" - height="356" + height="408" layout="topleft" left="3" name="friends_accordion" - top="0" - width="307"> + right="-2" + top_pad="2"> <accordion_tab layout="topleft" height="172" @@ -257,251 +366,145 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M width="307" /> </accordion_tab> </accordion> - <panel - background_visible="true" - follows="left|right|bottom" - height="27" - label="bottom_panel" - layout="topleft" - left="3" - name="bottom_panel" - top_pad="0" - width="313"> - - <layout_stack - animate="false" - border_size="0" - follows="left|right|bottom" - height="25" - layout="topleft" - orientation="horizontal" - top_pad="1" - left="0" - name="bottom_panel" - width="308"> - <layout_panel - auto_resize="false" - height="25" - layout="topleft" - name="options_gear_btn_panel" - user_resize="false" - width="32"> - <menu_button - follows="bottom|left" - tool_tip="Show additional options" - height="25" - image_hover_unselected="Toolbar_Left_Over" - image_overlay="OptionsMenu_Off" - image_selected="Toolbar_Left_Selected" - image_unselected="Toolbar_Left_Off" - layout="topleft" - left="0" - name="friends_viewsort_btn" - top="0" - width="31" /> - </layout_panel> - <layout_panel - auto_resize="false" - height="25" - layout="topleft" - name="add_btn_panel" - user_resize="false" - width="32"> - <button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Middle_Over" - image_overlay="AddItem_Off" - image_selected="Toolbar_Middle_Selected" - image_unselected="Toolbar_Middle_Off" - layout="topleft" - left="0" - name="add_btn" - tool_tip="Offer friendship to a Resident" - top="0" - width="31" /> - </layout_panel> - <layout_panel - auto_resize="true" - height="25" - layout="topleft" - name="dummy_panel" - user_resize="false" - width="210"> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Middle_Off" - layout="topleft" - left="0" - top="0" - name="dummy_icon" - width="210" /> - </layout_panel> - <layout_panel - auto_resize="false" - height="25" - layout="topleft" - name="trash_btn_panel" - user_resize="false" - width="31"> - <dnd_button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Right_Over" - image_overlay="TrashItem_Off" - image_selected="Toolbar_Right_Selected" - image_unselected="Toolbar_Right_Off" - left="0" - layout="topleft" - name="del_btn" - tool_tip="Remove selected person from your Friends list" - top="0" - width="31"/> - </layout_panel> - </layout_stack><!-- - - <button - follows="bottom|left" - tool_tip="Options" - height="25" - image_hover_unselected="Toolbar_Left_Over" - image_overlay="OptionsMenu_Off" - image_selected="Toolbar_Left_Selected" - image_unselected="Toolbar_Left_Off" - layout="topleft" - left="0" - name="friends_viewsort_btn" - top="1" - width="31" /> - <button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Middle_Over" - image_overlay="AddItem_Off" - image_selected="Toolbar_Middle_Selected" - image_unselected="Toolbar_Middle_Off" - layout="topleft" - left_pad="1" - name="add_btn" - tool_tip="Offer friendship to a Resident" - width="31" /> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Middle_Off" - layout="topleft" - left_pad="1" - name="dummy_icon" - width="209" - /> - <button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Right_Over" - image_overlay="TrashItem_Off" - image_selected="Toolbar_Right_Selected" - image_unselected="Toolbar_Right_Off" - layout="topleft" - left_pad="1" - name="del_btn" - tool_tip="Remove selected person from your Friends list" - width="31" /> - --></panel> <text follows="all" height="450" left="13" name="no_friends_help_text" - top="10" - width="293" + right="-13" + top="37" wrap="true" /> </panel> + +<!-- ================================= GROUPS tab =========================== --> + <panel background_opaque="true" background_visible="true" bg_alpha_color="DkGray" bg_opaque_color="DkGray" + bottom="-1" follows="all" - height="383" - label="MY GROUPS" + label="GROUPS" layout="topleft" left="0" help_topic="people_groups_tab" name="groups_panel" - top="0" - width="313"> + right="-1" + top="0"> <!-- *NOTE: no_groups_msg & group_list attributes are not defined as translatable in VLT. See EXT-5931 Values are set from appropriate strings at the top of file via LLPeoplePanel::postBuild() --> - <group_list - allow_select="true" - follows="all" - height="356" - layout="topleft" - left="3" - name="group_list" - top="0" - width="307" /> <panel - background_visible="true" - follows="left|right|bottom" + follows="left|top|right" height="27" label="bottom_panel" layout="topleft" left="0" - name="bottom_panel" - top_pad="0" - width="313"> - <menu_button - follows="bottom|left" - tool_tip="Options" - height="25" - image_hover_unselected="Toolbar_Left_Over" - image_overlay="OptionsMenu_Off" - image_selected="Toolbar_Left_Selected" - image_unselected="Toolbar_Left_Off" - layout="topleft" - left="3" - name="groups_viewsort_btn" - top="1" - width="31" /> - <button - follows="bottom|left" + name="groups_buttons_panel" + right="-1" + top="0"> + <filter_editor + follows="left|top|right" + height="23" + layout="topleft" + left="6" + label="Filter Groups" + max_length_chars="300" + name="groups_filter_input" + text_color="Black" + text_pad_left="10" + top="4" + width="177" /> + <menu_button + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="8" + name="groups_gear_btn" + tool_tip="Actions on selected group" + top="3" + width="31" /> + <menu_button + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_sort" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="2" + menu_filename="menu_people_groups_view.xml" + menu_position="bottomleft" + name="groups_view_btn" + tool_tip="View/sort options" + top_delta="0" + width="31" /> + <menu_button + follows="right" height="25" image_hover_unselected="Toolbar_Middle_Over" image_overlay="AddItem_Off" image_selected="Toolbar_Middle_Selected" image_unselected="Toolbar_Middle_Off" layout="topleft" - left_pad="1" + left_pad="2" + menu_filename="menu_group_plus.xml" + menu_position="bottomleft" name="plus_btn" tool_tip="Join group/Create new group" - width="31" /> - <button - follows="bottom|left" + top_delta="0" + width="31"> + <validate_callback + function="People.Group.Plus.Validate" /> + </menu_button> + <dnd_button + follows="right" height="25" image_hover_unselected="Toolbar_Middle_Over" - image_overlay="Activate_Checkmark" + image_overlay="TrashItem_Off" image_selected="Toolbar_Middle_Selected" image_unselected="Toolbar_Middle_Off" + left_pad="2" layout="topleft" - left_pad="1" - name="activate_btn" - tool_tip="Activate selected group" - width="31" /> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Right_Off" - layout="topleft" - left_pad="1" - name="dummy_icon" - width="212" - /> + name="minus_btn" + tool_tip="Leave selected group" + top_delta="0" + width="31"> + <commit_callback + function="People.Group.Minus" /> + </dnd_button> </panel> + <text + type="string" + length="1" + follows="all" + height="14" + layout="topleft" + right="-10" + top_pad="4" + left="3" + name="groupcount"> + You belong to [COUNT] groups, and can join [REMAINING] more. + </text> + <group_list + allow_select="true" + follows="all" + height="388" + layout="topleft" + left="3" + name="group_list" + right="-2" + top_pad="4" /> </panel> + +<!-- ================================= RECENT tab =========================== --> + <panel background_opaque="true" background_visible="true" @@ -514,273 +517,133 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M left="0" help_topic="people_recent_tab" name="recent_panel" - top="0" - width="313"> - <avatar_list - allow_select="true" - follows="all" - height="356" - layout="topleft" - left="3" - multi_select="true" - name="avatar_list" - show_last_interaction_time="true" - top="0" - width="307" /> + right="-1" + top="0"> <panel - background_visible="true" - follows="left|right|bottom" + follows="left|top|right" height="27" label="bottom_panel" layout="topleft" - left="3" - name="bottom_panel" - top_pad="0" - width="313"> - <menu_button - follows="bottom|left" - tool_tip="Options" - height="25" - image_hover_unselected="Toolbar_Left_Over" - image_overlay="OptionsMenu_Off" - image_selected="Toolbar_Left_Selected" - image_unselected="Toolbar_Left_Off" - layout="topleft" - name="recent_viewsort_btn" - top="1" - width="31" /> - <button - follows="bottom|left" + left="0" + name="recent_buttons_panel" + right="-1" + top="0"> + <filter_editor + follows="left|top|right" + height="23" + layout="topleft" + left="6" + label="Filter People" + max_length_chars="300" + name="recent_filter_input" + text_color="Black" + text_pad_left="10" + top="4" + width="177" /> + <button + commit_callback.function="People.Gear" + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="8" + name="gear_btn" + tool_tip="Actions on selected person" + top="3" + width="31" /> + <menu_button + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_sort" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="2" + menu_filename="menu_people_recent_view.xml" + menu_position="bottomleft" + name="recent_view_btn" + tool_tip="View/sort options" + top_delta="0" + width="31" /> + <button + follows="right" height="25" image_hover_unselected="Toolbar_Middle_Over" image_overlay="AddItem_Off" image_selected="Toolbar_Middle_Selected" image_unselected="Toolbar_Middle_Off" layout="topleft" - left_pad="1" + left_pad="2" name="add_friend_btn" - tool_tip="Add selected Resident to your friends List" + tool_tip="Offer friendship to a resident" + top_delta="0" width="31"> - <commit_callback - function="People.addFriend" /> - </button> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Right_Off" - layout="topleft" - left_pad="1" - name="dummy_icon" - width="244" - /> + <commit_callback + function="People.AddFriend" /> + </button> + <dnd_button + enabled="false" + follows="right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="TrashItem_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + left_pad="2" + layout="topleft" + name="recent_del_btn" + tool_tip="Remove selected person as a friend" + top_delta="0" + width="31"> + <commit_callback + function="People.DelFriend" /> + </dnd_button> </panel> + <avatar_list + allow_select="true" + follows="all" + height="351" + layout="topleft" + left="3" + multi_select="true" + name="avatar_list" + show_last_interaction_time="true" + right="-2" + top_pad="4" /> </panel> - </tab_container> - <panel - follows="bottom|left|right" - height="23" - layout="topleft" - left="8" - top_pad="4" - name="button_bar" - width="313"> -<!--********************************Profile; IM; Call, Share, Teleport********************************--> - <layout_stack - follows="bottom|left|right" - height="23" - layout="topleft" - name="bottom_bar_ls" - left="0" - orientation="horizontal" - top_pad="0" - width="313"> +<!-- ================================= BLOCKED tab ========================== --> - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left="0" - name="view_profile_btn_lp" - user_resize="false" - auto_resize="true" - width="68"> - <button - follows="bottom|left|right" - height="23" - label="Profile" - layout="topleft" - left="1" - name="view_profile_btn" - tool_tip="Show picture, groups, and other Residents information" - top="0" - width="67" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="im_btn_lp" - user_resize="false" - auto_resize="true" - width="41"> - <button - follows="bottom|left|right" - left="1" - height="23" - label="IM" - layout="topleft" - name="im_btn" - tool_tip="Open instant message session" - top="0" - width="40" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="call_btn_lp" - user_resize="false" - auto_resize="true" - width="52"> - <button - follows="bottom|left|right" - left="1" - height="23" - label="Call" - layout="topleft" - name="call_btn" - tool_tip="Call this Resident" - top="0" - width="51" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="share_btn_lp" - user_resize="false" - auto_resize="true" - width="66"> - <button - follows="bottom|left|right" - left="1" - height="23" - label="Share" - layout="topleft" - name="share_btn" - tool_tip="Share an inventory item" - top="0" - width="65" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="teleport_btn_lp" - user_resize="false" - auto_resize="true" - width="77"> - <button - follows="bottom|left|right" - left="1" - height="23" - label="Teleport" - layout="topleft" - name="teleport_btn" - tool_tip="Offer teleport" - top="0" - width="76" /> - </layout_panel> - </layout_stack> - -<!--********************************Group Profile; Group Chat; Group Call buttons************************--> - <layout_stack - follows="bottom|left|right" - height="23" - layout="topleft" - mouse_opaque="false" - name="bottom_bar_ls1" - left="0" - orientation="horizontal" - top="0" - width="313"> - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left="0" - mouse_opaque="false" - name="group_info_btn_lp" - user_resize="false" - auto_resize="true" - width="108"> - <button - follows="bottom|left|right" - left="1" - height="23" - label="Group Profile" - layout="topleft" - mouse_opaque="false" - name="group_info_btn" - tool_tip="Show group information" - top="0" - width="107" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - mouse_opaque="false" - name="chat_btn_lp" - user_resize="false" - auto_resize="true" - width="101"> - <button - follows="bottom|left|right" - left="1" - height="23" - label="Group Chat" - layout="topleft" - mouse_opaque="false" - name="chat_btn" - tool_tip="Open chat session" - top="0" - width="100" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - mouse_opaque="false" - name="group_call_btn_lp" - user_resize="false" - auto_resize="true" - width="96"> - <button - follows="bottom|left|right" - left="1" - height="23" - label="Group Call" - layout="topleft" - mouse_opaque="false" - name="group_call_btn" - tool_tip="Call this group" - top="0" - width="95" /> - </layout_panel> - </layout_stack> - </panel> + <panel + background_opaque="true" + background_visible="true" + bg_alpha_color="DkGray" + bg_opaque_color="DkGray" + follows="all" + height="383" + label="BLOCKED" + layout="topleft" + left="0" + help_topic="people_blocked_tab" + name="blocked_panel" + right="-1" + top="0"> + <panel + class="panel_block_list_sidetray" + height="383" + name="panel_block_list_sidetray" + filename="panel_block_list_sidetray.xml" + follows="all" + label="Blocked Residents & Objects" + layout="topleft" + left="0" + font="SansSerifBold" + top="0" + right="-1" /> + </panel> + </tab_container> </panel> 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 aebbc51be1..3f67a48b14 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" @@ -86,6 +85,7 @@ top_delta="0" width="95" /> <check_box + height="10" bottom_delta="20" follows="left|top" label="Constrain proportions" @@ -99,7 +99,6 @@ layout="topleft" left="0" name="postcard_image_format_quality_lp" - user_resize="false" auto_resize="true" top="0" right="-1" @@ -113,11 +112,11 @@ label="Image quality" label_width="80" layout="topleft" - left="10" + left="0" max_val="100" name="image_quality_slider" top_pad="7" - width="200" /> + width="190" /> <text type="string" follows="left|top" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml index 2cc9d9c1b0..50fd57494f 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml @@ -138,7 +138,7 @@ initial_value="1" layout="topleft" left_pad="0" - max_val="1.4" + max_val="1.5" min_val="0.75" name="ui_scale_slider" top_pad="-14" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml index caf7fc85f5..9db3816c92 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml @@ -1,219 +1,494 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - border="true" - follows="left|top|right|bottom" - height="408" - label="Text Chat" - layout="topleft" - left="102" - name="chat" - top="1" - width="517"> - <text - follows="left|top" - layout="topleft" - left="30" - height="12" - name="font_size" - width="120" - top="10"> - Font size: - </text> - <radio_group - height="30" - layout="topleft" - left="40" - control_name="ChatFontSize" - name="chat_font_size" - top_pad="0" - width="440"> - <radio_item - height="16" - label="Small" - layout="topleft" - left="0" - name="radio" - value="0" - top="10" - width="125" /> - <radio_item - height="16" - label="Medium" - layout="topleft" - left_delta="145" - name="radio2" - value="1" - top_delta="0" - width="125" /> - <radio_item - height="16" - label="Large" - layout="topleft" - left_delta="170" - name="radio3" - value="2" - top_delta="0" - width="125" /> - </radio_group> - + border="true" + has_border="true" + height="408" + label="Text Chat" + layout="topleft" + left="102" + name="chat" + top="1" + width="517"> + + <panel + border="false" + height="60" + layout="topleft" + top="10" + left="13" + width="517"> + <check_box - control_name="PlayTypingAnim" - height="16" - initial_value="true" - label="Play typing animation when chatting" - layout="topleft" - left="30" - name="play_typing_animation" - top_pad="10" - width="400" /> + control_name="PlayTypingAnim" + height="16" + initial_value="true" + label="Play typing animation when chatting" + layout="topleft" + top="0" + name="play_typing_animation" + width="330"> + </check_box> + <check_box - enabled="false" - height="16" - label="Email me IMs when I'm offline" - layout="topleft" - left_delta="0" - name="send_im_to_email" - top_pad="5" - width="400" /> + enabled="false" + height="16" + label="Email me IMs when I'm offline" + layout="topleft" + name="send_im_to_email" + top_pad="6" + width="330"> + </check_box> + <check_box - enabled="false" - height="16" - label="Enable plain text IM and chat history" - layout="topleft" - left_delta="0" - name="plain_text_chat_history" - top_pad="5" - width="400" /> + control_name="VoiceCallsFriendsOnly" + height="16" + label="Only friends and groups can call or IM me" + layout="topleft" + name="voice_call_friends_only_check" + top_pad="6" + width="350"> + </check_box> + + <text + layout="topleft" + left="345" + height="12" + name="font_size" + width="120" + top="0"> + Font size: + </text> + + <combo_box + control_name="ChatFontSize" + height="23" + layout="topleft" + left="341" + name="chat_font_size" + top_pad="5" + width="100"> + <item + label="Small" + name="Small" + value="0"/> + <item + label="Medium" + name="Medium" + value="1"/> + <item + label="Large" + name="Large" + value="2"/> + </combo_box> + <check_box - control_name="UseChatBubbles" - follows="left|top" - height="16" - label="Bubble Chat" - layout="topleft" - left_delta="0" - top_pad="5" - name="bubble_text_chat" - width="150" /> + control_name="UseChatBubbles" + height="16" + label="Bubble Chat" + layout="topleft" + top_pad="4" + name="bubble_text_chat" + width="330"> + </check_box> + + </panel> + + <panel + border="false" + height="165" + layout="topleft" + left="13" + width="517"> + <text - name="show_ims_in_label" - follows="left|top" - layout="topleft" - left="30" - height="20" - width="170" - top_pad="15"> - Show IMs in: + layout="topleft" + height="12" + name="notifications" + left="0" + width="120"> + Notifications </text> <text - name="requires_restart_label" - follows="left|top" - layout="topleft" - top_delta="0" - left="170" - height="20" - width="130" - text_color="White_25"> - (requires restart) - </text> - <radio_group - follows="left|top" - height="30" - left="40" - control_name="ChatWindow" - name="chat_window" - top_pad="0" - tool_tip="Show your Instant Messages in separate floaters, or in one floater with many tabs (Requires restart)" - width="150"> - <radio_item - height="16" - label="Separate Windows" - layout="topleft" - left="0" - name="radio" - value="0" - top="0" - width="150" /> - <radio_item - height="16" - label="Tabs" + layout="topleft" + height="12" + name="friend_ims" + width="145" + left="0" + top_pad="13"> + Friend IMs: + </text> + <combo_box + control_name="NotificationFriendIMOptions" + height="23" + layout="topleft" + left_pad="5" + top_delta="-6" + name="FriendIMOptions" + width="223"> + <item + label="Open Conversations window" + name="OpenConversationsWindow" + value="openconversations"/> + <item + label="Pop up the message" + name="PopUpMessage" + value="toast"/> + <item + label="Flash toolbar button" + name="FlashToolbarButton" + value="flash"/> + <item + label="None" + name="None" + value="none"/> + </combo_box> + <text + layout="topleft" + height="12" + name="non_friend_ims" + width="145" + left="0" + top_pad="9"> + Non-friend IMs: + </text> + <combo_box + control_name="NotificationNonFriendIMOptions" + height="23" + layout="topleft" + left_pad="5" + top_delta="-6" + name="NonFriendIMOptions" + width="223"> + <item + label="Open Conversations window" + name="OpenConversationsWindow" + value="openconversations"/> + <item + label="Pop up the message" + name="PopUpMessage" + value="toast"/> + <item + label="Flash toolbar button" + name="FlashToolbarButton" + value="flash"/> + <item + label="None" + name="None" + value="none"/> + </combo_box> + <text + layout="topleft" + left="0" + height="13" + name="conference_ims" + width="145" + top_pad="9"> + Conference IMs: + </text> + <combo_box + control_name="NotificationConferenceIMOptions" + height="23" + layout="topleft" + left_pad="5" + top_delta="-6" + name="ConferenceIMOptions" + width="223"> + <item + label="Open Conversations window" + name="OpenConversationsWindow" + value="openconversations"/> + <item + label="Pop up the message" + name="PopUpMessage" + value="toast"/> + <item + label="Flash toolbar button" + name="FlashToolbarButton" + value="flash"/> + <item + label="None" + name="None" + value="none"/> + </combo_box> + <text + layout="topleft" + left="0" + height="13" + name="group_chat" + width="145" + top_pad="9"> + Group chat: + </text> + <combo_box + control_name="NotificationGroupChatOptions" + height="23" + layout="topleft" + left_pad="5" + top_delta="-6" + name="GroupChatOptions" + width="223"> + <item + label="Open Conversations window" + name="OpenConversationsWindow" + value="openconversations"/> + <item + label="Pop up the message" + name="PopUpMessage" + value="toast"/> + <item + label="Flash toolbar button" + name="FlashToolbarButton" + value="flash"/> + <item + label="None" + name="None" + value="none"/> + </combo_box> + <text + layout="topleft" + left="0" + height="12" + name="nearby_chat" + width="145" + top_pad="9"> + Nearby chat: + </text> + <combo_box + control_name="NotificationNearbyChatOptions" + height="23" + layout="topleft" + left_pad="5" + top_delta="-6" + name="NearbyChatOptions" + width="223"> + <item + label="Open Conversations window" + name="OpenConversationsWindow" + value="openconversations"/> + <item + label="Pop up the message" + name="PopUpMessage" + value="toast"/> + <item + label="Flash toolbar button" + name="FlashToolBarButton" + value="flash"/> + <item + label="None" + name="None" + value="none"/> + </combo_box> + <text + layout="topleft" + left="0" + height="13" + name="notifications_alert" + width="500" + top_pad="9" + visible="true" + text_color="DrYellow"> + To temporarily stop all notifications, use Communicate > Do Not Disturb. + </text> + + </panel> + + <panel + border="false" + height="50" layout="topleft" - left_delta="0" - name="radio2" - value="1" - top_pad="5" - width="150" /> - </radio_group> + left="13" + top_pad="10" + width="517"> + <text - name="disable_toast_label" - follows="left|top" - layout="topleft" - top_pad="20" - left="30" - height="10" - width="400"> - Enable incoming chat popups: - </text> + layout="topleft" + left="0" + name="play_sound" + width="100" + top_pad="8" + visible="true"> + Play sound: + </text> + <check_box + control_name="PlaySoundNewConversation" + height="16" + label="New conversation" + layout="topleft" + left_pad="15" + top_pad="-10" + name="new_conversation" + width="150" /> + <check_box + control_name="PlaySoundIncomingVoiceCall" + height="16" + label="Incoming voice call" + layout="topleft" + top_pad="6" + name="incoming_voice_call" + width="150" /> <check_box - control_name="EnableGroupChatPopups" - name="EnableGroupChatPopups" - label="Group Chats" - layout="topleft" - top_pad="5" - left_delta="10" - height="20" - tool_tip="Check to see popups when a Group Chat message arrives" - width="400" /> + control_name="PlaySoundTeleportOffer" + height="16" + label="Teleport offer" + layout="topleft" + left_pad="35" + top_pad="-38" + name="teleport_offer" + width="150" /> <check_box - control_name="EnableIMChatPopups" - name="EnableIMChatPopups" - label="IM Chats" - layout="topleft" - top_pad="5" - height="16" - tool_tip="Check to see popups when an instant message arrives" - width="400" /> - <spinner - control_name="NearbyToastLifeTime" - decimal_digits="0" - follows="left|top" - height="23" - increment="1" - initial_value="23" - label="Nearby chat toasts life time:" - label_width="285" - layout="topleft" - left="45" - max_val="60" - min_val="1" - name="nearby_toasts_lifetime" - top_pad="10" - width="325" /> - <spinner - control_name="NearbyToastFadingTime" - decimal_digits="0" - follows="left|top" - height="23" - increment="1" - initial_value="3" - label="Nearby chat toasts fading time:" - label_width="285" - layout="topleft" - left_delta="0" - max_val="60" - min_val="0" - name="nearby_toasts_fadingtime" - top_pad="3" - width="325" /> + control_name="PlaySoundInventoryOffer" + height="16" + label="Inventory offer" + layout="topleft" + top_pad="6" + name="inventory_offer" + width="150" /> + + </panel> + + <view_border + bevel_style="none" + height="0" + layout="topleft" + left="13" + name="cost_text_border" + top_pad="5" + width="495"/> + + <panel + height="50" + layout="topleft" + left="13" + top_pad="10" + width="505"> + + <text + layout="topleft" + left="0" + text_color="White" + height="12" + top="5" + width="55"> + Save: + </text> + + <combo_box + enabled="false" + control_name="KeepConversationLogTranscripts" + height="23" + layout="topleft" + left_pad="5" + name="chat_font_size" + top="0" + width="165"> + <item + label="Log and transcripts" + value="2"/> + <item + label="Log only" + value="1"/> + <item + label="No log or transcripts" + value="0"/> + </combo_box> + + <button + enabled="false" + height="23" + label="Clear log..." + layout="topleft" + left_pad="5" + top="0" + name="clear_log" + width="110"> + <commit_callback + function="Pref.ClearLog" /> + </button> + + <button + enabled="false" + height="23" + label="Delete transcripts..." + layout="topleft" + left_pad="5" + top="0" + name="delete_transcripts" + width="147"> + <button.commit_callback + function="Pref.DeleteTranscripts" /> + </button> + + <text + layout="topleft" + left="0" + text_color="White" + height="12" + top_pad="15" + width="55"> + Location: + </text> + + <line_editor + enabled="false" + control_name="InstantMessageLogPath" + border_style="line" + border_thickness="1" + font="SansSerif" + height="23" + layout="topleft" + left_pad="55" + max_length="4096" + name="log_path_string" + top_delta="-5" + width="185"> + </line_editor> + + <button + enabled="false" + follows="left|top" + height="23" + label="Browse..." + label_selected="Browse" + layout="topleft" + left_pad="5" + name="log_path_button" + top_delta="0" + width="112"> + <commit_callback function="Pref.LogPath" /> + </button> + + </panel> + + <button + height="23" + label="Translation..." + layout="topleft" + left="9" + name="ok_btn" + top="-29" + width="170"> + <commit_callback + function="Pref.TranslationSettings" /> + </button> <button - follows="left|top" - height="23" - label="Chat Translation Settings" - layout="topleft" - left="30" - name="ok_btn" - top="-40" - width="170"> - <button.commit_callback - function="Pref.TranslationSettings" /> + height="23" + layout="topleft" + top_pad="-23" + left_pad="5" + name="autoreplace_showgui" + commit_callback.function="Pref.AutoReplace" + label="Auto-Replace..." + width="150"> + </button> + <button + height="23" + layout="topleft" + top_pad="-23" + left_pad="5" + name="spellcheck_showgui" + commit_callback.function="Pref.SpellChecker" + label="Spell Checking..." + width="150"> </button> -</panel>
\ No newline at end of file + +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml index 2b22f0d6e3..9e825fe516 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml @@ -362,7 +362,7 @@ follows="left|top" height="16" increment="0.01" - initial_value="0.8" + initial_value="1.0" layout="topleft" label_width="115" label="Active:" @@ -380,7 +380,7 @@ follows="left|top" height="16" increment="0.01" - initial_value="0.5" + initial_value="0.95" layout="topleft" label_width="115" label="Inactive:" 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..ea0f7d8593 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml @@ -331,7 +331,7 @@ </text> <radio_group control_name="LetterKeysFocusChatBar" - height="20" + height="34" layout="topleft" left="35" top_pad="0" @@ -339,7 +339,7 @@ <radio_item label="Starts local chat" name="radio_start_chat" - top_delta="20" + top="0" layout="topleft" height="16" left="0" @@ -364,7 +364,7 @@ layout="topleft" left="30" name="title_afk_text" - top_pad="15" + top_pad="5" width="190"> Away timeout: </text> @@ -409,10 +409,10 @@ name="text_box3" top_pad="3" width="240"> - Busy mode response: + Do Not Disturb response: </text> <text_editor - control_name="BusyModeResponse" + control_name="DoNotDisturbModeResponse" text_readonly_color="LabelDisabledColor" bg_writeable_color="LtGray" use_ellipses="false" @@ -420,8 +420,8 @@ follows="left|top" height="29" layout="topleft" - left="50" - name="busy_response" + left="30" + name="do_not_disturb_response" width="470" word_wrap="true"> log_in_to_change diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index f7666bdc4c..cd243d40a4 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -55,30 +55,57 @@ name="LowGraphicsDivet" top_delta="-2" width="2" /> + <icon + color="0.12 0.12 0.12 1" + height="14" + image_name="Rounded_Square" + layout="topleft" + left_pad="41" + name="LowMidraphicsDivet" + top_delta="-2" + width="2" /> <icon color="0.12 0.12 0.12 1" height="14" image_name="Rounded_Square" layout="topleft" - left_pad="83" + left_pad="41" name="MidGraphicsDivet" top_delta="0" width="2" /> + <icon + color="0.12 0.12 0.12 1" + height="14" + image_name="Rounded_Square" + layout="topleft" + left_pad="41" + name="MidHighGraphicsDivet" + top_delta="0" + width="2" /> <icon color="0.12 0.12 0.12 1" height="14" image_name="Rounded_Square" layout="topleft" - left_pad="85" + left_pad="41" name="HighGraphicsDivet" top_delta="0" width="2" /> + <icon + color="0.12 0.12 0.12 1" + height="14" + image_name="Rounded_Square" + layout="topleft" + left_pad="41" + name="HighUltraGraphicsDivet" + top_delta="0" + width="2" /> <icon color="0.12 0.12 0.12 1" height="14" image_name="Rounded_Square" layout="topleft" - left_pad="83" + left_pad="41" name="UltraGraphicsDivet" top_delta="0" width="2" /> @@ -91,7 +118,7 @@ initial_value="0" layout="topleft" left="120" - max_val="3" + max_val="6" name="QualityPerformanceSelection" show_text="false" top_delta="-2" 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..78743d26bb 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml @@ -1,73 +1,69 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - border="true" - follows="left|top|right|bottom" - height="408" - label="Communication" - layout="topleft" - left="102" - name="im" - top="1" - width="517"> - <panel.string - name="log_in_to_change"> - log in to change - </panel.string> - <button - follows="left|bottom" - height="23" - label="Clear History" - tool_tip="Clear login image, last location, teleport history, web, and texture cache" - layout="topleft" - left="30" - name="clear_cache" - top="10" - width="145"> - <button.commit_callback - function="Pref.WebClearCache" /> - </button> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_pad="10" - mouse_opaque="false" - name="cache_size_label_l" - top_delta="3" - text_color="LtGray_50" - width="300"> - (Locations, images, web, search history) - </text> - <check_box - height="16" - enabled="false" - label="Show me in Search results" - layout="topleft" - left="30" - name="online_searchresults" - top_pad="20" - width="350" /> - <check_box - height="16" - enabled="false" - label="Only friends and groups know I'm online" - layout="topleft" - left="30" - name="online_visibility" - 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" - layout="topleft" - left="30" - name="voice_call_friends_only_check" - top_pad="10" - width="350" /> + border="true" + follows="left|top|right|bottom" + height="408" + label="Communication" + layout="topleft" + left="102" + name="im" + top="1" + width="517"> + + <panel.string + name="log_in_to_change"> + log in to change + </panel.string> + + <button + follows="left|bottom" + height="23" + label="Clear History" + tool_tip="Clear login image, last location, teleport history, web, and texture cache" + layout="topleft" + left="30" + name="clear_cache" + top="10" + width="145"> + <button.commit_callback + function="Pref.WebClearCache" /> + </button> + + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_pad="10" + mouse_opaque="false" + name="cache_size_label_l" + top_delta="3" + text_color="LtGray_50" + width="300"> + (Locations, images, web, search history) + </text> + + <check_box + height="16" + enabled="false" + label="Show me in Search results" + layout="topleft" + left="30" + name="online_searchresults" + top_pad="20" + width="350" /> + + <check_box + height="16" + enabled="false" + label="Only friends and groups know I'm online" + layout="topleft" + left="30" + name="online_visibility" + top_pad="30" + width="350" /> + <check_box enabled_control="EnableVoiceChat" control_name="AutoDisengageMic" @@ -88,100 +84,7 @@ name="favorites_on_login_check" top_pad="10" width="350" /> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="30" - mouse_opaque="false" - name="Logs:" - top_pad="20" - width="350"> - Chat Logs: - </text> - <check_box - enabled="false" - control_name="LogNearbyChat" - height="16" - label="Save nearby chat logs on my computer" - layout="topleft" - left="30" - name="log_nearby_chat" - top_pad="10" - width="350"> - </check_box> - <check_box - enabled="false" - control_name="LogInstantMessages" - height="16" - label="Save IM logs on my computer" - layout="topleft" - left="30" - name="log_instant_messages" - top_pad="10" - width="350"> - </check_box> - <check_box - control_name="LogTimestamp" - enabled="false" - height="16" - label="Add timestamp to each line in chat log" - layout="topleft" - left_delta="0" - name="show_timestamps_check_im" - top_pad="10" - width="237" /> - <check_box - control_name="LogFileNamewithDate" - enabled="false" - height="16" - label="Add datestamp to log file name." - layout="topleft" - left_delta="5" - name="logfile_name_datestamp" - top_pad="10" - width="350"/> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_delta="0" - mouse_opaque="false" - name="log_path_desc" - top_pad="30" - width="128"> - Location of logs: - </text> - <line_editor - bottom="366" - control_name="InstantMessageLogPath" - follows="top|left|right" - halign="right" - height="23" - layout="topleft" - left_delta="0" - mouse_opaque="false" - name="log_path_string" - top_pad="5" - width="250"/> - <button - enabled="false" - follows="right|bottom" - height="23" - label="Browse" - label_selected="Browse" - layout="topleft" - left_pad="5" - name="log_path_button" - top_delta="0" - width="145"> - <button.commit_callback - function="Pref.LogPath" /> - </button> + <button follows="left|bottom" height="23" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml index a7078ce2e1..4aeea8823e 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -122,7 +122,7 @@ layout="topleft" left_delta="0" name="external" - value="1" + value="true" top="0" tool_tip="Use the default system web browser for help, web links, etc. Not recommended if running full screen." width="480" /> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index 1f92244eb9..b71586aab1 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -63,7 +63,7 @@ layout="topleft" left_pad="0" name="mute_chb_label" - top_delta="0" + top_delta="-1" width="150" wrap="true"> Mute when minimized 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_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml deleted file mode 100644 index f5a9daa994..0000000000 --- a/indra/newview/skins/default/xui/en/panel_profile.xml +++ /dev/null @@ -1,458 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - follows="all" - height="430" - label="Profile" - layout="topleft" - left="0" - name="panel_profile" - top="0" - width="317"> - <string - name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string - name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=en - </string> - <string - name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=en - </string> - <string - name="my_account_link_url" - value="http://secondlife.com/account" /> - <string - name="no_partner_text" - value="None" /> - <string - name="no_group_text" - value="None" /> - <string - name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string - name="name_text_args"> - [NAME] - </string> - <string - name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack - name="layout" - orientation="vertical" - follows="all" - layout="topleft" - left="0" - top="0" - height="400" - width="317" - border_size="0"> - <layout_panel - name="profile_stack" - follows="all" - layout="topleft" - top="0" - left="0" - height="400" - width="317"> - <scroll_container - color="DkGray2" - follows="all" - layout="topleft" - left="0" - name="profile_scroll" - opaque="true" - height="400" - width="317" - top="0"> - <panel - layout="topleft" - follows="left|top|right" - height="505" - min_height="505" - name="profile_scroll_panel" - top="0" - left="0" - width="297"> - <panel - follows="left|top|right" - height="124" - layout="topleft" - left="13" - name="second_life_image_panel" - top="0" - width="297"> - <texture_picker - allow_no_texture="true" - default_image_name="None" - enabled="false" - fallback_image="Generic_Person_Large" - follows="top|left" - height="124" - layout="topleft" - left="0" - name="2nd_life_pic" - top="10" - width="102" /> - <text - follows="left|top|right" - font.style="BOLD" - height="15" - layout="topleft" - left_pad="10" - name="title_sl_descr_text" - text_color="white" - top_delta="0" - value="[SECOND_LIFE]:" - width="180" /> - <expandable_text - follows="left|top|right" - height="97" - layout="topleft" - left="107" - textbox.max_length="512" - textbox.show_context_menu="true" - name="sl_description_edit" - top_pad="-3" - translate="false" - width="180" - expanded_bg_visible="true" - expanded_bg_color="DkGray"> - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra orci et justo sagittis aliquet.Nullamma lesuada mauris sit amet ipsum. adipiscing elit. Ae nean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. - </expandable_text> - </panel> - <panel - follows="left|top|right" - height="124" - layout="topleft" - top_pad="0" - left="13" - name="first_life_image_panel" - width="297"> - <texture_picker - allow_no_texture="true" - default_image_name="None" - enabled="false" - fallback_image="Generic_Person_Large" - follows="top|left" - height="124" - layout="topleft" - left="0" - name="real_world_pic" - width="102" /> - <text - follows="left|top|right" - font.style="BOLD" - height="15" - layout="topleft" - left_pad="10" - name="title_rw_descr_text" - text_color="white" - top_delta="0" - value="Real World:" - width="180" /> - <expandable_text - follows="left|top|right" - height="97" - layout="topleft" - left="107" - textbox.max_length="512" - textbox.show_context_menu="true" - name="fl_description_edit" - top_pad="-3" - translate="false" - width="180" - expanded_bg_visible="true" - expanded_bg_color="DkGray"> - Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. - </expandable_text> - </panel> - <text - follows="left|top" - height="15" - font.style="BOLD" - font="SansSerifMedium" - layout="topleft" - left="10" - name="homepage_edit" - top_pad="0" - translate="false" - value="http://librarianavengers.org" - width="300" - word_wrap="false" - use_ellipses="true" /> - <text - follows="left|top" - font.style="BOLD" - height="10" - layout="topleft" - left="10" - name="title_member_text" - text_color="white" - top_pad="10" - value="Resident Since:" - width="300" /> - <text_editor - allow_scroll="false" - bg_visible="false" - follows="left|top" - h_pad="0" - height="15" - layout="topleft" - left="10" - name="register_date" - read_only="true" - translate="false" - v_pad="0" - value="05/31/2376" - width="300" - word_wrap="true" /> - <text - follows="left|top" - font.style="BOLD" - height="15" - layout="topleft" - left="10" - name="title_acc_status_text" - text_color="white" - top_pad="5" - value="Account Status:" - width="300" /> - <!-- <text - type="string" - follows="left|top" - font="SansSerifSmall" - height="15" - layout="topleft" - left_pad="10" - name="my_account_link" - top_delta="0" - value="Go to Dashboard" - width="100"/> --> - <text_editor - allow_scroll="false" - bg_visible="false" - follows="left|top" - h_pad="0" - height="28" - layout="topleft" - left="10" - name="acc_status_text" - read_only="true" - top_pad="0" - translate="false" - v_pad="0" - width="300" - word_wrap="true"> - Resident. No payment info on file. - Linden. - </text_editor> - <text - follows="left|top" - font.style="BOLD" - height="15" - layout="topleft" - left="10" - name="title_partner_text" - text_color="white" - top_pad="3" - value="Partner:" - width="300" /> - <panel - follows="left|top" - height="15" - layout="topleft" - left="10" - name="partner_data_panel" - top_pad="0" - width="300"> - <text - follows="left|top" - height="10" - initial_value="(retrieving)" - layout="topleft" - left="0" - parse_urls="true" - name="partner_text" - top="0" - use_ellipses="true" - width="300" /> - </panel> - <text - follows="left|top" - font.style="BOLD" - height="13" - layout="topleft" - left="10" - name="title_groups_text" - text_color="white" - top_pad="3" - value="Groups:" - width="300" /> - <expandable_text - follows="all" - height="103" - layout="topleft" - left="7" - name="sl_groups" - textbox.max_length="512" - textbox.show_context_menu="true" - top_pad="0" - translate="false" - width="290" - expanded_bg_visible="true" - expanded_bg_color="DkGray"> - Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. Aenean viverra tulip moosetop. Slan de heelish marfnik tooplod. Sum sum to whop de wompam booster copm. - </expandable_text> - </panel> - </scroll_container> - </layout_panel> - -</layout_stack> - - <layout_stack - name="layout_verb_buttons" - orientation="horizontal" - follows="bottom|left|right" - layout="topleft" - left="2" - top_pad="1" - height="30" - width="315" - border_size="0"> - <layout_panel - follows="bottom|left" - height="30" - layout="topleft" - name="profile_buttons_panel" - top="0" - auto_resize="false" - width="317"> - - <layout_stack - follows="bottom|left|right" - height="23" - layout="topleft" - name="bottom_bar_ls" - left="0" - orientation="horizontal" - top_pad="5" - width="317"> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left="0" - name="add_friend_btn_lp" - user_resize="false" - auto_resize="true" - width="121"> - <button - follows="bottom|left|right" - height="23" - label="Add Friend" - layout="topleft" - left="1" - mouse_opaque="false" - name="add_friend" - tool_tip="Offer friendship to the Resident" - top="0" - width="120" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="im_btn_lp" - user_resize="false" - auto_resize="true" - width="22"> - <button - follows="bottom|left|right" - height="23" - label="IM" - layout="topleft" - name="im" - tool_tip="Open instant message session" - top="0" - left="1" - width="21" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="call_btn_lp" - user_resize="false" - auto_resize="true" - width="52"> - <button - follows="bottom|left|right" - height="23" - label="Call" - layout="topleft" - name="call" - tool_tip="Call this Resident" - left="1" - top="0" - use_ellipses="true" - width="51" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="chat_btn_lp" - user_resize="false" - auto_resize="true" - width="93"> - <button - follows="bottom|left|right" - height="23" - label="Teleport" - layout="topleft" - name="teleport" - tool_tip="Offer teleport" - left="1" - top="0" - use_ellipses="true" - width="92" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="overflow_btn_lp" - user_resize="false" - auto_resize="false" - width="24"> - <menu_button - follows="bottom|left|right" - height="23" - label="▼" - layout="topleft" - name="overflow_btn" - tool_tip="Pay money to or share inventory with the Resident" - left="1" - top="0" - width="23" /> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> - -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml deleted file mode 100644 index 646875b52e..0000000000 --- a/indra/newview/skins/default/xui/en/panel_profile_view.xml +++ /dev/null @@ -1,162 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - background_visible="true" - follows="all" - height="570" - layout="topleft" - min_height="350" - name="panel_target_profile" - left="0" - width="333"> - <string - name="status_online"> - Online - </string> - <string - name="status_offline"> - Offline - </string> - <button - follows="top|left" - height="24" - image_hover_unselected="BackButton_Over" - image_pressed="BackButton_Press" - image_unselected="BackButton_Off" - layout="topleft" - name="back" - left="10" - tab_stop="false" - top="2" - width="30" - use_draw_context_alpha="false" /> - <text - top="10" - follows="top|left" - height="13" - layout="topleft" - left="45" - name="display_name_label" - text_color="LtGray" - value="Display Name:" - width="80" /> - <text - top_delta="0" - follows="top|left" - height="13" - layout="topleft" - left="45" - name="solo_username_label" - text_color="LtGray" - value="Username:" - visible="false" - width="80" /> - <text - follows="top|right" - halign="right" - height="13" - layout="topleft" - right="-15" - name="status" - text_color="LtGray_50" - top_delta="0" - value="Online" - width="150" /> - <text - follows="top|left|right" - font="SansSerifBigBold" - height="29" - layout="topleft" - left="45" - name="user_name_small" - text_color="LtGray" - top="22" - value="Jack oh look at me this is a super duper long name" - use_ellipses="true" - word_wrap="true" - visible="false" - width="255" /> - <text - follows="top|left|right" - font="SansSerifHugeBold" - height="27" - layout="topleft" - left="45" - name="user_name" - text_color="LtGray" - translate="false" - top="25" - value="TestString PleaseIgnore" - visible="true" - use_ellipses="true" - width="258" /> - <button - name="copy_to_clipboard" - layout="topleft" - follows="top|right" - image_overlay="Copy" - top_delta="0" - right="-15" - height="21" - width="21" - tab_stop="false" - tool_tip="Copy to Clipboard"/> - <text - follows="top|left" - height="13" - layout="topleft" - left="45" - name="user_label" - text_color="LtGray" - top_pad="10" - value="Username:" - width="70" /> - <text - follows="top|left" - height="20" - layout="topleft" - left_pad="0" - name="user_slid" - text_color="EmphasisColor" - font="SansSerifBold" - top_delta="-2" - translate="false" - use_ellipses="true" - value="teststring.pleaseignore" - width="195" - wrap="true "/> - <tab_container - follows="all" - height="489" - halign="center" - layout="topleft" - left="5" - min_width="333" - name="tabs" - tab_min_width="80" - tab_height="30" - tab_position="top" - top_pad="5" - width="317"> - <panel - class="panel_profile" - filename="panel_profile.xml" - label="PROFILE" - layout="topleft" - help_topic="profile_profile_tab" - name="panel_profile" /> - <panel - class="panel_picks" - filename="panel_picks.xml" - label="PICKS" - layout="topleft" - help_topic="profile_picks_tab" - name="panel_picks" /> - <panel - class="panel_notes" - filename="panel_notes.xml" - label="NOTES & PRIVACY" - layout="topleft" - help_topic="profile_notes_tab" - name="panel_notes" /> - </tab_container> -</panel> 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_covenant.xml b/indra/newview/skins/default/xui/en/panel_region_covenant.xml index df16f6fd37..112f12500d 100644 --- a/indra/newview/skins/default/xui/en/panel_region_covenant.xml +++ b/indra/newview/skins/default/xui/en/panel_region_covenant.xml @@ -57,7 +57,7 @@ mouse_opaque="false" name="estate_name_text" top_delta="0" - width="150"> + width="350"> mainland </text> <text @@ -79,7 +79,7 @@ mouse_opaque="false" name="estate_owner_text" top_delta="0" - width="150"> + width="350"> (none) </text> <text diff --git a/indra/newview/skins/default/xui/en/panel_region_debug.xml b/indra/newview/skins/default/xui/en/panel_region_debug.xml index 4550603134..81b2281adb 100644 --- a/indra/newview/skins/default/xui/en/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/en/panel_region_debug.xml @@ -194,11 +194,11 @@ <button follows="left|top" height="20" - label="Delay Restart" + label="Cancel Restart" layout="topleft" left_pad="155" name="cancel_restart_btn" - tool_tip="Delay region restart by one hour" + tool_tip="Cancel region restart" top_delta="0" width="150" /> </panel> 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..76a82212ae 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="Are age 18 or older" 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 18 or older 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..765b07ed8b 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" @@ -148,6 +158,7 @@ text_readonly_color="DkGray" width="487" show_line_numbers="true" + enable_tooltip_paste="true" word_wrap="true"> Loading... </text_editor> diff --git a/indra/newview/skins/default/xui/en/panel_script_question_toast.xml b/indra/newview/skins/default/xui/en/panel_script_question_toast.xml new file mode 100644 index 0000000000..b0436bb6dc --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_script_question_toast.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<panel + background_opaque="false" + border_visible="false" + background_visible="true" + bg_alpha_color="PanelNotificationBackground" + bg_opaque_color="PanelNotificationBackground" + chrome="true" + height="270" + label="script_question_panel" + layout="topleft" + left="0" + name="panel_script_question_toast" + top="0" + width="305"> + <text + follows="left|right|top" + font="SansSerifBold" + height="160" + layout="topleft" + left="10" + mouse_opaque="false" + name="top_info_message" + parse_highlights="true" + parse_urls="true" + text_color="NotifyCautionBoxColor" + top="10" + value="" + width="285" + wrap="true"/> + <panel + background_visible="false" + follows="left|right|top" + height="30" + label="buttons_panel" + layout="topleft" + name="buttons_panel" + top_pad="10" + width="285"> + </panel> + <text + follows="all" + font="SansSerifBold" + height="55" + layout="topleft" + mouse_opaque="false" + name="bottom_info_message" + parse_highlights="true" + parse_urls="true" + text_color="NotifyCautionBoxColor" + top_pad="5" + value="" + width="285" + wrap="true"/> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml index 9057ebb65e..71d808fa4b 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml @@ -114,6 +114,7 @@ width="95" /> <check_box bottom_delta="20" + height="10" follows="left|top" label="Constrain proportions" layout="topleft" 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..781ab17403 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" @@ -133,6 +132,7 @@ width="95" /> <check_box bottom_delta="20" + height="10" follows="left|top" label="Constrain proportions" layout="topleft" @@ -145,7 +145,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..0dd357aa1a 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" @@ -120,6 +119,7 @@ top_delta="0" width="95" /> <check_box + height="10" bottom_delta="20" label="Constrain proportions" layout="topleft" @@ -132,7 +132,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..dd2a0c6627 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -35,8 +35,8 @@ </panel.string> <panel height="18" - left="-370" - width="160" + left="-395" + width="185" top="1" follows="right|top" name="balance_bg"> @@ -67,10 +67,9 @@ label_shadow="true" name="buyL" pad_right="0" - pad_bottom="2" tool_tip="Click to buy more L$" top="0" - width="55" /> + width="80" /> <button halign="left" font="SansSerifSmall" @@ -87,8 +86,6 @@ left_pad="0" label_shadow="true" name="goShop" - pad_right="0" - pad_bottom="2" tool_tip="Open Second Life Marketplace" top="0" width="65" /> @@ -132,6 +129,5 @@ left_pad="5" top="2" name="volume_btn" - tool_tip="Global Volume Control" width="16" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_sys_well_item.xml b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml index 5e74689c5a..007b73a4bc 100644 --- a/indra/newview/skins/default/xui/en/panel_sys_well_item.xml +++ b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml @@ -13,7 +13,7 @@ follows="left|right" background_opaque="false" background_visible="true" - bg_alpha_color="0.0 0.0 0.0 0.0" > + bg_alpha_color="SysWellItemUnselected" > <text clip_partial="true" top="2" @@ -22,7 +22,7 @@ height="28" layout="topleft" follows="right|left" - text_color="white" + text_color="White" use_ellipses="true" word_wrap="true" mouse_opaque="false" diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml index c89e1dc215..c5b0be0616 100644 --- a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml +++ b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml @@ -44,7 +44,7 @@ parse_urls="false" use_ellipses="true" name="region" - text_color="white" + text_color="White" top="4" value="..." width="330" /> diff --git a/indra/newview/skins/default/xui/en/panel_toast.xml b/indra/newview/skins/default/xui/en/panel_toast.xml index b9e714dd30..37a904bca8 100644 --- a/indra/newview/skins/default/xui/en/panel_toast.xml +++ b/indra/newview/skins/default/xui/en/panel_toast.xml @@ -10,7 +10,6 @@ --> <floater - open_positioning="none" legacy_header_height="0" header_height="0" name="toast" @@ -21,7 +20,6 @@ width="310" left="0" top="0" - follows="right|bottom" background_visible="false" bg_opaque_image="Toast_Over" bg_alpha_image="Toast_Background" @@ -60,7 +58,7 @@ left="20" name="toast_text" word_wrap="true" - text_color="white" + text_color="White" top="5" translate="false" use_ellipses="true" 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..f5c559fe1d 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"> @@ -96,13 +93,12 @@ left="0" mouse_opaque="false" tab_stop="false" - name="stand_stop_flying_container" + name="state_management_buttons_container" visible="false" width="200"/> </layout_panel> - <layout_panel name="right_toolbar_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/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml index 7b22b2cce1..6adede0362 100644 --- a/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml +++ b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml @@ -8,41 +8,289 @@ border="false" chrome="true" follows="bottom" - height="150" + height="155" layout="topleft" name="volumepulldown_floater" - width="32"> - <slider - control_name="AudioLevelMaster" - follows="left|top" - left="0" - top="1" - orientation="vertical" - height="120" - increment="0.05" - initial_value="0.5" - layout="topleft" - name="mastervolume" - show_text="false" - slider_label.halign="right" - top_pad="2" - volume="true"> - <slider.commit_callback - function="Vol.setControlFalse" - parameter="MuteAudio" /> - </slider> - <button - left="10" - top_pad="9" - width="12" - height="12" - follows="top|left" - name="prefs_btn" - image_unselected="Icon_Gear_Foreground" - image_disabled="Icon_Gear_Background" - image_pressed="Icon_Gear_Press" - scale_image="false"> - <button.commit_callback - function="Vol.GoAudioPrefs" /> - </button> + width="225"> + <slider + control_name="AudioLevelMaster" + follows="top|left" + font.style="BOLD" + height="15" + increment="0.025" + initial_value="0.5" + label="Master" + label_width="60" + left="10" + width="160" + layout="topleft" + name="System Volume" + show_text="false" + top="10" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteAudio" /> + </slider> + <button + control_name="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16" /> + <slider + control_name="AudioLevelUI" + disabled_control="MuteAudio" + follows="left|top" + height="15" + increment="0.025" + initial_value="0.5" + label="Buttons" + label_width="60" + left="10" + width="160" + layout="topleft" + name="UI Volume" + show_text="false" + top_pad="4" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteUI" /> + </slider> + <button + control_name="MuteUI" + disabled_control="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16" /> + <slider + control_name="AudioLevelAmbient" + disabled_control="MuteAudio" + follows="left|top" + height="15" + increment="0.025" + initial_value="0.5" + label="Ambient" + label_width="60" + left="10" + width="160" + layout="topleft" + name="Wind Volume" + show_text="false" + top_pad="4" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteAmbient" /> + </slider> + <button + control_name="MuteAmbient" + disabled_control="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16" /> + <slider + control_name="AudioLevelSFX" + disabled_control="MuteAudio" + follows="left|top" + height="15" + increment="0.025" + initial_value="0.5" + label="Sounds" + label_width="60" + left="10" + width="160" + layout="topleft" + name="SFX Volume" + show_text="false" + top_pad="4" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteSounds" /> + </slider> + <button + control_name="MuteSounds" + disabled_control="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16"> + <button.commit_callback + function="Pref.SetSounds"/> + </button> + <check_box + name="gesture_audio_play_btn" + control_name="EnableGestureSounds" + disabled_control="MuteAudio" + height="16" + layout="topleft" + left_pad="5" + tool_tip="Enable sounds from gestures" + top_delta="2" + width="350"/> + <slider + control_name="AudioLevelMusic" + disabled_control="MuteAudio" + follows="left|top" + height="15" + increment="0.025" + initial_value="0.5" + label="Music" + label_width="60" + left="10" + width="160" + layout="topleft" + name="Music Volume" + show_text="false" + top_pad="4" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteMusic" /> + </slider> + <button + control_name="MuteMusic" + disabled_control="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16" /> + <check_box + control_name="AudioStreamingMusic" + height="16" + tool_tip="Enable Streaming Music" + layout="topleft" + left_pad="5" + name="enable_music" + top_delta="2" + width="350"> + <check_box.commit_callback + function="Pref.updateMediaAutoPlayCheckbox"/> + </check_box> + <slider + control_name="AudioLevelMedia" + disabled_control="MuteAudio" + follows="left|top" + height="16" + increment="0.025" + initial_value="0.5" + label="Media" + label_width="60" + left="10" + width="160" + layout="topleft" + name="Media Volume" + show_text="false" + top_pad="4" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteMedia" /> + </slider> + <button + control_name="MuteMedia" + disabled_control="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16" /> + <check_box + label_text.halign="left" + follows="left|top" + height="16" + control_name ="AudioStreamingMedia" + tool_tip="Enable Streaming Media" + layout="topleft" + top_delta="2" + left_pad="5" + name="enable_media" + width="110"> + <check_box.commit_callback + function="Pref.updateMediaAutoPlayCheckbox"/> + </check_box> + <slider + control_name="AudioLevelVoice" + disabled_control="MuteAudio" + follows="left|top" + height="16" + increment="0.025" + initial_value="0.5" + label="Voice" + label_width="60" + left="10" + width="160" + layout="topleft" + top_pad="4" + name="Voice Volume" + show_text="false" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteVoice" /> + </slider> + <button + control_name="MuteVoice" + disabled_control="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16" /> + <check_box + label_text.halign="left" + follows="left|top" + height="16" + control_name ="EnableVoiceChat" + disabled_control="CmdLineDisableVoice" + tool_tip="Enable Voice Chat" + layout="topleft" + top_delta="2" + left_pad="5" + name="enable_voice_check" + width="110"/> </panel> diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml index b52784d6bc..14bd349480 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" - auto_resize="true" - user_resize="false" + layout="topleft" + auto_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,14 @@ 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 + control_name="InventoryInboxToggleState" label="Received items" - font="SansSerifMedium" + font="SansSerifMedium" name="inbox_btn" height="35" width="308" @@ -127,15 +105,16 @@ [NUM] new </text> <panel + name="inbox_inventory_placeholder_panel" follows="all" left="10" - bottom="200" + bottom="235" width="308" top="35" bg_opaque_color="InventoryBackgroundColor" background_visible="true" background_opaque="true" - tool_tip="Drag and drop items to your inventory to manage and use them" + tool_tip="Drag and drop items to your inventory to use them" > <text name="inbox_inventory_placeholder" @@ -145,7 +124,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 +132,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 +158,6 @@ left="0" mouse_opaque="false" name="info_btn_lp" - user_resize="false" auto_resize="true" width="101"> <button @@ -334,7 +179,6 @@ left_pad="1" mouse_opaque="false" name="share_btn_lp" - user_resize="false" auto_resize="true" width="100"> <button @@ -356,7 +200,6 @@ left_pad="1" mouse_opaque="false" name="shop_btn_lp" - user_resize="false" auto_resize="true" width="100"> <button @@ -406,8 +249,7 @@ </layout_stack> </panel> </panel> - -<panel + <panel follows="all" layout="topleft" left="0" @@ -420,8 +262,7 @@ visible="false" width="330"> </panel> - -<panel + <panel follows="all" layout="topleft" left="0" diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index 54a312bd59..c5dfb703e5 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -11,6 +11,10 @@ name="unknown"> (unknown) </panel.string> + <panel.string + name="unknown_multiple"> + (unknown / multiple) + </panel.string> <panel.string name="public"> (public) diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml index 6600339ad7..6ee8fc3a4c 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml @@ -31,6 +31,14 @@ You can't modify these objects </panel.string> <panel.string + name="text modify info 5"> + You can't modify this object across a region boundary + </panel.string> + <panel.string + name="text modify info 6"> + You can't modify these objects across a region boundary + </panel.string> + <panel.string name="text modify warning"> This object has linked parts </panel.string> @@ -267,23 +275,27 @@ <combo_box.item label="Touch (default)" name="Touch/grab(default)" - value="Touch/grab (default)" /> + value="Touch" /> <combo_box.item label="Sit on object" name="Sitonobject" - value="Sit on object" /> + value="Sit" /> <combo_box.item label="Buy object" name="Buyobject" - value="Buy object" /> + value="Buy" /> <combo_box.item label="Pay object" name="Payobject" - value="Pay object" /> + value="Pay" /> <combo_box.item label="Open" name="Open" value="Open" /> + <combo_box.item + label="Zoom" + name="Zoom" + value="Zoom" /> </combo_box> <panel border="false" @@ -300,7 +312,7 @@ <text type="string" length="1" - left="10" + left="5" top_pad="15" text_color="EmphasisColor" height="15" @@ -448,9 +460,27 @@ tool_tip="Let people see this object in search results" /> <text type="string" + follows="left|top" + name="pathfinding_attributes_label" + top_pad="6" + width="150" + left="5"> + Pathfinding attributes: + </text> + <text + type="string" + follows="left|top" text_color="EmphasisColor" + name="pathfinding_attributes_value" + width="130" + word_wrap="false" + left_pad="0"> + </text> + <text + type="string" + text_color="EmphasisColor" length="1" - top_pad="15" + top_pad="10" follows="left|top" layout="topleft" left="10" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index befcc5dd87..5aa743b32d 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,17 +49,17 @@ <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> <string name="Quit">Quit</string> - <string name="create_account_url">http://join.secondlife.com/</string> + <string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string> <string name="LoginFailedViewerNotPermitted"> The viewer you are using can no longer access Second Life. Please visit the following page to download a new viewer: @@ -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> @@ -287,7 +295,7 @@ Please try logging in again in a minute.</string> <!-- llvoavatar. Displayed in the avatar chat bubble --> <string name="AvatarEditingAppearance">(Editing Appearance)</string> <string name="AvatarAway">Away</string> - <string name="AvatarBusy">Busy</string> + <string name="AvatarDoNotDisturb">Do Not Disturb</string> <string name="AvatarMuted">Blocked</string> <!-- animations --> @@ -361,6 +369,9 @@ Please try logging in again in a minute.</string> <string name="anim_yes_happy">Yes (Happy)</string> <string name="anim_yes_head">Yes</string> + <!-- build floater --> + <string name="multiple_textures">Multiple</string> + <!-- world map --> <string name="texture_loading">Loading...</string> <string name="worldmap_offline">Offline</string> @@ -373,6 +384,8 @@ Please try logging in again in a minute.</string> <string name="ST_NO_JOINT">Can't find ROOT or JOINT.</string> <!-- Chat --> + <string name="NearbyChatTitle">Nearby chat</string> + <string name="NearbyChatLabel">(Nearby chat)</string> <string name="whisper">whispers:</string> <string name="shout">shouts:</string> <string name="ringing">Connecting to in-world Voice Chat...</string> @@ -382,6 +395,7 @@ Please try logging in again in a minute.</string> <string name="reconnect_nearby">You will now be reconnected to Nearby Voice Chat</string> <string name="ScriptQuestionCautionChatGranted">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS].</string> <string name="ScriptQuestionCautionChatDenied">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS].</string> + <string name="AdditionalPermissionsRequestHeader">If you allow access to your account, you will also be allowing the object to:</string> <string name="ScriptTakeMoney">Take Linden dollars (L$) from you</string> <string name="ActOnControlInputs">Act on your control inputs</string> <string name="RemapControlInputs">Remap your control inputs</string> @@ -392,8 +406,10 @@ Please try logging in again in a minute.</string> <string name="AddAndRemoveJoints">Add and remove joints with other objects</string> <string name="ChangePermissions">Change its permissions</string> <string name="TrackYourCamera">Track your camera</string> - <string name="ControlYourCamera">Control your camera</string> + <string name="ControlYourCamera">Control your camera</string> <string name="NotConnected">Not Connected</string> + <string name="AgentNameSubst">(You)</string> <!-- Substitution for agent name --> + <string name="TeleportYourAgent">Teleport you</string> <!-- Sim Access labels --> <string name="SIM_ACCESS_PG">General</string> @@ -427,9 +443,11 @@ 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> + <string name="dictionary_files">Dictionaries</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. @@ -657,7 +675,7 @@ Sets the texture u & v scales for the chosen face or ALL_SIDES </string> <string name="LSLTipText_llOffsetTexture" translate="false"> llOffsetTexture(float u, float v, integer face) -Sets the texture u & v offsets for the chosen face or ALL_SIDES +Sets the texture u & v offsets for the chosen face or ALL_SIDES </string> <string name="LSLTipText_llRotateTexture" translate="false"> llRotateTexture(float rotation, integer face) @@ -775,9 +793,9 @@ Sets the script timer to zero float llGetAndResetTime() Returns the script time in seconds and then resets the script timer to zero </string> - <string name="LSLTipText_llSoplayund" translate="false"> + <string name="LSLTipText_llSound" translate="false"> llSound(string sound, float volume, integer queue, integer loop) -Plays sound at volume and whether it should loop or not +Plays sound at volume and whether it should loop or not. </string> <string name="LSLTipText_llPlaySound" translate="false"> llPlaySound(string sound, float volume) @@ -1432,7 +1450,7 @@ integer llScriptDanger(vector pos) Returns TRUE if pos is over public land, sandbox land, land that doesn't allow everyone to edit and build, or land that doesn't allow outside scripts </string> <string name="LSLTipText_llDialog" translate="false"> -llDialog(key avatar, string message, list buttons, integer chat_channel +llDialog(key avatar, string message, list buttons, integer chat_channel) Shows a dialog box on the avatar's screen with a message and up to 12 buttons. If a button is pressed, the avatar says the text of the button label on chat_channel. </string> @@ -1653,7 +1671,7 @@ Returns a list containing results of the sent query </string> <string name="LSLTipText_llModPow" translate="false"> integer llModPow(integer a, integer b, integer c) -Returns a raised to the b power, mod c. ( (a**b)%c ) +Returns a raised to the b power, mod c. ( (a**b)%c ) b is capped at 0xFFFF (16 bits). </string> <string name="LSLTipText_llGetInventoryType" translate="false"> @@ -1766,10 +1784,10 @@ integer llGetParcelMaxPrims(vector pos, integer sim_wide) Returns the maximum number of prims allowed on the parcel at pos </string> <string name="LSLTipText_llGetParcelDetails" translate="false"> - list llGetParcelDetails(vector pos, list params) - Returns the parcel details specified in params for the parcel at pos. - Params is one or more of: PARCEL_DETAILS_NAME, _DESC, _OWNER, _GROUP, _AREA, _ID, _SEE_AVATARS - </string> +list llGetParcelDetails(vector pos, list params) +Returns the parcel details specified in params for the parcel at pos. +Params is one or more of: PARCEL_DETAILS_NAME, _DESC, _OWNER, _GROUP, _AREA, _ID, _SEE_AVATARS + </string> <string name="LSLTipText_llSetLinkPrimitiveParams" translate="false"> llSetLinkPrimitiveParams(integer linknumber, list rules) Sets primitive parameters for linknumber based on rules @@ -1858,78 +1876,203 @@ Releases the specified URL, it will no longer be usable <string name="LSLTipText_llHTTPResponse" translate="false"> llHTTPResponse(key request_id, integer status, string body) Responds to request_id with status and body - </string> + </string> <string name="LSLTipText_llGetHTTPHeader" translate="false"> string llGetHTTPHeader(key request_id, string header) Returns the value for header for request_id </string> - <string name="LSLTipText_llSetPrimMediaParams" translate="false"> + <string name="LSLTipText_llSetPrimMediaParams" translate="false"> llSetPrimMediaParams(integer face, list params) Sets the media params for a particular face on an object. If media is not already on this object, add it. List is a set of name/value pairs in no particular order. Params not specified are unchanged, or if new media is added then set to the default specified. The possible names are below, along with the types of values and what they mean. - </string> - <string name="LSLTipText_llGetPrimMediaParams" translate="false"> + </string> + <string name="LSLTipText_llGetPrimMediaParams" translate="false"> list llGetPrimMediaParams(integer face, list params) Returns the media params for a particular face on an object, given the desired list of names, in the order requested. (Returns an empty list if no media exists on the face.) - </string> - <string name="LSLTipText_llClearPrimMedia" translate="false"> + </string> + <string name="LSLTipText_llClearPrimMedia" translate="false"> llClearPrimMedia(integer face) Clears (deletes) the media and all params from the given face. - </string> -<string name="LSLTipText_llSetLinkPrimitiveParamsFast" translate="false"> + </string> + <string name="LSLTipText_llSetLinkPrimitiveParamsFast" translate="false"> llSetLinkPrimitiveParamsFast(integer linknumber,list rules) Set primitive parameters for linknumber based on rules. -</string> -<string name="LSLTipText_llGetLinkPrimitiveParams" translate="false"> + </string> + <string name="LSLTipText_llGetLinkPrimitiveParams" translate="false"> llGetLinkPrimitiveParams(integer linknumber,list rules) Get primitive parameters for linknumber based on rules. -</string> -<string name="LSLTipText_llLinkParticleSystem" translate="false"> + </string> + <string name="LSLTipText_llLinkParticleSystem" translate="false"> llLinkParticleSystem(integer linknumber,list rules) Creates a particle system based on rules. Empty list removes particle system from object. List format is [ rule1, data1, rule2, data2 . . . rulen, datan ]. -</string> -<string name="LSLTipText_llSetLinkTextureAnim" translate="false"> + </string> + <string name="LSLTipText_llSetLinkTextureAnim" translate="false"> llSetLinkTextureAnim(integer link, integer mode, integer face, integer sizex, integer sizey, float start, float length, float rate) -Animate the texture on the specified prim's face/faces. -</string> -<string name="LSLTipText_llGetLinkNumberOfSides" translate="false"> +Animate the texture on the specified prim's face/faces. + </string> + <string name="LSLTipText_llGetLinkNumberOfSides" translate="false"> integer llGetLinkNumberOfSides(integer link) Returns the number of sides of the specified linked prim. -</string> -<string name="LSLTipText_llGetUsername" translate="false"> + </string> + <string name="LSLTipText_llGetUsername" translate="false"> string llGetUsername(key id) Returns the single-word username of an avatar, iff the avatar is in the current region, otherwise the empty string. -</string> -<string name="LSLTipText_llRequestUsername" translate="false"> + </string> + <string name="LSLTipText_llRequestUsername" translate="false"> key llRequestUsername(key id) Requests single-word username of an avatar. When data is available the dataserver event will be raised. -</string> -<string name="LSLTipText_llGetDisplayName" translate="false"> - string llGetDisplayName(key id) - Returns the name of an avatar, iff the avatar is in the current simulator, and the name has been cached, otherwise the same as llGetUsername. Use llRequestDisplayName if you absolutely must have the display name. -</string> -<string name="LSLTipText_llRequestDisplayName" translate="false"> + </string> + <string name="LSLTipText_llGetDisplayName" translate="false"> +string llGetDisplayName(key id) +Returns the name of an avatar, iff the avatar is in the current simulator, and the name has been cached, otherwise the same as llGetUsername. Use llRequestDisplayName if you absolutely must have the display name. + </string> + <string name="LSLTipText_llRequestDisplayName" translate="false"> key llRequestDisplayName(key id) Requests name of an avatar. When data is available the dataserver event will be raised. -</string> -<string name="LSLTipText_llRegionSayTo" translate="false"> -llRegionSayTo(key target, integer channel, string msg) -Sends msg on channel (not DEBUG_CHANNEL) directly to prim or avatar target anywhere within the region -</string> -<string name="LSLTipText_llGetEnv" translate="false"> + </string> + <string name="LSLTipText_llGetEnv" translate="false"> llGetEnv(string name) Returns a string with the requested data about the region -</string> - + </string> + <string name="LSLTipText_llCastRay" translate="false"> +llCastRay(vector start, vector end, list params) +Casts a ray into the physics world from 'start' to 'end' and returns data according to details in params. + </string> + <string name="LSLTipText_llRegionSayTo" translate="false"> +llRegionSayTo(key target, integer channel, string msg) +Sends msg on channel (not DEBUG_CHANNEL) directly to prim or avatar target anywhere within the region. + </string> + <string name="LSLTipText_llGetSPMaxMemory" translate="false"> +integer llGetSPMaxMemory() +Returns the maximum used memory for the current script. Only valid after using PROFILE_SCRIPT_MEMORY. Non-mono scripts always use 16k. + </string> + <string name="LSLTipText_llGetUsedMemory" translate="false"> +integer llGetUsedMemory() +Returns the current used memory for the current script. Non-mono scripts always use 16k. + </string> + <string name="LSLTipText_llScriptProfiler" translate="false"> +llScriptProfiler(integer flags) +Enabled or disables script profiling options. Currently only supports PROFILE_SCRIPT_MEMORY (mono only) and PROFILE_NONE. +MAY SIGNIFICANTLY REDUCE SCRIPT PERFORMANCE! + </string> + <string name="LSLTipText_llSetMemoryLimit" translate="false"> +integer llSetMemoryLimit(integer mem) + </string> + <string name="LSLTipText_llGetMemoryLimit" translate="false"> +integer llGetMemoryLimit() + </string> + <string name="LSLTipText_llSetLinkMedia" translate="false"> +llSetLinkMedia(integer link, integer face, list params) +Set the media params for a particular face on linked prim. List is a set of name/value pairs (in no particular order). The possible names are below, along with the types of values and what they mean. If media is not already on this object, add it. Params not specified are unchanged, or if new media is added set to the default specified. + </string> + <string name="LSLTipText_llGetLinkMedia" translate="false"> +list llGetLinkMedia(integer link, integer face, list params) +Get the media params for a particular face on linked prim, given the desired list of names. Returns a list of values in the order requested. Returns an empty list if no media exists on the face. + </string> + <string name="LSLTipText_llClearLinkMedia" translate="false"> +llClearLinkMedia(integer link, integer face) +Clears (deletes) the media and all params from the given face on linked prim. + </string> + <string name="LSLTipText_llSetContentType" translate="false"> +llSetContentType(key id, integer content_type) + </string> + <string name="LSLTipText_llLinkSitTarget" translate="false"> +llLinkSitTarget(integer link, vector offset, rotation rot) +Set the sit location for this object (if offset == <0,0,0> clear it) + </string> + <string name="LSLTipText_llAvatarOnLinkSitTarget" translate="false"> +key llAvatarOnLinkSitTarget(integer link) +If an avatar is sitting on the sit target, return the avatar's key, NULL_KEY otherwise + </string> + <string name="LSLTipText_llSetLinkCamera" translate="false"> +llSetLinkCamera(integer link, vector eye, vector at) + </string> + <string name="LSLTipText_llSetVelocity" translate="false"> +llSetVelocity(vector velocity, integer local) +Sets an objects velocity, in local coords if local == TRUE (if the script is physical) + </string> + <string name="LSLTipText_llSetAngularVelocity" translate="false"> +llSetAngularVelocity(vector angular_velocity, integer local) +Sets an objects angular velocity, in local coords if local == TRUE (if the script is physical) + </string> + <string name="LSLTipText_llSetPhysicsMaterial" translate="false"> +llSetPhysicsMaterial(integer flags, float gravity_multiplier, float restitution, float friction, float density ) +Sets the requested attributes of the root object's physics material. + </string> + <string name="LSLTipText_llGetPhysicsMaterial" translate="false"> +llGetPhysicsMaterial() returns the gravity multiplier, restitution, friction, and density of the linkset as a list in that order. + </string> + <string name="LSLTipText_llGetMassMKS" translate="false"> +llGetMassMKS() returns the mass of the linkset in kilograms. + </string> + <string name="LSLTipText_llGenerateKey" translate="false"> +llGenerateKey() +Retun a unique generated key + </string> + <string name="LSLTipText_llSetKeyframedMotion" translate="false"> +llSetKeyframedMotion(list keyframes, list options) +Requests that a nonphysical object be keyframed according to keyframe list. + </string> + <string name="LSLTipText_llTransferLindenDollars" translate="false"> +key llTransferLindenDollars(key destination, integer amount) +Transfer amount of linden dollars (L$) from script owner to destination. Returns a key to a corresponding transaction_result event for the success of the transfer. + </string> + <string name="LSLTipText_llGetParcelMusicURL" translate="false"> +string llGetParcelMusicURL() +Gets the streaming audio URL for the parcel of land on which the object is located. + </string> + <string name="LSLTipText_llSetRegionPos" translate="false"> +integer llSetRegionPos(vector pos) +Sets the position anywhere within the region (if the object isn't physical) + </string> + <string name="LSLTipText_llNavigateTo" translate="false"> +llNavigateTo(vector point, list options) +For AI Character: Navigate to destination. + </string> + <string name="LSLTipText_llCreateCharacter" translate="false"> +llCreateCharacter(list options) +Convert linkset to AI Character which can navigate the world. + </string> + <string name="LSLTipText_llPursue" translate="false"> +llPursue(key target, list options) +For AI Character: Chase after a target. + </string> + <string name="LSLTipText_llWanderWithin" translate="false"> +llWanderWithin(vector center, float radius, list options) +For AI Character: Wander within a specified volume. + </string> + <string name="LSLTipText_llFleeFrom" translate="false"> +llFleeFrom(vector source, float radius, list options) +For AI Character: Flee from a point. + </string> + <string name="LSLTipText_llPatrolPoints" translate="false"> +llPatrolPoints(list points, list options) +For AI Character: Patrol a list of points. + </string> + <string name="LSLTipText_llExecCharacterCmd" translate="false"> +llExecCharacterCmd(integer cmd, list options) +For AI Character: Execute a character command. + </string> + <string name="LSLTipText_llDeleteCharacter" translate="false"> +llDeleteCharacter() +Convert linkset from AI Character to Physics object. + </string> + <string name="LSLTipText_llUpdateCharacter" translate="false"> +llUpdateCharacter(list options) +Change the AI Character's settings. + </string> + <string name="LSLTipText_llEvade" translate="false"> +llEvade(key target, list options) +For AI Character: Evade a specified target. + </string> + <string name="LSLTipText_llGetClosestNavPoint" translate="false"> +list llGetClosestNavPoint(vector point, list options) +For AI Character: Get the closest navigable point to the point provided. + </string> - <!-- Avatar busy/away mode --> - <string name="AvatarSetNotAway">Not Away</string> - <string name="AvatarSetAway">Away</string> - <string name="AvatarSetNotBusy">Not Busy</string> - <string name="AvatarSetBusy">Busy</string> <!-- Wearable Types --> <string name="shape">Shape</string> @@ -1950,7 +2093,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 +2130,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 +2171,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">Your Marketplace purchases will appear here. You may then drag them into your inventory to use them.</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> @@ -2120,19 +2267,26 @@ Returns a string with the requested data about the region <string name="InvFolder Gestures">Gestures</string> <string name="InvFolder Favorite">My Favorites</string> <!-- historically default name of the Favorites folder can start from either "f" or "F" letter. - We should localize both of them with the same value --> + Also, it can be written as "Favorite" or "Favorites". + We should localize all variants of them with the same value --> <string name="InvFolder favorite">My Favorites</string> + <string name="InvFolder Favorites">My Favorites</string> + <string name="InvFolder favorites">My Favorites</string> <string name="InvFolder Current Outfit">Current Outfit</string> <string name="InvFolder Initial Outfits">Initial Outfits</string> <string name="InvFolder My Outfits">My Outfits</string> <string name="InvFolder Accessories">Accessories</string> <string name="InvFolder Meshes">Meshes</string> + <string name="InvFolder Received Items">Received Items</string> + <string name="InvFolder Merchant Outbox">Merchant Outbox</string> <!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694--> <string name="InvFolder Friends">Friends</string> + <string name="InvFolder Received Items">Received Items</string> <string name="InvFolder All">All</string> <string name="no_attachments">No attachments worn</string> + <string name="Attachments remain">Attachments ([COUNT] slots remain)</string> <!-- inventory FVBridge --> <!-- This is used in llpanelinventory.cpp when constructing a context menu for an item for Sale --> @@ -2313,7 +2467,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> @@ -2353,7 +2507,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> @@ -2366,10 +2520,10 @@ 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 'busy mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing.</string> + <string name="DoNotDisturbModeResponseDefault">This resident has turned on 'Do Not Disturb' and will see your message later.</string> <!-- Mute --> <string name="MuteByName">(By name)</string> @@ -2396,7 +2550,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> @@ -2428,9 +2582,6 @@ Returns a string with the requested data about the region <string name="GroupMoneyDebits">Debits</string> <string name="GroupMoneyDate">[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]</string> - <!-- viewer object --> - <string name="ViewerObjectContents">Contents</string> - <!-- Viewer menu --> <string name="AcquiredItems">Acquired Items</string> <string name="Cancel">Cancel</string> @@ -3175,8 +3326,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="LocationCtrlAdultIconTooltip">Adult Region</string> <string name="LocationCtrlModerateIconTooltip">Moderate Region</string> <string name="LocationCtrlGeneralIconTooltip">General Region</string> - <string name="LocationCtrlSeeAVsTooltip">Avatars visible and chat allowed outside of this parcel</string> - + <string name="LocationCtrlSeeAVsTooltip">Avatars inside this parcel cannot be seen or heard by avatars outside this parcel</string> + <string name="LocationCtrlPathfindingDirtyTooltip">Objects that move may not behave correctly in this region until the region is rebaked.</string> + <string name="LocationCtrlPathfindingDisabledTooltip">Dynamic pathfinding is not enabled on this region.</string> <!-- Strings used by the (currently Linux) auto-updater app --> <string name="UpdaterWindowTitle"> [APP_NAME] Update @@ -3224,12 +3376,16 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="IM_to_label">To</string> <string name="IM_moderator_label">(Moderator)</string> <string name="Saved_message">(Saved [LONG_TIMESTAMP])</string> + <string name="IM_unblock_only_groups_friends">To see this message, you must uncheck 'Only friends and groups can call or IM me' in Preferences/Privacy.</string> + <string name="OnlineStatus">Online</string> + <string name="OfflineStatus">Offline</string> <!-- voice calls --> <string name="answered_call">Your call has been answered</string> <string name="you_started_call">You started a voice call</string> <string name="you_joined_call">You joined the voice call</string> - <string name="name_started_call">[NAME] started a voice call</string> + <string name="you_auto_rejected_call-im">You automatically rejected the voice call while 'Do Not Disturb' was on.</string> + <string name="name_started_call">[NAME] started a voice call</string> <string name="ringing-im"> Joining voice call... @@ -3244,7 +3400,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. Connecting... </string> <string name="conference-title"> - Ad-hoc Conference + Multi-person chat </string> <string name="conference-title-incoming"> Conference with [AGENT_NAME] @@ -3273,7 +3429,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" --> @@ -3299,7 +3455,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"> @@ -3312,12 +3468,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> @@ -3325,7 +3481,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"> @@ -3346,9 +3502,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 --> @@ -3358,6 +3514,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="you_paid_ldollars_no_info">You paid L$[AMOUNT].</string> <string name="you_paid_ldollars_no_reason">You paid [NAME] L$[AMOUNT].</string> <string name="you_paid_ldollars_no_name">You paid L$[AMOUNT] [REASON].</string> + <string name="you_paid_failure_ldollars">You failed to pay [NAME] L$[AMOUNT] [REASON].</string> + <string name="you_paid_failure_ldollars_no_info">You failed to pay L$[AMOUNT].</string> + <string name="you_paid_failure_ldollars_no_reason">You failed to pay [NAME] L$[AMOUNT].</string> + <string name="you_paid_failure_ldollars_no_name">You failed to pay L$[AMOUNT] [REASON].</string> <string name="for item">for [ITEM]</string> <string name="for a parcel of land">for a parcel of land</string> <string name="for a land access pass">for a land access pass</string> @@ -3366,20 +3526,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--> @@ -3473,23 +3633,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> @@ -3522,7 +3682,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. @@ -3666,6 +3826,7 @@ Try enclosing path to the editor with double quotes. <string name="Command_Avatar_Label">Avatar</string> <string name="Command_Build_Label">Build</string> <string name="Command_Chat_Label">Chat</string> + <string name="Command_Conversations_Label">Conversations</string> <string name="Command_Compass_Label">Compass</string> <string name="Command_Destinations_Label">Destinations</string> <string name="Command_Gestures_Label">Gestures</string> @@ -3674,7 +3835,8 @@ Try enclosing path to the editor with double quotes. <string name="Command_Map_Label">Map</string> <string name="Command_Marketplace_Label">Marketplace</string> <string name="Command_MiniMap_Label">Mini-map</string> - <string name="Command_Move_Label">Move</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> @@ -3683,7 +3845,7 @@ Try enclosing path to the editor with double quotes. <string name="Command_Search_Label">Search</string> <string name="Command_Snapshot_Label">Snapshot</string> <string name="Command_Speak_Label">Speak</string> - <string name="Command_View_Label">View</string> + <string name="Command_View_Label">Camera controls</string> <string name="Command_Voice_Label">Voice settings</string> <string name="Command_AboutLand_Tooltip">Information about the land you're visiting</string> @@ -3691,6 +3853,7 @@ Try enclosing path to the editor with double quotes. <string name="Command_Avatar_Tooltip">Choose a complete avatar</string> <string name="Command_Build_Tooltip">Building objects and reshaping terrain</string> <string name="Command_Chat_Tooltip">Chat with people nearby using text</string> + <string name="Command_Conversations_Tooltip">Converse with everyone</string> <string name="Command_Compass_Tooltip">Compass</string> <string name="Command_Destinations_Tooltip">Destinations of interest</string> <string name="Command_Gestures_Tooltip">Gestures for your avatar</string> @@ -3700,6 +3863,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> @@ -3725,6 +3889,13 @@ Try enclosing path to the editor with double quotes. <string name="Preview">Preview</string> <string name="Normal">Normal</string> + <!-- Pathfinding --> + <string name="Pathfinding_Wiki_URL">http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer</string> + <string name="Pathfinding_Object_Attr_None">None</string> + <string name="Pathfinding_Object_Attr_Permanent">Affects navmesh</string> + <string name="Pathfinding_Object_Attr_Character">Character</string> + <string name="Pathfinding_Object_Attr_MultiSelect">(Multiple)</string> + <!-- Snapshot image quality levels --> <string name="snapshot_quality_very_low">Very Low</string> <string name="snapshot_quality_low">Low</string> @@ -3732,4 +3903,20 @@ Try enclosing path to the editor with double quotes. <string name="snapshot_quality_high">High</string> <string name="snapshot_quality_very_high">Very High</string> + <string name="TeleportMaturityExceeded">The Resident cannot visit this region.</string> + + <!-- Spell check settings floater --> + <string name="UserDictionary">[User]</string> + + <!-- Conversation log messages --> + <string name="logging_calls_disabled_log_empty"> + Conversations are not being logged. To begin keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat. + </string> + <string name="logging_calls_disabled_log_not_empty"> + No more conversations will be logged. To resume keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat. + </string> + <string name="logging_calls_enabled_log_empty"> + There are no logged conversations. After you contact someone, or someone contacts you, a log entry will be shown here. + </string> + </strings> diff --git a/indra/newview/skins/default/xui/en/teleport_strings.xml b/indra/newview/skins/default/xui/en/teleport_strings.xml index dce6b8dd6d..fdf41991cd 100644 --- a/indra/newview/skins/default/xui/en/teleport_strings.xml +++ b/indra/newview/skins/default/xui/en/teleport_strings.xml @@ -45,6 +45,9 @@ Go to 'Welcome Island Public' to repeat the tutorial. <message name="no_inventory_host"> The inventory system is currently unavailable. </message> + <message name="MustGetAgeRegion"> + You must be age 18 or over to enter this region. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -80,5 +83,8 @@ Go to 'Welcome Island Public' to repeat the tutorial. <message name="requesting"> Requesting Teleport... </message> - </message_set> + <message name="pending"> + Pending Teleport... + </message> + </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/en/widgets/avatar_list_item.xml b/indra/newview/skins/default/xui/en/widgets/avatar_list_item.xml index 1bb3188cc8..8a4ccb19f9 100644 --- a/indra/newview/skins/default/xui/en/widgets/avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/widgets/avatar_list_item.xml @@ -17,13 +17,13 @@ <voice_call_invited_style font="SansSerifSmall" font.style="NORMAL" - color="0.5 0.5 0.5 0.5"/> + color="AvatarListItemIconVoiceInvitedColor"/> <!-- styles for avatar item JOINED to voice call --> <voice_call_joined_style font="SansSerifSmall" font.style="NORMAL" - color="white"/> + color="White"/> <!-- styles for avatar item which HAS LEFT voice call --> <voice_call_left_style @@ -35,11 +35,11 @@ <online_style font="SansSerifSmall" font.style="NORMAL" - color="white"/> + color="White"/> <!-- styles for OFFLINE avatar item --> <offline_style font="SansSerifSmall" font.style="NORMAL" - color="0.5 0.5 0.5 1.0"/> + color="Gray"/> </avatar_list_item> diff --git a/indra/newview/skins/default/xui/en/widgets/bodyparts_list_item.xml b/indra/newview/skins/default/xui/en/widgets/bodyparts_list_item.xml index 0eec002006..0016a8cf53 100644 --- a/indra/newview/skins/default/xui/en/widgets/bodyparts_list_item.xml +++ b/indra/newview/skins/default/xui/en/widgets/bodyparts_list_item.xml @@ -24,7 +24,7 @@ parse_urls="false" use_ellipses="true" name="item_name" - text_color="white" + text_color="White" top="5" value="..." width="359" /> diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml index e2baba92a3..2b2c3faf91 100644 --- a/indra/newview/skins/default/xui/en/widgets/button.xml +++ b/indra/newview/skins/default/xui/en/widgets/button.xml @@ -21,7 +21,7 @@ font="SansSerifSmall" hover_glow_amount="0.15" halign="center" - pad_bottom="3" + pad_bottom="1" height="23" scale_image="true" handle_right_mouse="true" diff --git a/indra/newview/skins/default/xui/en/widgets/chat_editor.xml b/indra/newview/skins/default/xui/en/widgets/chat_editor.xml new file mode 100644 index 0000000000..f9facb593a --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/chat_editor.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<chat_editor + name="chat_editor" + show_context_menu="true"/> diff --git a/indra/newview/skins/default/xui/en/widgets/check_box.xml b/indra/newview/skins/default/xui/en/widgets/check_box.xml index cca64fad2a..8947024e45 100644 --- a/indra/newview/skins/default/xui/en/widgets/check_box.xml +++ b/indra/newview/skins/default/xui/en/widgets/check_box.xml @@ -10,7 +10,7 @@ text_readonly_color="LabelDisabledColor"/> <check_box.check_button name="CheckboxCtrl Button" left="2" - bottom="2" + bottom="1" width="13" height="13" commit_on_return="false" diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml deleted file mode 100644 index 0e29ed0d0b..0000000000 --- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml +++ /dev/null @@ -1,55 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<chiclet_im_adhoc - height="23" - name="im_adhoc_chiclet" - show_speaker="false" - width="25"> - <chiclet_im_adhoc.chiclet_button - height="25" - image_selected="PushButton_On" - image_unselected="PushButton_Off" - name="chiclet_button" - tab_stop="false" - width="25" /> - <chiclet_im_adhoc.speaker - image_mute="Parcel_VoiceNo_Light" - image_off="VoicePTT_Off_Dark" - image_on="VoicePTT_On_Dark" - image_level_1="VoicePTT_Lvl1_Dark" - image_level_2="VoicePTT_Lvl2_Dark" - image_level_3="VoicePTT_Lvl3_Dark" - auto_update="true" - draw_border="false" - height="24" - left="25" - bottom="1" - name="speaker" - visible="false" - width="20" /> - <chiclet_im_adhoc.avatar_icon - bottom="3" - follows="left|top|bottom" - height="20" - left="2" - mouse_opaque="false" - name="adhoc_icon" - width="21" /> - <chiclet_im_adhoc.unread_notifications - halign="center" - height="23" - left="25" - mouse_opaque="false" - name="unread" - text_color="white" - v_pad="3" - visible="false" - width="20" /> - <chiclet_im_adhoc.new_message_icon - bottom="11" - height="14" - image_name="Unread_Chiclet" - left="12" - name="new_message_icon" - visible="false" - width="14" /> -</chiclet_im_adhoc>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml deleted file mode 100644 index 77011139bf..0000000000 --- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<chiclet_im_group - height="23" - name="im_group_chiclet" - show_speaker="false" - width="25"> - <chiclet_im_group.chiclet_button - height="25" - image_selected="PushButton_On" - image_unselected="PushButton_Off" - name="chiclet_button" - tab_stop="false" - width="25" /> - <chiclet_im_group.speaker - image_mute="Parcel_VoiceNo_Light" - image_off="VoicePTT_Off_Dark" - image_on="VoicePTT_On_Dark" - image_level_1="VoicePTT_Lvl1_Dark" - image_level_2="VoicePTT_Lvl2_Dark" - image_level_3="VoicePTT_Lvl3_Dark" - auto_update="true" - draw_border="false" - height="24" - left="25" - bottom="1" - name="speaker" - visible="false" - width="20" /> - <chiclet_im_group.group_icon - bottom="3" - default_icon="Generic_Group" - follows="left|top|bottom" - height="20" - left="2" - mouse_opaque="false" - name="group_icon" - width="21" /> - <chiclet_im_group.unread_notifications - height="23" - halign="center" - left="25" - mouse_opaque="false" - name="unread" - text_color="white" - v_pad="3" - visible="false" - width="20"/> - <chiclet_im_group.new_message_icon -bottom="11" - height="14" - image_name="Unread_Chiclet" - left="12" - name="new_message_icon" - visible="false" - width="14" /> -</chiclet_im_group>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml deleted file mode 100644 index 8b56a8f0f6..0000000000 --- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<chiclet_im_p2p - height="23" - name="im_p2p_chiclet" - show_speaker="false" - width="25"> - <chiclet_im_p2p.chiclet_button - height="25" - image_selected="PushButton_On" - image_unselected="PushButton_Off" - name="chiclet_button" - tab_stop="false" - width="25"/> - <chiclet_im_p2p.speaker - image_mute="Parcel_VoiceNo_Light" - image_off="VoicePTT_Off_Dark" - image_on="VoicePTT_On_Dark" - image_level_1="VoicePTT_Lvl1_Dark" - image_level_2="VoicePTT_Lvl2_Dark" - image_level_3="VoicePTT_Lvl3_Dark" - auto_update="true" - draw_border="false" - height="24" - left="25" - bottom="1" - name="speaker" - visible="false" - width="20" /> - <chiclet_im_p2p.avatar_icon - bottom="3" - color="white" - follows="left|top|bottom" - height="20" - left="2" - mouse_opaque="false" - name="avatar_icon" - width="21" /> - <chiclet_im_p2p.unread_notifications - height="23" - halign="center" - left="25" - mouse_opaque="false" - name="unread" - text_color="white" - v_pad="3" - visible="false" - width="20"/> - <chiclet_im_p2p.new_message_icon - bottom="11" - height="14" - image_name="Unread_Chiclet" - left="12" - name="new_message_icon" - visible="false" - width="14" /> -</chiclet_im_p2p> diff --git a/indra/newview/skins/default/xui/en/widgets/clothing_list_item.xml b/indra/newview/skins/default/xui/en/widgets/clothing_list_item.xml index 96d72c78a6..d83f44737e 100644 --- a/indra/newview/skins/default/xui/en/widgets/clothing_list_item.xml +++ b/indra/newview/skins/default/xui/en/widgets/clothing_list_item.xml @@ -24,7 +24,7 @@ parse_urls="false" use_ellipses="true" name="item_name" - text_color="white" + text_color="White" top="5" value="..." width="359" /> diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml new file mode 100755 index 0000000000..b83d9122f7 --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<conversation_view_participant + folder_arrow_image="Folder_Arrow" + item_height="24" + item_top_pad="0" + selection_image="Rounded_Square" + mouse_opaque="true" + follows="left|top|right" + left_pad="0" + icon_pad="10" + icon_width="20" + text_pad="7" + text_pad_right="4" + arrow_size="12" + max_folder_item_overlap="2" +> +<avatar_icon + follows="left" + height="20" + default_icon_name="Generic_Person" + layout="topleft" + top="2" + width="20" /> +<info_button + follows="right" + height="16" + image_pressed="Info_Press" + image_unselected="Info_Over" + right="-28" + name="info_btn" + width="16" /> +<output_monitor + follows="right" + auto_update="true" + draw_border="false" + height="16" + right="-3" + mouse_opaque="true" + name="speaking_indicator" + visible="true" + width="20" /> +</conversation_view_participant> diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml new file mode 100644 index 0000000000..b8c39eec1d --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<conversation_view_session + folder_arrow_image="Folder_Arrow" + folder_indentation="8" + item_height="24" + item_top_pad="4" + selection_image="Rounded_Square" + mouse_opaque="true" + follows="left|top|right" + left_pad="5" + icon_pad="2" + icon_width="16" + text_pad="1" + text_pad_right="4" + arrow_size="12" + max_folder_item_overlap="2"/> diff --git a/indra/newview/skins/default/xui/en/widgets/dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/en/widgets/dummy_clothing_list_item.xml index 6c60624805..8c805da048 100644 --- a/indra/newview/skins/default/xui/en/widgets/dummy_clothing_list_item.xml +++ b/indra/newview/skins/default/xui/en/widgets/dummy_clothing_list_item.xml @@ -9,7 +9,7 @@ width="380"> <item_icon height="16" - color="0.75 0.75 0.75 1" + color="LtGray" follows="top|left" image_name="Inv_Object" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/widgets/floater.xml b/indra/newview/skins/default/xui/en/widgets/floater.xml index adbb183317..97a5ae7d4e 100644 --- a/indra/newview/skins/default/xui/en/widgets/floater.xml +++ b/indra/newview/skins/default/xui/en/widgets/floater.xml @@ -2,7 +2,7 @@ <!-- See also settings.xml UIFloater* settings for configuration --> <floater name="floater" - open_positioning="none" + positioning="none" layout="topleft" bg_opaque_color="FloaterFocusBackgroundColor" bg_alpha_color="FloaterDefaultBackgroundColor" diff --git a/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml b/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml index 6fa74f403d..bbd53ccb12 100644 --- a/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml +++ b/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml @@ -7,4 +7,10 @@ selection_image="Rounded_Square" mouse_opaque="true" follows="left|top|right" - /> + left_pad="5" + icon_pad="2" + icon_width="16" + text_pad="1" + text_pad_right="4" + arrow_size="12" + max_folder_item_overlap="2"/> diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml index 77d8024cb2..590a4730a9 100644 --- a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml +++ b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml @@ -5,7 +5,13 @@ item_height="20" item_top_pad="4" selection_image="Rounded_Square" - > + left_pad="5" + icon_pad="2" + icon_width="16" + text_pad="1" + text_pad_right="4" + arrow_size="12" + max_folder_item_overlap="2"> <new_badge label="New" label_offset_horiz="-1" diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml index 830c27bdac..d5b10e7f51 100644 --- a/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml +++ b/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml @@ -1,2 +1,3 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<inbox_inventory_panel show_load_status="false" /> +<inbox_inventory_panel show_load_status="false" + start_folder.type="inbox"/> diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml index 44436fb6f2..61ec046649 100644 --- a/indra/newview/skins/default/xui/en/widgets/location_input.xml +++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml @@ -112,6 +112,22 @@ follows="right|top" image_name="Parcel_Health_Dark" /> + <pathfinding_dirty_icon + name="pathfinding_dirty_icon" + width="22" + height="18" + top="21" + follows="right|top" + image_name="Pathfinding_Dirty" + /> + <pathfinding_disabled_icon + name="pathfinding_disabled_icon" + width="22" + height="18" + top="21" + follows="right|top" + image_name="Pathfinding_Disabled" + /> <!-- Default text color is invisible on top of nav bar background --> <damage_text name="damage_text" 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 deleted file mode 100644 index 0792996107..0000000000 --- a/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<outbox_folder_view_folder - folder_arrow_image="Folder_Arrow" - folder_indentation="8" - item_height="20" - 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/tab_container.xml b/indra/newview/skins/default/xui/en/widgets/tab_container.xml index 3e2202b20f..0586119681 100644 --- a/indra/newview/skins/default/xui/en/widgets/tab_container.xml +++ b/indra/newview/skins/default/xui/en/widgets/tab_container.xml @@ -11,7 +11,7 @@ label_pad_left - padding to the left of tab button labels halign="center" font="SansSerifSmall" tab_height="21" - label_pad_bottom="2" + label_pad_bottom="1" label_pad_left="4"> <!-- Possible additional attributes for tabs: diff --git a/indra/newview/skins/default/xui/en/widgets/text.xml b/indra/newview/skins/default/xui/en/widgets/text.xml index 134f2d7522..2102074674 100644 --- a/indra/newview/skins/default/xui/en/widgets/text.xml +++ b/indra/newview/skins/default/xui/en/widgets/text.xml @@ -9,6 +9,7 @@ h_pad="0" allow_scroll="false" text_readonly_color="LabelTextColor" + text_tentative_color="TextFgTentativeColor" bg_writeable_color="FloaterDefaultBackgroundColor" use_ellipses="false" bg_visible="false" diff --git a/indra/newview/skins/default/xui/en/widgets/toolbar.xml b/indra/newview/skins/default/xui/en/widgets/toolbar.xml index 0aa478ace9..0ace37a5dc 100644 --- a/indra/newview/skins/default/xui/en/widgets/toolbar.xml +++ b/indra/newview/skins/default/xui/en/widgets/toolbar.xml @@ -30,9 +30,9 @@ image_overlay_alignment="left" use_ellipses="true" auto_resize="true" - button_flash_count="99999" - button_flash_rate="1.0" - flash_color="EmphasisColor"/> + button_flash_count="4" + button_flash_rate="0.5" + flash_color="BeaconColor"/> <button_icon pad_left="10" pad_right="10" image_bottom_pad="10" @@ -51,7 +51,7 @@ chrome="true" use_ellipses="true" auto_resize="true" - button_flash_count="99999" - button_flash_rate="1.0" - flash_color="EmphasisColor"/> + button_flash_count="4" + button_flash_rate="0.5" + flash_color="BeaconColor"/> </toolbar> diff --git a/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/window_shade.xml index e3f2072819..23eb2f13fb 100644 --- a/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml +++ b/indra/newview/skins/default/xui/en/widgets/window_shade.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<outbox_inventory_panel show_load_status="false" /> +<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..3696c7e12c 100644 --- a/indra/newview/skins/default/xui/es/floater_about.xml +++ b/indra/newview/skins/default/xui/es/floater_about.xml @@ -66,33 +66,34 @@ Versión del servidor de voz: [VOICE_VERSION] </panel> <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. + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion + APR Copyright (C) 2011 The Apache Software Foundation + Collada DOM Copyright 2006 Sony Computer Entertainment Inc. + cURL Copyright (C) 1996-2010, 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, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. + 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) 2002, Xiphophorus + OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. + PCRE Copyright (c) 1997-2012 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-2012 Jean-loup Gailly and Mark Adler. -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..f8c40d798a 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 > 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 'empujones' (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 'seguro', desactivando el daño en combate. Si no, se activa el daño en combate."/> <check_box label="Sin 'empujones'" 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: + Los avatares de otras parcelas pueden ver 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> @@ -461,12 +460,12 @@ los media: <text name="Limit access to this parcel to:"> Acceso a esta parcela </text> - <check_box label="Permitir el acceso público [MATURITY]" name="public_access"/> + <check_box label="Permitir el acceso público (si no seleccionas esta opción, se crearán lÃneas de prohibición)" name="public_access"/> <text name="Only Allow"> - Restringir el acceso a residentes verificados con: + Permitir únicamente el acceso a los Residentes que: </text> - <check_box label="Información de pago aportada [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Expulsa a los Residentes no identificados."/> - <check_box label="Verificación de edad [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Expulsa a los Residentes que no hayan verificado su edad. Más información en [SUPPORT_SITE]."/> + <check_box label="Han aportado información de pago [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Para poder acceder a esta parcela los Residentes deben haber aportado información de pago en su cuenta. Para más información, ver [SUPPORT_SITE]."/> + <check_box label="Son mayores de 18 años [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Para poder acceder a esta parcela los Residentes deben ser mayores de 18 años. Para más información, consulta [SUPPORT_SITE]."/> <check_box label="Acceso permitido al grupo: [GROUP]" name="GroupCheck" tool_tip="Elija el grupo en la pestaña General."/> <check_box label="Vender pases a:" name="PassCheck" tool_tip="Permitir acceso temporal a esta parcela"/> <combo_box name="pass_combo"> diff --git a/indra/newview/skins/default/xui/es/floater_animation_preview.xml b/indra/newview/skins/default/xui/es/floater_animation_preview.xml deleted file mode 100644 index d57405f7e5..0000000000 --- a/indra/newview/skins/default/xui/es/floater_animation_preview.xml +++ /dev/null @@ -1,187 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview" title=""> - <floater.string name="failed_to_initialize"> - Fallo al iniciar el movimiento - </floater.string> - <floater.string name="anim_too_long"> - El archivo de la animación dura [LENGTH] segundos. - -La duración máxima de una animación es de [MAX_LENGTH] segundos. - </floater.string> - <floater.string name="failed_file_read"> - No se ha podido leer el archivo de la animación. - -[STATUS] - </floater.string> - <floater.string name="E_ST_OK"> - OK - </floater.string> - <floater.string name="E_ST_EOF"> - Fin prematuro del archivo. - </floater.string> - <floater.string name="E_ST_NO_CONSTRAINT"> - No se puede leer la definición de la restricción. - </floater.string> - <floater.string name="E_ST_NO_FILE"> - No se puede abrir el archivo BVH. - </floater.string> - <floater.string name="E_ST_NO_HIER"> - 'HIERARCHY header' inválido. - </floater.string> - <floater.string name="E_ST_NO_JOINT"> - No se pueden encontrar 'ROOT' o 'JOINT'. - </floater.string> - <floater.string name="E_ST_NO_NAME"> - No se puede obtener el nombre 'JOINT'. - </floater.string> - <floater.string name="E_ST_NO_OFFSET"> - No se puede encontrar 'OFFSET'. - </floater.string> - <floater.string name="E_ST_NO_CHANNELS"> - No se puede encontrar 'CHANNELS'. - </floater.string> - <floater.string name="E_ST_NO_ROTATION"> - No se puede conseguir el orden de la rotación. - </floater.string> - <floater.string name="E_ST_NO_AXIS"> - No se puede encontrar el eje de rotación. - </floater.string> - <floater.string name="E_ST_NO_MOTION"> - No se puede encontrar 'MOTION'. - </floater.string> - <floater.string name="E_ST_NO_FRAMES"> - No se puede conseguir el número de frames. - </floater.string> - <floater.string name="E_ST_NO_FRAME_TIME"> - No se puede conseguir el tiempo del frame. - </floater.string> - <floater.string name="E_ST_NO_POS"> - No se pueden conseguir los valores de la posición. - </floater.string> - <floater.string name="E_ST_NO_ROT"> - No se pueden conseguir los valores de la rotación. - </floater.string> - <floater.string name="E_ST_NO_XLT_FILE"> - No se puede abrir el archivo de traducción. - </floater.string> - <floater.string name="E_ST_NO_XLT_HEADER"> - No se puede leer el encabezamiento de la traducción. - </floater.string> - <floater.string name="E_ST_NO_XLT_NAME"> - No se puede leer la traducción de los nombres. - </floater.string> - <floater.string name="E_ST_NO_XLT_IGNORE"> - No se puede leer la traducción de los valores ignorados. - </floater.string> - <floater.string name="E_ST_NO_XLT_RELATIVE"> - No se puede leer el valor relativo de la traducción. - </floater.string> - <floater.string name="E_ST_NO_XLT_OUTNAME"> - No se puede leer la traducción del valor 'outname' - </floater.string> - <floater.string name="E_ST_NO_XLT_MATRIX"> - No se puede leer la matriz de traducciones. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGECHILD"> - No se puede conseguir el nombre 'mergechild'. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGEPARENT"> - No se puede conseguir el nombre 'mergeparent'. - </floater.string> - <floater.string name="E_ST_NO_XLT_PRIORITY"> - No se puede obtener el valor prioritario. - </floater.string> - <floater.string name="E_ST_NO_XLT_LOOP"> - No se puede conseguir el valor del bucle. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEIN"> - No se pueden conseguir los valores 'easeIn'. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEOUT"> - No se pueden conseguir los valores 'easeOut'. - </floater.string> - <floater.string name="E_ST_NO_XLT_HAND"> - No se puede conseguir el valor de 'hand morph'. - </floater.string> - <floater.string name="E_ST_NO_XLT_EMOTE"> - No se puede leer el nombre del gesto. - </floater.string> - <floater.string name="E_ST_BAD_ROOT"> - Nombre incorrecto de 'root joint', usa "hip". - </floater.string> - <text name="name_label"> - Nombre: - </text> - <text name="description_label"> - Descripción: - </text> - <spinner label="Prioridad:" name="priority" tool_tip="Controla qué otras animaciones pueden ser anuladas por ésta"/> - <check_box label="Bucle:" name="loop_check" tool_tip="Hace esta animación en bucle"/> - <spinner label="Empieza(%)" name="loop_in_point" tool_tip="Indica el punto en el que la animación vuelve a empezar"/> - <spinner label="Acaba(%)" name="loop_out_point" tool_tip="Indica el punto en el que la animación acaba el bucle"/> - <text name="hand_label"> - Posición de las manos - </text> - <combo_box name="hand_pose_combo" tool_tip="Controla qué hacen las manos durante la animación"> - <combo_box.item label="Extendidas" name="Spread"/> - <combo_box.item label="Relajadas" name="Relaxed"/> - <combo_box.item label="Ambas señalan" name="PointBoth"/> - <combo_box.item label="Puño" name="Fist"/> - <combo_box.item label="La izq. relajada" name="RelaxedLeft"/> - <combo_box.item label="La izq. señala" name="PointLeft"/> - <combo_box.item label="Puño izq." name="FistLeft"/> - <combo_box.item label="La der. relajada" name="RelaxedRight"/> - <combo_box.item label="La der. señala" name="PointRight"/> - <combo_box.item label="Puño der." name="FistRight"/> - <combo_box.item label="La derecha saluda" name="SaluteRight"/> - <combo_box.item label="Escribiendo" name="Typing"/> - <combo_box.item label="'Paz' en la der." name="PeaceRight"/> - </combo_box> - <text name="emote_label"> - Expresión - </text> - <combo_box name="emote_combo" tool_tip="Controla qué hace la cara durante la animación"> - <item label="(ninguno)" name="[None]" value=""/> - <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> - <item label="Con miedo" name="Afraid" value="Miedo"/> - <item label="Enfado" name="Angry" value="Enfado"/> - <item label="Gran sonrisa" name="BigSmile" value="Gran sonrisa"/> - <item label="Aburrimiento" name="Bored" value="Aburrimiento"/> - <item label="Llorar" name="Cry" value="Lloro"/> - <item label="Desdén" name="Disdain" value="Desdén"/> - <item label="Avergonzarse" name="Embarrassed" value="Vergüenza"/> - <item label="Fruncir el ceño" name="Frown" value="Fruncir el ceño"/> - <item label="Beso" name="Kiss" value="Beso"/> - <item label="ReÃr" name="Laugh" value="Risa"/> - <item label="Sacar la lengua" name="Plllppt" value="Sacar la lengua"/> - <item label="Rechazo" name="Repulsed" value="Rechazo"/> - <item label="Triste" name="Sad" value="Tristeza"/> - <item label="Encogerse de hombros" name="Shrug" value="Encogerse de hombros"/> - <item label="Sonrisa" name="Smile" value="Sonrisa"/> - <item label="Sorpresa" name="Surprise" value="Sorpresa"/> - <item label="Guiño" name="Wink" value="Guiño"/> - <item label="Preocupación" name="Worry" value="Preocupación"/> - </combo_box> - <text name="preview_label"> - Vista previa mientras - </text> - <combo_box name="preview_base_anim" tool_tip="Compruebe cómo se comporta su animación a la vez que el avatar realiza acciones comunes."> - <item label="De pie" name="Standing" value="De pie"/> - <item label="Caminando" name="Walking" value="Caminando"/> - <item label="Sentado/a" name="Sitting" value="Sentado"/> - <item label="Volando" name="Flying" value="Volando"/> - </combo_box> - <spinner label="Combinar (sec)" name="ease_in_time" tool_tip="Tiempo (en segundos) en el que se combinan las animaciones"/> - <spinner label="Dejar de combinar (sec)" name="ease_out_time" tool_tip="Tiempo (en segundos) en el que dejan de combinarse las animaciones"/> - <button bottom_delta="-32" name="play_btn" tool_tip="Ejecutar tu animación"/> - <button name="pause_btn" tool_tip="Pausar tu animación"/> - <button label="" name="stop_btn" tool_tip="Parar la repetición de la animación"/> - <slider label="" name="playback_slider"/> - <text name="bad_animation_text"> - No se ha podido leer el archivo de la animación. - -Recomendamos usar archivos BVH exportados de Poser 4. - </text> - <button label="Subir ([AMOUNT] L$)" name="ok_btn"/> - <button label="Cancelar" name="cancel_btn"/> -</floater> diff --git a/indra/newview/skins/default/xui/es/floater_autoreplace.xml b/indra/newview/skins/default/xui/es/floater_autoreplace.xml new file mode 100644 index 0000000000..15abccc376 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="Configuración de reemplazo automático"> + <check_box label="Habilitar el reemplazo automático" name="autoreplace_enable" tool_tip="Al escribir el texto del chat, reemplaza las palabras clave especificadas con la sustitución correspondiente"/> + <button label="Importar lista..." name="autoreplace_import_list" tool_tip="Carga una lista previamente exportada desde un archivo."/> + <button label="Exportar lista..." name="autoreplace_export_list" tool_tip="Guarda la lista seleccionada en un archivo para poder compartirla."/> + <button label="Lista nueva..." name="autoreplace_new_list" tool_tip="Crea una lista nueva."/> + <button label="Eliminar lista" name="autoreplace_delete_list" tool_tip="Elimina la lista seleccionada."/> + <button name="autoreplace_list_up" tool_tip="Aumenta la prioridad de esta lista."/> + <button name="autoreplace_list_down" tool_tip="Baja la prioridad de esta lista."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Palabra clave" name="keyword"/> + <scroll_list.columns label="Reemplazo" name="replacement"/> + </scroll_list> + <button label="Añadir..." name="autoreplace_add_entry"/> + <button label="Eliminar" name="autoreplace_delete_entry"/> + <button label="Guardar entrada" name="autoreplace_save_entry" tool_tip="Guarda esta entrada."/> + <button label="Guardar cambios" name="autoreplace_save_changes" tool_tip="Guarda todos los cambios."/> + <button label="Cancelar" name="autoreplace_cancel" tool_tip="Descarta todos los cambios."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </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_buy_land.xml b/indra/newview/skins/default/xui/es/floater_buy_land.xml index 9d33b69de9..005fe90318 100644 --- a/indra/newview/skins/default/xui/es/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/es/floater_buy_land.xml @@ -160,7 +160,7 @@ para cubrir esta parcela. Podrá o no unirse o dividirse. </text> <text name="covenant_text"> - Debes aceptar el Contrato del Estado: + Debes aceptar el Contrato del estado: </text> <text left="470" name="covenant_timestamp_text"/> <text_editor name="covenant_editor"> diff --git a/indra/newview/skins/default/xui/es/floater_camera.xml b/indra/newview/skins/default/xui/es/floater_camera.xml index cdcb9a146b..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> @@ -9,15 +9,6 @@ <floater.string name="move_tooltip"> Mover la cámara arriba y abajo, izquierda y derecha </floater.string> - <floater.string name="camera_modes_title"> - Modos de cámara - </floater.string> - <floater.string name="pan_mode_title"> - Orbital - Zoom - Panorámica - </floater.string> - <floater.string name="presets_mode_title"> - Vistas predefinidas - </floater.string> <floater.string name="free_mode_title"> Centrar el objeto </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..02369c9a43 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> +<floater name="nearby_chat" title="CHAT"> + <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..c351db5eae 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"> @@ -25,6 +25,10 @@ Activar VBO: </text> <check_box initial_value="true" label="Activar OpenGL Vertex Buffer Objects" name="vbo" tool_tip="En hardware moderno, habilitar esta opción mejora el rendimiento. Pero en hardware antiguo, el habilitarlo hace que, frecuentemente, se obtenga una implementación pobre de VBO, lo que puede provocarle caÃdas."/> + <text name="tc label"> + Activar S3TC: + </text> + <check_box initial_value="verdadero" label="Activar la compresión de texturas (requiere reiniciar)" name="texture compression" tool_tip="Comprime las texturas de la memoria de vÃdeo, lo cual permite cargar texturas de una resolución más alta, pero con una cierta pérdida de calidad del color."/> <slider label="Memoria para texturas (MB):" name="GraphicsCardTextureMemory" tool_tip="Cantidad de memoria asignada a las texturas. Por defecto es la memoria de la tarjeta de vÃdeo. Reducir esta cantidad puede mejorar el rendimiento, pero también hacer que las texturas se vean borrosas."/> <spinner label="Intensidad de la niebla:" name="fog"/> <button label="OK" label_selected="OK" name="OK"/> diff --git a/indra/newview/skins/default/xui/es/floater_inventory.xml b/indra/newview/skins/default/xui/es/floater_inventory.xml deleted file mode 100644 index 0f0ba2fce6..0000000000 --- a/indra/newview/skins/default/xui/es/floater_inventory.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="MI INVENTARIO"> - <floater.string name="Title"> - MI INVENTARIO - </floater.string> - <floater.string name="TitleFetching"> - MI INVENTARIO (obteniendo [ITEM_COUNT] Ãtems...) [FILTER] - </floater.string> - <floater.string name="TitleCompleted"> - MI INVENTARIO ([ITEM_COUNT] Ãtems) [FILTER] - </floater.string> - <floater.string name="Fetched"> - Obtenido - </floater.string> - <panel label="Panel del inventario" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml new file mode 100644 index 0000000000..a7c17fc136 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_merchant_outbox" title="BUZÓN DE SALIDA DE COMERCIANTE"> + <string name="OutboxFolderCount1"> + 1 carpeta + </string> + <string name="OutboxFolderCountN"> + [NUM] carpetas + </string> + <string name="OutboxImporting"> + Enviando carpetas... + </string> + <string name="OutboxInitializing"> + Inicializando... + </string> + <panel label=""> + <panel> + <panel name="outbox_inventory_placeholder_panel"> + <text name="outbox_inventory_placeholder_title"> + Cargando... + </text> + </panel> + </panel> + <panel> + <button label="Enviar al Mercado" name="outbox_import_btn" tool_tip="Poner en el escaparate de Mi Mercado"/> + </panel> + </panel> +</floater> 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..e2313bce99 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> @@ -89,19 +92,54 @@ <text initial_value="Triángulos" name="triangles" value="Triángulos"/> <text initial_value="Vértices" name="vertices" value="Vértices"/> <text initial_value="Alto" name="high_label" value="Alto"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Cargar desde archivo"/> + <item name="Generate" value="Generar"/> + </combo_box> <button label="Buscar..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="LÃmite de triángulo"/> + <item name="Error Threshold" value="Margen de error"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Medio" name="medium_label" value="Medio"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Cargar desde archivo"/> + <item name="Generate" value="Generar"/> + <item name="Use LoD above" value="Usar nivel de detalle superior"/> + </combo_box> <button label="Buscar..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="LÃmite de triángulo"/> + <item name="Error Threshold" value="Margen de error"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Bajo" name="low_label" value="Bajo"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Cargar desde archivo"/> + <item name="Generate" value="Generar"/> + <item name="Use LoD above" value="Usar nivel de detalle superior"/> + </combo_box> <button label="Buscar..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="LÃmite de triángulo"/> + <item name="Error Threshold" value="Margen de error"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="MÃnimo" name="lowest_label" value="MÃnimo"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Cargar desde archivo"/> + <item name="Generate" value="Generar"/> + <item name="Use LoD above" value="Usar nivel de detalle superior"/> + </combo_box> <button label="Buscar..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="LÃmite de triángulo"/> + <item name="Error Threshold" value="Margen de error"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Generar normales" name="gen_normals"/> diff --git a/indra/newview/skins/default/xui/es/floater_model_wizard.xml b/indra/newview/skins/default/xui/es/floater_model_wizard.xml deleted file mode 100644 index c4eb5e955a..0000000000 --- a/indra/newview/skins/default/xui/es/floater_model_wizard.xml +++ /dev/null @@ -1,205 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Model Wizard" title="CARGAR ASISTENTE DE MODELO"> - <button label="5. Subir" name="upload_btn"/> - <button label="4. Revisar" name="review_btn"/> - <button label="3. FÃsica" name="physics_btn"/> - <button label="2. Optimizar" name="optimize_btn"/> - <button label="1. Seleccionar archivo" name="choose_file_btn"/> - <panel name="choose_file_panel"> - <panel name="header_panel"> - <text name="header_text"> - Elige el archivo de modelo - </text> - </panel> - <panel name="content"> - <text name="advanced_users_text"> - Usuarios avanzados: si tienes experiencia con las herramientas de creación de contenidos 3D, quizá te interese utilizar la función de subida avanzada. - </text> - <button label="Cambiar al modo Avanzado" name="switch_to_advanced"/> - <text name="Cache location"> - Elige el archivo de modelo que deseas subir - </text> - <button label="Buscar..." label_selected="Buscar..." name="browse"/> - <text name="dimensions"> - X Y Z - </text> - <text name="warning_label"> - ATENCIÓN: - </text> - <text name="warning_text"> - No podrás completar el paso final de la subida de este modelo a los servidores de Second Life. [secondlife:///app/floater/learn_more Averigua cómo] configurar tu cuenta para subir modelos de malla. - </text> - </panel> - </panel> - <panel name="optimize_panel"> - <panel name="header_panel"> - <text name="header_text"> - Optimizar el modelo - </text> - </panel> - <text name="description"> - Hemos optimizado el rendimiento del modelo, pero puedes ajustarlo más si lo deseas. - </text> - <panel name="content"> - <text name="high_detail_text"> - Generar el nivel de detalle: Alto - </text> - <text name="medium_detail_text"> - Generar el nivel de detalle: Medio - </text> - <text name="low_detail_text"> - Generar el nivel de detalle: Bajo - </text> - <text name="lowest_detail_text"> - Generar el nivel de detalle: MÃnimo - </text> - </panel> - <panel name="content2"> - <button label="Recalcular la geometrÃa" name="recalculate_geometry_btn"/> - <text name="lod_label"> - Vista previa de geometrÃa - </text> - <combo_box name="preview_lod_combo" tool_tip="LOD para ver en renderizado de prueba"> - <combo_item name="high"> - Detalle alto - </combo_item> - <combo_item name="medium"> - Detalles medios - </combo_item> - <combo_item name="low"> - Detalle bajo - </combo_item> - <combo_item name="lowest"> - Detalles mÃnimos - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="physics_panel"> - <panel name="header_panel"> - <text name="header_text"> - Ajustar la fÃsica - </text> - </panel> - <text name="description"> - Crearemos una forma para la apariencia exterior del modelo. Ajusta el nivel de detalle de la forma según se necesite para el propósito proyectado del modelo. - </text> - <panel name="content"> - <button label="Recalcular fÃsica" name="recalculate_physics_btn"/> - <button label="Recalculando..." name="recalculating_physics_btn"/> - <text name="lod_label"> - Prueba de fÃsica - </text> - <combo_box name="preview_lod_combo2" tool_tip="LOD para ver en renderizado de prueba"> - <combo_item name="high"> - Detalle alto - </combo_item> - <combo_item name="medium"> - Detalles medios - </combo_item> - <combo_item name="low"> - Detalle bajo - </combo_item> - <combo_item name="lowest"> - Detalles mÃnimos - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="review_panel"> - <panel name="header_panel"> - <text name="header_text"> - Revisar - </text> - </panel> - <panel name="content"> - <text name="review_prim_equiv"> - Impacto en la parcela/región: [EQUIV] equivalentes en prim - </text> - <text name="review_fee"> - Cargaremos en tu cuenta el precio de subida de L$ [FEE]. - </text> - <text name="review_confirmation"> - Al pulsar en el botón de subida, confirmas que posees los derechos necesarios sobre el material que contiene el modelo. - </text> - </panel> - </panel> - <panel name="upload_panel"> - <panel name="header_panel"> - <text name="header_text"> - Subida finalizada - </text> - </panel> - <text name="model_uploaded_text"> - Se ha subido tu modelo. - </text> - <text name="inventory_text"> - Puedes buscar la carpeta Objetos en tu inventario. - </text> - <text name="charged_fee"> - Se han cargado [FEE] L$ en tu cuenta. - </text> - </panel> - <button label="<< Atrás" name="back"/> - <button label="Siguiente >>" name="next"/> - <button label="Calcular pesos y precio >>" name="calculate"/> - <button label="Calculando..." name="calculating"/> - <button label="Subir" name="upload" tool_tip="Cargar al simulador"/> - <button label="Cancelar" name="cancel"/> - <button label="Cerrar" name="close"/> - <spinner name="import_scale" value="1.0"/> - <string name="status_idle"> - Inactivo - </string> - <string name="status_parse_error"> - Problema de análisis de DAE - consulta los datos en el registro. - </string> - <string name="status_reading_file"> - Cargando... - </string> - <string name="status_generating_meshes"> - Generando redes... - </string> - <string name="status_vertex_number_overflow"> - Error: El número de intersección es superior a 65534. Cancelado. - </string> - <string name="bad_element"> - Error: el elemento no es válido - </string> - <string name="high"> - Alto - </string> - <string name="medium"> - Media - </string> - <string name="low"> - Bajo - </string> - <string name="lowest"> - MÃnimo - </string> - <string name="mesh_status_good"> - Factúralo. - </string> - <string name="mesh_status_na"> - N/A - </string> - <string name="mesh_status_none"> - Ninguno - </string> - <string name="mesh_status_submesh_mismatch"> - Los niveles de detalle poseen un número distinto de caras a las que se pueden aplicar texturas. - </string> - <string name="mesh_status_mesh_mismatch"> - Los niveles de detalle poseen un número distinto de ejemplos de red. - </string> - <string name="mesh_status_too_many_vertices"> - El nivel de detalle posee demasiadas intersecciones. - </string> - <string name="mesh_status_missing_lod"> - Falta un nivel de detalle requerido. - </string> - <string name="layer_all"> - Todo - </string> -</floater> 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_nearby_chat.xml b/indra/newview/skins/default/xui/es/floater_nearby_chat.xml deleted file mode 100644 index b3b8cdcfff..0000000000 --- a/indra/newview/skins/default/xui/es/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="CHAT"> - <check_box label="Traducir chat" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/es/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/es/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..e3ee0563d2 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="Personajes de pathfinding"> + <floater.string name="messaging_get_inprogress"> + Consultando los personajes de pathfinding... + </floater.string> + <floater.string name="messaging_get_error"> + Se ha detectado un error al consultar los personajes de pathfinding. + </floater.string> + <floater.string name="messaging_complete_none_found"> + No hay personajes de pathfinding. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] personajes seleccionados de [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + En esta región no está permitido el pathfinding. + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Cargando] + </floater.string> + <floater.string name="character_owner_unknown"> + [Desconocido] + </floater.string> + <floater.string name="character_owner_group"> + [grupo] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nombre" name="name"/> + <scroll_list.columns label="Descripción" name="description"/> + <scroll_list.columns label="Propietario" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="Altitud" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + Personajes: + </text> + <button label="Actualizar la lista" name="refresh_objects_list"/> + <button label="Seleccionar todo" name="select_all_objects"/> + <button label="No seleccionar ninguno" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + Acciones en los personajes seleccionados: + </text> + <check_box label="Mostrar baliza" name="show_beacon"/> + <check_box label="Mostrar la cápsula de fÃsica" name="show_physics_capsule"/> + <button label="Tomar" name="take_objects"/> + <button label="Tomar una copia" name="take_copy_objects"/> + <button label="Teleportarme a él" name="teleport_me_to_object" tool_tip="Se habilita solo cuando está seleccionado un personaje."/> + <button label="Devolver" name="return_objects"/> + <button label="Eliminar" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/es/floater_pathfinding_console.xml new file mode 100644 index 0000000000..e93ecc9e10 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="Vista/prueba de pathfinding"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + No se encuentra la implementación de la biblioteca de localización de rutas. + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + En esta región no está permitido el pathfinding. + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + Esperando a que termine la carga de la región. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Comprobando el estado del navmesh. + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Descargando el navmesh. + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + El navmesh se ha modificado en el servidor. Descargando el último navmesh. + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + Se ha descargado el último navmesh. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + No se puede descargar el navmesh correctamente. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + El navmesh tiene cambios pendientes. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + El navmesh se está construyendo. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + Algunas regiones del navmesh tienen cambios pendientes. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + Algunas regiones del navmesh se están construyendo. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + Algunas regiones del navmesh tienen cambios pendientes y otras se están construyendo. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + El navmesh está actualizado. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + No se encuentra la implementación de la biblioteca de localización de rutas. + </floater.string> + <floater.string name="pathing_region_not_enabled"> + En esta región no está permitido el pathfinding. + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Elige los puntos inicial y final. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Elige el punto inicial. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Elige el punto final. + </floater.string> + <floater.string name="pathing_path_valid"> + La ruta se muestra de color naranja. + </floater.string> + <floater.string name="pathing_path_invalid"> + No se encuentra una ruta entre los puntos seleccionados. + </floater.string> + <floater.string name="pathing_error"> + Error durante la generación de la ruta. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Vista" name="view_panel"> + <text name="show_label"> + Mostrar: + </text> + <check_box label="Mundo virtual" name="show_world"/> + <check_box label="Solamente los objetos movibles" name="show_world_movables_only"/> + <check_box label="Navmesh" name="show_navmesh"/> + <text name="show_walkability_label"> + Mostrar el mapa de transitabilidad: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="No mostrar" name="show_heatmap_mode_none"/> + <combo_box.item label="Personaje de tipo A" name="show_heatmap_mode_a"/> + <combo_box.item label="Personaje de tipo B" name="show_heatmap_mode_b"/> + <combo_box.item label="Personaje de tipo C" name="show_heatmap_mode_c"/> + <combo_box.item label="Personaje de tipo D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Objetos transitables" name="show_walkables"/> + <check_box label="Volúmenes materiales" name="show_material_volumes"/> + <check_box label="Obstáculos estáticos" name="show_static_obstacles"/> + <check_box label="Volúmenes de exclusión" name="show_exclusion_volumes"/> + <check_box label="Plano de agua" name="show_water_plane"/> + <check_box label="Con visión de rayos X" name="show_xray"/> + </panel> + <panel label="Probar ruta" name="test_panel"> + <text name="ctrl_click_label"> + Ctrl-clic para seleccionar el punto inicial. + </text> + <text name="shift_click_label"> + Mayús-clic para seleccionar el punto final. + </text> + <text name="character_width_label"> + Ancho del personaje + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + Tipo de personaje + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Ninguno" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Borrar ruta" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/es/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..e6f864eef5 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Linksets de pathfinding"> + <floater.string name="messaging_get_inprogress"> + Consultando los linksets de pathfinding... + </floater.string> + <floater.string name="messaging_get_error"> + Se ha detectado un error al consultar los linksets de pathfinding. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Modificando los linksets de pathfinding seleccionados... + </floater.string> + <floater.string name="messaging_set_error"> + Se ha detectado un error al modificar los linksets de pathfinding seleccionados. + </floater.string> + <floater.string name="messaging_complete_none_found"> + No hay linksets de pathfinding. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] linksets seleccionados de [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + En esta región no está permitido el pathfinding. + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terreno] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Cargando] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Desconocido] + </floater.string> + <floater.string name="linkset_owner_group"> + [grupo] + </floater.string> + <floater.string name="linkset_is_scripted"> + Sà + </floater.string> + <floater.string name="linkset_is_not_scripted"> + No + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + Desconocido + </floater.string> + <floater.string name="linkset_use_walkable"> + Objeto transitable + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Obstáculo estático + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Obstáculo móvil + </floater.string> + <floater.string name="linkset_use_material_volume"> + Volumen material + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + Volumen de exclusión + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Inmaterial móvil + </floater.string> + <floater.string name="linkset_is_terrain"> + [no modificable] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [restringido] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [cóncavo] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [restringido,cóncavo] + </floater.string> + <floater.string name="linkset_choose_use"> + Elegir la utilización del linkset... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="Filtrar por utilización de linkset..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Objeto transitable" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Obstáculo estático" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Obstáculo móvil" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Volumen material" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="Volumen de exclusión" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Inmaterial móvil" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Aplicar" name="apply_filters"/> + <button label="Limpiar" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nombre (prim raÃz)" name="name"/> + <scroll_list.columns label="Descripción (prim raÃz)" name="description"/> + <scroll_list.columns label="Propietario" name="owner"/> + <scroll_list.columns label="Con scripts" name="scripted"/> + <scroll_list.columns label="Impacto" name="land_impact"/> + <scroll_list.columns label="Distancia" name="dist_from_you"/> + <scroll_list.columns label="Utilización de linkset" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + Linksets: + </text> + <button label="Actualizar la lista" name="refresh_objects_list"/> + <button label="Seleccionar todo" name="select_all_objects"/> + <button label="No seleccionar ninguno" name="select_none_objects"/> + </panel> + <panel> + <check_box label="Mostrar baliza" name="show_beacon"/> + <button label="Tomar" name="take_objects"/> + <button label="Tomar una copia" name="take_copy_objects"/> + <button label="Teleportarme a él" name="teleport_me_to_object"/> + <button label="Devolver" name="return_objects"/> + <button label="Eliminar" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + Transitabilidad: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="Transitabilidad de los personajes de tipo A. El tipo del personaje del ejemplo es humanoide."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="Transitabilidad de los personajes de tipo B. El tipo del personaje del ejemplo es criatura."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="Transitabilidad de los personajes de tipo C. El tipo del personaje del ejemplo es mecánico."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="Transitabilidad de los personajes de tipo D. El tipo del personaje del ejemplo es otro."/> + <button label="Aplicar cambios" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Humanoide) + </text> + <text name="suggested_use_b_label"> + (Criatura) + </text> + <text name="suggested_use_c_label"> + (Mecánico) + </text> + <text name="suggested_use_d_label"> + (Otro) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_postcard.xml b/indra/newview/skins/default/xui/es/floater_postcard.xml deleted file mode 100644 index b5b9805fe2..0000000000 --- a/indra/newview/skins/default/xui/es/floater_postcard.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="FOTO POR CORREO"> - <text name="to_label"> - Correo del destinatario: - </text> - <text name="from_label"> - Su correo: - </text> - <text name="name_label"> - Su nombre: - </text> - <text name="subject_label"> - Asunto: - </text> - <line_editor label="Escriba aquà el asunto." name="subject_form"/> - <text name="msg_label"> - Mensaje: - </text> - <text_editor name="msg_form"> - Escriba aquà el mensaje. - </text_editor> - <text name="fine_print"> - Si su destinatario se registra en [SECOND_LIFE], -usted conseguirá un bono de referido. - </text> - <button label="Cancelar" name="cancel_btn"/> - <button label="Enviar" name="send_btn"/> - <string name="default_subject"> - Postal desde [SECOND_LIFE]. - </string> - <string name="default_message"> - ¡Mira esto! - </string> - <string name="upload_message"> - Enviando... - </string> -</floater> 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_spellcheck.xml b/indra/newview/skins/default/xui/es/floater_spellcheck.xml new file mode 100644 index 0000000000..b664b96928 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="Configuración del corrector ortográfico"> + <check_box label="Habilitar la revisión ortográfica" name="spellcheck_enable"/> + <text name="spellcheck_main"> + Diccionario principal: + </text> + <text label="Registros:" name="spellcheck_additional"> + Diccionarios adicionales: + </text> + <text name="spellcheck_available"> + Disponibles + </text> + <text name="spellcheck_active"> + Activos + </text> + <button label="Eliminar" name="spellcheck_remove_btn"/> + <button label="Importar..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/es/floater_spellcheck_import.xml new file mode 100644 index 0000000000..bd86ed00da --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Importar diccionario"> + <button label="Examinar" label_selected="Examinar" name="dictionary_path_browse"/> + <button label="Importar" name="ok_btn"/> + <button label="Cancelar" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_stats.xml b/indra/newview/skins/default/xui/es/floater_stats.xml index ba4af2e866..00601920f2 100644 --- a/indra/newview/skins/default/xui/es/floater_stats.xml +++ b/indra/newview/skins/default/xui/es/floater_stats.xml @@ -14,8 +14,11 @@ <stat_bar label="KTris generados por segundo" name="ktrissec"/> <stat_bar label="Objetos en total" name="objs"/> <stat_bar label="Objetos nuevos" name="newobjs"/> + <stat_bar label="Ãndice de aciertos de caché de objetos" name="object_cache_hits"/> </stat_view> <stat_view label="Textura" name="texture"> + <stat_bar label="Ãndice de aciertos de caché" name="texture_cache_hits"/> + <stat_bar label="Latencia de lectura de caché" name="texture_cache_read_latency"/> <stat_bar label="Número" name="numimagesstat"/> <stat_bar label="Raw: número" name="numrawimagesstat"/> <stat_bar label="GL Mem" name="gltexmemstat"/> @@ -44,6 +47,12 @@ <stat_bar label="Objetos con bajo nivel de detalle" name="physicslodtasks"/> <stat_bar label="Memoria asignada" name="physicsmemoryallocated"/> </stat_view> + <stat_bar label="Scripts ejecutados" name="simpctscriptsrun"/> + <stat_view label="Pathfinding" name="simpathfinding"> + <stat_bar label="Tiempo de paso de IA" name="simsimaistepmsec"/> + <stat_bar label="Pasos de silueta omitidos" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Personajes actualizados" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_view label="Tiempo (ms)" name="simperf"> <stat_bar label="Tiempo total de los frames" name="simframemsec"/> <stat_bar label="Tiempo de red" name="simnetmsec"/> diff --git a/indra/newview/skins/default/xui/es/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/es/floater_test_layout_stacks.xml new file mode 100644 index 0000000000..b479d5f6d6 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_test_layout_stacks.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="LAYOUTSTACK TESTS"/> diff --git a/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml index ed2787ea60..93bc9f293c 100644 --- a/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml @@ -1,24 +1,36 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="texture picker" title="DESTACADO: TEXTURA"> - <string name="choose_picture"> + <floater.string name="choose_picture"> Pulse para elegir una imagen - </string> + </floater.string> + <floater.string name="pick title"> + Elegir: + </floater.string> <text name="Multiple"> Texturas múltiples </text> + <radio_group name="mode_selection"> + <radio_item label="Inventario" name="inventory" value="0"/> + <radio_item label="Local" name="local" value="1"/> + </radio_group> <text name="unknown"> Tamaño: [DIMENSIONS] </text> <button label="Por defecto" label_selected="Por defecto" name="Default" width="84"/> - <button label="Ninguna" label_selected="Ninguna" left="90" name="None"/> <button label="Blanca" label_selected="Blanca" name="Blank"/> - <check_box label="Ver las carpetas" name="show_folders_check"/> - <search_editor label="Filtrar las texturas" name="inventory search editor"/> - <check_box label="Aplicarlo ahora" name="apply_immediate_check"/> + <button label="Ninguna" label_selected="Ninguna" left="90" name="None"/> <button label="" label_selected="" name="Pipette"/> - <button label="Cancelar" label_selected="Cancelar" name="Cancel"/> + <check_box initial_value="true" label="Vista previa inmediata" name="apply_immediate_check"/> + <text name="preview_disabled" value="Vista previa inhabilitada"/> + <filter_editor label="Filtrar las texturas" name="inventory search editor"/> + <check_box initial_value="false" label="Ver las carpetas" name="show_folders_check"/> + <button label="Añadir" label_selected="Añadir" name="l_add_btn"/> + <button label="Eliminar" label_selected="Eliminar" name="l_rem_btn"/> + <button label="Subir" label_selected="Subir" name="l_upl_btn"/> + <scroll_list name="l_name_list"> + <column label="Nombre" name="unit_name"/> + <column label="ID" name="unit_id_HIDDEN"/> + </scroll_list> <button label="OK" label_selected="OK" name="Select"/> - <string name="pick title"> - Elegir: - </string> + <button label="Cancelar" label_selected="Cancelar" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/es/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/es/floater_texture_fetch_debugger.xml new file mode 100644 index 0000000000..59aaf7f74a --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_texture_fetch_debugger.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="TexFetchDebugger" title="Depurador de obtención de texturas"> + <text name="total_num_fetched_label"> + 1, Número total de texturas obtenidas: [NUM] + </text> + <text name="total_num_fetching_requests_label"> + 2, Número total de solicitudes de obtención: [NUM] + </text> + <text name="total_num_cache_hits_label"> + 3, Número total de aciertos de caché: [NUM] + </text> + <text name="total_num_visible_tex_label"> + 4, Número total de texturas visibles: [NUM] + </text> + <text name="total_num_visible_tex_fetch_req_label"> + 5, Número total de solicitudes de obtención de texturas visibles: [NUM] + </text> + <text name="total_fetched_data_label"> + 6, Número total de datos obtenidos: [SIZE1] KB, Datos descodificados: [SIZE2] KB, [PIXEL] MPÃxeles + </text> + <text name="total_fetched_vis_data_label"> + 7, Número total de datos visibles: [SIZE1] KB, Datos descodificados: [SIZE2] KB + </text> + <text name="total_fetched_rendered_data_label"> + 8, Número total de datos representados: [SIZE1] KB, Datos descodificados: [SIZE2] KB, [PIXEL] MPÃxeles + </text> + <text name="total_time_cache_read_label"> + 9, Tiempo total en lecturas de caché: [TIME] segundos + </text> + <text name="total_time_cache_write_label"> + 10, Tiempo total en escrituras de caché: [TIME] segundos + </text> + <text name="total_time_decode_label"> + 11, Tiempo total en descodificaciones: [TIME] segundos + </text> + <text name="total_time_gl_label"> + 12, Tiempo total en la creación de texturas gl: [TIME] segundos + </text> + <text name="total_time_http_label"> + 13, Tiempo total en obtención de HTTP: [TIME] segundos + </text> + <text name="total_time_fetch_label"> + 14, Tiempo total en obtención completa: [TIME] segundos + </text> + <text name="total_time_refetch_vis_cache_label"> + 15, Volviendo a obtener visibles de la caché, Tiempo: [TIME] segundos, Obtenidos: [SIZE] KB, [PIXEL] MPÃxeles + </text> + <text name="total_time_refetch_all_cache_label"> + 16, Volviendo a obtener todas las texturas de caché, Tiempo: [TIME] segundos, Obtenidos: [SIZE] KB, [PIXEL] MPÃxeles + </text> + <text name="total_time_refetch_vis_http_label"> + 17, Volviendo a obtener visibles de HTTP, Tiempo: [TIME] segundos, Obtenidos: [SIZE] KB, [PIXEL] MPÃxeles + </text> + <text name="total_time_refetch_all_http_label"> + 18, Volviendo a obtener todas las texturas de HTTP, Tiempo: [TIME] segundos, Obtenidos: [SIZE] KB, [PIXEL] MPÃxeles + </text> + <spinner label="19, Proporción de texeles/pÃxeles:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, Fuente de texturas: + </text> + <radio_group name="texture_source"> + <radio_item label="Caché + HTTP" name="0"/> + <radio_item label="Solo HTTP" name="1"/> + </radio_group> + <button label="Iniciar" name="start_btn"/> + <button label="Restablecer" name="clear_btn"/> + <button label="Cerrar" name="close_btn"/> + <button label="Lectura de caché" name="cacheread_btn"/> + <button label="Escritura de caché" name="cachewrite_btn"/> + <button label="HTTP" name="http_btn"/> + <button label="Descodificar" name="decode_btn"/> + <button label="Textura GL" name="gl_btn"/> + <button label="Volver a obtener caché de vis." name="refetchviscache_btn"/> + <button label="Volver a obtener toda la caché" name="refetchallcache_btn"/> + <button label="Volver a obtener HTTP de vis." name="refetchvishttp_btn"/> + <button label="Volver a obtener todo el HTTP" name="refetchallhttp_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_tools.xml b/indra/newview/skins/default/xui/es/floater_tools.xml index 650b4b457d..15462c3726 100644 --- a/indra/newview/skins/default/xui/es/floater_tools.xml +++ b/indra/newview/skins/default/xui/es/floater_tools.xml @@ -128,6 +128,12 @@ <panel.string name="text modify info 4"> No puedes modificar estos objetos </panel.string> + <panel.string name="text modify info 5"> + No se puede modificar este objeto a través del lÃmite de una región + </panel.string> + <panel.string name="text modify info 6"> + No se pueden modificar estos objetos a través del lÃmite de una región + </panel.string> <panel.string name="text modify warning"> Para configurar los permisos, debes seleccionar el objeto completo </panel.string> @@ -177,12 +183,12 @@ <combo_box.item label="Zoom" name="Zoom"/> </combo_box> <check_box label="En venta:" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Copia" name="Copy"/> <combo_box.item label="Contenidos" name="Contents"/> <combo_box.item label="Original" name="Original"/> </combo_box> - <spinner label="Precio: L$" name="Edit Cost"/> <check_box label="Mostrar en la búsqueda" name="search_check" tool_tip="Dejar que la gente vea este objeto en los resultados de la búsqueda"/> <panel name="perms_build"> <text name="perm_modify"> @@ -218,6 +224,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Atributos de pathfinding: + </text> + </panel> </panel> <panel label="Objeto" name="Object"> <check_box label="Bloqueado" name="checkbox locked" tool_tip="Previene que el objeto sea movido o borrado. Suele ser útil mientras se construye, para prevenir que se modifique sin querer."/> diff --git a/indra/newview/skins/default/xui/es/floater_top_objects.xml b/indra/newview/skins/default/xui/es/floater_top_objects.xml index 033633bd22..bb53f116c2 100644 --- a/indra/newview/skins/default/xui/es/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/es/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> Tiempo </floater.string> - <floater.string name="scripts_mono_time_label"> - Tiempo en Mono - </floater.string> <floater.string name="top_colliders_title"> Objetos que colisionan </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="Nombre" name="name"/> <scroll_list.columns label="Propietario" name="owner"/> <scroll_list.columns label="Posición" name="location"/> + <scroll_list.columns label="Parcela" name="parcel"/> <scroll_list.columns label="Tiempo" name="time"/> - <scroll_list.columns label="Tiempo en Mono" name="mono_time"/> <scroll_list.columns label="URLs" name="URLs"/> + <scroll_list.columns label="Memoria (KB)" name="memory"/> </scroll_list> <text name="id_text"> ID del objeto: @@ -48,6 +46,10 @@ Propietario: </text> <button label="Filtro" name="filter_owner_btn"/> + <text name="parcel_name_text"> + Parcela: + </text> + <button label="Filtro" name="filter_parcel_btn"/> <button label="Actualizar" name="refresh_btn"/> <button label="Devolver lo seleccionado" name="return_selected_btn" width="170"/> <button label="Devolver todo" left="190" name="return_all_btn"/> 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/floater_window_size.xml b/indra/newview/skins/default/xui/es/floater_window_size.xml index f57ce08eac..6c1ad02319 100644 --- a/indra/newview/skins/default/xui/es/floater_window_size.xml +++ b/indra/newview/skins/default/xui/es/floater_window_size.xml @@ -7,10 +7,17 @@ Definir el tamaño de la ventana: </text> <combo_box name="window_size_combo" tool_tip="ancho x alto"> - <combo_box.item label="1000 x 700 (por defecto)" name="item0"/> - <combo_box.item label="1024 x 768" name="item1"/> - <combo_box.item label="1280 x 720 (720 p)" name="item2"/> - <combo_box.item label="1920 x 1080 (1080 p)" name="item3"/> + <combo_box.item label="1000 x 700 (por defecto)" name="item1"/> + <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/> + <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/> + <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/> + <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/> + <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/> + <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/> + <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/> + <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/> + <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/> + <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/> </combo_box> <button label="Configurar" name="set_btn"/> <button label="Cancelar" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/es/menu_bottomtray.xml b/indra/newview/skins/default/xui/es/menu_bottomtray.xml deleted file mode 100644 index 40058a1749..0000000000 --- a/indra/newview/skins/default/xui/es/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="Botón Hablar" name="EnableVoiceChat"/> - <menu_item_check label="Botón Gestos" name="ShowGestureButton"/> - <menu_item_check label="Botón Moverse" name="ShowMoveButton"/> - <menu_item_check label="Botón Vista" name="ShowCameraButton"/> - <menu_item_check label="Botón Foto" name="ShowSnapshotButton"/> - <menu_item_check label="Botón Construir" name="ShowBuildButton"/> - <menu_item_check label="Botón Buscar" name="ShowSearchButton"/> - <menu_item_check label="Botón Mapa" name="ShowWorldMapButton"/> - <menu_item_check label="Botón Minimapa" name="ShowMiniMapButton"/> - <menu_item_call label="Cortar" name="NearbyChatBar_Cut"/> - <menu_item_call label="Copiar" name="NearbyChatBar_Copy"/> - <menu_item_call label="Pegar" name="NearbyChatBar_Paste"/> - <menu_item_call label="Borrar" name="NearbyChatBar_Delete"/> - <menu_item_call label="Seleccionar todo" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/es/menu_im_well_button.xml b/indra/newview/skins/default/xui/es/menu_im_well_button.xml deleted file mode 100644 index c8f6c217cc..0000000000 --- a/indra/newview/skins/default/xui/es/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<context_menu name="IM Well Button Context Menu"> - <menu_item_call label="Cerrar todo" name="Close All"/> -</context_menu> diff --git a/indra/newview/skins/default/xui/es/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/es/menu_inspect_object_gear.xml index bcdc25894f..9d0a8c50ef 100644 --- a/indra/newview/skins/default/xui/es/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/es/menu_inspect_object_gear.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<menu name="Gear Menu"> +<toggleable_menu name="Gear Menu"> <menu_item_call label="Tocar" name="touch"/> <menu_item_call label="Sentarse" name="sit"/> <menu_item_call label="Pagar" name="pay"/> @@ -12,7 +12,8 @@ <menu_item_call label="Añadir" name="add"/> <menu_item_call label="Denunciar" name="report"/> <menu_item_call label="Ignorar" name="block"/> + <menu_item_call label="No ignorar" name="unblock"/> <menu_item_call label="Acercar el zoom" name="zoom_in"/> <menu_item_call label="Quitar" name="remove"/> <menu_item_call label="Más información" name="more_info"/> -</menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/es/menu_inventory.xml b/indra/newview/skins/default/xui/es/menu_inventory.xml index f1f1ef091f..803d3f1331 100644 --- a/indra/newview/skins/default/xui/es/menu_inventory.xml +++ b/indra/newview/skins/default/xui/es/menu_inventory.xml @@ -67,6 +67,7 @@ <menu_item_call label="Borrar carpeta del sistema" name="Delete System Folder"/> <menu_item_call label="Empezar multiconferencia" name="Conference Chat Folder"/> <menu_item_call label="Escuchar" name="Sound Play"/> + <menu_item_call label="Copiar la SLurl" name="url_copy"/> <menu_item_call label="Acerca del hito" name="About Landmark"/> <menu_item_call label="Escuchar en el mundo" name="Animation Play"/> <menu_item_call label="Ejecutarla para usted" name="Animation Audition"/> @@ -84,6 +85,6 @@ <menu_item_call label="Añadir" name="Wearable Add"/> <menu_item_call label="Quitarse" name="Take Off"/> <menu_item_call label="Copiar al Buzón de salida de comerciante" name="Merchant Copy"/> - <menu_item_call label="Mover al Buzón de salida de comerciante" name="Merchant Move"/> + <menu_item_call label="Enviar al Mercado" name="Marketplace Send"/> <menu_item_call label="--sin opciones--" name="--no options--"/> </menu> diff --git a/indra/newview/skins/default/xui/es/menu_login.xml b/indra/newview/skins/default/xui/es/menu_login.xml index e3abf7ad62..289ac3f075 100644 --- a/indra/newview/skins/default/xui/es/menu_login.xml +++ b/indra/newview/skins/default/xui/es/menu_login.xml @@ -16,8 +16,8 @@ <menu_item_call label="Definir el tamaño de la ventana..." name="Set Window Size..."/> <menu_item_call label="Mostrar los 'TOS'" name="TOS"/> <menu_item_call label="Mostrar mensaje crÃtico" name="Critical"/> - <menu_item_call label="Prueba de navegadores de medios" name="Web Browser Test"/> <menu_item_call label="Prueba de depuración de ventanas de contenido web" name="Web Content Floater Debug Test"/> + <menu label="Configurar el nivel de registro" name="Set Logging Level"/> <menu_item_check label="Mostrar el selector de Grid" name="Show Grid Picker"/> <menu_item_call label="Mostrar la consola de notificaciones" name="Show Notifications Console"/> </menu> diff --git a/indra/newview/skins/default/xui/es/menu_mode_change.xml b/indra/newview/skins/default/xui/es/menu_mode_change.xml deleted file mode 100644 index 608505d192..0000000000 --- a/indra/newview/skins/default/xui/es/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="Básico" name="BasicMode"/> - <menu_item_check label="Avanzado" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/es/menu_object.xml b/indra/newview/skins/default/xui/es/menu_object.xml index d8c75eaf47..33ea8c88d8 100644 --- a/indra/newview/skins/default/xui/es/menu_object.xml +++ b/indra/newview/skins/default/xui/es/menu_object.xml @@ -5,6 +5,8 @@ </menu_item_call> <menu_item_call label="Editar" name="Edit..."/> <menu_item_call label="Construir" name="Build"/> + <menu_item_call label="Mostrar en linksets" name="show_in_linksets"/> + <menu_item_call label="Mostrar en personajes" name="show_in_characters"/> <menu_item_call label="Abrir" name="Open"/> <menu_item_call label="Sentarme aquÃ" name="Object Sit"/> <menu_item_call label="Levantarme" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/es/menu_text_editor.xml b/indra/newview/skins/default/xui/es/menu_text_editor.xml index 095e461734..6253463725 100644 --- a/indra/newview/skins/default/xui/es/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/es/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(desconocido)" name="Suggestion 1"/> + <menu_item_call label="(desconocido)" name="Suggestion 2"/> + <menu_item_call label="(desconocido)" name="Suggestion 3"/> + <menu_item_call label="(desconocido)" name="Suggestion 4"/> + <menu_item_call label="(desconocido)" name="Suggestion 5"/> + <menu_item_call label="Añadir al diccionario" name="Add to Dictionary"/> + <menu_item_call label="Añadir a ignorados" name="Add to Ignore"/> <menu_item_call label="Cortar" name="Cut"/> <menu_item_call label="Copiar" name="Copy"/> <menu_item_call label="Pegar" name="Paste"/> 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 0714e7f2c6..d80150ef6d 100644 --- a/indra/newview/skins/default/xui/es/menu_viewer.xml +++ b/indra/newview/skins/default/xui/es/menu_viewer.xml @@ -1,55 +1,61 @@ <?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"/> <menu_item_check label="Correr siempre" name="Always Run"/> <menu_item_call label="Parar mis animaciones" name="Stop Animating My Avatar"/> + <menu_item_call label="Caminar / Correr / Volar..." name="Walk / run / fly"/> </menu> <menu label="Estado" name="Status"> <menu_item_call label="Ausente" name="Set Away"/> <menu_item_call label="Ocupado" name="Set Busy"/> </menu> - <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="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_check label="Mostrar los HUD anexados" name="Show HUD Attachments"/> <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_item_call label="Lista de ignorados" name="Block List"/> </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 +64,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 label="Sol" name="Sun"> <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"/> @@ -120,6 +125,11 @@ <menu_item_call label="Definir los scripts a ejecutar" name="Set Scripts to Running"/> <menu_item_call label="Configurar scripts como no ejecutándose" name="Set Scripts to Not Running"/> </menu> + <menu label="Pathfinding" name="Pathfinding"> + <menu_item_call label="Linksets..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="Personajes..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="Ver/probar..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Opciones" name="Options"> <menu_item_check label="Mostrar los permisos avanzados" name="DebugPermissions"/> <menu_item_check label="Seleccionar sólo mis objetos" name="Select Only My Objects"/> @@ -140,11 +150,13 @@ <menu_item_call label="Animación ([COST] L$)..." name="Upload Animation"/> <menu_item_call label="Modelo..." name="Upload Model"/> <menu_item_call label="Masivo ([COST] L$ por archivo)..." name="Bulk Upload"/> + <menu_item_call label="Configurar los permisos por defecto de subida" name="perm prefs"/> </menu> <menu_item_call label="Deshacer" name="Undo"/> <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"/> @@ -168,26 +180,25 @@ <menu_item_check label="Ocultar las partÃculas" name="Hide Particles"/> <menu_item_check label="Ocultar lo seleccionado" name="Hide Selected"/> <menu_item_check label="Realzar las transparencias" name="Highlight Transparent"/> - <menu_item_check label="Mostrar los HUD anexados" name="Show HUD Attachments"/> <menu_item_check label="Mostrar el Punto de Mira en la vista subjetiva" name="ShowCrosshairs"/> </menu> <menu label="Objetos representados" name="Rendering Types"> - <menu_item_check label="Simple" name="Simple"/> - <menu_item_check label="Alfa" name="Alpha"/> - <menu_item_check label="Ãrbol" name="Tree"/> - <menu_item_check label="Avatares" name="Character"/> - <menu_item_check label="Parche de superficie" name="Surface Patch"/> - <menu_item_check label="Cielo" name="Sky"/> - <menu_item_check label="Agua" name="Water"/> - <menu_item_check label="Terreno" name="Ground"/> - <menu_item_check label="volumen" name="Volume"/> - <menu_item_check label="Hierba" name="Grass"/> - <menu_item_check label="Nubes" name="Clouds"/> - <menu_item_check label="PartÃculas" name="Particles"/> - <menu_item_check label="Efectos de relieve" name="Bump"/> + <menu_item_check label="Simple" name="Rendering Type Simple"/> + <menu_item_check label="Alfa" name="Rendering Type Alpha"/> + <menu_item_check label="Ãrbol" name="Rendering Type Tree"/> + <menu_item_check label="Avatares" name="Rendering Type Character"/> + <menu_item_check label="Parcela de superficie" name="Rendering Type Surface Patch"/> + <menu_item_check label="Cielo" name="Rendering Type Sky"/> + <menu_item_check label="Agua" name="Rendering Type Water"/> + <menu_item_check label="Terreno" name="Rendering Type Ground"/> + <menu_item_check label="Volumen" name="Rendering Type Volume"/> + <menu_item_check label="Hierba" name="Rendering Type Grass"/> + <menu_item_check label="Nubes" name="Rendering Type Clouds"/> + <menu_item_check label="PartÃculas" name="Rendering Type Particles"/> + <menu_item_check label="Efectos de relieve" name="Rendering Type Bump"/> </menu> <menu label="Rasgos renderizados" name="Rendering Features"> - <menu_item_check label="UI" name="UI"/> + <menu_item_check label="UI" name="ToggleUI"/> <menu_item_check label="Seleccionado" name="Selected"/> <menu_item_check label="Realzados" name="Highlighted"/> <menu_item_check label="Texturas dinámicas" name="Dynamic Textures"/> @@ -198,11 +209,8 @@ <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"/> @@ -211,13 +219,6 @@ <menu_item_check label="Flycam del joystick" name="Joystick Flycam"/> <menu_item_call label="Volver a la vista por defecto" name="Reset View"/> <menu_item_call label="Mirar al último que habló" name="Look at Last Chatter"/> - <menu label="Seleccionar la herramienta de construcción" name="Select Tool"> - <menu_item_call label="Herramienta Visión" name="Focus"/> - <menu_item_call label="Herramienta Mover" name="Move"/> - <menu_item_call label="Herramienta Editar" name="Edit"/> - <menu_item_call label="Herramienta Crear" name="Create"/> - <menu_item_call label="Herramienta Terreno" name="Land"/> - </menu> <menu_item_call label="Acercar el zoom" name="Zoom In"/> <menu_item_call label="Zoom por defecto" name="Zoom Default"/> <menu_item_call label="Alejar el zoom" name="Zoom Out"/> @@ -230,11 +231,10 @@ <menu_item_check label="Texture Console" name="Texture Console"/> <menu_item_check label="Debug Console" name="Debug Console"/> <menu_item_call label="Notifications Console" name="Notifications"/> - <menu_item_check label="Texture Size Console" name="Texture Size"/> - <menu_item_check label="Texture Category Console" name="Texture Category"/> <menu_item_check label="Fast Timers" name="Fast Timers"/> <menu_item_check label="Memory" name="Memory"/> <menu_item_check label="Datos de la escena" name="Scene Statistics"/> + <menu_item_call label="Consola de depuración de obtención de texturas" name="Texture Fetch Debug Console"/> <menu_item_call label="Region Info to Debug Console" name="Region Info to Debug Console"/> <menu_item_check label="Camera" name="Camera"/> <menu_item_check label="Wind" name="Wind"/> @@ -271,8 +271,16 @@ <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="Bytes de adjunto" name="attachment bytes"/> <menu_item_check label="Esculpir" name="Sculpt"/> + <menu label="Densidad de textura" name="Texture Density"> + <menu_item_check label="Ninguna" name="None"/> + <menu_item_check label="Actual" name="Current"/> + <menu_item_check label="Deseada" name="Desired"/> + <menu_item_check label="Completa" name="Full"/> + </menu> </menu> <menu label="Rendering" name="Rendering"> <menu_item_check label="Axes" name="Axes"/> @@ -280,7 +288,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"/> @@ -295,11 +302,10 @@ <menu_item_call label="Drop a Packet" name="Drop a Packet"/> </menu> <menu_item_call label="Bumps, Pushes & Hits" name="Bumps, Pushes &amp; Hits"/> - <menu label="World" name="World"> - <menu_item_check label="Region Sun Override" name="Sim Sun Override"/> - <menu_item_check label="Beacon flashing effect" name="Cheesy Beacon"/> - <menu_item_check label="Fixed Weather" name="Fixed Weather"/> - <menu_item_call label="Dump Region Object Cache" name="Dump Region Object Cache"/> + <menu label="Mundo virtual" name="DevelopWorld"> + <menu_item_check label="Anular el sol del Sim" name="Sim Sun Override"/> + <menu_item_check label="MeteorologÃa fija" name="Fixed Weather"/> + <menu_item_call label="Volcar la caché de objetos de la región" name="Dump Region Object Cache"/> </menu> <menu label="UI" name="UI"> <menu_item_call label="Prueba de navegadores de medios" name="Web Browser Test"/> @@ -319,11 +325,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="Head" name="Head"/> - <menu_item_call label="Upper Body" name="Upper Body"/> - <menu_item_call label="Lower Body" name="Lower Body"/> - <menu_item_call label="Skirt" name="Skirt"/> + <menu_item_call label="Iris" name="Grab Iris"/> + <menu_item_call label="Cabeza" name="Grab Head"/> + <menu_item_call label="Parte superior del cuerpo" name="Grab Upper Body"/> + <menu_item_call label="Parte inferior del cuerpo" name="Grab Lower Body"/> + <menu_item_call label="Falda" name="Grab Skirt"/> </menu> <menu label="Character Tests" name="Character Tests"> <menu_item_call label="Toggle Character Geometry" name="Toggle Character Geometry"/> @@ -340,17 +346,19 @@ <menu_item_check label="HTTP Textures" name="HTTP Textures"/> <menu_item_check label="Inventario HTTP" name="HTTP Inventory"/> <menu_item_check label="Console Window on next Run" name="Console Window"/> + <menu label="Configurar el nivel de registro" name="Set Logging Level"/> <menu_item_call label="Request Admin Status" name="Request Admin Options"/> <menu_item_call label="Leave Admin Status" name="Leave Admin Options"/> <menu_item_check label="Show Admin Menu" name="View Admin Options"/> </menu> <menu label="Admin" name="Admin"> - <menu label="Object"> - <menu_item_call label="Coger una copia" name="Take Copy"/> - <menu_item_call label="Force Owner To Me" name="Force Owner To Me"/> - <menu_item_call label="Force Owner Permissive" name="Force Owner Permissive"/> + <menu label="Objeto" name="AdminObject"> + <menu_item_call label="Tomar una copia" name="Admin Take Copy"/> + <menu_item_call label="Forzar que yo sea el propietario" name="Force Owner To Me"/> + <menu_item_call label="Forzar permiso al propietario" name="Force Owner Permissive"/> <menu_item_call label="Eliminar" name="Delete"/> - <menu_item_call label="Lock" name="Lock"/> + <menu_item_call label="Bloquear" name="Lock"/> + <menu_item_call label="Obtener ID de objetos" name="Get Assets IDs"/> </menu> <menu label="Parcel" name="Parcel"> <menu_item_call label="Force Owner To Me" name="Owner To Me"/> @@ -367,5 +375,16 @@ <menu label="Take Off Clothing" name="Take Off Clothing"> <menu_item_call label="FÃsica" name="Physics"/> </menu> + <menu label="Ayuda" name="DeprecatedHelp"> + <menu_item_call label="Blog oficial" name="Official Linden Blog"/> + <menu_item_call label="Portal de programación" name="Scripting Portal"/> + <menu label="Informes de fallos" name="Bug Reporting"> + <menu_item_call label="Public Issue Tracker" name="Public Issue Tracker"/> + <menu_item_call label="Ayuda del Public Issue Tracker" name="Publc Issue Tracker Help"/> + <menu_item_call label="Informes de fallos - instrucciones" name="Bug Reporing 101"/> + <menu_item_call label="Problemas de seguridad" name="Security Issues"/> + <menu_item_call label="Wiki QA" name="QA Wiki"/> + </menu> + </menu> </menu> </menu_bar> diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index 3fe0072a20..7dfb27717d 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -86,17 +92,38 @@ Asegúrate de que tu conexión a Internet está funcionando adecuadamente. <usetemplate canceltext="Cancelar" name="yesnocancelbuttons" notext="No guardarlos" yestext="Guardarlos"/> </notification> <notification name="ConfirmNoCopyToOutbox"> - No tienes permiso para copiar este objeto en el Buzón de salida de comerciante. ¿Estás seguro de que quieres mover el objeto siguiente? - [ITEM_NAME] - <usetemplate name="okcancelbuttons" notext="No" yestext="SÃ"/> + No tienes permiso para copiar uno o varios de estos objetos en el Buzón de salida de comerciante. Puedes moverlos o dejártelos. + <usetemplate name="okcancelbuttons" notext="No mover objeto(s)" yestext="Mover objeto(s)"/> + </notification> + <notification name="OutboxFolderCreated"> + Se ha creado una carpeta nueva para cada objeto que has transferido al nivel superior de tu Buzón de salida de comerciante. + <usetemplate ignoretext="Se ha creado una carpeta nueva en el Buzón de salida de comerciante" name="okignore" yestext="OK"/> </notification> - <notification name="OutboxUploadComplete"> - EnvÃo al mercado finalizado. - <usetemplate name="okbutton" yestext="¡Hurra!"/> + <notification name="OutboxImportComplete"> + Éxito + +Todas las carpetas se han enviado correctamente al Mercado. + <usetemplate ignoretext="Todas las carpetas enviadas al Mercado" name="okignore" yestext="OK"/> </notification> - <notification name="OutboxUploadHadErrors"> - El envÃo al mercado ha tenido errores. Corrige los problemas de tu buzón de salida y repite la operación. Muchas gracias. - <usetemplate name="okbutton" yestext="Reintentar"/> + <notification name="OutboxImportHadErrors"> + Algunas carpetas no se han transferido + +Han ocurrido errores al enviar algunas carpetas al Mercado. Dichas carpetas todavÃa están en tu Buzón de salida de comerciante. + +Puedes consultar más información en el [[MARKETPLACE_IMPORTS_URL] registro de errores]. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="OutboxImportFailed"> + Error de transferencia + +No se han enviado carpetas al Mercado a causa de un error del sistema o de la red. Vuelve a intentarlo más tarde. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="OutboxInitFailed"> + Error al inicializar el mercado + +La inicialización del mercado ha fallado por un error del sistema o de la red. Vuelve a intentarlo más tarde. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CompileQueueSaveText"> Hubo un problema al subir el texto de un script por la siguiente razón: [REASON]. Por favor, inténtalo más tarde. @@ -336,13 +363,19 @@ Tienes que volver a introducir el nombre de usuario de tu avatar. Necesitas una cuenta para acceder a [SECOND_LIFE]. ¿Te gustarÃa crear una ahora? <url name="url"> - https://join.secondlife.com/index.php?lang=es-ES + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Volver a intentarlo" yestext="Crear una cuenta nueva"/> </notification> <notification name="InvalidCredentialFormat"> Escribe el nombre de usuario o el nombre y el apellido de tu avatar en el campo Nombre de usuario e inicia sesión otra vez. </notification> + <notification name="InvalidGrid"> + '[GRID]' no es un identificador de cuadrÃcula válido. + </notification> + <notification name="InvalidLocationSLURL"> + Tu localización inicial no especifica una cuadrÃcula válida. + </notification> <notification name="DeleteClassified"> ¿Borrar el clasificado '[NAME]'? No se reembolsan las cuotas pagadas. @@ -446,8 +479,8 @@ El objeto debe de haber sido borrado o estar fuera de rango ('out of range& Al guardar un script compilado, hubo un problema por: [REASON]. Por favor, vuelve a intentar guardarlo más tarde.. </notification> <notification name="StartRegionEmpty"> - Perdón, no está definida tu Posición inicial. -Por favor, escribe el nombre de la región en el cajetÃn de Posición inicial, o elige para esa posición Mi Base o Mi última posición. + No está definida tu región inicial. +Por favor, escribe el nombre de la región en el cuadro de Posición inicial o elige para esa posición Mi Base o Mi última posición. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CouldNotStartStopScript"> @@ -469,6 +502,15 @@ El objeto debe de haber sido borrado o estar fuera de rango ('out of range& </url> <usetemplate ignoretext="El hardware de mi ordenador no está admitido" name="okcancelignore" notext="No" yestext="SÃ"/> </notification> + <notification name="IntelOldDriver"> + Probablemente ya existe un controlador más reciente para tu procesador de gráficos. La actualización del controlador de gráficos puede mejorar sustancialmente el rendimiento. + + ¿Deseas visitar [_URL] para comprobar si hay controladores actualizados? + <url name="url"> + http://www.intel.com/p/es_XL/support/detect/graphics + </url> + <usetemplate ignoretext="Mi controlador de gráficos no está actualizado" name="okcancelignore" notext="No" yestext="SÃ"/> + </notification> <notification name="UnknownGPU"> Tu sistema usa una tarjeta gráfica que [APP_NAME] no reconoce. Suele suceder con hardware nuevo que todavÃa no ha sido probado con [APP_NAME]. Probablemente todo irá bien, pero deberás ajustar tus configuraciones gráficas. @@ -569,6 +611,9 @@ todos los objetos. Por favor, asegúrate de que no hay ninguno bloqueado, y de que eres el propietario de todos. </notification> + <notification name="CannotLinkPermanent"> + No se pueden vincular objetos a través de lÃmites de región. + </notification> <notification name="CannotLinkDifferentOwners"> Imposible enlazarlos, porque hay objetos de distintos propietarios. @@ -950,6 +995,41 @@ no tienes el permiso de comprar terreno para el grupo que tienes activado actual <button name="Cancel" text="Cancelar"/> </form> </notification> + <notification label="Añadir lista de reemplazo automático" name="AddAutoReplaceList"> + Nombre de la nueva lista: + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="Cambiar nombre de la lista de reemplazo automático" name="RenameAutoReplaceList"> + El nombre '[DUPNAME]' ya se está utilizando. + Escribe un nombre nuevo que sea único: + <form name="form"> + <button name="ReplaceList" text="Reemplazar la lista actual"/> + <button name="SetName" text="Usar un nombre nuevo"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + La palabra clave debe ser una palabra única y el reemplazo no puede estar vacÃo. + </notification> + <notification name="InvalidAutoReplaceList"> + La lista de reemplazo no es válida. + </notification> + <notification name="SpellingDictImportRequired"> + Debes especificar un archivo, un nombre y un idioma. + </notification> + <notification name="SpellingDictIsSecondary"> + El diccionario [DIC_NAME] aparentemente no contiene un archivo "aff", lo cual significa que es un diccionario "secundario". +Puedes utilizarlo como un diccionario adicional, pero no como el diccionario principal. + +Consulta https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + No se puede copiar + [FROM_NAME] + a + [TO_NAME] + </notification> <notification label="Guardar el vestuario" name="SaveOutfitAs"> Guardar como un nuevo vestuario lo que estoy llevando: <form name="form"> @@ -981,7 +1061,7 @@ no tienes el permiso de comprar terreno para el grupo que tienes activado actual </form> </notification> <notification name="RemoveFromFriends"> - ¿Quieres eliminar a [NAME] de tu lista de amigos? + ¿Quieres eliminar a <nolink>[NAME]</nolink> de tu lista de amigos? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> <notification name="RemoveMultipleFromFriends"> @@ -1114,8 +1194,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 '[LAST_GPU]' +a '[THIS_GPU]' + </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] @@ -1126,7 +1211,7 @@ El precio de compra del terreno no se le devolverá al propietario. Si se vende Se te ha llevado a una región cercana. </notification> <notification name="AvatarMovedLast"> - En estos momentos no está disponible tu última posición. + En estos momentos no está disponible la posición solicitada. Se te ha llevado a una región cercana. </notification> <notification name="AvatarMovedHome"> @@ -1144,9 +1229,8 @@ Puedes usar [SECOND_LIFE] de forma normal; los demás residentes te verán corre <notification name="FirstRun"> Se ha completado la instalación de [SECOND_LIFE]. -Si es la primera vez que usas [SECOND_LIFE], debes crear una cuenta antes de poder iniciar una sesión. -¿Volver a [http://join.secondlife.com secondlife.com] para crear una cuenta nueva? - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Cuenta nueva..."/> +Si es la primera vez que usas [SECOND_LIFE], debes crear una cuenta para poder iniciar una sesión. + <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Crear cuenta..."/> </notification> <notification name="LoginPacketNeverReceived"> Tenemos problemas de conexión. Puede deberse a un problema de tu conexión a Internet o de [SECOND_LIFE_GRID]. @@ -1437,8 +1521,8 @@ 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]. -¿Dejar el grupo? + Actualmente perteneces al grupo <nolink>[GROUP]</nolink>. +¿Deseas abandonar el grupo? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> <notification name="ConfirmKick"> @@ -1668,83 +1752,128 @@ Se cambiarán miles de regiones, y se provocará un colapso en el espacio del se <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> <notification name="RegionEntryAccessBlocked"> - No estás autorizado en esa región por su nivel de calificación. Puede deberse a que no hay información validada de tu edad. - -Por favor, comprueba que tienes instalado el último visor, y dirÃgete a la Base de Conocimientos para más detalles sobre el acceso a zonas con este nivel de calificación. + Tus preferencias de contenido actuales te impiden visitar la región que has seleccionado. Puedes cambiar las preferencias en Yo > Preferencias > General. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - No estás autorizado en esa región por su nivel de calificación. - -¿Quieres ir a la Base de Conocimientos para aprender más sobre el nivel de calificación? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/es + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="No puedo entrar a esta región dado el nivel de calificación" name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> + <usetemplate ignoretext="Paso a otra región: la región que intentas visitar tiene un contenido solo accesible para los adultos." name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - No estás autorizado en esa región por su nivel de calificación. + La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos. </notification> <notification name="RegionEntryAccessBlocked_Change"> - No estás autorizado en esta región por tus preferencias sobre el nivel de calificación. - -Para entrar en la región que deseas, cambia tu preferencia de nivel de calificación. Esto te permitirá buscar contenidos [REGIONMATURITY] y tener acceso a ellos. Para deshacer los cambios, elige Yo > Preferencias > General. + La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Podemos cambiar tus preferencias o tú puedes cancelar la visita. Después de cambiar tus preferencias, intenta otra vez acceder a la región. <form name="form"> - <button name="OK" text="Cambiar las preferencias"/> - <button default="true" name="Cancel" text="Cerrar"/> - <ignore name="ignore" text="Mis preferencias sobre nivel de calificación me impiden entrar a esta región"/> + <button name="OK" text="Cambiar preferencias"/> + <button default="true" name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Paso a otra región: tus preferencias de contenido no te permiten visitar la región que has seleccionado."/> + </form> + </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + Estamos experimentando dificultades técnicas con el teleporte porque tus preferencias no están sincronizadas con el servidor. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + Tus preferencias de contenido actuales te impiden visitar la región que has seleccionado. Puedes cambiar las preferencias en Yo > Preferencias > General. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos. + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="Teleportarme: la región que intentas visitar tiene un contenido solo accesible para los adultos." name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Podemos cambiar tus preferencias y proceder a teleportarte o bien tú puedes cancelar el teleporte. + <form name="form"> + <button name="OK" text="Cambiar y continuar"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Teleportar (reiniciable): tus preferencias de contenido no te permiten visitar la región que has seleccionado."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Puedes cambiar tus preferencias o bien cancelar el teleporte. Después de cambiar tus preferencias, intenta teleportarte otra vez. + <form name="form"> + <button name="OK" text="Cambiar preferencias"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Teleportar (no reiniciable): tus preferencias de contenido no te permiten visitar la región que has seleccionado."/> </form> </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + Estamos experimentando dificultades técnicas con el teleporte porque tus preferencias no están sincronizadas con el servidor. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - Tu preferencia de nivel de calificación actual es [RATING]. + No recibirás más notificaciones cuando vayas a visitar una región con un contenido [RATING]. En el futuro, puedes cambiar tus preferencias de contenido en Yo > Preferencias > General en la barra de menús. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + En este momento no se pueden cambiar tus preferencias para ver el contenido [PREFERRED_MATURITY]. Tus preferencias se han restablecido para que puedas ver el contenido [ACTUAL_MATURITY]. Si deseas cambiar las preferencias otra vez, en la barra de menús, selecciona Yo > Preferencias > General. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - No puedes reclamar este terreno por su nivel de calificación. Puede deberse a que no hay información validada de tu edad. - -Por favor, comprueba que tienes instalado el último visor, y dirÃgete a la Base de Conocimientos para más detalles sobre el acceso a zonas con este nivel de calificación. + Tus preferencias actuales de calificación de contenido te impiden reclamar el terreno que has seleccionado. Puedes cambiar las preferencias en Yo > Preferencias > General. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - No puedes reclamar este terreno por su nivel de calificación. - -¿Quieres ir a la Base de Conocimientos para más información sobre el nivel de calificación? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + Solo los adultos pueden reclamar este terreno. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/es + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="No puedo reclamar este terreno dado el nivel de calificación" name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> + <usetemplate ignoretext="Solo los adultos pueden reclamar este terreno." name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - No puedes reclamar este terreno debido a su nivel de calificación. + El terreno que intentas reclamar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + El terreno que intentas reclamar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos. </notification> <notification name="LandClaimAccessBlocked_Change"> - No puedes reclamar este terreno por tus preferencias sobre el nivel de calificación. - -Puedes pulsar 'Cambiar las Preferencias' para incrementar las preferencias del nivel de calificación y, asÃ, poder entrar. En adelante, podrás buscar y acceder a contenido [REGIONMATURITY]. Si más adelante quieres deshacer este cambio, ve a Yo > Preferencias > General. - <usetemplate ignoretext="Mis preferencias sobre el nivel de calificación me impiden reclamar este terreno" name="okcancelignore" notext="Cerrar" yestext="Cambiar preferencia"/> + El terreno que intentas reclamar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Podemos cambiar tus preferencias y después puedes volver a intentar reclamar el terreno. + <form name="form"> + <button name="OK" text="Cambiar preferencias"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Tus preferencias de contenido no te permiten reclamar el terreno que has seleccionado."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - No puedes comprar este terreno por su nivel de calificación. Puede deberse a que no hay información validada de tu edad. - -Por favor, comprueba que tienes instalado el último visor, y dirÃgete a la Base de Conocimientos para más detalles sobre el acceso a zonas con este nivel de calificación. + Tus preferencias actuales de calificación de contenido te impiden comprar el terreno que has seleccionado. Puedes cambiar las preferencias en Yo > Preferencias > General. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - No puedes comprar este terreno por tus preferencias de nivel de calificación. - -¿Quieres ir a la Base de Conocimientos para más información sobre el nivel de calificación? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Solo los adultos pueden comprar este terreno. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/es + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="No puedo comprar este terreno dado el nivel de calificación" name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> + <usetemplate ignoretext="Solo los adultos pueden comprar este terreno." name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - No puedes comprar este terreno por su nivel de calificación. + El terreno que intentas comprar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + El terreno que intentas comprar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos. </notification> <notification name="LandBuyAccessBlocked_Change"> - No puedes comprar este terreno por tus preferencias sobre el nivel de calificación. - -Puedes pulsar 'Cambiar las Preferencias' para incrementar las preferencias del nivel de calificación y, asÃ, poder entrar. En adelante, podrás buscar y acceder a contenido [REGIONMATURITY]. Si más adelante quieres deshacer este cambio, ve a Yo > Preferencias > General. - <usetemplate ignoretext="Mis preferencias sobre el nivel de calificación me impiden comprar el terreno" name="okcancelignore" notext="Cerrar" yestext="Cambiar preferencia"/> + El terreno que intentas comprar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Podemos cambiar tus preferencias y después puedes volver a intentar comprar el terreno. + <form name="form"> + <button name="OK" text="Cambiar preferencias"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Tus preferencias de contenido no te permiten comprar el terreno que has seleccionado."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Hay demasiados prims seleccionados. Por favor, selecciona [MAX_PRIM_COUNT] o menos y vuelve a intentarlo @@ -1799,10 +1928,9 @@ Puedes pulsar 'Cambiar las Preferencias' para incrementar las preferen </form> </notification> <notification label="Cambiada la calificación de la región" name="RegionMaturityChange"> - Se ha actualizado el nivel de calificación de esta región. + Se ha cambiando el nivel de calificación de esta región. Puede que lleve algún tiempo hasta que el cambio se vea reflejado en el mapa. - -Para entrar a regiones Adultas, los Residentes deben haber verificado su cuenta, bien verificando la edad o bien verificando una forma de pago. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="Desajuste en la versión de voz" name="VoiceVersionMismatch"> Esta versión de [APP_NAME] no es compatible con la prestación de voz de esta región. Para que el chat de voz funcione correctamente debes actualizar [APP_NAME]. @@ -1920,7 +2048,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"/> @@ -2085,14 +2219,11 @@ PublÃcala en una página web para que otros puedan acceder fácilmente a esta p <usetemplate ignoretext="Ponerme la ropa que estoy creando mientras modifico mi apariencia" name="okcancelignore" notext="No" yestext="SÃ"/> </notification> <notification name="NotAgeVerified"> - Para acceder al contenido Adulto y los lugares de Second Life con dicho carácter, debes tener por lo menos 18 años. Visita la página de verificación de edad para confirmar que tienes más de 18 años. -Al hacerlo se iniciará el navegador web. - -[_URL] - <url name="url" option="0"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="No he verificado mi edad" name="okcancelignore" notext="Cancelar" yestext="Ir a Verificación de la edad"/> + El lugar que intentas visitar tiene el acceso restringido a los Residentes mayores de 18 años. + <usetemplate ignoretext="No tengo la edad suficiente para visitar áreas restringidas por edad." name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + Localización restringida para mayores de 18 años. </notification> <notification name="Cannot enter parcel: no payment info on file"> Para visitar este sitio debes haber aportado información de pago en tu cuenta. ¿Quieres ir al sitio web de [SECOND_LIFE] y configurar esto? @@ -2128,10 +2259,10 @@ Al hacerlo se iniciará el navegador web. Asunto: [SUBJECT], Mensaje: [MESSAGE] </notification> <notification name="FriendOnline"> - [NAME] está conectado + <nolink>[NAME]</nolink> está conectado </notification> <notification name="FriendOffline"> - [NAME] está desconectado + <nolink>[NAME]</nolink> está desconectado </notification> <notification name="AddSelfFriend"> Aunque eres muy agradable, no puedes añadirte como amigo a ti mismo. @@ -2244,14 +2375,16 @@ Por favor, selecciona un sólo objeto. Se ha rehusado tu tarjeta de visita. </notification> <notification name="TeleportToLandmark"> - Puedes teleportarte a lugares como '[NAME]' 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 'Teleportar' 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 'Teleportar'.) + Para teleportarte a lugares como '[NAME]', pulsa el botón "Lugares", + y selecciona la pestaña Hitos en la ventana que se abre. Pulsa en un + hito para seleccionarlo y luego pulsa 'Teleportar' 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 'Teleportar'.) </notification> <notification name="TeleportToPerson"> - Puedes contactar con un Residente como '[NAME]' abriendo el panel Gente en el lado derecho de tu pantalla. -Elige al Residente de la lista y pulsa 'MI' en la parte inferior del panel. -(También puedes pulsar dos veces en su nombre o pulsarlo con el botón derecho y elegir 'MI'). + Para ponerte en contacto con Residentes como '[NAME]', pulsa el botón "Gente", selecciona un Residente en la ventana que se abre y después pulsa en 'MI' 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 'MI'). </notification> <notification name="CantSelectLandFromMultipleRegions"> No puedes seleccionar un terreno que cruce las fronteras entre servidores. @@ -2272,6 +2405,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: @@ -2348,6 +2484,23 @@ Aquà no puedes volar. <notification name="NoBuild"> Este terreno tiene desactivado el poder construir. Aquà no puedes ni construir ni crear objetos. </notification> + <notification name="PathfindingDirty"> + La región contiene cambios de pathfinding pendientes. Si tienes derechos de construcción, puedes recargarla pulsando el botón “Recargar regiónâ€. + </notification> + <notification name="DynamicPathfindingDisabled"> + Esta región no tiene activado el pathfinding dinámico. Los objetos programados que utilicen llamadas LSL de pathfinding pueden tener un comportamiento inesperado en ella. + </notification> + <notification name="PathfindingRebakeNavmesh"> + Si cambias ciertos objetos en esta región, otros objetos móviles podrÃan tener un comportamiento incorrecto. Para que los objetos móviles se comporten correctamente, pulsa el botón “Recargar la regiónâ€. Si quieres más información, elige “Ayudaâ€. + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Ayuda" ignoretext="Si cambias ciertos objetos en esta región, otros objetos móviles podrÃan tener un comportamiento incorrecto." name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Se ha producido un error. Puede haber ocurrido un problema en la red o el servidor, o quizás no tengas derechos de construcción. Este problema podrÃa resolverse cerrando la sesión e iniciando una sesión nueva. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> Esta parcela oculta los avatares y el chat de texto de otras parcelas. No podrás ver a los residentes que estén fuera la parcela ni ellos podrán verte a ti. El chat de texto regular del canal 0 también está bloqueado. </notification> @@ -2366,9 +2519,7 @@ Los scripts no funcionan aquÃ, excepto los pertenecientes al propietario del te Sólo puedes reclamar terreno público de la región en que estás. </notification> <notification name="RegionTPAccessBlocked"> - No estás autorizado en esa región por su nivel de calificación. Debes validar tu edad y/o instalar el último visor. - -Por favor, dirÃgete a la Base de Conocimientos para más detalles sobre el acceso a zonas con este nivel de calificación. + Tus preferencias de contenido actuales te impiden visitar la región que has seleccionado. Puedes cambiar las preferencias en Yo > Preferencias > General. </notification> <notification name="URBannedFromRegion"> Se te ha prohibido el acceso a la región. @@ -2379,11 +2530,11 @@ Por favor, dirÃgete a la Base de Conocimientos para más detalles sobre el acce <notification name="ImproperPaymentStatus"> No tienes el estado de pago adecuado para entrar a esta región. </notification> - <notification name="MustGetAgeRgion"> - Debes tener verificada la edad para entrar a esta región + <notification name="MustGetAgeRegion"> + Solo pueden acceder a esta región los mayores de 18 años. </notification> <notification name="MustGetAgeParcel"> - Debes haber verificado tu edad para entrar a esta parcela. + Para acceder a esta parcela debes ser mayor de 18 años. </notification> <notification name="NoDestRegion"> No se ha encontrada la región de destino. @@ -2483,14 +2634,35 @@ Por favor, vuelve a intentarlo en unos momentos. </form> </notification> <notification name="TeleportOffered"> - [NAME_SLURL] te ha ofrecido teleportarte a su posición: + [NAME_SLURL] te ofrece teleportarte a su localización: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="Teleportar"/> <button name="Cancel" text="Cancelar"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] te ofrece teleportarte a su localización: + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Esta región tiene un contenido [REGION_CONTENT_MATURITY, pero tus preferencias actuales no te autorizan a ver los contenidos [REGION_CONTENT_MATURITY]. Podemos cambiar tus preferencias y proceder a teleportarte o bien tú puedes cancelar el teleporte. + <form name="form"> + <button name="Teleport" text="Cambiar y continuar"/> + <button name="Cancel" text="Cancelar"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] te ofrece teleportarte a su localización: + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +No obstante, el contenido de esta región solo es accesible para los adultos. + </notification> <notification name="TeleportOfferSent"> Teleporte ofrecido a [TO_NAME] </notification> @@ -2526,10 +2698,10 @@ Por favor, vuelve a intentarlo en unos momentos. </form> </notification> <notification name="FriendshipAccepted"> - [NAME] ha aceptado tu oferta de amistad. + <nolink>[NAME]</nolink> ha aceptado tu ofrecimiento de amistad. </notification> <notification name="FriendshipDeclined"> - [NAME] ha rehusado tu oferta de amistad. + <nolink>[NAME]</nolink> ha rechazado tu ofrecimiento de amistad. </notification> <notification name="FriendshipAcceptedByMe"> Aceptado el ofrecimiento de amistad. @@ -2585,33 +2757,23 @@ Del objeto: <nolink>[OBJECTNAME]</nolink>, propietario: [NAME]? </form> </notification> <notification name="ScriptQuestionCaution"> - Un objeto de nombre '<nolink>[OBJECTNAME]</nolink>', propiedad de '[NAME]', quiere: - -[QUESTIONS] -Si no confias en este objeto y en su creador, deberÃas rehusar esta petición. - -¿Autorizar esta petición? + Atención: El objeto '<nolink>[OBJECTNAME]</nolink>' solicita un acceso total a tu cuenta de dólares Linden. Si le autorizas el acceso, podrá retirar fondos de tu cuenta en cualquier momento o vaciarla por completo, de manera permanente y sin más advertencias. + +Estas solicitudes pocas veces son legÃtimas. No autorices el acceso si no conoces la razón exacta por la que desea el acceso a tu cuenta. <form name="form"> - <button name="Grant" text="Autorizar"/> + <button name="Grant" text="Permitir acceso total"/> <button name="Deny" text="Denegar"/> - <button name="Details" text="Detalles..."/> </form> </notification> <notification name="ScriptDialog"> '<nolink>[TITLE]</nolink>' de [NAME] [MESSAGE] - <form name="form"> - <button name="Mute" text="Ignorar"/> - <button name="Ignore" text="Ignorar"/> - </form> + <form name="form"/> </notification> <notification name="ScriptDialogGroup"> '<nolink>[TITLE]</nolink>' de [GROUPNAME] [MESSAGE] - <form name="form"> - <button name="Mute" text="Ignorar"/> - <button name="Ignore" text="Ignorar"/> - </form> + <form name="form"/> </notification> <notification name="BuyLindenDollarSuccess"> ¡Gracias por tu pago! @@ -2807,6 +2969,18 @@ Con los siguientes residentes: [RESIDENTS] <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> + <notification name="ShareFolderConfirmation"> + Sólo puedes compartir una carpeta en cada momento. + +¿Estás seguro de que quieres compartir los elementos siguientes? + +<nolink>[ITEMS]</nolink> + +Con los siguientes Residentes: + +[RESIDENTS] + <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Aceptar"/> + </notification> <notification name="ItemsShared"> Los elementos se han compartido correctamente. </notification> @@ -2885,6 +3059,10 @@ Has actualizado una textura obtenida mediante bake de [RESOLUTION] para '[B ( [EXISTENCE] segundos con vida ) Has actualizado de manera local una textura obtenida mediante bake de [RESOLUTION] para '[BODYREGION]' después de [TIME] segundos. </notification> + <notification name="LivePreviewUnavailable"> + No se puede mostrar una vista previa de esta textura porque es de tipo 'no copiable' y/o 'no transferible'. + <usetemplate ignoretext="Advertirme si el modo Vista previa inmediata no está disponible para las texturas 'no copiable' y/o 'no transferible'" name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> ¿Estás seguro de que deseas salir de esta multiconferencia? <usetemplate ignoretext="Confirma antes de salir de la llamada" name="okcancelignore" notext="No" yestext="SÃ"/> @@ -3053,6 +3231,62 @@ Al ocultar el botón Hablar se desactiva la función de voz. Esta acción ocultará todos los botones y elementos de menú. Para restaurarlos, pulsa otra vez en [SHORTCUT]. <usetemplate ignoretext="Confirmar antes de ocultar la IU" name="okcancelignore" notext="Cancelar" yestext="OK"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + El indicador de inmaterial de algunos linksets seleccionados se conmutará. + +¿Quieres continuar? + <usetemplate ignoretext="El indicador de inmaterial de algunos linksets seleccionados se conmutará." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' debido a restricciones de los permisos del linkset. Estos linksets se configurarán como '[RESTRICTED_TYPE]'. + +¿Quieres continuar? + <usetemplate ignoretext="Algunos de los linksets seleccionados no pueden configurarse debido a restricciones de los permisos del linkset." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' porque su forma no es convexa. + +¿Quieres continuar? + <usetemplate ignoretext="Algunos de los linksets seleccionados no pueden configurarse porque su forma no es convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + El indicador de inmaterial de algunos linksets seleccionados se conmutará. + +Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' debido a restricciones de los permisos del linkset. Estos linksets se configurarán como '[RESTRICTED_TYPE]'. + +¿Quieres continuar? + <usetemplate ignoretext="El indicador de inmaterial de algunos linksets seleccionados se conmutará y otros no se podrán establecer debido a restricciones de los permisos del linkset." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + El indicador de inmaterial de algunos linksets seleccionados se conmutará. + +Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' porque su forma no es convexa. + +¿Quieres continuar? + <usetemplate ignoretext="El indicador de inmaterial de algunos linksets seleccionados se conmutará y otros no se podrán establecer porque la forma no es convexa" name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' debido a restricciones de los permisos del linkset. Estos linksets se configurarán como '[RESTRICTED_TYPE]'. + +Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' porque su forma no es convexa. Los tipos de utilización de estos linksets no cambiarán. + +¿Quieres continuar? + <usetemplate ignoretext="Algunos de los linksets seleccionados no pueden configurarse debido a restricciones de los permisos del linkset y porque su forma no es convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + El indicador de inmaterial de algunos linksets seleccionados se conmutará. + +Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' debido a restricciones de los permisos del linkset. Estos linksets se configurarán como '[RESTRICTED_TYPE]'. + +Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' porque su forma no es convexa. Los tipos de utilización de estos linksets no cambiarán. + +¿Quieres continuar? + <usetemplate ignoretext="El indicador de inmaterial de algunos linksets seleccionados se conmutará y otros no se podrán establecer debido a restricciones de los permisos del linkset y porque su forma no es convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + El objeto que has seleccionado afecta al navmesh. Al cambiarlo a una Ruta flexible se eliminará del navmesh. + <usetemplate ignoretext="El objeto que has seleccionado afecta al navmesh. Al cambiarlo a una Ruta flexible se eliminará del navmesh." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> <global name="UnsupportedGLRequirements"> Parece que no tienes el hardware apropiado para [APP_NAME]. [APP_NAME] requiere una tarjeta gráfica OpenGL que admita texturas múltiples ('multitexture support'). Si la tienes, comprueba que tienes los últimos 'drivers' para tu tarjeta gráfica, asà como los últimos parches y 'service packs' para tu sistema operativo. @@ -3077,4 +3311,24 @@ También puedes buscar en el Mapa lugares marcados como "Puntos de Informac <global name="You died and have been teleported to your home location"> Has muerto y te has teleportado a tu Base. </global> + <notification name="LocalBitmapsUpdateFileNotFound"> + [FNAME] no se ha podido actualizar porque el archivo ya no se encuentra. +Desactivando futuras actualizaciones de este archivo. + </notification> + <notification name="LocalBitmapsUpdateFailedFinal"> + [FNAME] se ha intentado abrir o descodificar durante [NRETRIES] intentos sin éxito, y ahora se considera roto. +Desactivando futuras actualizaciones de este archivo. + </notification> + <notification name="LocalBitmapsVerifyFail"> + Se ha intentado añadir un archivo de imagen [FNAME] no válido o ilegible, que no se puede abrir ni descodificar. +Intento cancelado. + </notification> + <notification name="PathfindingReturnMultipleItems"> + Vas a devolver [NUM_ITEMS] objetos. ¿Estás seguro de que deseas continuar? + <usetemplate ignoretext="¿Estás seguro de que quieres devolver varios objetos?" name="okcancelignore" notext="No" yestext="SÃ"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + Vas a eliminar [NUM_ITEMS] objetos. ¿Estás seguro de que deseas continuar? + <usetemplate ignoretext="¿Estás seguro de que quieres eliminar varios elementos?" name="okcancelignore" notext="No" yestext="SÃ"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/es/panel_bottomtray.xml b/indra/newview/skins/default/xui/es/panel_bottomtray.xml deleted file mode 100644 index 2b1d017a2d..0000000000 --- a/indra/newview/skins/default/xui/es/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Activa/Desactiva el micrófono"/> - <string name="VoiceControlBtnToolTip" value="Muestra/Oculta el panel del control de voz"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Hablar" label_selected="Hablar" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="Gestos" name="Gesture" tool_tip="Muestra/Oculta los gestos"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Moverme" name="movement_btn" tool_tip="Muestra/Oculta los controles del movimiento"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Visión" name="camera_btn" tool_tip="Muestra/Oculta los controles de la cámara"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button label="" name="snapshots" tool_tip="Hacer una foto"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="Construir" name="build_btn" tool_tip="Muestra/Oculta las herramientas de construcción"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="Buscar" name="search_btn" tool_tip="Muestra/Oculta la búsqueda"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Mapa" name="world_map_btn" tool_tip="Muestra/Oculta el mapa del mundo"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Minimapa" name="mini_map_btn" tool_tip="Muestra/Oculta el minimapa"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Conversaciones"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="Notificaciones"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> 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_group_invite.xml b/indra/newview/skins/default/xui/es/panel_group_invite.xml index 0d877f78f2..319e9d0f1b 100644 --- a/indra/newview/skins/default/xui/es/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/es/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> Alguno de los Residentes que has elegido ya están en el grupo: no se les enviará la invitación. </panel.string> + <panel.string name="invite_selection_too_large"> + Las invitaciones al grupo no se han enviado: has seleccionado demasiados Residentes. Solo se permiten 100 invitaciones al grupo por solicitud. + </panel.string> <text bottom_delta="-96" height="72" name="help_text" width="214"> Puedes elegir a varios Residentes para invitarles a tu grupo. Para empezar, pulsa 'Abrir el selector de residentes'. </text> diff --git a/indra/newview/skins/default/xui/es/panel_login.xml b/indra/newview/skins/default/xui/es/panel_login.xml index 0e94cbe70b..1d7f077fe7 100644 --- a/indra/newview/skins/default/xui/es/panel_login.xml +++ b/indra/newview/skins/default/xui/es/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/index.php?lang=es-ES - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php?lang=es </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + INICIAR SESIÓN + </text> <text name="username_text"> Nombre de usuario: </text> @@ -15,34 +15,32 @@ <text name="password_text"> Contraseña: </text> - <check_box label="Recordar la contraseña" name="remember_check"/> - <button label="Iniciar sesión" name="connect_btn"/> - <text name="mode_selection_text"> - Modo: - </text> - <combo_box name="mode_combo" tool_tip="Selecciona el modo. Elige Básico para una exploración rápida y fácil y para chatear. Elige Avanzado para tener acceso a más funciones."> - <combo_box.item label="Básico" name="Basic"/> - <combo_box.item label="Avanzado" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Empezar en: </text> <combo_box name="start_location_combo"> <combo_box.item label="Mi última posición" name="MyLastLocation"/> <combo_box.item label="Mi Base" name="MyHome"/> - <combo_box.item label="<Escribe en qué región>" name="Typeregionname"/> + <combo_box.item label="<Escribe el nombre de la región>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Registrarme + <layout_panel name="links_login_panel"> + <text name="login_help"> + ¿Necesitas ayuda para conectarte? </text> <text name="forgot_password_text"> ¿Olvidaste el nombre de usuario o la contraseña? </text> - <text name="login_help"> - ¿Necesitas ayuda para conectarte? + <button label="Iniciar sesión" name="connect_btn"/> + <check_box label="Recordar la contraseña" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + CREA TU CUENTA </text> + <button label="Iniciar ahora" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/es/panel_my_profile.xml b/indra/newview/skins/default/xui/es/panel_my_profile.xml deleted file mode 100644 index 29e5e6f652..0000000000 --- a/indra/newview/skins/default/xui/es/panel_my_profile.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Perfil" name="panel_profile"> - <string name="no_partner_text" value="Ninguno/a"/> - <string name="no_group_text" value="Ninguno"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="scroll_content_panel"> - <panel name="second_life_image_panel"> - <text name="display_name_descr_text"> - Nombre de usuario - </text> - <text name="name_descr_text"> - Nombre mostrado - </text> - <button label="Perfil" name="see_profile_btn" tool_tip="Ver el perfil de este avatar"/> - </panel> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/es/panel_navigation_bar.xml b/indra/newview/skins/default/xui/es/panel_navigation_bar.xml index 1b7f5d5a9f..d36c6283bc 100644 --- a/indra/newview/skins/default/xui/es/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/es/panel_navigation_bar.xml @@ -3,7 +3,7 @@ <layout_stack name="nvp_stack"> <layout_panel name="navigation_layout_panel"> <panel name="navigation_panel"> - <pull_button name="back_btn" tool_tip="Volver a lo localización anterior"/> + <pull_button name="back_btn" tool_tip="Volver a la localización anterior"/> <pull_button name="forward_btn" tool_tip="Ir una localización adelante"/> <button name="home_btn" tool_tip="Teleportar a mi Base"/> <location_input label="Lugar" name="location_combo"/> 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_nearby_chat_bar.xml b/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml index af2b6e920b..e6ca59f912 100644 --- a/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="chat_bar"> +<panel name="nearby_chat"> <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/panel_notes.xml b/indra/newview/skins/default/xui/es/panel_notes.xml deleted file mode 100644 index 00d4caf468..0000000000 --- a/indra/newview/skins/default/xui/es/panel_notes.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Notas y Privacidad" name="panel_notes"> - <layout_stack name="layout"> - <layout_panel name="notes_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <text name="status_message" value="Mis notas privadas:"/> - <text name="status_message2" value="Permitir que esta persona:"/> - <check_box label="Vea si estoy conectado" name="status_check"/> - <check_box label="Me vea en el mapa" name="map_check"/> - <check_box label="Edite, borre o coja mis objetos" name="objects_check"/> - </panel> - </scroll_container> - </layout_panel> - <layout_panel name="notes_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Añadir como amigo" name="add_friend" tool_tip="Ofrecer amistad a este Residente"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="MI" name="im" tool_tip="Abrir una sesión de mensajes instantáneos"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Llamar" name="call" tool_tip="Llamar a este Residente"/> - </layout_panel> - <layout_panel name="show_on_map_btn_lp"> - <button label="Mapa" name="show_on_map_btn" tool_tip="Mostrar al Residente en el mapa"/> - </layout_panel> - <layout_panel name="teleport_btn_lp"> - <button label="Teleporte" name="teleport" tool_tip="Ofrecer teleporte"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</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..b0b6114e88 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,7 @@ <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="Traducción…" name="ok_btn"/> + <button label="Reemplazo automático..." name="autoreplace_showgui"/> + <button label="Revisión ortográfica..." name="spellcheck_showgui"/> </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_profile.xml b/indra/newview/skins/default/xui/es/panel_profile.xml deleted file mode 100644 index 334c0541af..0000000000 --- a/indra/newview/skins/default/xui/es/panel_profile.xml +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Perfil" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=es-ES - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=es - </string> - <string name="my_account_link_url" value="http://secondlife.com/my/account/index.php?lang=es-ES"/> - <string name="no_partner_text" value="Ninguno"/> - <string name="no_group_text" value="Ninguno"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <panel name="second_life_image_panel"> - <text name="title_sl_descr_text" value="[SECOND_LIFE]:"/> - </panel> - <panel name="first_life_image_panel"> - <text name="title_rw_descr_text" value="Mundo real:"/> - </panel> - <text name="title_member_text" value="Residente desde:"/> - <text name="title_acc_status_text" value="Estado de la cuenta:"/> - <text name="title_partner_text" value="Compañero/a:"/> - <panel name="partner_data_panel"> - <text initial_value="(obteniendo)" name="partner_text"/> - </panel> - <text name="title_groups_text" value="Grupos:"/> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> - <layout_stack name="layout_verb_buttons"> - <layout_panel name="profile_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Añadir como amigo" name="add_friend" tool_tip="Ofrecer amistad a este Residente"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="MI" name="im" tool_tip="Abrir una sesión de mensajes instantáneos"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Llamar" name="call" tool_tip="Llamar a este Residente"/> - </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="Teleporte" name="teleport" tool_tip="Ofrecer teleporte"/> - </layout_panel> - <layout_panel name="overflow_btn_lp"> - <menu_button label="â–¼" name="overflow_btn" tool_tip="Pagar dinero al Residente o compartir algo del inventario con él"/> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="profile_me_buttons_panel"> - <button label="Editar el perfil" name="edit_profile_btn" tool_tip="Modificar tu información personal"/> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/es/panel_profile_view.xml b/indra/newview/skins/default/xui/es/panel_profile_view.xml deleted file mode 100644 index cb374dee52..0000000000 --- a/indra/newview/skins/default/xui/es/panel_profile_view.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_target_profile"> - <string name="status_online"> - Conectado/a - </string> - <string name="status_offline"> - Desconectado/a - </string> - <text name="display_name_label" value="Nombre mostrado:"/> - <text name="solo_username_label" value="Nombre de usuario:"/> - <text name="status" value="Conectado/a"/> - <text name="user_name_small" value="Jack, ¿has visto esto? Es un nombre larguÃsimo."/> - <button name="copy_to_clipboard" tool_tip="Copiar al portapapeles"/> - <text name="user_label" value="Nombre de usuario:"/> - <tab_container name="tabs"> - <panel label="PERFIL" name="panel_profile"/> - <panel label="DESTACADOS" name="panel_picks"/> - <panel label="NOTAS Y PRIVACIDAD" name="panel_notes"/> - </tab_container> -</panel> diff --git a/indra/newview/skins/default/xui/es/panel_region_debug.xml b/indra/newview/skins/default/xui/es/panel_region_debug.xml index 64162220a6..71bdba1a25 100644 --- a/indra/newview/skins/default/xui/es/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/es/panel_region_debug.xml @@ -36,5 +36,5 @@ <button label="?" left="297" name="top_scripts_help"/> <button label="Reiniciar la región" name="restart_btn" tool_tip="Cuenta atrás de 2 minutos y reiniciar la región"/> <button label="?" name="restart_help"/> - <button label="Retrasar el reinicio" name="cancel_restart_btn" tool_tip="Retrasar una hora el reinicio de la región"/> + <button label="Cancelar reinicio" name="cancel_restart_btn" tool_tip="Cancelar el reinicio de región"/> </panel> diff --git a/indra/newview/skins/default/xui/es/panel_region_estate.xml b/indra/newview/skins/default/xui/es/panel_region_estate.xml index c51c3815d1..6089dfb8db 100644 --- a/indra/newview/skins/default/xui/es/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/es/panel_region_estate.xml @@ -10,7 +10,7 @@ (desconocido) </text> <text name="owner_text"> - Propietario del Estado: + Propietario del estado: </text> <text name="estate_owner"> (desconocido) @@ -23,10 +23,10 @@ <check_box label="Permitir el acceso público" name="externally_visible_check"/> <button label="?" name="externally_visible_help"/> <text name="Only Allow"> - Restringir el acceso a cuentas verificadas por: + Permitir únicamente el acceso a los Residentes que: </text> - <check_box label="Información de pago aportada" name="limit_payment" tool_tip="Expulsa a los Residentes no identificados."/> - <check_box label="Verificación de la edad" name="limit_age_verified" tool_tip="Expulsa a los Residentes que no hayan verificado su edad. Más información en [SUPPORT_SITE]."/> + <check_box label="Han aportado la información de pago." name="limit_payment" tool_tip="Para poder acceder a este estado los Residentes deben haber aportado información de pago en su cuenta. Para más información, ver [SUPPORT_SITE]."/> + <check_box label="Son mayores de 18 años" name="limit_age_verified" tool_tip="Para poder acceder a este estado, los Residentes deben ser mayores de 18 años. Para más información, consulta [SUPPORT_SITE]."/> <check_box label="Permitir el chat de voz" name="voice_chat_check"/> <button label="?" name="voice_chat_help"/> <check_box label="Permitir el teleporte a cualquier punto" name="allow_direct_teleport"/> @@ -39,7 +39,7 @@ </string> <button label="?" name="abuse_email_address_help"/> <button label="Aplicar" name="apply_btn"/> - <button label="Expulsar a un Residente del Estado..." name="kick_user_from_estate_btn"/> + <button label="Expulsar a un Residente del estado..." name="kick_user_from_estate_btn"/> <button label="Enviar un mensaje al estado..." name="message_estate_btn"/> <text name="estate_manager_label"> Administradores del estado: diff --git a/indra/newview/skins/default/xui/es/panel_region_texture.xml b/indra/newview/skins/default/xui/es/panel_region_texture.xml deleted file mode 100644 index 047e8f2f30..0000000000 --- a/indra/newview/skins/default/xui/es/panel_region_texture.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Texturas del terreno" name="Textures"> - <text name="region_text_lbl"> - Región: - </text> - <text name="region_text"> - desconocida - </text> - <text name="detail_texture_text" width="380"> - Texturas del terreno (se requieren archivos .tga de 512x512 y 24 bites) - </text> - <text name="height_text_lbl"> - 1 (Baja) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (Alta) - </text> - <text name="height_text_lbl5"> - Rangos de la elevación de la textura - </text> - <text name="height_text_lbl6"> - Noroeste - </text> - <text name="height_text_lbl7"> - Noreste - </text> - <text name="height_text_lbl8"> - Suroeste - </text> - <text name="height_text_lbl9"> - Sureste - </text> - <spinner label="Baja" name="height_start_spin_0"/> - <spinner label="Baja" name="height_start_spin_1"/> - <spinner label="Baja" name="height_start_spin_2"/> - <spinner label="Baja" name="height_start_spin_3"/> - <spinner label="Alta" name="height_range_spin_0"/> - <spinner label="Alta" name="height_range_spin_1"/> - <spinner label="Alta" name="height_range_spin_2"/> - <spinner label="Alta" name="height_range_spin_3"/> - <text name="height_text_lbl10"> - Estos valores representan la gama de mezclas para las texturas superiores. - </text> - <text name="height_text_lbl11"> - Midiendo en metros, el valor BAJA es la altura MÃXIMA de la textura #1, y el valor ALTA es la altura MÃNIMA de la textura #4. - </text> - <text name="height_text_lbl12"> - y el valor ALTA es la altura MÃNIMA de la textura #4. - </text> - <button label="Aplicar" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/es/panel_script_ed.xml b/indra/newview/skins/default/xui/es/panel_script_ed.xml index 46952c6974..4c4077b96f 100644 --- a/indra/newview/skins/default/xui/es/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/es/panel_script_ed.xml @@ -22,6 +22,8 @@ <menu label="Archivo" name="File"> <menu_item_call label="Guardar" name="Save"/> <menu_item_call label="Deshacer todos los cambios" name="Revert All Changes"/> + <menu_item_call label="Cargar desde archivo..." name="LoadFromFile"/> + <menu_item_call label="Guardar en archivo..." name="SaveToFile"/> </menu> <menu label="Editar" name="Edit"> <menu_item_call label="Deshacer" name="Undo"/> diff --git a/indra/newview/skins/default/xui/es/panel_script_question_toast.xml b/indra/newview/skins/default/xui/es/panel_script_question_toast.xml new file mode 100644 index 0000000000..a2d0237da0 --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_script_question_toast.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel label="script_question_panel" name="panel_script_question_toast"> + <panel label="buttons_panel" name="buttons_panel"/> +</panel> diff --git a/indra/newview/skins/default/xui/es/panel_side_tray.xml b/indra/newview/skins/default/xui/es/panel_side_tray.xml deleted file mode 100644 index cf5afb3cd1..0000000000 --- a/indra/newview/skins/default/xui/es/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Manejar la barra lateral." name="sidebar_openclose" tab_title="Barra lateral"/> - <sidetray_tab description="Inicio." name="sidebar_home" tab_title="Inicio"> - <panel label="Inicio" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Edita tu perfil público y tus destacados." name="sidebar_me" tab_title="Mi perfil"> - <panel_container name="panel_container"> - <panel label="Yo" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Encuentra a tus amigos, contactos y gente que esté cerca." name="sidebar_people" tab_title="Gente"> - <panel_container name="panel_container"> - <panel label="Perfil del grupo" name="panel_group_info_sidetray"/> - <panel label="Residentes y objetos ignorados" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Encontrar lugares donde ir o que ya visitaste." label="Lugares" name="sidebar_places" tab_title="Lugares"> - <panel label="Lugares" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="Mira tu inventario." name="sidebar_inventory" tab_title="Mi inventario"> - <panel label="Modificar el inventario" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Cambia tu apariencia y tu 'look' actual." name="sidebar_appearance" tab_title="Mi apariencia"> - <panel label="Modificar la apariencia" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> 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..7eead3bc18 100644 --- a/indra/newview/skins/default/xui/es/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/es/panel_status_bar.xml @@ -15,10 +15,10 @@ <panel.string name="buycurrencylabel"> [AMT] L$ </panel.string> - <panel name="balance_bg"> + <panel left="-410" name="balance_bg" width="200"> <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/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/es/panel_volume_pulldown.xml new file mode 100644 index 0000000000..426783aa8e --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater" width="215"> + <slider label="General" label_width="55" name="System Volume" width="155"/> + <slider label="Botones" label_width="55" name="UI Volume" width="155"/> + <slider label="Ambiental" label_width="55" name="Wind Volume" width="155"/> + <slider label="Sonidos" label_width="55" name="SFX Volume" width="155"/> + <check_box name="gesture_audio_play_btn" tool_tip="Activar sonidos de los gestos"/> + <slider label="Música" label_width="55" name="Music Volume" width="155"/> + <check_box name="enable_music" tool_tip="Activar música en streaming"/> + <slider label="Media" label_width="55" name="Media Volume" width="155"/> + <check_box name="enable_media" tool_tip="Activar media en streaming"/> + <slider label="Voz" label_width="55" name="Voice Volume" width="155"/> + <check_box name="enable_voice_check" tool_tip="Activar el chat de voz"/> +</panel> diff --git a/indra/newview/skins/default/xui/es/sidepanel_inventory.xml b/indra/newview/skins/default/xui/es/sidepanel_inventory.xml index 79d0cb84e8..f68dcc65e3 100644 --- a/indra/newview/skins/default/xui/es/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/es/sidepanel_inventory.xml @@ -2,47 +2,24 @@ <panel label="Cosas" name="objects panel"> <panel label="" name="sidepanel__inventory_panel"> <layout_stack name="inventory_layout_stack"> - <layout_panel name="inbox_outbox_layout_panel"> - <layout_stack name="inbox_outbox_layout_stack"> - <layout_panel name="inbox_layout_panel"> - <panel label="" name="marketplace_inbox"> - <string name="InboxLabelWithArg"> - Objetos recibidos ([NUM]) - </string> - <string name="InboxLabelNoArg"> - Objetos recibidos - </string> - <button label="Objetos recibidos" name="inbox_btn"/> - <text name="inbox_fresh_new_count"> - [NUM] nuevos - </text> - <panel tool_tip="Drag and drop items to your inventory to manage and use them"> - <text name="inbox_inventory_placeholder"> - Aquà se entregarán las compras realizadas en el mercado. - </text> - </panel> - </panel> - </layout_panel> - <layout_panel name="outbox_layout_panel"> - <panel label="" name="marketplace_outbox"> - <string name="OutboxLabelWithArg"> - Buzón de salida de comerciante ([NUM]) - </string> - <string name="OutboxLabelNoArg"> - Buzón de salida de comerciante - </string> - <button label="Buzón de salida de comerciante" name="outbox_btn"/> - <button label="" name="outbox_sync_btn" tool_tip="Poner en el escaparate de Mi Mercado"/> - <panel> - <panel name="outbox_inventory_placeholder_panel"> - <text name="outbox_inventory_placeholder_title"> - Cargando... - </text> - </panel> - </panel> - </panel> - </layout_panel> - </layout_stack> + <layout_panel name="inbox_layout_panel"> + <panel label="" name="marketplace_inbox"> + <string name="InboxLabelWithArg"> + Objetos recibidos ([NUM]) + </string> + <string name="InboxLabelNoArg"> + Objetos recibidos + </string> + <button label="Objetos recibidos" name="inbox_btn"/> + <text name="inbox_fresh_new_count"> + [NUM] nuevos + </text> + <panel tool_tip="Drag and drop items to your inventory to manage and use them"> + <text name="inbox_inventory_placeholder"> + Aquà se entregarán las compras realizadas en el mercado. + </text> + </panel> + </panel> </layout_panel> </layout_stack> <panel name="button_panel"> diff --git a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml index ef7c6781be..176247f90e 100644 --- a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (desconocidas) </panel.string> + <panel.string name="unknown_multiple"> + (desconocido/múltiple) + </panel.string> <panel.string name="public"> (público) </panel.string> diff --git a/indra/newview/skins/default/xui/es/sidepanel_task_info.xml b/indra/newview/skins/default/xui/es/sidepanel_task_info.xml index bd814ecc66..9da2958953 100644 --- a/indra/newview/skins/default/xui/es/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/es/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> No puedes modificar estos objetos </panel.string> + <panel.string name="text modify info 5"> + No se puede modificar este objeto a través del lÃmite de una región + </panel.string> + <panel.string name="text modify info 6"> + No se pueden modificar estos objetos a través del lÃmite de una región + </panel.string> <panel.string name="text modify warning"> Este objeto tiene partes enlazadas </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Precio: L$" name="Edit Cost"/> <check_box label="Mostrar en la búsqueda" name="search_check" tool_tip="Permitir que la gente vea este objeto en los resultados de la búsqueda"/> + <text name="pathfinding_attributes_label"> + Atributos de pathfinding: + </text> <text name="B:"> B: </text> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index 4cae6ce5e8..52bcab54e5 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -128,7 +128,7 @@ Salir </string> <string name="create_account_url"> - http://join.secondlife.com/index.php?lang=es-ES + http://join.secondlife.com/index.php?lang=es-ES&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> Ya no puedes acceder a Second Life con el visor que estás utilizando. Visita la siguiente página para descargar un nuevo visor: @@ -171,9 +171,9 @@ Actualmente, solo se permite iniciar sesión a los empleados. Consulta www.secondlife.com/status si deseas obtener actualizaciones. </string> <string name="LoginFailedPremiumOnly"> - Se ha restringido de manera temporal el inicio de sesión en Second Life con el fin de garantizar una experiencia óptima a nuestros residentes. - -Aquellos usuarios que dispongan de cuentas gratuitas no podrán acceder a Second Life durante este perÃodo de tiempo, ya que el propósito de esta medida es obtener espacio suficiente para los residentes que hayan pagado por acceder a Second Life. + Las conexiones a Second Life se han restringido provisionalmente para garantizar que los usuarios que ya están conectados tengan la mejor experiencia posible. + +Durante este tiempo, las personas con cuentas gratuitas no podrán acceder a Second Life, ya que tienen prioridad los usuarios con una cuenta de pago. </string> <string name="LoginFailedComputerProhibited"> No se puede acceder a Second Life desde este ordenador. @@ -330,17 +330,35 @@ Intenta iniciar sesión de nuevo en unos instantes. Aquà se puede arrastrar sólo un Ãtem </string> <string name="TooltipPrice" value="[AMOUNT] L$:"/> + <string name="TooltipOutboxDragToWorld"> + No puedes colocar objetos en tu buzón de salida de comerciante + </string> <string name="TooltipOutboxNoTransfer"> - Uno o varios de estos objetos no se pueden vender o transferir a otro usuario. + Uno o varios de estos objetos no se pueden vender o transferir. + </string> + <string name="TooltipOutboxNotInInventory"> + Tu buzón de salida de comerciante sólo puede aceptar objetos procedentes directamente de tu inventario </string> <string name="TooltipOutboxWorn"> - Llevas puestos uno o más de estos objetos. QuÃtatelos del avatar y vuelve a intentar moverlos. + No puedes poner artÃculos que llevas puestos en el buzón de salida de comerciante + </string> + <string name="TooltipOutboxCallingCard"> + No puedes poner tarjetas de visita en tu buzón de salida de comerciante </string> <string name="TooltipOutboxFolderLevels"> - Esta carpeta tiene demasiados niveles de subcarpetas. Reorganiza las carpetas interiores de forma que tengas como máximo 4 niveles de profundidad (la carpeta raÃz contiene A, que contiene B, que contiene C). + La profundidad de carpetas anidadas excede de 3 + </string> + <string name="TooltipOutboxTooManyFolders"> + El número de subcarpetas de la carpeta de nivel superior excede de 20 </string> <string name="TooltipOutboxTooManyObjects"> - Esta carpeta contiene más de 200 objetos. Guarda algunos objetos en una caja para disminuir su cantidad. + El número de elementos de la carpeta de nivel superior excede de 200 + </string> + <string name="TooltipDragOntoOwnChild"> + No puedes mover una carpeta a su carpeta secundaria + </string> + <string name="TooltipDragOntoSelf"> + No puedes mover una carpeta dentro de sà misma </string> <string name="TooltipHttpUrl"> Pulsa para ver esta página web @@ -586,6 +604,9 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="mesh"> red </string> + <string name="AvatarEditingAppearance"> + (Edición de Apariencia) + </string> <string name="AvatarAway"> Ausente </string> @@ -850,6 +871,9 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="ScriptQuestionCautionChatDenied"> A '[OBJECTNAME]', un objeto propiedad de '[OWNERNAME]', localizado en [REGIONNAME] con la posición [REGIONPOS], se le ha denegado el permiso para: [PERMISSIONS]. </string> + <string name="AdditionalPermissionsRequestHeader"> + Si autorizas el acceso a tu cuenta, también permitirás al objeto: + </string> <string name="ScriptTakeMoney"> Cogerle a usted dólares Linden (L$) </string> @@ -883,6 +907,9 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="ControlYourCamera"> Controlar su cámara </string> + <string name="TeleportYourAgent"> + Teleportarte + </string> <string name="SIM_ACCESS_PG"> General </string> @@ -958,6 +985,12 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="choose_the_directory"> Elegir directorio </string> + <string name="script_files"> + Scripts + </string> + <string name="dictionary_files"> + Diccionarios + </string> <string name="AvatarSetNotAway"> Salir del estado ausente </string> @@ -1196,43 +1229,36 @@ 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. + Aquà aparecerán algunos de los objetos que recibas, como los regalos Premium. Después puedes arrastrarlos a tu inventario. </string> <string name="MarketplaceURL"> - http://marketplace.[DOMAIN_NAME] + https://marketplace.[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 + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4 </string> - <string name="InventoryOutboxCreationErrorTitle"> - Tu Buzón de salida de comerciante no está configurado correctamente + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard </string> - <string name="InventoryOutboxCreationErrorTooltip"> - Error de configuración del Buzón de salida de comerciante + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports </string> - <string name="InventoryOutboxCreationError"> - Ponte en contacto con el servicio de atención al cliente para resolver el problema. + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more </string> <string name="InventoryOutboxNotMerchantTitle"> - Cualquiera puede vender objetos en el mercado - </string> - <string name="InventoryOutboxNotMerchantTooltip"> - ¡Hazte comerciante! + Cualquier usuario puede vender objetos en el mercado. </string> + <string name="InventoryOutboxNotMerchantTooltip"/> <string name="InventoryOutboxNotMerchant"> - [[MARKETPLACE_URL] El Mercado de Second Life] pone en venta más de un millón de productos virtuales, todos ellos creados por residentes. Tú también puedes vender los objetos que crees, asà como algunos de los objetos que hayas comprado. Es fácil y es gratuito. [[LEARN_MORE_URL] Más información] o [[CREATE_STORE_URL] crea una tienda] en el mercado para empezar. + Para hacerte comerciante debes [[MARKETPLACE_CREATE_STORE_URL] crear una tienda del Mercado]. </string> <string name="InventoryOutboxNoItemsTitle"> - Una nueva forma para enviar objetos al mercado - </string> - <string name="InventoryOutboxNoItemsTooltip"> - Arrastra y coloca aquà los objetos que desees preparar para venderlos en el mercado + El buzón de salida está vacÃo. </string> + <string name="InventoryOutboxNoItemsTooltip"/> <string name="InventoryOutboxNoItems"> - Arrastra a esta zona los objetos o carpetas que desees vender. Aparecerá una copia del objeto, sin quitarlo de tu inventario, salvo que el objeto arrastrado sea "no copiable". Cuando estés listo para enviar los objetos al mercado, pulsa en el botón Subir. Cuando se hayan trasladado los objetos a tu inventario en el mercado, desaparecerán de esta carpeta. + Arrastra carpetas a esta sección y pulsa en "Enviar al Mercado" para incluirlas en la lista de venta del [[MARKETPLACE_DASHBOARD_URL] Mercado]. </string> <string name="Marketplace Error None"> Sin errores @@ -1364,6 +1390,12 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="InvFolder favorite"> Mis Favoritos </string> + <string name="InvFolder Favorites"> + Mis Favoritos + </string> + <string name="InvFolder favorites"> + Mis Favoritos + </string> <string name="InvFolder Current Outfit"> Vestuario actual </string> @@ -1379,6 +1411,12 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="InvFolder Meshes"> Redes </string> + <string name="InvFolder Received Items"> + Objetos recibidos + </string> + <string name="InvFolder Merchant Outbox"> + Buzón de salida de comerciante + </string> <string name="InvFolder Friends"> Amigos </string> @@ -1388,6 +1426,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> @@ -1514,6 +1555,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> @@ -3748,6 +3795,12 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE]. <string name="LocationCtrlSeeAVsTooltip"> Los avatares están visibles y está permitido el chat fuera de esta parcela </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Los objetos que se mueven pueden presentar un comportamiento incorrecto en la región hasta que ésta se recargue. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + Esta región no tiene activado el pathfinding dinámico. + </string> <string name="UpdaterWindowTitle"> Actualizar [APP_NAME] </string> @@ -3940,6 +3993,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> @@ -3993,7 +4058,7 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE]. </string> <string name="uploading_abuse_report"> Subiendo... - + Denuncia de infracción </string> <string name="New Shape"> @@ -4261,7 +4326,7 @@ Denuncia de infracción <string name="server_is_down"> Parece que hay algún problema que ha escapado a nuestros controles. - Visita status.secondlifegrid.net para ver si hay alguna incidencia conocida que esté afectando al servicio. + Visita status.secondlifegrid.net para ver si hay alguna incidencia conocida que esté afectando al servicio. Si sigues teniendo problemas, comprueba la configuración de la red y del servidor de seguridad. </string> <string name="dateTimeWeekdaysNames"> @@ -4350,6 +4415,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> @@ -4720,7 +4791,10 @@ 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_Outbox_Label"> + Buzón de salida de comerciante </string> <string name="Command_People_Label"> Gente @@ -4747,10 +4821,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 @@ -4794,6 +4868,9 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas <string name="Command_Move_Tooltip"> Desplazando el avatar </string> + <string name="Command_Outbox_Tooltip"> + Transfiere objetos a tu mercado para venderlos + </string> <string name="Command_People_Tooltip"> Amigos, grupos y personas próximas </string> @@ -4822,7 +4899,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 @@ -4848,4 +4934,40 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas <string name="Normal"> Normal </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Ninguno + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Afecta al navmesh + </string> + <string name="Pathfinding_Object_Attr_Character"> + Personaje + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Múltiple) + </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> + <string name="TeleportMaturityExceeded"> + El Residente no puede visitar esta región. + </string> + <string name="UserDictionary"> + [Usuario] + </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..94975a83f8 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 ('Isla de Ayuda'). -Vaya a la 'Welcome Island Public' ('Isla Pública de Ayuda') 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. @@ -44,6 +44,9 @@ Vaya a la 'Welcome Island Public' ('Isla Pública de Ayuda') <message name="no_inventory_host"> En estos momentos no está disponible el sistema del inventario. </message> + <message name="MustGetAgeRegion"> + Solo pueden acceder a esta región los mayores de 18 años. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -79,5 +82,8 @@ Vaya a la 'Welcome Island Public' ('Isla Pública de Ayuda') <message name="requesting"> Solicitando teleporte... </message> + <message name="pending"> + Teleporte pendiente... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml index 4d02513a53..a659cb4245 100644 --- a/indra/newview/skins/default/xui/fr/floater_about.xml +++ b/indra/newview/skins/default/xui/fr/floater_about.xml @@ -66,33 +66,34 @@ Version serveur vocal : [VOICE_VERSION] </panel> <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. + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion + APR Copyright (C) 2011 The Apache Software Foundation + Collada DOM Copyright 2006 Sony Computer Entertainment Inc. + cURL Copyright (C) 1996-2010, 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, 2006 David Turner, Robert Wilhelm et Werner Lemberg. + 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) 2002, Xiphophorus + OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. + PCRE Copyright (c) 1997-2012 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-2012 Jean-Loup Gailly et Mark Adler. -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'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'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..25c49b97b5 100644 --- a/indra/newview/skins/default/xui/fr/floater_about_land.xml +++ b/indra/newview/skins/default/xui/fr/floater_about_land.xml @@ -132,9 +132,9 @@ 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="Acheter le 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'un résident, avoir un contenu défini et ne pas être aux enchères."/> <button label="Infos sur les scripts" name="Scripts..." width="110"/> <button label="Acheter pour le groupe" label_selected="Acheter pour le groupe..." name="Buy For Group..."/> @@ -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'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'est pas cochée, ils ne pourront voler que lorsqu'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'est pas cochée, ils ne pourront voler que lorsqu'ils arrivent et passent au dessus de votre terrain."/> <text name="allow_label2"> Construire : </text> @@ -335,12 +337,9 @@ 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'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'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"/> + <check_box label="Voir le lieu dans la recherche (30 L$/sem.)" name="ShowDirectoryCheck" tool_tip="Afficher la parcelle dans les résultats de recherche"/> <combo_box name="land category with adult"> <combo_box.item label="Toutes catégories" name="item0"/> <combo_box.item label="Appartenant aux Lindens" name="item1"/> @@ -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 à : + Les avatars sur d'autres parcelles peuvent voir 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'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'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'arrivée : [LANDING] </text> @@ -440,7 +439,7 @@ musique : <text name="Sound:"> Son : </text> - <check_box label="Limiter les gestes et sons d'objet à cette parcelle" name="check sound local"/> + <check_box label="Limiter les sons des gestes et des objets à cette parcelle" name="check sound local"/> <text name="Avatar Sounds:"> Sons d'avatar : </text> @@ -466,12 +465,12 @@ musique : <text name="Limit access to this parcel to:"> Accès à cette parcelle </text> - <check_box label="Autoriser l'accès public [MATURITY]" name="public_access"/> + <check_box label="Autoriser l'accès public (des lignes d'interdiction seront créées si cette case n'est pas cochée)" name="public_access"/> <text name="Only Allow"> - Limiter l'accès aux résidents vérifiés par : + Conditions d'accès des résidents : </text> - <check_box label="Informations de paiement enregistrées [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Bannir les résidents non identifiés."/> - <check_box label="Vérification de l'âge [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Bannir les résidents qui n'ont pas vérifié leur âge. Consultez la page [SUPPORT_SITE] pour plus d'informations."/> + <check_box label="Informations de paiement enregistrées [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Pour pouvoir accéder à cette parcelle, les résidents doivent avoir enregistré des informations de paiement. Consultez le [SUPPORT_SITE] pour plus d'informations."/> + <check_box label="Avoir plus de 18 ans [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Pour accéder à cette parcelle, les résidents doivent avoir au moins 18 ans. Consultez le [SUPPORT_SITE] pour plus d'informations."/> <check_box label="Autoriser l'accès au groupe : [GROUP]" name="GroupCheck" tool_tip="Définir le groupe à l'onglet Général."/> <check_box label="Vendre des pass à  :" name="PassCheck" tool_tip="Autoriser un accès temporaire à cette parcelle"/> <combo_box name="pass_combo" width="110"> diff --git a/indra/newview/skins/default/xui/fr/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/fr/floater_animation_anim_preview.xml new file mode 100644 index 0000000000..e82518ce80 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_animation_anim_preview.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Anim Preview" title="ANIMATION.ANIM"> + <text name="name_label"> + Nom : + </text> + <text name="description_label"> + Description : + </text> + <button label="Charger ([AMOUNT] L$)" name="ok_btn"/> + <button label="Annuler" label_selected="Annuler" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_animation_preview.xml b/indra/newview/skins/default/xui/fr/floater_animation_bvh_preview.xml index aa42fe6150..84c40b5987 100644 --- a/indra/newview/skins/default/xui/fr/floater_animation_preview.xml +++ b/indra/newview/skins/default/xui/fr/floater_animation_bvh_preview.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview" title=""> +<floater name="Animation Preview"> <floater.string name="failed_to_initialize"> - Echec de l'initialisation du mouvement + Échec de l'initialisation du mouvement </floater.string> <floater.string name="anim_too_long"> - Le fichier d'animation fait [LENGTH] secondes. + La durée du fichier d'animation est de [LENGTH] secondes. -La longueur maximale est de [MAX_LENGTH] secondes. +La limite maximale est de [MAX_LENGTH] secondes. </floater.string> <floater.string name="failed_file_read"> Impossible de lire le fichier d'animation. @@ -17,7 +17,7 @@ La longueur maximale est de [MAX_LENGTH] secondes. Ok </floater.string> <floater.string name="E_ST_EOF"> - Fichier incomplet. + Fin prématurée du fichier. </floater.string> <floater.string name="E_ST_NO_CONSTRAINT"> Impossible de lire la définition des contraintes. @@ -32,13 +32,13 @@ La longueur maximale est de [MAX_LENGTH] secondes. Impossible de trouver ROOT ou JOINT. </floater.string> <floater.string name="E_ST_NO_NAME"> - Impossible de trouver le nom JOINT. + Impossible d'obtenir le nom JOINT. </floater.string> <floater.string name="E_ST_NO_OFFSET"> Impossible de trouver OFFSET. </floater.string> <floater.string name="E_ST_NO_CHANNELS"> - Impossible de trouver les CHANNELS. + CHANNELS introuvables. </floater.string> <floater.string name="E_ST_NO_ROTATION"> Impossible d'obtenir l'ordre de rotation. @@ -50,16 +50,16 @@ La longueur maximale est de [MAX_LENGTH] secondes. Impossible de trouver MOTION. </floater.string> <floater.string name="E_ST_NO_FRAMES"> - Impossible d'obtenir le nombre de cadres. + Impossible d'obtenir le nombre d'images. </floater.string> <floater.string name="E_ST_NO_FRAME_TIME"> - Impossible d'obtenir le temps du cadre. + Impossible d'obtenir la durée des images. </floater.string> <floater.string name="E_ST_NO_POS"> - Impossible de trouver les valeurs de la position. + Impossible d'obtenir les valeurs de position. </floater.string> <floater.string name="E_ST_NO_ROT"> - Impossible de trouver les valeurs de rotation. + Impossible d'obtenir les valeurs de rotation. </floater.string> <floater.string name="E_ST_NO_XLT_FILE"> Impossible d'ouvrir le fichier de traduction. @@ -68,37 +68,37 @@ La longueur maximale est de [MAX_LENGTH] secondes. Impossible de lire l'en-tête de traduction. </floater.string> <floater.string name="E_ST_NO_XLT_NAME"> - Impossible de lire la traduction. + Impossible de lire les noms de traduction. </floater.string> <floater.string name="E_ST_NO_XLT_IGNORE"> - Impossible de lire la traduction. + Impossible de lire la valeur ignorant la traduction. </floater.string> <floater.string name="E_ST_NO_XLT_RELATIVE"> - Impossible de lire la valeur de traduction relative. + Impossible de lire la valeur relative de la traduction. </floater.string> <floater.string name="E_ST_NO_XLT_OUTNAME"> - Impossible de lire la traduction. + Impossible de lire la valeur outname de la traduction. </floater.string> <floater.string name="E_ST_NO_XLT_MATRIX"> Impossible de lire la matrice de traduction. </floater.string> <floater.string name="E_ST_NO_XLT_MERGECHILD"> - Impossible de trouver le nom mergechild. + Impossible d'obtenir le nom mergechild. </floater.string> <floater.string name="E_ST_NO_XLT_MERGEPARENT"> - Impossible de trouver le nom mergeparent. + Impossible d'obtenir le nom mergeparent. </floater.string> <floater.string name="E_ST_NO_XLT_PRIORITY"> - Impossible de définir la valeur de la priorité. + Impossible d'obtenir la valeur priority. </floater.string> <floater.string name="E_ST_NO_XLT_LOOP"> - Impossible de définir la valeur de la boucle + Impossible d'obtenir la valeur loop. </floater.string> <floater.string name="E_ST_NO_XLT_EASEIN"> - Impossible de trouver les valeurs easeIn. + Impossible d'obtenir les valeurs easeIn. </floater.string> <floater.string name="E_ST_NO_XLT_EASEOUT"> - Impossible de trouver les valeurs easeOut. + Impossible d'obtenir les valeurs easeOut. </floater.string> <floater.string name="E_ST_NO_XLT_HAND"> Impossible d'obtenir la valeur hand morph. @@ -107,7 +107,7 @@ La longueur maximale est de [MAX_LENGTH] secondes. Impossible de lire le nom emote. </floater.string> <floater.string name="E_ST_BAD_ROOT"> - Nom de racine incorrect. + Nom root joint incorrect ; utiliser "hip". </floater.string> <text name="name_label"> Nom : @@ -115,34 +115,33 @@ La longueur maximale est de [MAX_LENGTH] secondes. <text name="description_label"> Description : </text> - <spinner label="Priorité" name="priority" tool_tip="Contrôle quelles autres animations peuvent être remplacées par cette animation"/> - <check_box label="Boucle" left="6" name="loop_check" tool_tip="Lit cette animation en boucle"/> - <spinner label="Début (%)" label_width="65" name="loop_in_point" tool_tip="Définit un point de l'animation auquel retourne la boucle" width="105"/> - <spinner label="Fin (%)" name="loop_out_point" tool_tip="Définit un point de l'animation qui met fin à la boucle"/> + <spinner label="Priorité" name="priority" tool_tip="Contrôle quelles autres animations peuvent être remplacées par cette animation."/> + <check_box label="Boucle" name="loop_check" tool_tip="Entraîne la lecture en boucle de cette animation."/> + <spinner label="Début (%)" name="loop_in_point" tool_tip="Définit le point de l'animation auquel retourne la boucle."/> + <spinner label="Fin (%)" name="loop_out_point" tool_tip="Définit le point de l'animation auquel se termine la boucle."/> <text name="hand_label"> - Mouvement de -main + Pose des mains </text> - <combo_box label="" name="hand_pose_combo" tool_tip="Contrôle ce que font les mains pendant l'animation"> - <combo_box.item label="Espacement" name="Spread"/> + <combo_box name="hand_pose_combo" tool_tip="Contrôle ce que font les mains pendant l'animation."> + <combo_box.item label="Écartées" name="Spread"/> <combo_box.item label="Détendues" name="Relaxed"/> - <combo_box.item label="Pointer (les deux)" name="PointBoth"/> + <combo_box.item label="Montrer du doigt (les deux)" name="PointBoth"/> <combo_box.item label="Poing" name="Fist"/> <combo_box.item label="Détendue (gauche)" name="RelaxedLeft"/> - <combo_box.item label="Pointer (gauche)" name="PointLeft"/> + <combo_box.item label="Montrer du doigt (gauche)" name="PointLeft"/> <combo_box.item label="Poing (gauche)" name="FistLeft"/> <combo_box.item label="Détendue (droite)" name="RelaxedRight"/> - <combo_box.item label="Pointer (droite)" name="PointRight"/> + <combo_box.item label="Montrer du doigt (droite)" name="PointRight"/> <combo_box.item label="Poing (droite)" name="FistRight"/> - <combo_box.item label="Saluer (droite)" name="SaluteRight"/> - <combo_box.item label="Taper" name="Typing"/> - <combo_box.item label="Paix (main droite)" name="PeaceRight"/> + <combo_box.item label="Salut (droite)" name="SaluteRight"/> + <combo_box.item label="Clavier" name="Typing"/> + <combo_box.item label="Paix (droite)" name="PeaceRight"/> </combo_box> <text name="emote_label"> Expression </text> - <combo_box label="" name="emote_combo" tool_tip="Contrôle ce que fait le visage pendant l'animation"> - <item label="(aucun)" name="[None]" value=""/> + <combo_box name="emote_combo" tool_tip="Contrôle ce que fait le visage pendant l'animation."> + <item label="(Aucune)" name="[None]" value=""/> <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> <item label="Effrayé" name="Afraid" value="Effrayé"/> <item label="En colère" name="Angry" value="En colère"/> @@ -154,35 +153,33 @@ main <item label="Froncer les sourcils" name="Frown" value="Froncer les sourcils"/> <item label="Embrasser" name="Kiss" value="Embrasser"/> <item label="Rire" name="Laugh" value="Rire"/> - <item label="Plllppt" name="Plllppt" value="Tirer la langue"/> + <item label="Tirer la langue" name="Plllppt" value="Tirer la langue"/> <item label="Dégoût" name="Repulsed" value="Dégoût"/> <item label="Triste" name="Sad" value="Triste"/> <item label="Hausser les épaules" name="Shrug" value="Hausser les épaules"/> <item label="Sourire" name="Smile" value="Sourire"/> <item label="Surprise" name="Surprise" value="Surprise"/> <item label="Clin d'Å“il" name="Wink" value="Clin d'Å“il"/> - <item label="Soucis" name="Worry" value="Inquiétude"/> + <item label="Inquiétude" name="Worry" value="Inquiétude"/> </combo_box> <text name="preview_label"> - Prévisualiser -pendant + Aperçu </text> - <combo_box label="" name="preview_base_anim" tool_tip="Utilisez cette option pour tester votre animation pendant que votre avatar fait des choses banales."> + <combo_box name="preview_base_anim" tool_tip="Permet de tester le comportement de l'animation lorsque votre avatar effectue certaines actions courantes."> <item label="Debout" name="Standing" value="Debout"/> - <item label="Marche" name="Walking" value="Marche"/> + <item label="En marche" name="Walking" value="En marche"/> <item label="Assis" name="Sitting" value="Assis"/> - <item label="Vol" name="Flying" value="Vol"/> + <item label="En vol" name="Flying" value="En vol"/> </combo_box> - <spinner label="Transition début (s)" name="ease_in_time" tool_tip="Durée (en secondes) de l'entrée en fondu de l'animation"/> - <spinner label="Transition fin (s)" name="ease_out_time" tool_tip="Durée (en secondes) de la sortie en fondu de l'animation"/> - <button label="" name="play_btn" tool_tip="Lire votre animation"/> - <button name="pause_btn" tool_tip="Pauser votre animation"/> - <button label="" name="stop_btn" tool_tip="Arrêter le playback"/> - <slider label="" name="playback_slider"/> + <spinner label="Transition début (s)" name="ease_in_time" tool_tip="Durée (en secondes) de l'entrée en fondu de l'animation."/> + <spinner label="Transition fin (s)" name="ease_out_time" tool_tip="Durée (en secondes) de la sortie en fondu de l'animation."/> + <button name="play_btn" tool_tip="Lire l'animation."/> + <button name="pause_btn" tool_tip="Suspendre l'animation."/> + <button name="stop_btn" tool_tip="Arrêter la lecture de l'animation."/> <text name="bad_animation_text"> Impossible de lire le fichier d'animation. -Nous recommandons les fichiers BVH extraits de Poser 4. +Les fichiers BVH exportés depuis Poser 4 sont recommandés. </text> <button label="Charger ([AMOUNT] L$)" name="ok_btn"/> <button label="Annuler" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/fr/floater_autoreplace.xml b/indra/newview/skins/default/xui/fr/floater_autoreplace.xml new file mode 100644 index 0000000000..1d19181692 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="Paramètres Rechercher/Remplacer"> + <check_box label="Activer la fonction Rechercher/Remplacer" name="autoreplace_enable" tool_tip="Lors de la saisie du texte d'un chat, remplace chaque mot-clé spécifié par la valeur correspondante."/> + <button label="Importer une liste..." name="autoreplace_import_list" tool_tip="Charger une liste précédemment exportée à partir d'un fichier."/> + <button label="Exporter la liste..." name="autoreplace_export_list" tool_tip="Enregistrer la liste sélectionnée dans un fichier afin de pouvoir la partager."/> + <button label="Nouvelle liste..." name="autoreplace_new_list" tool_tip="Créer une nouvelle liste."/> + <button label="Supprimer la liste" name="autoreplace_delete_list" tool_tip="Supprimer la liste sélectionnée."/> + <button name="autoreplace_list_up" tool_tip="Augmenter la priorité de cette liste."/> + <button name="autoreplace_list_down" tool_tip="Diminuer la priorité de cette liste."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Mot-clé" name="keyword"/> + <scroll_list.columns label="Remplacement" name="replacement"/> + </scroll_list> + <button label="Ajouter..." name="autoreplace_add_entry"/> + <button label="Supprimer" name="autoreplace_delete_entry"/> + <button label="Enregistrer" name="autoreplace_save_entry" tool_tip="Enregistrer cette entrée."/> + <button label="Enregistrer les modifications" name="autoreplace_save_changes" tool_tip="Enregistrer toutes les modifications."/> + <button label="Annuler" name="autoreplace_cancel" tool_tip="Ignorer toutes les modifications."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </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'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'achète que des L$, pas l'objet. </text> <text bottom_delta="16" name="purchase_warning_notenough"> Vous n'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 97ff246c4d..893e389f69 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="CONTRÔLE DE LA CAMÉRA"> <floater.string name="rotate_tooltip"> Faire tourner la caméra autour du point central </floater.string> @@ -9,15 +9,6 @@ <floater.string name="move_tooltip"> Déplacer la caméra vers le haut et le bas, la gauche et la droite </floater.string> - <floater.string name="camera_modes_title"> - Modes - </floater.string> - <floater.string name="pan_mode_title"> - Rotation - Zoom - Panoramique - </floater.string> - <floater.string name="presets_mode_title"> - Préréglages - </floater.string> <floater.string name="free_mode_title"> Voir l'objet </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..7dcb9a280d 100644 --- a/indra/newview/skins/default/xui/fr/floater_chat_bar.xml +++ b/indra/newview/skins/default/xui/fr/floater_chat_bar.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="chat_bar" title="CHAT PRÈS DE MOI"> - <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"/> +<floater name="nearby_chat" title="CHAT PRÈS DE MOI"> + <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="Afficher/masquer le journal de chat près de vous."/> </panel> </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml index 0100419bc5..5ec68458e1 100644 --- a/indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml +++ b/indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml @@ -22,13 +22,13 @@ Remarque : si vous changez votre préréglage de nom, un nouveau préréglage sera créé et celui existant restera tel quel. </text> <text name="hint_item1"> - - Cliquez sur un repère pour modifier le réglage du ciel et l'heure associés. + - Modifier un réglage de ciel/heure : clic sur le repère </text> <text name="hint_item2"> - - Cliquez sur les repères et faites-les glisser afin de définir les heures de transition. + - Heures de transition : clic-glissement des repères </text> <text name="hint_item3"> - - Déplacez le marqueur en forme de triangle pour afficher un aperçu du cycle du jour. + - Aperçu du cycle du jour : déplacement du triangle </text> <panel name="day_cycle_slider_panel"> <multi_slider initial_value="0" name="WLTimeSlider"/> @@ -91,11 +91,11 @@ </text> </panel> <text name="WLCurKeyPresetText"> - Réglage du ciel : + Régl. ciel : </text> <combo_box label="Préréglage" name="WLSkyPresets"/> <text name="WLCurKeyTimeText"> - Heure : + H. : </text> <time name="time" value="6h"/> <check_box label="Appliquer ce nouveau cycle du jour" name="make_default_cb"/> diff --git a/indra/newview/skins/default/xui/fr/floater_environment_settings.xml b/indra/newview/skins/default/xui/fr/floater_environment_settings.xml index 9ea47a3dd7..ea12749d27 100644 --- a/indra/newview/skins/default/xui/fr/floater_environment_settings.xml +++ b/indra/newview/skins/default/xui/fr/floater_environment_settings.xml @@ -18,7 +18,7 @@ <combo_box.item label="-Effectuer une sélection-" name="item0"/> </combo_box> <text name="sky_dayc_settings_title"> - Ciel / Cycle du jour + Ciel/Cycle du jour </text> <radio_group name="sky_dayc_settings_radio_group"> <radio_item label="Ciel fixe" name="my_sky_settings"/> diff --git a/indra/newview/skins/default/xui/fr/floater_god_tools.xml b/indra/newview/skins/default/xui/fr/floater_god_tools.xml index e4c53d866c..0d21a8af32 100644 --- a/indra/newview/skins/default/xui/fr/floater_god_tools.xml +++ b/indra/newview/skins/default/xui/fr/floater_god_tools.xml @@ -71,8 +71,8 @@ <button label="Supprimer tous les objets scriptés de la cible sur les terrains des autres" label_selected="Supprimer tous les objets scriptés de la cible sur les terrains des autres" name="Delete Target's Scripted Objects On Others Land" tool_tip="Supprimer tous les objets scriptés appartenant à la cible sur les terrains ne lui appartenant pas. Les objets non copiables seront renvoyés."/> <button label="Supprimer les objets scriptés de la cible sur *tous* les terrains" label_selected="Supprimer les objets scriptés de la cible sur *tous* les terrains" name="Delete Target's Scripted Objects On *Any* Land" tool_tip="Supprimer les objets scriptés appartenant à la cible dans cette région. Les objets non copiables seront renvoyés."/> <button label="Supprimer *tous* les objets de la cible" label_selected="Supprimer *tous* les objets de la cible" name="Delete *ALL* Of Target's Objects" tool_tip="Supprimer tous les objets appartenant à la cible dans cette région. Les objets non copiables seront renvoyés."/> - <button label="Afficher les collisions les plus consommatrices" label_selected="Afficher les collisions les plus consommatrices" name="Get Top Colliders" tool_tip="Dresse une liste des objets avec les callbacks les plus fréquents. " width="300"/> - <button label="Afficher les objets scriptés les plus consommateurs" label_selected="Afficher les objets scriptés les plus consommateurs" name="Get Top Scripts" tool_tip="Dresse une liste des objets qui passent le plus de temps à exécuter des scripts." width="300"/> + <button label="Collisions les plus consommatrices" label_selected="Collisions les plus consommatrices" name="Get Top Colliders" tool_tip="Liste des objets avec les callbacks les plus fréquents. " width="300"/> + <button label="Scripts les plus consommateurs" label_selected="Scripts les plus consommateurs" name="Get Top Scripts" tool_tip="Liste des objets passant le plus de temps à exécuter des scripts." width="300"/> <button label="Résumé des scripts" label_selected="Résumé des scripts" name="Scripts digest" tool_tip="Dresse une liste des scripts et de leurs occurrences." width="300"/> </panel> <panel label="Requête" name="request"> 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..098f8fc713 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"> @@ -25,6 +25,10 @@ Activer le VBO : </text> <check_box initial_value="true" label="Activer OpenGL Vertex Buffer Objects" name="vbo" tool_tip="Sur un matériel moderne, cette option permet une meilleure performance. Par contre, sur un matériel plus ancien, les VBO sont souvent mal implémentés et peuvent causer des crashs lorsqu'ils sont activés."/> + <text name="tc label"> + Activer S3TC : + </text> + <check_box initial_value="vraie" label="Activer la compression des textures (redémarrage requis)" name="texture compression" tool_tip="Comprime les textures en mémoire vidéo afin de permettre de charger des textures de résolution plus élevée au prix d'une certaine qualité de couleur."/> <slider label="Mémoire textures (Mo) :" name="GraphicsCardTextureMemory" tool_tip="Quantité de mémoire à affecter aux textures. Utilise la mémoire de la carte vidéo par défaut. Si vous réduisez ce paramètre, cela peut améliorer les performances, mais les textures risquent d'être floues."/> <spinner label="Indice du brouillard :" name="fog"/> <button label="OK" label_selected="OK" name="OK"/> diff --git a/indra/newview/skins/default/xui/fr/floater_inventory.xml b/indra/newview/skins/default/xui/fr/floater_inventory.xml deleted file mode 100644 index 200c07e522..0000000000 --- a/indra/newview/skins/default/xui/fr/floater_inventory.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="MON INVENTAIRE"> - <floater.string name="Title"> - MON INVENTAIRE - </floater.string> - <floater.string name="TitleFetching"> - MON INVENTAIRE (récupération de [ITEM_COUNT] articles en cours) [FILTER] - </floater.string> - <floater.string name="TitleCompleted"> - MON INVENTAIRE ([ITEM_COUNT] articles) [FILTER] - </floater.string> - <floater.string name="Fetched"> - Récupéré - </floater.string> - <panel label="Panneau Inventaire" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_land_holdings.xml b/indra/newview/skins/default/xui/fr/floater_land_holdings.xml index 10fe132623..ff728e3aaa 100644 --- a/indra/newview/skins/default/xui/fr/floater_land_holdings.xml +++ b/indra/newview/skins/default/xui/fr/floater_land_holdings.xml @@ -7,7 +7,7 @@ <column label="Surface" name="area"/> <column label="" name="hidden"/> </scroll_list> - <button label="Téléporter" label_selected="Téléporter" name="Teleport" tool_tip="Téléportez-vous au milieu de ce terrain."/> + <button label="Téléportation" label_selected="Téléportation" name="Teleport" tool_tip="Téléportez-vous au milieu de ce terrain."/> <button label="Carte" label_selected="Carte" name="Show on Map" tool_tip="Afficher ce terrain sur la carte du monde"/> <text name="contrib_label"> Vos contributions : diff --git a/indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml new file mode 100644 index 0000000000..b491dd6aed --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_merchant_outbox" title="BOÃŽTE D'ENVOI VENDEUR"> + <string name="OutboxFolderCount1"> + 1 dossier + </string> + <string name="OutboxFolderCountN"> + [NUM] dossiers + </string> + <string name="OutboxImporting"> + Envoi de dossiers... + </string> + <string name="OutboxInitializing"> + Initialisation... + </string> + <panel label=""> + <panel> + <panel name="outbox_inventory_placeholder_panel"> + <text name="outbox_inventory_placeholder_title"> + Chargement... + </text> + </panel> + </panel> + <panel> + <button label="Envoyer vers la Place du marché" name="outbox_import_btn" tool_tip="Vers ma vitrine de la Place du marché"/> + </panel> + </panel> +</floater> 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..bd3dae6599 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'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> @@ -89,19 +92,54 @@ <text initial_value="Triangles" name="triangles" value="Triangles"/> <text initial_value="Sommets" name="vertices" value="Sommets"/> <text initial_value="Élevé" name="high_label" value="Élevé"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Depuis un fichier"/> + <item name="Generate" value="Génération"/> + </combo_box> <button label="Parcourir..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="Triangles max"/> + <item name="Error Threshold" value="Seuil d'erreur"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Moyen" name="medium_label" value="Moyen"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Depuis un fichier"/> + <item name="Generate" value="Génération"/> + <item name="Use LoD above" value="Niveau de détail du dessus"/> + </combo_box> <button label="Parcourir..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="Triangles max"/> + <item name="Error Threshold" value="Seuil d'erreur"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Faible" name="low_label" value="Faible"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Depuis un fichier"/> + <item name="Generate" value="Génération"/> + <item name="Use LoD above" value="Niveau de détail du dessus"/> + </combo_box> <button label="Parcourir..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="Triangles max"/> + <item name="Error Threshold" value="Seuil d'erreur"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="Le plus faible" name="lowest_label" value="Le plus faible"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Depuis un fichier"/> + <item name="Generate" value="Génération"/> + <item name="Use LoD above" value="Niveau de détail du dessus"/> + </combo_box> <button label="Parcourir..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="Triangles max"/> + <item name="Error Threshold" value="Seuil d'erreur"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Génération de normales" name="gen_normals"/> @@ -137,7 +175,7 @@ </panel> <panel name="physics analysis"> <text name="method_label"> - Étape 2 : Analyse + Étape 2 : Analyser </text> <text name="analysis_method_label"> Moyen : @@ -163,7 +201,7 @@ Passes : </text> <text name="Detail Scale label"> - Échelle de détail : + Échelle détail : </text> <text name="Retain%_label"> Retenue : @@ -189,7 +227,7 @@ </panel> <panel label="Option de chargement" name="modifiers_panel"> <text name="scale_label"> - Echelle (1 = pas d'échelle) : + Échelle (1 = aucune) : </text> <spinner name="import_scale" value="1.0"/> <text name="dimensions_label"> @@ -200,21 +238,21 @@ </text> <check_box label="Inclure les textures" name="upload_textures"/> <text name="include_label"> - Pour les modèles d'avatar uniquement : + Modèles d'avatar uniquement : </text> - <check_box label="Inclure la pondération de la peau :" name="upload_skin"/> - <check_box label="Inclure la position des articulations :" name="upload_joints"/> + <check_box label="Inclure pondération de la peau :" name="upload_skin"/> + <check_box label="Inclure position des articulations :" name="upload_joints"/> <text name="pelvis_offset_label"> - Décalage Z (élever ou abaisser l'avatar) : + Décalage Z (élever/abaisser l'avatar) : </text> <spinner name="pelvis_offset" value="0.0"/> </panel> </tab_container> <panel name="weights_and_warning_panel"> - <button label="Calculer les poids et les frais." name="calculate_btn" tool_tip="Calculer les poids et les frais."/> + <button label="Calculer les poids et les frais" name="calculate_btn" tool_tip="Calculer les poids et les frais."/> <button label="Annuler" name="cancel_btn"/> <button label="Charger le modèle" name="ok_btn" tool_tip="Charger dans le simulateur"/> - <button label="Effacer les paramètres et réinitialiser le formulaire" name="reset_btn"/> + <button label="Effacer les paramètres / réinitialiser le formulaire" name="reset_btn"/> <text name="upload_fee"> Frais de chargement : [FEE] L$ </text> diff --git a/indra/newview/skins/default/xui/fr/floater_model_wizard.xml b/indra/newview/skins/default/xui/fr/floater_model_wizard.xml deleted file mode 100644 index cd2eb761ec..0000000000 --- a/indra/newview/skins/default/xui/fr/floater_model_wizard.xml +++ /dev/null @@ -1,205 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Model Wizard" title="ASSISTANT DE CHARGEMENT DE MODÈLE"> - <button label="5. Chargement" name="upload_btn"/> - <button label="4. Vérification" name="review_btn"/> - <button label="3. Propriétés physiques" name="physics_btn"/> - <button label="2. Optimisation" name="optimize_btn"/> - <button label="1. Sélection du fichier" name="choose_file_btn"/> - <panel name="choose_file_panel"> - <panel name="header_panel"> - <text name="header_text"> - Choisir un fichier de modèle - </text> - </panel> - <panel name="content"> - <text name="advanced_users_text"> - Utilisateurs expérimentés : si vous êtes habitué à utiliser des outils de création de contenu en 3D, l'outil de chargement avancé est mis à votre disposition. - </text> - <button label="Passer à Avancé" name="switch_to_advanced"/> - <text name="Cache location"> - Choisir un fichier de modèle à charger - </text> - <button label="Parcourir..." label_selected="Parcourir..." name="browse"/> - <text name="dimensions"> - X Y Z - </text> - <text name="warning_label"> - AVERTISSEMENT : - </text> - <text name="warning_text"> - Vous ne pourrez pas effectuer l'étape de chargement finale du modèle sur les serveurs Second Life. [secondlife:///app/floater/learn_more Découvrez comment] configurer votre compte pour les chargements de modèle de maillage. - </text> - </panel> - </panel> - <panel name="optimize_panel"> - <panel name="header_panel"> - <text name="header_text"> - Optimiser le modèle - </text> - </panel> - <text name="description"> - Le modèle a été optimisé en termes de performances. Vous pouvez l'ajuster si vous le souhaitez. - </text> - <panel name="content"> - <text name="high_detail_text"> - Générer le niveau de détail : Élevé - </text> - <text name="medium_detail_text"> - Générer le niveau de détail : Moyen - </text> - <text name="low_detail_text"> - Générer le niveau de détail : Faible - </text> - <text name="lowest_detail_text"> - Générer le niveau de détail : Le plus faible - </text> - </panel> - <panel name="content2"> - <button label="Recalcul géométrique" name="recalculate_geometry_btn"/> - <text name="lod_label"> - Aperçu de la géométrie - </text> - <combo_box name="preview_lod_combo" tool_tip="Niveau de détail à afficher en rendu d'aperçu."> - <combo_item name="high"> - Niveau de détail élevé - </combo_item> - <combo_item name="medium"> - Niveau de détail moyen - </combo_item> - <combo_item name="low"> - Niveau de détail faible - </combo_item> - <combo_item name="lowest"> - Niveau de détail le plus faible - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="physics_panel"> - <panel name="header_panel"> - <text name="header_text"> - Ajuster les propriétés physiques - </text> - </panel> - <text name="description"> - Une forme va être créée pour l'enveloppe externe du modèle. Ajustez le niveau de détail de la forme en fonction de l'objectif souhaité pour votre modèle. - </text> - <panel name="content"> - <button label="Recalcul physique" name="recalculate_physics_btn"/> - <button label="Recalcul en cours..." name="recalculating_physics_btn"/> - <text name="lod_label"> - Aperçu des propriétés physiques - </text> - <combo_box name="preview_lod_combo2" tool_tip="Niveau de détail à afficher en rendu d'aperçu."> - <combo_item name="high"> - Niveau de détail élevé - </combo_item> - <combo_item name="medium"> - Niveau de détail moyen - </combo_item> - <combo_item name="low"> - Niveau de détail faible - </combo_item> - <combo_item name="lowest"> - Niveau de détail le plus faible - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="review_panel"> - <panel name="header_panel"> - <text name="header_text"> - Vérification - </text> - </panel> - <panel name="content"> - <text name="review_prim_equiv"> - Impact sur la parcelle/région : équivalent à [EQUIV] prims - </text> - <text name="review_fee"> - Votre compte sera débité de [FEE] L$ de frais de chargement. - </text> - <text name="review_confirmation"> - En cliquant sur le bouton de chargement, vous confirmez que vous disposez des droits appropriés sur le contenu du modèle. - </text> - </panel> - </panel> - <panel name="upload_panel"> - <panel name="header_panel"> - <text name="header_text"> - Chargement terminé - </text> - </panel> - <text name="model_uploaded_text"> - Votre modèle a été chargé. - </text> - <text name="inventory_text"> - Vous le trouverez dans le dossier Objets de votre inventaire. - </text> - <text name="charged_fee"> - Votre compte a été débité de [FEE] L$. - </text> - </panel> - <button label="<< Préc." name="back"/> - <button label="Suiv. >>" name="next"/> - <button label="Calculer les poids et les frais >>" name="calculate"/> - <button label="Calcul en cours..." name="calculating"/> - <button label="Charger" name="upload" tool_tip="Charger dans le simulateur."/> - <button label="Annuler" name="cancel"/> - <button label="Fermer" name="close"/> - <spinner name="import_scale" value="1.0"/> - <string name="status_idle"> - Inactif - </string> - <string name="status_parse_error"> - Problème d'analyse de fichier .dae ; reportez-vous au journal pour plus de détails. - </string> - <string name="status_reading_file"> - Chargement... - </string> - <string name="status_generating_meshes"> - Génération des maillages... - </string> - <string name="status_vertex_number_overflow"> - Erreur : valeur de sommet supérieure à 65534. Opération abandonnée. - </string> - <string name="bad_element"> - Erreur : élément non valide - </string> - <string name="high"> - Élevé - </string> - <string name="medium"> - Moyen - </string> - <string name="low"> - Faible - </string> - <string name="lowest"> - Le plus faible - </string> - <string name="mesh_status_good"> - Bon à publier ! - </string> - <string name="mesh_status_na"> - N/A - </string> - <string name="mesh_status_none"> - Aucun - </string> - <string name="mesh_status_submesh_mismatch"> - Un nombre différent de faces d'application de texture est associé aux niveaux de détail. - </string> - <string name="mesh_status_mesh_mismatch"> - Un nombre différent d'instances de maillage est associé aux niveaux de détail. - </string> - <string name="mesh_status_too_many_vertices"> - Trop de sommets pour le niveau de détail. - </string> - <string name="mesh_status_missing_lod"> - Niveau de détail requis manquant. - </string> - <string name="layer_all"> - Tout - </string> -</floater> 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_nearby_chat.xml b/indra/newview/skins/default/xui/fr/floater_nearby_chat.xml deleted file mode 100644 index 8bbd34baae..0000000000 --- a/indra/newview/skins/default/xui/fr/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="CHAT PRÈS DE MOI"> - <check_box label="Traduction du chat" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_object_weights.xml b/indra/newview/skins/default/xui/fr/floater_object_weights.xml index f1b063a3da..2667188308 100644 --- a/indra/newview/skins/default/xui/fr/floater_object_weights.xml +++ b/indra/newview/skins/default/xui/fr/floater_object_weights.xml @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="object_weights" title="AVANCÉ"> <floater.string name="nothing_selected" value="--"/> - <text name="selected_text" value="SELECTIONNÉ"/> + <text name="selected_text" value="SÉLECTION"/> <text name="objects" value="--"/> <text name="objects_label" value="Objets"/> <text name="prims" value="--"/> <text name="prims_label" value="Prims"/> - <text name="weights_of_selected_text" value="POIDS DES OBJETS SELECTIONNÉS"/> + <text name="weights_of_selected_text" value="POIDS DE LA SÉLECTION"/> <text name="download" value="--"/> - <text name="download_label" value="Télécharger"/> + <text name="download_label" value="Téléchargement"/> <text name="physics" value="--"/> - <text name="physics_label" value="Propriétés physiques"/> + <text name="physics_label" value="Physique"/> <text name="server" value="--"/> <text name="server_label" value="Serveur"/> <text name="display" value="--"/> - <text name="display_label" value="Afficher"/> + <text name="display_label" value="Affichage"/> <text name="land_impacts_text" value="IMPACTS SUR LE TERRAIN"/> <text name="selected" value="--"/> <text name="selected_label" value="Sélection"/> <text name="rezzed_on_land" value="--"/> - <text name="rezzed_on_land_label" value="Rezzé sur le terrain"/> + <text name="rezzed_on_land_label" value="Rezzés sur le terrain"/> <text name="remaining_capacity" value="--"/> <text name="remaining_capacity_label" value="Capacité restante"/> <text name="total_capacity" value="--"/> <text name="total_capacity_label" value="Capacité totale"/> - <text name="help_SLURL" value="[secondlife:///app/help/object_weights What is all this?...]"/> + <text name="help_SLURL" value="[secondlife:///app/help/object_weights De quoi s'agit-il ?...]"/> </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/fr/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..7c9109c011 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="Personnages de recherche de chemin"> + <floater.string name="messaging_get_inprogress"> + Requête relative aux personnages de recherche de chemin en cours... + </floater.string> + <floater.string name="messaging_get_error"> + Erreur lors de la requête relative aux personnages de recherche de chemin. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Aucun personnage de recherche de chemin. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] personnages sélectionnés sur [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + La recherche de chemin n'a pas été activée pour cette région. + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Chargement] + </floater.string> + <floater.string name="character_owner_unknown"> + [Inconnu] + </floater.string> + <floater.string name="character_owner_group"> + [Groupe] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nom" name="name"/> + <scroll_list.columns label="Description" name="description"/> + <scroll_list.columns label="Propriétaire" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="Altitude" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + Personnages : + </text> + <button label="Actualiser" name="refresh_objects_list"/> + <button label="Tout sélectionner" name="select_all_objects"/> + <button label="Ne rien sélectionner" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + Actions sur les personnages sélectionnés : + </text> + <check_box label="Afficher la balise" name="show_beacon"/> + <check_box label="Afficher la capsule physique" name="show_physics_capsule"/> + <button label="Prendre" name="take_objects"/> + <button label="Prendre une copie" name="take_copy_objects"/> + <button label="M'y téléporter" name="teleport_me_to_object" tool_tip="Activé uniquement lorsqu'un personnage est sélectionné."/> + <button label="Renvoyer" name="return_objects"/> + <button label="Supprimer" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/fr/floater_pathfinding_console.xml new file mode 100644 index 0000000000..02d969dc08 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="Vue/Test de recherche de chemin"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + Implémentation de la bibliothèque de recherche de chemin introuvable + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + La recherche de chemin n'a pas été activée pour cette région. + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + En attente de fin de chargement de la région. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Vérification de l'état du maillage de navigation. + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Téléchargement du maillage de navigation. + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + Maillage de navigation modifié sur le serveur. Téléchargement du plus récent. + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + Le maillage de navigation le plus récent a été téléchargé. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + Impossible de télécharger le maillage de navigation. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + Des modifications sont en attente concernant le maillage de navigation. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + Maillage de navigation en cours de création. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + Des modifications sont en attente pour certaines régions de maillage de navigation. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + Certaines régions de maillage de navigation sont en cours de création. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + Des modifications sont en attente pour certaines régions de maillage de navigation et d'autres sont en cours de création. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + Maillage de navigation à jour. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + Implémentation de la bibliothèque de recherche de chemin introuvable + </floater.string> + <floater.string name="pathing_region_not_enabled"> + La recherche de chemin n'a pas été activée pour cette région. + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Choisissez un point de départ et un point d'arrivée. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Choisissez un point de départ. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Choisissez un point d'arrivée. + </floater.string> + <floater.string name="pathing_path_valid"> + Le chemin s'affiche en orange. + </floater.string> + <floater.string name="pathing_path_invalid"> + Impossible de trouver un chemin entre les points choisis. + </floater.string> + <floater.string name="pathing_error"> + Erreur lors de la génération du chemin. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Vue" name="view_panel"> + <text name="show_label"> + Afficher : + </text> + <check_box label="Monde" name="show_world"/> + <check_box label="Mobiles uniquement" name="show_world_movables_only"/> + <check_box label="Maillage de navigation" name="show_navmesh"/> + <text name="show_walkability_label"> + Où marcher est possible : + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="Ne pas afficher" name="show_heatmap_mode_none"/> + <combo_box.item label="Type de personnage A" name="show_heatmap_mode_a"/> + <combo_box.item label="Type de personnage B" name="show_heatmap_mode_b"/> + <combo_box.item label="Type de personnage C" name="show_heatmap_mode_c"/> + <combo_box.item label="Type de personnage D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Marche possible" name="show_walkables"/> + <check_box label="Volumes de matériau" name="show_material_volumes"/> + <check_box label="Obstacles statiques" name="show_static_obstacles"/> + <check_box label="Volumes d'exclusion" name="show_exclusion_volumes"/> + <check_box label="Plan de l'eau" name="show_water_plane"/> + <check_box label="Mode rayons X" name="show_xray"/> + </panel> + <panel label="Chemin test" name="test_panel"> + <text name="ctrl_click_label"> + Ctrl-clic : sélection point de départ + </text> + <text name="shift_click_label"> + Maj-clic : sélection point d'arrivée + </text> + <text name="character_width_label"> + Largeur du personnage + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + Type de personnage + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Aucun" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Effacer chemin" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/fr/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..894ec6dd9c --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Groupes de liens de recherche de chemin"> + <floater.string name="messaging_get_inprogress"> + Requête relative aux groupes de liens de recherche de chemin en cours... + </floater.string> + <floater.string name="messaging_get_error"> + Erreur lors de la requête relative aux groupes de liens de recherche de chemin. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Modification des groupes de liens de recherche de chemin sélectionnés... + </floater.string> + <floater.string name="messaging_set_error"> + Erreur lors de la modification des groupes de liens de recherche de chemin sélectionnés. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Aucun groupe de liens de recherche de chemin. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] groupes de liens sélectionnés sur [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + La recherche de chemin n'a pas été activée pour cette région. + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terrain] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Chargement] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Inconnu] + </floater.string> + <floater.string name="linkset_owner_group"> + [Groupe] + </floater.string> + <floater.string name="linkset_is_scripted"> + Oui + </floater.string> + <floater.string name="linkset_is_not_scripted"> + Non + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + Inconnu + </floater.string> + <floater.string name="linkset_use_walkable"> + Marche possible + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Obstacle statique + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Obstacle mobile + </floater.string> + <floater.string name="linkset_use_material_volume"> + Volume de matériau + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + Volume d'exclusion + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Fantôme mobile + </floater.string> + <floater.string name="linkset_is_terrain"> + [Non modifiable] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [Restriction] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [Concave] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [Restriction,Concave] + </floater.string> + <floater.string name="linkset_choose_use"> + Choisir un usage de groupe de liens... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="Filtrer par usage..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Marche possible" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Obstacle statique" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Obstacle mobile" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Volume de matériau" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="Volume d'exclusion" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Fantôme mobile" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Appliquer" name="apply_filters"/> + <button label="Effacer" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nom (prim racine)" name="name"/> + <scroll_list.columns label="Description (prim racine)" name="description"/> + <scroll_list.columns label="Propriétaire" name="owner"/> + <scroll_list.columns label="Scripté" name="scripted"/> + <scroll_list.columns label="Impact" name="land_impact"/> + <scroll_list.columns label="Distance" name="dist_from_you"/> + <scroll_list.columns label="Usage du groupe de liens" name="linkset_use"/> + <scroll_list.columns label="% A" name="a_percent"/> + <scroll_list.columns label="% B" name="b_percent"/> + <scroll_list.columns label="% C" name="c_percent"/> + <scroll_list.columns label="% D" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + Groupes de liens : + </text> + <button label="Actualiser" name="refresh_objects_list"/> + <button label="Tout sélectionner" name="select_all_objects"/> + <button label="Ne rien sélectionner" name="select_none_objects"/> + </panel> + <panel> + <check_box label="Afficher la balise" name="show_beacon"/> + <button label="Prendre" name="take_objects"/> + <button label="Prendre une copie" name="take_copy_objects"/> + <button label="M'y téléporter" name="teleport_me_to_object"/> + <button label="Renvoyer" name="return_objects"/> + <button label="Supprimer" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + Marche possible : + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="Marche possible pour les personnages de type A. Exemple de type de personnage : humanoïde."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="Marche possible pour les personnages de type B. Exemple de type de personnage : créature."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="Marche possible pour les personnages de type C. Exemple de type de personnage : mécanique."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="Marche possible pour les personnages de type D. Exemple de type de personnage : autre."/> + <button label="Appliquer les changements" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Humanoïde) + </text> + <text name="suggested_use_b_label"> + (Créature) + </text> + <text name="suggested_use_c_label"> + (Mécanique) + </text> + <text name="suggested_use_d_label"> + (Autre) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_postcard.xml b/indra/newview/skins/default/xui/fr/floater_postcard.xml deleted file mode 100644 index e65dfb09b4..0000000000 --- a/indra/newview/skins/default/xui/fr/floater_postcard.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="ENVOYER LA PHOTO PAR E-MAIL"> - <text name="to_label"> - E-mail du destinataire : - </text> - <text name="from_label"> - Votre e-mail : - </text> - <text name="name_label"> - Votre nom : - </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> - <text name="fine_print"> - Si le destinataire s'inscrit sur [SECOND_LIFE], vous recevrez un bonus. - </text> - <button label="Annuler" name="cancel_btn"/> - <button label="Envoyer" name="send_btn"/> - <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> -</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_preview_animation.xml b/indra/newview/skins/default/xui/fr/floater_preview_animation.xml index a9407abfde..6488089c06 100644 --- a/indra/newview/skins/default/xui/fr/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/fr/floater_preview_animation.xml @@ -6,6 +6,6 @@ <text name="desc txt"> Description : </text> - <button label="Jouer dans Second Life" label_selected="Stop" name="Anim play btn" tool_tip="Lire cette animation de façon à ce que les autres puissent la voir" width="131"/> - <button label="Jouer localement" label_selected="Stop" left="160" name="Anim audition btn" tool_tip="Lire cette animation de façon à ce que vous soyez la seule personne à pouvoir la voir" width="120"/> + <button label="Exécuter dans SL" label_selected="Arrêter" name="Inworld" tool_tip="Lire cette animation de façon à ce que les autres la voient dans Second Life."/> + <button label="Exécuter localement" label_selected="Arrêter" name="Locally" tool_tip="Lire cette animation de façon à ce que vous soyez la seule personne à la voir."/> </floater> 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'inventaire + </string> + <string name="local_progress_str"> + Enregistrement sur l'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'inventaire effectué ! + </string> + <string name="local_succeeded_str"> + Enregistrement sur l'ordinateur effectué ! + </string> + <string name="profile_failed_str"> + Échec de chargement de l'image sur le flux de votre profil. + </string> + <string name="postcard_failed_str"> + Échec d'envoi par e-mail. + </string> + <string name="inventory_failed_str"> + Échec d'enregistrement dans l'inventaire. + </string> + <string name="local_failed_str"> + Échec d'enregistrement sur l'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'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'image" name="image_quality_slider"/> - <text name="layer_type_label"> - Capturer : - </text> - <combo_box label="Couches d'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'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_spellcheck.xml b/indra/newview/skins/default/xui/fr/floater_spellcheck.xml new file mode 100644 index 0000000000..635db52ffa --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="Paramètres du vérificateur orthographique"> + <check_box label="Activer le vérificateur orthographique" name="spellcheck_enable"/> + <text name="spellcheck_main"> + Diction. principal : + </text> + <text label="Journaux :" name="spellcheck_additional"> + Dictionnaires supplémentaires : + </text> + <text name="spellcheck_available"> + Disponibles + </text> + <text name="spellcheck_active"> + Actifs + </text> + <button label="Supprimer" name="spellcheck_remove_btn"/> + <button label="Importer..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/fr/floater_spellcheck_import.xml new file mode 100644 index 0000000000..c8c76c672d --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Importation d'un dictionnaire"> + <button label="Parcourir" label_selected="Parcourir" name="dictionary_path_browse"/> + <button label="Importer" name="ok_btn"/> + <button label="Annuler" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_stats.xml b/indra/newview/skins/default/xui/fr/floater_stats.xml index a74a338bd7..d6bd187956 100644 --- a/indra/newview/skins/default/xui/fr/floater_stats.xml +++ b/indra/newview/skins/default/xui/fr/floater_stats.xml @@ -14,8 +14,11 @@ <stat_bar label="KTris par s" name="ktrissec"/> <stat_bar label="Objets totaux" name="objs"/> <stat_bar label="Nouveaux objets" name="newobjs"/> + <stat_bar label="Taux de réussite du cache des objets" name="object_cache_hits"/> </stat_view> <stat_view label="Texture" name="texture"> + <stat_bar label="Taux de réussite du cache" name="texture_cache_hits"/> + <stat_bar label="Latence de lecture du cache" name="texture_cache_read_latency"/> <stat_bar label="Nombre" name="numimagesstat"/> <stat_bar label="Nombre brut" name="numrawimagesstat"/> <stat_bar label="Mém GL" name="gltexmemstat"/> @@ -38,7 +41,7 @@ <stat_view label="Simulateur" name="sim"> <stat_bar label="Dilatation temporelle" name="simtimedilation"/> <stat_bar label="FPS sim" name="simfps"/> - <stat_bar label="Propriétés physiques FPS" name="simphysicsfps"/> + <stat_bar label="FPS physique" name="simphysicsfps"/> <stat_view label="Détails des propriétés physiques" name="physicsdetail"> <stat_bar label="Objets fixés" name="physicspinnedtasks"/> <stat_bar label="Objets LOD faibles" name="physicslodtasks"/> @@ -50,20 +53,26 @@ <stat_bar label="Objets" name="simobjects"/> <stat_bar label="Objets actifs" name="simactiveobjects"/> <stat_bar label="Scripts actifs" name="simactivescripts"/> + <stat_bar label="Scripts exécutés" name="simpctscriptsrun"/> <stat_bar label="Événements de scripts" name="simscripteps"/> + <stat_view label="Recherche de chemin" name="simpathfinding"> + <stat_bar label="Durée de l'étape IA" name="simsimaistepmsec"/> + <stat_bar label="Étapes de silhouette ignorées" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Personnages mis à jour" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_bar label="Paquets en entrée" name="siminpps"/> <stat_bar label="Paquets en sortie" name="simoutpps"/> - <stat_bar label="En attente des téléchargements" name="simpendingdownloads"/> - <stat_bar label="En attente des chargements" name="simpendinguploads"/> + <stat_bar label="Téléchargements en attente" name="simpendingdownloads"/> + <stat_bar label="Chargements en attente" name="simpendinguploads"/> <stat_bar label="Total Unacked Bytes" name="simtotalunackedbytes"/> <stat_view label="Temps (ms)" name="simperf"> - <stat_bar label="Durée du cadre totale" name="simframemsec"/> + <stat_bar label="Durée totale de l'image" name="simframemsec"/> <stat_bar label="Durée nette" name="simnetmsec"/> - <stat_bar label="Durée physique" name="simsimphysicsmsec"/> - <stat_bar label="Durée de la simulation" name="simsimothermsec"/> - <stat_bar label="Durée de l'avatar" name="simagentmsec"/> + <stat_bar label="Durée sim (physique)" name="simsimphysicsmsec"/> + <stat_bar label="Durée sim (autre)" name="simsimothermsec"/> + <stat_bar label="Durée des avatars" name="simagentmsec"/> <stat_bar label="Durée des images" name="simimagesmsec"/> - <stat_bar label="Durée du script" name="simscriptmsec"/> + <stat_bar label="Durée des scripts" name="simscriptmsec"/> <stat_bar label="Temps d'inactivité" name="simsparemsec"/> <stat_view label="Détails Temps (ms)" name="timedetails"> <stat_bar label="Etape propr. physiques" name="simsimphysicsstepmsec"/> diff --git a/indra/newview/skins/default/xui/fr/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/fr/floater_test_layout_stacks.xml new file mode 100644 index 0000000000..b479d5f6d6 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_test_layout_stacks.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="LAYOUTSTACK TESTS"/> diff --git a/indra/newview/skins/default/xui/fr/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/fr/floater_test_text_vertical_aligment.xml new file mode 100644 index 0000000000..702170ef52 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_test_text_vertical_aligment.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="FLOATER TEST"/> diff --git a/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml index 381bcceb00..f86c1a4217 100644 --- a/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml @@ -1,24 +1,36 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="texture picker" title="CHOISIR : TEXTURE"> - <string name="choose_picture"> + <floater.string name="choose_picture"> Cliquez pour sélectionner une image - </string> + </floater.string> + <floater.string name="pick title"> + Choisir : + </floater.string> <text name="Multiple"> Textures multiples </text> + <radio_group name="mode_selection"> + <radio_item label="Inventaire" name="inventory" value="0"/> + <radio_item label="Local" name="local" value="1"/> + </radio_group> <text name="unknown"> Taille : [DIMENSIONS] </text> <button label="Défaut" label_selected="Défaut" name="Default" width="60"/> - <button label="Aucune" label_selected="Aucune" left="68" name="None" width="60"/> <button label="Vierge" label_selected="Vierge" name="Blank" width="60"/> - <check_box label="Afficher les dossiers" name="show_folders_check"/> - <search_editor label="Filtrer les textures" name="inventory search editor"/> - <check_box label="Appliquer maintenant" name="apply_immediate_check"/> + <button label="Aucune" label_selected="Aucune" left="68" name="None" width="60"/> <button bottom="-240" label="" label_selected="" name="Pipette"/> - <button label="Annuler" label_selected="Annuler" name="Cancel"/> + <check_box initial_value="true" label="Aperçu direct" name="apply_immediate_check"/> + <text name="preview_disabled" value="Aperçu désactivé"/> + <filter_editor label="Filtrer les textures" name="inventory search editor"/> + <check_box initial_value="false" label="Afficher les dossiers" name="show_folders_check"/> + <button label="Ajouter" label_selected="Ajouter" name="l_add_btn"/> + <button label="Supprimer" label_selected="Supprimer" name="l_rem_btn"/> + <button label="Charger" label_selected="Charger" name="l_upl_btn"/> + <scroll_list name="l_name_list"> + <column label="Nom" name="unit_name"/> + <column label="ID" name="unit_id_HIDDEN"/> + </scroll_list> <button label="OK" label_selected="OK" name="Select"/> - <string name="pick title"> - Choisir : - </string> + <button label="Annuler" label_selected="Annuler" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/fr/floater_texture_fetch_debugger.xml new file mode 100644 index 0000000000..caae15ea17 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_texture_fetch_debugger.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="TexFetchDebugger" title="Outil de débogage de la récupération des textures"> + <text name="total_num_fetched_label"> + 1, nombre total de textures récupérées : [NUM] + </text> + <text name="total_num_fetching_requests_label"> + 2, nombre total de demandes de récupération : [NUM] + </text> + <text name="total_num_cache_hits_label"> + 3, nombre total de présences dans le cache : [NUM] + </text> + <text name="total_num_visible_tex_label"> + 4, nombre total de textures visibles : [NUM] + </text> + <text name="total_num_visible_tex_fetch_req_label"> + 5, nombre total de demandes de récupération de textures visibles : [NUM] + </text> + <text name="total_fetched_data_label"> + 6, nombre total de données récupérées : [SIZE1] Ko, données décodées : [SIZE2] Ko, [PIXEL] Mpixels + </text> + <text name="total_fetched_vis_data_label"> + 7, nombre total de données visibles : [SIZE1] Ko, données décodées : [SIZE2] Ko + </text> + <text name="total_fetched_rendered_data_label"> + 8, nombre total de données rendues : [SIZE1] Ko, données décodées : [SIZE2] Ko, [PIXEL] Mpixels + </text> + <text name="total_time_cache_read_label"> + 9, durée totale des lectures du cache : [TIME] secondes + </text> + <text name="total_time_cache_write_label"> + 10, durée totale des écritures du cache : [TIME] secondes + </text> + <text name="total_time_decode_label"> + 11, durée totale des décodages : [TIME] secondes + </text> + <text name="total_time_gl_label"> + 12, durée totale de la création de textures GL : [TIME] secondes + </text> + <text name="total_time_http_label"> + 13, durée totale de la récupération HTTP : [TIME] secondes + </text> + <text name="total_time_fetch_label"> + 14, durée totale de la récupération intégrale : [TIME] secondes + </text> + <text name="total_time_refetch_vis_cache_label"> + 15, nouvelle récupération des données visibles du cache, Durée : [TIME] secondes, Récupéré : [SIZE] Ko, [PIXEL] Mpixels + </text> + <text name="total_time_refetch_all_cache_label"> + 16, nouvelle récupération de toutes les textures du cache, Durée : [TIME] secondes, Récupéré : [SIZE] Ko, [PIXEL] Mpixels + </text> + <text name="total_time_refetch_vis_http_label"> + 17, nouvelle récupération des données visibles de la requête HTTP, Durée : [TIME] secondes, Récupéré : [SIZE] Ko, [PIXEL] Mpixels + </text> + <text name="total_time_refetch_all_http_label"> + 18, nouvelle récupération de toutes les textures de la requête HTTP, Durée : [TIME] secondes, Récupéré : [SIZE] Ko, [PIXEL] Mpixels + </text> + <spinner label="19, taux de texels/pixels :" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, source des textures : + </text> + <radio_group name="texture_source"> + <radio_item label="Cache + HTTP" name="0"/> + <radio_item label="HTTP uniquement" name="1"/> + </radio_group> + <button label="Démarrer" name="start_btn"/> + <button label="Réinitialiser" name="clear_btn"/> + <button label="Fermer" name="close_btn"/> + <button label="Lecture du cache" name="cacheread_btn"/> + <button label="Écriture du cache" name="cachewrite_btn"/> + <button label="HTTP" name="http_btn"/> + <button label="Décoder" name="decode_btn"/> + <button label="Texture GL" name="gl_btn"/> + <button label="Récupérer à nouveau les données visibles du cache" name="refetchviscache_btn"/> + <button label="Récupérer cache" name="refetchallcache_btn"/> + <button label="Récupérer à nouveau les données visibles de la requête HTTP" name="refetchvishttp_btn"/> + <button label="Récupérer HTTP" name="refetchallhttp_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_tools.xml b/indra/newview/skins/default/xui/fr/floater_tools.xml index 1ecf47f2e5..bcc3423862 100644 --- a/indra/newview/skins/default/xui/fr/floater_tools.xml +++ b/indra/newview/skins/default/xui/fr/floater_tools.xml @@ -1,5 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="toolbox floater" short_title="OUTILS POUR LA CONSTRUCTION" title=""> + <floater.string name="grid_screen_text"> + Écran + </floater.string> + <floater.string name="grid_local_text"> + Local + </floater.string> + <floater.string name="grid_world_text"> + Monde + </floater.string> + <floater.string name="grid_reference_text"> + Référence + </floater.string> + <floater.string name="grid_attachment_text"> + Élément attaché + </floater.string> <floater.string name="status_rotate"> Pour faire tourner l'objet, faites glisser les bandes de couleur. </floater.string> @@ -63,7 +78,12 @@ </text> <check_box initial_value="true" label="Étirer les textures" name="checkbox stretch textures"/> <check_box initial_value="true" label="Fixer" name="checkbox snap to grid"/> - <button label="Options..." label_selected="Options..." name="Options..." tool_tip="Afficher d'autres options de grille"/> + <combo_box name="combobox grid mode" tool_tip="Choisir le type d'axe de grille pour le positionnement de l'objet."> + <combo_box.item label="Monde" name="World"/> + <combo_box.item label="Local" name="Local"/> + <combo_box.item label="Référence" name="Reference"/> + </combo_box> + <button label="" label_selected="Options..." name="Options..." tool_tip="Afficher d'autres options de grille"/> <button label="" label_selected="" name="ToolCube" tool_tip="Cube"/> <button label="" label_selected="" name="ToolPrism" tool_tip="Prisme droit"/> <button label="" label_selected="" name="ToolPyramid" tool_tip="Pyramide"/> @@ -79,7 +99,7 @@ <button label="" label_selected="" name="ToolRing" tool_tip="Anneau"/> <button label="" label_selected="" name="ToolTree" tool_tip="Arbre"/> <button label="" label_selected="" name="ToolGrass" tool_tip="Herbe"/> - <check_box label="Maintenir l'outil sélectionné" name="checkbox sticky"/> + <check_box label="Maintenir l'outil sélect." name="checkbox sticky"/> <check_box label="Copier la sélection" name="checkbox copy selection"/> <check_box initial_value="true" label="Centrer" name="checkbox copy centers"/> <check_box label="Pivoter" name="checkbox copy rotates"/> @@ -106,7 +126,7 @@ Aucune sélection effectuée. </text> <text name="remaining_capacity"> - [CAPACITY_STRING] [secondlife:///app/openfloater/object_weights More info] + [CAPACITY_STRING] [secondlife:///app/openfloater/object_weights Plus d'infos] </text> <tab_container name="Object Info Tabs"> <panel label="Général" name="General"> @@ -128,6 +148,12 @@ <panel.string name="text modify info 4"> Vous ne pouvez pas modifier ces objets </panel.string> + <panel.string name="text modify info 5"> + Impossible de modifier cet objet au-delà de la frontière d'une région + </panel.string> + <panel.string name="text modify info 6"> + Impossible de modifier ces objets au-delà de la frontière d'une région + </panel.string> <panel.string name="text modify warning"> Sélectionnez l'objet en entier </panel.string> @@ -177,12 +203,12 @@ <combo_box.item label="Zoomer" name="Zoom"/> </combo_box> <check_box label="À vendre :" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Copie" name="Copy"/> <combo_box.item label="Contenus" name="Contents"/> <combo_box.item label="Original" name="Original"/> </combo_box> - <spinner label="Prix : L$" name="Edit Cost"/> <check_box label="Afficher dans la recherche" name="search_check" tool_tip="Afficher l'objet dans les résultats de recherche"/> <panel name="perms_build"> <text name="perm_modify"> @@ -218,6 +244,11 @@ F : </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Attributs de recherche de chemin : + </text> + </panel> </panel> <panel label="Objet" name="Object"> <check_box label="Verrouillé" name="checkbox locked" tool_tip="Empêche l'objet d'être déplacé ou supprimé. Utile pendant la construction pour éviter les modifications involontaires."/> diff --git a/indra/newview/skins/default/xui/fr/floater_top_objects.xml b/indra/newview/skins/default/xui/fr/floater_top_objects.xml index 42352e7c1e..eb084d9184 100644 --- a/indra/newview/skins/default/xui/fr/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/fr/floater_top_objects.xml @@ -1,16 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="top_objects" title="Objets les plus utilisés"> +<floater name="top_objects" title="Objets les plus consommateurs"> <floater.string name="top_scripts_title"> - Scripts principaux + Scripts les plus consommateurs </floater.string> <floater.string name="top_scripts_text"> [COUNT] scripts prenant un total de [TIME] ms </floater.string> <floater.string name="scripts_score_label"> - Heure - </floater.string> - <floater.string name="scripts_mono_time_label"> - Heure Mono + Temps </floater.string> <floater.string name="top_colliders_title"> Collisions les plus consommatrices @@ -32,9 +29,10 @@ <scroll_list.columns label="Nom" name="name"/> <scroll_list.columns label="Propriétaire" name="owner"/> <scroll_list.columns label="Lieu" name="location"/> - <scroll_list.columns label="Heure" name="time"/> - <scroll_list.columns label="Heure Mono" name="mono_time"/> + <scroll_list.columns label="Parcelle" name="parcel"/> + <scroll_list.columns label="Temps" name="time"/> <scroll_list.columns label="URL" name="URLs"/> + <scroll_list.columns label="Mémoire (Ko)" name="memory"/> </scroll_list> <text name="id_text"> ID de l'objet : @@ -43,11 +41,15 @@ <text name="obj_name_text"> Nom : </text> - <button label="Filtre" name="filter_object_btn"/> + <button label="Filtrer" name="filter_object_btn"/> <text name="owner_name_text"> Propriétaire : </text> - <button label="Filtre" name="filter_owner_btn"/> + <button label="Filtrer" name="filter_owner_btn"/> + <text name="parcel_name_text"> + Parcelle : + </text> + <button label="Filtrer" name="filter_parcel_btn"/> <button label="Rafraîchir" name="refresh_btn"/> <button label="Renvoyer" name="return_selected_btn"/> <button label="Tout renvoyer" name="return_all_btn"/> diff --git a/indra/newview/skins/default/xui/fr/floater_toybox.xml b/indra/newview/skins/default/xui/fr/floater_toybox.xml index e6fa212c65..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 LA BARRE D'OUTILS"> +<floater name="Toybox" title="BOUTONS DES BARRES D'OUTILS"> <text name="toybox label 1"> - Ajouter ou supprimer des boutons en les faisant glisser vers les barres d'outils ou à partir de ces dernières. + Ajouter ou supprimer des boutons : les faire glisser vers ou depuis les barres d'outils. </text> <text name="toybox label 2"> - Les boutons s'afficheront comme indiqué ou comme des icônes, en fonction des paramètres de chaque barre d'outils. + Ils s'afficheront comme indiqué ou comme des icônes, selon les paramètres de barre d'outils. </text> - <button label="Restaurer les choix par défaut" label_selected="Restaurer les choix par défaut" name="btn_restore_defaults"/> + <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'application Bing non vérifié. Veuillez réessayer. + </string> + <string name="google_api_key_not_verified"> + Clé d'API Google non vérifiée. Veuillez réessayer. + </string> + <string name="bing_api_key_verified"> + ID d'application Bing vérifié. + </string> + <string name="google_api_key_verified"> + Clé d'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'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'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'y a personne près de vous avec le chat vocal activé diff --git a/indra/newview/skins/default/xui/fr/floater_voice_effect.xml b/indra/newview/skins/default/xui/fr/floater_voice_effect.xml index 92ee6ecf24..671fb5c14d 100644 --- a/indra/newview/skins/default/xui/fr/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/fr/floater_voice_effect.xml @@ -42,13 +42,16 @@ <string name="effect_Demon"> Démon </string> + <string name="effect_Female Elf"> + Femme elfe + </string> <string name="effect_Flirty"> Flirt </string> <string name="effect_Foxy"> Séduction </string> - <string name="effect_Halloween_2010_Bonus"> + <string name="effect_Halloween 2010 Bonus"> Halloween_2010_Bonus </string> <string name="effect_Helium"> @@ -57,9 +60,18 @@ <string name="effect_Husky"> Rauque </string> + <string name="effect_Husky Whisper"> + Murmure rauque + </string> <string name="effect_Intercom"> Interphone </string> + <string name="effect_Julia"> + Julia + </string> + <string name="effect_Lo Lilt"> + Mélodieux + </string> <string name="effect_Macho"> Macho </string> @@ -69,6 +81,9 @@ <string name="effect_Mini"> Mini </string> + <string name="effect_Model"> + Modèle + </string> <string name="effect_Nano"> Nano </string> @@ -90,6 +105,9 @@ <string name="effect_Roxanne"> Roxanne </string> + <string name="effect_Rumble"> + Grondement + </string> <string name="effect_Sabrina"> Sabrina </string> @@ -102,6 +120,9 @@ <string name="effect_Shorty"> Petite voix </string> + <string name="effect_Smaller"> + Plus faible + </string> <string name="effect_Sneaky"> Sournois </string> diff --git a/indra/newview/skins/default/xui/fr/floater_window_size.xml b/indra/newview/skins/default/xui/fr/floater_window_size.xml index cbda4390d8..11c2e439bd 100644 --- a/indra/newview/skins/default/xui/fr/floater_window_size.xml +++ b/indra/newview/skins/default/xui/fr/floater_window_size.xml @@ -7,10 +7,17 @@ Définir la taille de la fenêtre : </text> <combo_box name="window_size_combo" tool_tip="largeur x hauteur"> - <combo_box.item label="1 000 x 700 (défaut)" name="item0"/> - <combo_box.item label="1 024 x 768" name="item1"/> - <combo_box.item label="1 280 x 720 (720 p)" name="item2"/> - <combo_box.item label="1 920 x 1 080 (1 080p)" name="item3"/> + <combo_box.item label="1000 x 700 (par défaut)" name="item1"/> + <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/> + <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/> + <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/> + <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/> + <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/> + <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/> + <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/> + <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/> + <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/> + <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/> </combo_box> <button label="Choisir" name="set_btn"/> <button label="Annuler" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/fr/menu_bottomtray.xml b/indra/newview/skins/default/xui/fr/menu_bottomtray.xml deleted file mode 100644 index d0d245b286..0000000000 --- a/indra/newview/skins/default/xui/fr/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="Bouton Parler" name="EnableVoiceChat"/> - <menu_item_check label="Bouton Geste" name="ShowGestureButton"/> - <menu_item_check label="Bouton Bouger" name="ShowMoveButton"/> - <menu_item_check label="Bouton Affichage" name="ShowCameraButton"/> - <menu_item_check label="Bouton Photo" name="ShowSnapshotButton"/> - <menu_item_check label="Bouton Construire" name="ShowBuildButton"/> - <menu_item_check label="Bouton Rechercher" name="ShowSearchButton"/> - <menu_item_check label="Bouton Carte" name="ShowWorldMapButton"/> - <menu_item_check label="Bouton Mini-carte" name="ShowMiniMapButton"/> - <menu_item_call label="Couper" name="NearbyChatBar_Cut"/> - <menu_item_call label="Copier" name="NearbyChatBar_Copy"/> - <menu_item_call label="Coller" name="NearbyChatBar_Paste"/> - <menu_item_call label="Supprimer" name="NearbyChatBar_Delete"/> - <menu_item_call label="Tout sélectionner" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/fr/menu_group_plus.xml b/indra/newview/skins/default/xui/fr/menu_group_plus.xml index 0db5afedc7..ad76f11d79 100644 --- a/indra/newview/skins/default/xui/fr/menu_group_plus.xml +++ b/indra/newview/skins/default/xui/fr/menu_group_plus.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu name="menu_group_plus"> - <menu_item_call label="Rejoindre des groupes..." name="item_join"/> + <menu_item_call label="Rejoindre un groupe..." name="item_join"/> <menu_item_call label="Nouveau groupe..." name="item_new"/> </menu> diff --git a/indra/newview/skins/default/xui/fr/menu_im_well_button.xml b/indra/newview/skins/default/xui/fr/menu_im_well_button.xml deleted file mode 100644 index 8ef1529e6b..0000000000 --- a/indra/newview/skins/default/xui/fr/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<context_menu name="IM Well Button Context Menu"> - <menu_item_call label="Tout fermer" name="Close All"/> -</context_menu> diff --git a/indra/newview/skins/default/xui/fr/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/fr/menu_inspect_object_gear.xml index 074bb54cdc..f3b974aba5 100644 --- a/indra/newview/skins/default/xui/fr/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/fr/menu_inspect_object_gear.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<menu name="Gear Menu"> +<toggleable_menu name="Gear Menu"> <menu_item_call label="Toucher" name="touch"/> <menu_item_call label="M'asseoir" name="sit"/> <menu_item_call label="Payer" name="pay"/> @@ -12,7 +12,8 @@ <menu_item_call label="Ajouter" name="add"/> <menu_item_call label="Signaler" name="report"/> <menu_item_call label="Ignorer" name="block"/> + <menu_item_call label="Ne plus ignorer" name="unblock"/> <menu_item_call label="Zoomer en avant" name="zoom_in"/> <menu_item_call label="Supprimer" name="remove"/> <menu_item_call label="En savoir plus" name="more_info"/> -</menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/fr/menu_inventory.xml b/indra/newview/skins/default/xui/fr/menu_inventory.xml index 53df8d11da..627d3068c3 100644 --- a/indra/newview/skins/default/xui/fr/menu_inventory.xml +++ b/indra/newview/skins/default/xui/fr/menu_inventory.xml @@ -59,6 +59,7 @@ <menu_item_call label="Propriétés" name="Properties"/> <menu_item_call label="Renommer" name="Rename"/> <menu_item_call label="Copier l'UUID (identifiant universel unique)" name="Copy Asset UUID"/> + <menu_item_call label="Couper" name="Cut"/> <menu_item_call label="Copier" name="Copy"/> <menu_item_call label="Coller" name="Paste"/> <menu_item_call label="Coller comme lien" name="Paste As Link"/> @@ -67,11 +68,12 @@ <menu_item_call label="Supprimer le dossier système" name="Delete System Folder"/> <menu_item_call label="Démarrer le chat conférence" name="Conference Chat Folder"/> <menu_item_call label="Jouer" name="Sound Play"/> + <menu_item_call label="Copier la SLurl" name="url_copy"/> <menu_item_call label="À propos du repère" name="About Landmark"/> <menu_item_call label="Jouer dans Second Life" name="Animation Play"/> <menu_item_call label="Jouer localement" name="Animation Audition"/> <menu_item_call label="Envoyer un message instantané" name="Send Instant Message"/> - <menu_item_call label="Offrir de téléporter..." name="Offer Teleport..."/> + <menu_item_call label="Proposer une téléportation..." name="Offer Teleport..."/> <menu_item_call label="Démarrer le chat conférence" name="Conference Chat"/> <menu_item_call label="Activer" name="Activate"/> <menu_item_call label="Désactiver" name="Deactivate"/> @@ -84,6 +86,6 @@ <menu_item_call label="Ajouter" name="Wearable Add"/> <menu_item_call label="Enlever" name="Take Off"/> <menu_item_call label="Copier vers la boîte d'envoi vendeur" name="Merchant Copy"/> - <menu_item_call label="Déplacer vers la boîte d'envoi vendeur" name="Merchant Move"/> + <menu_item_call label="Envoyer vers la Place du marché" name="Marketplace Send"/> <menu_item_call label="--aucune option--" name="--no options--"/> </menu> diff --git a/indra/newview/skins/default/xui/fr/menu_login.xml b/indra/newview/skins/default/xui/fr/menu_login.xml index 8210c1be51..dc6b2793ca 100644 --- a/indra/newview/skins/default/xui/fr/menu_login.xml +++ b/indra/newview/skins/default/xui/fr/menu_login.xml @@ -17,8 +17,8 @@ <menu_item_call label="Définir la taille de la fenêtre..." name="Set Window Size..."/> <menu_item_call label="Afficher les conditions d'utilisation" name="TOS"/> <menu_item_call label="Afficher le message critique" name="Critical"/> - <menu_item_call label="Test du navigateur de médias" name="Web Browser Test"/> <menu_item_call label="Test de débogage de la fenêtre flottante du contenu Web" name="Web Content Floater Debug Test"/> + <menu label="Définir le niveau de connexion" name="Set Logging Level"/> <menu_item_check label="Afficher le sélecteur de grille" name="Show Grid Picker"/> <menu_item_call label="Afficher la console des notifications" name="Show Notifications Console"/> </menu> diff --git a/indra/newview/skins/default/xui/fr/menu_mode_change.xml b/indra/newview/skins/default/xui/fr/menu_mode_change.xml deleted file mode 100644 index 982a331c5b..0000000000 --- a/indra/newview/skins/default/xui/fr/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="Basique" name="BasicMode"/> - <menu_item_check label="Avancé" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/fr/menu_object.xml b/indra/newview/skins/default/xui/fr/menu_object.xml index c6db48a31c..573b6da582 100644 --- a/indra/newview/skins/default/xui/fr/menu_object.xml +++ b/indra/newview/skins/default/xui/fr/menu_object.xml @@ -5,6 +5,8 @@ </menu_item_call> <menu_item_call label="Modifier" name="Edit..."/> <menu_item_call label="Construire" name="Build"/> + <menu_item_call label="Voir parmi les groupes de liens" name="show_in_linksets"/> + <menu_item_call label="Voir parmi les personnages" name="show_in_characters"/> <menu_item_call label="Ouvrir" name="Open"/> <menu_item_call label="M'asseoir ici" name="Object Sit"/> <menu_item_call label="Me lever" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/fr/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/fr/menu_people_nearby_view_sort.xml index 0aad174fbd..8bb466b8d6 100644 --- a/indra/newview/skins/default/xui/fr/menu_people_nearby_view_sort.xml +++ b/indra/newview/skins/default/xui/fr/menu_people_nearby_view_sort.xml @@ -5,5 +5,5 @@ <menu_item_check label="Trier par distance" name="sort_distance"/> <menu_item_check label="Afficher les icônes des résidents" name="view_icons"/> <menu_item_check label="Afficher la carte" name="view_map"/> - <menu_item_call label="Afficher les résidents et les objets interdits" name="show_blocked_list"/> + <menu_item_call label="Afficher les résidents et les objets ignorés" name="show_blocked_list"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/fr/menu_text_editor.xml b/indra/newview/skins/default/xui/fr/menu_text_editor.xml index b6f429aec9..c31b0c8556 100644 --- a/indra/newview/skins/default/xui/fr/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/fr/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(inconnu)" name="Suggestion 1"/> + <menu_item_call label="(inconnu)" name="Suggestion 2"/> + <menu_item_call label="(inconnu)" name="Suggestion 3"/> + <menu_item_call label="(inconnu)" name="Suggestion 4"/> + <menu_item_call label="(inconnu)" name="Suggestion 5"/> + <menu_item_call label="Ajouter au dictionnaire" name="Add to Dictionary"/> + <menu_item_call label="Ajouter aux éléments à ignorer" name="Add to Ignore"/> <menu_item_call label="Couper" name="Cut"/> <menu_item_call label="Copier" name="Copy"/> <menu_item_call label="Coller" name="Paste"/> diff --git a/indra/newview/skins/default/xui/fr/menu_toolbars.xml b/indra/newview/skins/default/xui/fr/menu_toolbars.xml index bbfbe4b9ed..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_check label="Icônes et étiquettes" name="icons_with_text"/> + <menu_item_call label="Supprimer ce bouton" name="Remove button"/> + <menu_item_call label="Boutons des barres d'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 64cd463070..85020afe25 100644 --- a/indra/newview/skins/default/xui/fr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml @@ -1,55 +1,62 @@ <?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'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'inventaire" name="NewInventoryWindow"/> + <menu_item_call label="Endroits..." name="Places"/> + <menu_item_call label="Favoris..." name="Picks"/> + <menu_item_call label="Contrôles de la caméra..." name="Camera Controls"/> <menu label="Déplacement" name="Movement"> <menu_item_call label="M'asseoir" name="Sit Down Here"/> <menu_item_check label="Voler" name="Fly"/> <menu_item_check label="Toujours courir" name="Always Run"/> <menu_item_call label="Arrêter mon animation" name="Stop Animating My Avatar"/> + <menu_item_call label="Marcher / Courir / Voler..." name="Walk / run / fly"/> </menu> <menu label="Statut" name="Status"> <menu_item_call label="Absent" name="Set Away"/> <menu_item_call label="Occupé" name="Set Busy"/> </menu> - <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="Acheter des L$..." name="Buy and Sell L$"/> + <menu_item_call label="Boîte d'envoi vendeur..." name="MerchantOutbox"/> + <menu_item_call label="Page d'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'outils..." name="Toolbars"/> - <menu_item_call label="Cacher tous les contrôles" name="Hide UI"/> + <menu_item_call label="Boutons des barres d'outils..." name="Toolbars"/> + <menu_item_call label="Masquer tous les contrôles" name="Hide UI"/> + <menu_item_check label="Afficher les éléments HUD" name="Show HUD Attachments"/> <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_item_call label="Liste des ignorés" name="Block List"/> </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'interdiction" name="Ban Lines"/> <menu_item_check label="Balises" name="beacons"/> <menu_item_check label="Limites du terrain" name="Property Lines"/> @@ -58,16 +65,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 label="Luminosité" name="Sun"> <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'environnement" name="Enviroment Editor"> - <menu_item_call label="Paramètres d'environnement..." name="Enviroment Settings"/> + <menu label="Éditeur d'environnement" name="Environment Editor"> + <menu_item_call label="Paramètres d'environnement..." name="Environment Settings"/> <menu label="Préréglages de l'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"/> @@ -120,6 +126,11 @@ <menu_item_call label="Définir les scripts sur Exécution" name="Set Scripts to Running"/> <menu_item_call label="Définir les scripts sur Pas d'exécution" name="Set Scripts to Not Running"/> </menu> + <menu label="Recherche de chemin" name="Pathfinding"> + <menu_item_call label="Groupes de liens..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="Personnages..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="Vue / test..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Options" name="Options"> <menu_item_check label="Afficher les droits avancés" name="DebugPermissions"/> <menu_item_check label="Sélectionner mes objets uniquement" name="Select Only My Objects"/> @@ -140,11 +151,13 @@ <menu_item_call label="Animation ([COST] L$)..." name="Upload Animation"/> <menu_item_call label="Modèle..." name="Upload Model"/> <menu_item_call label="Lot ([COST] L$ par fichier)..." name="Bulk Upload"/> + <menu_item_call label="Définir les droits de chargement par défaut" name="perm prefs"/> </menu> <menu_item_call label="Annuler" name="Undo"/> <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"/> @@ -165,29 +178,28 @@ </menu> <menu label="Surbrillance et visibilité" name="Highlighting and Visibility"> <menu_item_check label="Balise animée" name="Cheesy Beacon"/> - <menu_item_check label="Cacher les particules" name="Hide Particles"/> + <menu_item_check label="Masquer les particules" name="Hide Particles"/> <menu_item_check label="Masquer la sélection" name="Hide Selected"/> <menu_item_check label="Mettre la transparence en surbrillance" name="Highlight Transparent"/> - <menu_item_check label="Afficher les éléments HUD" name="Show HUD Attachments"/> <menu_item_check label="Afficher le réticule de la vue subjective" name="ShowCrosshairs"/> </menu> <menu label="Types de rendu" name="Rendering Types"> - <menu_item_check label="Simple" name="Simple"/> - <menu_item_check label="Alpha" name="Alpha"/> - <menu_item_check label="Arbre" name="Tree"/> - <menu_item_check label="Avatars" name="Character"/> - <menu_item_check label="Patch de surface" name="Surface Patch"/> - <menu_item_check label="Ciel" name="Sky"/> - <menu_item_check label="Eau" name="Water"/> - <menu_item_check label="Sol" name="Ground"/> - <menu_item_check label="Volume" name="Volume"/> - <menu_item_check label="Herbe" name="Grass"/> - <menu_item_check label="Nuages" name="Clouds"/> - <menu_item_check label="Particules" name="Particles"/> - <menu_item_check label="Placage de relief" name="Bump"/> + <menu_item_check label="Simple" name="Rendering Type Simple"/> + <menu_item_check label="Alpha" name="Rendering Type Alpha"/> + <menu_item_check label="Arbre" name="Rendering Type Tree"/> + <menu_item_check label="Avatars" name="Rendering Type Character"/> + <menu_item_check label="Patch de surface" name="Rendering Type Surface Patch"/> + <menu_item_check label="Ciel" name="Rendering Type Sky"/> + <menu_item_check label="Eau" name="Rendering Type Water"/> + <menu_item_check label="Sol" name="Rendering Type Ground"/> + <menu_item_check label="Volume" name="Rendering Type Volume"/> + <menu_item_check label="Herbe" name="Rendering Type Grass"/> + <menu_item_check label="Nuages" name="Rendering Type Clouds"/> + <menu_item_check label="Particules" name="Rendering Type Particles"/> + <menu_item_check label="Placage de relief" name="Rendering Type Bump"/> </menu> <menu label="Fonctionnalités de rendu" name="Rendering Features"> - <menu_item_check label="Interface" name="UI"/> + <menu_item_check label="Interface" name="ToggleUI"/> <menu_item_check label="Sélection" name="Selected"/> <menu_item_check label="En surbrillance" name="Highlighted"/> <menu_item_check label="Textures dynamiques" name="Dynamic Textures"/> @@ -199,11 +211,8 @@ <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'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"/> @@ -212,13 +221,6 @@ <menu_item_check label="Joystick Flycam" name="Joystick Flycam"/> <menu_item_call label="Réinitialiser la vue" name="Reset View"/> <menu_item_call label="Regarder la dernière conversation" name="Look at Last Chatter"/> - <menu label="Sélectionner un outil de construction" name="Select Tool"> - <menu_item_call label="Outil de mise au point" name="Focus"/> - <menu_item_call label="Outil de déplacement" name="Move"/> - <menu_item_call label="Outil de modification" name="Edit"/> - <menu_item_call label="Outil de création" name="Create"/> - <menu_item_call label="Outil Terrain" name="Land"/> - </menu> <menu_item_call label="Zoomer en avant" name="Zoom In"/> <menu_item_call label="Zoom par défaut" name="Zoom Default"/> <menu_item_call label="Zoomer en arrière" name="Zoom Out"/> @@ -231,11 +233,10 @@ <menu_item_check label="Console de textures" name="Texture Console"/> <menu_item_check label="Console de débogage" name="Debug Console"/> <menu_item_call label="Console de notifications" name="Notifications"/> - <menu_item_check label="Console de tailles de textures" name="Texture Size"/> - <menu_item_check label="Console des catégories de textures" name="Texture Category"/> <menu_item_check label="Chronos" name="Fast Timers"/> <menu_item_check label="Mémoire" name="Memory"/> <menu_item_check label="Statistiques de la scène" name="Scene Statistics"/> + <menu_item_call label="Console de débogage de la récupération des textures" name="Texture Fetch Debug Console"/> <menu_item_call label="Infos de région vers la console de débogage" name="Region Info to Debug Console"/> <menu_item_call label="Infos de groupe vers la console de débogage" name="Group Info to Debug Console"/> <menu_item_call label="Infos de capacités vers la console de débogage" name="Capabilities Info to Debug Console"/> @@ -289,8 +290,16 @@ <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="Octets d'éléments attachés" name="attachment bytes"/> <menu_item_check label="Sculpture" name="Sculpt"/> + <menu label="Densité des textures" name="Texture Density"> + <menu_item_check label="Aucune" name="None"/> + <menu_item_check label="Actuelle" name="Current"/> + <menu_item_check label="Souhaitée" name="Desired"/> + <menu_item_check label="Complète" name="Full"/> + </menu> </menu> <menu label="Rendu" name="Rendering"> <menu_item_check label="Axes" name="Axes"/> @@ -301,7 +310,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)"/> @@ -309,7 +317,6 @@ <menu_item_check label="Textures d'animation" name="Animation Textures"/> <menu_item_check label="Désactiver les textures" name="Disable Textures"/> <menu_item_check label="Textures pleine résolution" name="Rull Res Textures"/> - <menu_item_check label="Audit Textures" name="Audit Textures"/> <menu_item_check label="Atlas des textures (expérimental)" name="Texture Atlas"/> <menu_item_check label="Rendu des lumières jointes" name="Render Attached Lights"/> <menu_item_check label="Rendu des particules jointes" name="Render Attached Particles"/> @@ -319,7 +326,7 @@ <menu_item_check label="Pauser l'avatar" name="AgentPause"/> <menu_item_call label="Activer le journal des messages" name="Enable Message Log"/> <menu_item_call label="Désactiver le journal des messages" name="Disable Message Log"/> - <menu_item_check label="Velocity Interpolate Objects" name="Velocity Interpolate Objects"/> + <menu_item_check label="Objets d'interpolation de vitesse" name="Velocity Interpolate Objects"/> <menu_item_check label="Interpolation ping des positions des objets" name="Ping Interpolate Object Positions"/> <menu_item_call label="Abandonner un paquet" name="Drop a Packet"/> </menu> @@ -332,11 +339,10 @@ <menu_item_call label="Commencer l'enregistrement" name="Start Record"/> <menu_item_call label="Arrêter l'enregistrement" name="Stop Record"/> </menu> - <menu label="Monde" name="World"> + <menu label="Monde" name="DevelopWorld"> <menu_item_check label="Ignorer les paramètres du soleil de la sim" name="Sim Sun Override"/> - <menu_item_check label="Balise animée" name="Cheesy Beacon"/> <menu_item_check label="Météo fixe" name="Fixed Weather"/> - <menu_item_call label="Dump Region Object Cache" name="Dump Region Object Cache"/> + <menu_item_call label="Vidage de cache d'objet de la région" name="Dump Region Object Cache"/> </menu> <menu label="Interface" name="UI"> <menu_item_call label="Test du navigateur de médias" name="Web Browser Test"/> @@ -366,18 +372,17 @@ </menu> <menu label="Avatar" name="Character"> <menu label="Récupérer la texture fixée" name="Grab Baked Texture"> - <menu_item_call label="Iris" name="Iris"/> - <menu_item_call label="Tête" name="Head"/> - <menu_item_call label="Haut du corps" name="Upper Body"/> - <menu_item_call label="Bas du corps" name="Lower Body"/> - <menu_item_call label="Jupe" name="Skirt"/> + <menu_item_call label="Iris" name="Grab Iris"/> + <menu_item_call label="Tête" name="Grab Head"/> + <menu_item_call label="Haut du corps" name="Grab Upper Body"/> + <menu_item_call label="Bas du corps" name="Grab Lower Body"/> + <menu_item_call label="Jupe" name="Grab Skirt"/> </menu> <menu label="Tests personnages" name="Character Tests"> <menu_item_call label="Apparence dans XML" name="Appearance To XML"/> <menu_item_call label="Basculer la géométrie des personnages" name="Toggle Character Geometry"/> <menu_item_call label="Test homme" name="Test Male"/> <menu_item_call label="Test femme" name="Test Female"/> - <menu_item_call label="Activer/désactiver PG" name="Toggle PG"/> <menu_item_check label="Autoriser la sélection de l'avatar" name="Allow Select Avatar"/> </menu> <menu_item_call label="Forcer les paramètres par défaut" name="Force Params to Default"/> @@ -398,20 +403,28 @@ <menu_item_check label="Textures HTTP" name="HTTP Textures"/> <menu_item_check label="Inventaire HTTP" name="HTTP Inventory"/> <menu_item_call label="Compresser les images" name="Compress Images"/> + <menu_item_call label="Activer Visual Leak Detector" name="Enable Visual Leak Detector"/> <menu_item_check label="Output Debug Minidump" name="Output Debug Minidump"/> <menu_item_check label="Console Window on next Run" name="Console Window"/> + <menu label="Définir le niveau de connexion" name="Set Logging Level"> + <menu_item_check label="Débogage" name="Debug"/> + <menu_item_check label="Infos" name="Info"/> + <menu_item_check label="Avertissement" name="Warning"/> + <menu_item_check label="Erreur" name="Error"/> + <menu_item_check label="Aucun" name="None"/> + </menu> <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_check label="Afficher le menu Admin" name="View Admin Options"/> </menu> <menu label="Admin" name="Admin"> - <menu label="Object"> - <menu_item_call label="Prendre une copie" name="Take Copy"/> - <menu_item_call label="Téléporter le propriétaire" name="Force Owner To Me"/> + <menu label="Objet" name="AdminObject"> + <menu_item_call label="Prendre une copie" name="Admin Take Copy"/> + <menu_item_call label="Me faire devenir propriétaire" name="Force Owner To Me"/> <menu_item_call label="Forcer la permission du propriétaire" name="Force Owner Permissive"/> <menu_item_call label="Supprimer" name="Delete"/> <menu_item_call label="Verrouiller" name="Lock"/> - <menu_item_call label="Obtenir les ID d'actifs" name="Get Assets IDs"/> + <menu_item_call label="Obtenir les ID des actifs" name="Get Assets IDs"/> </menu> <menu label="Parcelle" name="Parcel"> <menu_item_call label="Téléporter le propriétaire" name="Owner To Me"/> @@ -442,10 +455,10 @@ <menu_item_call label="Propriétés physiques" name="Physics"/> <menu_item_call label="Tous les habits" name="All Clothes"/> </menu> - <menu label="Aide" name="Help"> + <menu label="Aide" name="DeprecatedHelp"> <menu_item_call label="Blog officiel des Linden" name="Official Linden Blog"/> <menu_item_call label="Portail d'écriture de scripts" name="Scripting Portal"/> - <menu label="Signaler des bugs" name="Bug Reporting"> + <menu label="Signaler un bug" name="Bug Reporting"> <menu_item_call label="JIRA" name="Public Issue Tracker"/> <menu_item_call label="Aide du JIRA" name="Publc Issue Tracker Help"/> <menu_item_call label="Comment signaler des bugs" name="Bug Reporing 101"/> diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index 31c29029b5..30154d1873 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -86,16 +92,37 @@ Veuillez vérifier votre connexion Internet. <usetemplate canceltext="Cancel" name="yesnocancelbuttons" notext="Ne pas enregistrer" yestext="Enregistrer"/> </notification> <notification name="ConfirmNoCopyToOutbox"> - Vous n'êtes pas autorisé à copier cet article dans la boîte d'envoi vers la Place du marché. Voulez-vous vraiment déplacer l'article suivant ? - [ITEM_NAME] - <usetemplate name="okcancelbuttons" notext="Non" yestext="Oui"/> + Vous n'êtes pas autorisé à copier un ou plusieurs de ces articles dans la boîte d'envoi vendeur. Vous pouvez les déplacer ou les laisser. + <usetemplate name="okcancelbuttons" notext="Ne pas déplacer les articles" yestext="Déplacer les articles"/> + </notification> + <notification name="OutboxFolderCreated"> + Un nouveau dossier a été créé pour chaque article que vous avez transféré vers le niveau supérieur de votre boîte d'envoi vendeur. + <usetemplate ignoretext="Un nouveau dossier a été créé dans la boîte d'envoi vendeur." name="okignore" yestext="OK"/> + </notification> + <notification name="OutboxImportComplete"> + Transfert réussi + +Tous les dossiers ont été envoyés vers la Place du marché. + <usetemplate ignoretext="Tous les dossiers envoyés vers la Place du marché" name="okignore" yestext="OK"/> + </notification> + <notification name="OutboxImportHadErrors"> + Impossible de transférer certains dossiers + +Des erreurs se sont produites lors de l'envoi de certains dossiers vers la Place du marché. Ces dossiers sont toujours disponibles dans votre boîte d'envoi vendeur. + +Pour plus d'informations, consultez le [[MARKETPLACE_IMPORTS_URL] journal des erreurs]. + <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="OutboxUploadComplete"> - Chargement sur la Place du marché terminé. - <usetemplate name="okbutton" yestext="Hourra !"/> + <notification name="OutboxImportFailed"> + Échec de transfert + +Aucun dossier n'a été envoyé vers la Place du marché en raison d'une erreur système ou réseau. Veuillez réessayer ultérieurement. + <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="OutboxUploadHadErrors"> - Chargement sur la Place du marché effectué avec des erreurs ! Corrigez les problèmes dans votre boîte d'envoi et réessayez. Merci ! + <notification name="OutboxInitFailed"> + Échec d'initialisation de la Place du marché + +L'initialisation de la Place du marché a échoué en raison d'une erreur système ou réseau. Veuillez réessayer ultérieurement. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CompileQueueSaveText"> @@ -338,13 +365,19 @@ Vous devez saisir le nom d'utilisateur de votre avatar. Pour entrer dans [SECOND_LIFE], vous devez disposer d'un compte. Voulez-vous en créer un maintenant ? <url name="url"> - https://join.secondlife.com/index.php?lang=fr-FR + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Réessayer" yestext="Créer un compte"/> </notification> <notification name="InvalidCredentialFormat"> Saisissez soit le nom d'utilisateur soit à la fois le prénom et le nom de votre avatar dans le champ Nom d'utilisateur, puis connectez-vous. </notification> + <notification name="InvalidGrid"> + [GRID] n'est pas un identifiant de grille valide. + </notification> + <notification name="InvalidLocationSLURL"> + Grille non valide spécifiée au niveau du lieu de départ. + </notification> <notification name="DeleteClassified"> Supprimer l'annonce [NAME] ? Une fois payés, les frais ne sont pas remboursables. @@ -451,7 +484,7 @@ L'objet est peut-être inaccessible ou a peut-être été supprimé. </notification> <notification name="StartRegionEmpty"> Vous n'avez pas défini de région de départ. -Veuillez saisir le nom de la région dans la case Lieu de départ, ou choisissez Dernier emplacement ou Domicile comme Lieu de départ. +Saisissez le nom de la région voulue dans la case Lieu de départ ou choisissez Dernier emplacement ou Domicile comme lieu de départ. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CouldNotStartStopScript"> @@ -473,6 +506,15 @@ Consulter [_URL] pour en savoir plus ? </url> <usetemplate ignoretext="Mon matériel n'est pas pris en charge" name="okcancelignore" notext="Non" yestext="Oui"/> </notification> + <notification name="IntelOldDriver"> + Il existe probablement un pilote plus récent pour votre puce graphique. La mise à jour des pilotes graphiques est susceptible d'améliorer considérablement les performances. + + Visiter la page [_URL] pour rechercher d'éventuelles mises à jour de pilotes ? + <url name="url"> + http://www.intel.com/p/fr_FR/support/detect/graphics + </url> + <usetemplate ignoretext="Mon pilote graphique est obsolète." name="okcancelignore" notext="Non" yestext="Oui"/> + </notification> <notification name="UnknownGPU"> Votre système contient une carte graphique que [APP_NAME] ne reconnaît pas. Cela est souvent le cas avec le nouveau matériel qui n'a pas encore été testé avec [APP_NAME]. Cela ne posera probablement pas de problème, mais vous devrez peut-être ajuster vos paramètres graphiques. @@ -569,6 +611,9 @@ Vous pouvez lier un maximum de [MAX] objets. Assurez-vous que vous êtes le propriétaire de tous les objets et qu'aucun d'eux n'est verrouillé. </notification> + <notification name="CannotLinkPermanent"> + Impossible de lier des objets d'une région à une autre. + </notification> <notification name="CannotLinkDifferentOwners"> Impossible de lier car les objets n'ont pas tous le même propriétaire. @@ -648,7 +693,7 @@ Assurez-vous que le fichier a l'extension correcte. Impossible de créer le fichier de sortie : [FILE] </notification> <notification name="DoNotSupportBulkAnimationUpload"> - Actuellement, [APP_NAME] ne prend pas en charge le chargement de lots de fichiers d'animation. + Actuellement, [APP_NAME] ne prend pas en charge le chargement par lot de fichiers d'animation au format BVH. </notification> <notification name="CannotUploadReason"> Impossible de charger [FILE] suite au problème suivant : [REASON] @@ -949,6 +994,41 @@ Proposer à [NAME] de devenir votre ami(e) ? <button name="Cancel" text="Annuler"/> </form> </notification> + <notification label="Ajouter une liste Rechercher/Remplacer" name="AddAutoReplaceList"> + Nom de la nouvelle liste : + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="Renommer la liste Rechercher/Remplacer" name="RenameAutoReplaceList"> + Le nom [DUPNAME] est déjà utilisé. + Saisissez un nouveau nom unique : + <form name="form"> + <button name="ReplaceList" text="Remplacer la liste actuelle"/> + <button name="SetName" text="Utiliser le nouveau nom"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + Le mot-clé doit être constitué d'un seul mot et sa valeur de remplacement doit être renseignée. + </notification> + <notification name="InvalidAutoReplaceList"> + Liste de remplacement non valide. + </notification> + <notification name="SpellingDictImportRequired"> + Spécifiez un fichier, un nom et une langue. + </notification> + <notification name="SpellingDictIsSecondary"> + Le dictionnaire [DIC_NAME] ne semble pas contenir de fichier "aff" ; il s'agit donc d'un dictionnaire « secondaire ». +Vous pouvez l'utiliser comme dictionnaire supplémentaire mais pas comme dictionnaire principal. + +Voir https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + Impossible de copier + [FROM_NAME] + vers + [TO_NAME] + </notification> <notification label="Enregistrer la tenue" name="SaveOutfitAs"> Enregistrer ce que je porte comme nouvelle tenue : <form name="form"> @@ -980,7 +1060,7 @@ Proposer à [NAME] de devenir votre ami(e) ? </form> </notification> <notification name="RemoveFromFriends"> - Voulez-vous supprimer [NAME] de votre liste d'amis ? + Voulez-vous supprimer <nolink>[NAME]</nolink> de votre liste d'amis ? <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> </notification> <notification name="RemoveMultipleFromFriends"> @@ -1105,8 +1185,13 @@ Céder ces [AREA] m² de terrain au groupe [GROUP_NAME] ? <notification name="DisplaySetToSafe"> Les paramètres d'affichage sont au niveau le plus sûr, comme vous l'aviez indiqué. </notification> - <notification name="DisplaySetToRecommended"> - Vos paramètres d'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'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'affichage ont été modifiés selon les niveaux recommandés en raison d'un changement relatif au sous-système de rendu. </notification> <notification name="ErrorMessage"> [ERROR_MESSAGE] @@ -1117,7 +1202,7 @@ Céder ces [AREA] m² de terrain au groupe [GROUP_NAME] ? Vous avez été téléporté vers une région voisine. </notification> <notification name="AvatarMovedLast"> - Votre dernière destination n'est pas disponible actuellement. + La destination demandée n'est pas disponible actuellement. Vous avez été téléporté vers une région voisine. </notification> <notification name="AvatarMovedHome"> @@ -1136,8 +1221,7 @@ Vous pouvez utiliser [SECOND_LIFE] normalement, les autres résidents vous voien L'installation de [APP_NAME] est terminée. Si vous utilisez [SECOND_LIFE] pour la première fois, vous devez ouvrir un compte avant de pouvoir vous connecter. -Retourner sur [http://join.secondlife.com secondlife.com] pour ouvrir un nouveau compte ? - <usetemplate name="okcancelbuttons" notext="Continuer" yestext="Nouveau compte..."/> + <usetemplate name="okcancelbuttons" notext="Continuer" yestext="Créer un compte..."/> </notification> <notification name="LoginPacketNeverReceived"> Nous avons des difficultés à vous connecter. Il y a peut-être un problème avec votre connexion Internet ou la [SECOND_LIFE_GRID]. @@ -1279,7 +1363,7 @@ Dépasse la limite fixée à [MAX_AGENTS] [LIST_TYPE] de [NUM_EXCESS]. Veuillez choisir un objet à vendre et réessayer. </notification> <notification name="FinishedRawDownload"> - Chargement du fichier de terrain raw effectué vers : + Téléchargement du fichier de terrain raw effectué vers : [DOWNLOAD_PATH]. </notification> <notification name="DownloadWindowsMandatory"> @@ -1428,8 +1512,8 @@ 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]. -Quitter le groupe ? + Vous êtes actuellement membre du groupe <nolink>[GROUP]</nolink>. +Quitter le groupe ? <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> </notification> <notification name="ConfirmKick"> @@ -1658,83 +1742,128 @@ Cette action modifiera des milliers de régions et sera difficile à digérer po <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> </notification> <notification name="RegionEntryAccessBlocked"> - Votre catégorie d'accès ne vous autorise pas à pénétrer dans cette région. Cela vient peut-être du fait qu'il manquait des informations pour valider votre âge. - -Vérifiez que vous avez la toute dernière version du client et consultez les pages d'aide pour savoir comment accéder aux zones ayant ce niveau d'accès. + La région que vous essayez de visiter comporte du contenu dont le niveau dépasse celui de vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi > Préférences > Général. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - Votre catégorie d'accès ne vous permet pas de pénétrer dans cette région. - -Souhaitez-vous en savoir plus sur les différentes catégories d'accès ? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/fr + http://community.secondlife.com/t5/Base-de-connaissances/Cat%C3%A9gories-niveaux-de-contenu/ta-p/700311 </url> - <usetemplate ignoretext="Je ne peux pas pénétrer dans cette région car je n'ai pas accès à cette catégorie de contenu" name="okcancelignore" notext="Fermer" yestext="Consulter les pages d'aide"/> + <usetemplate ignoretext="Passage à une autre région : la région que vous essayez de visiter comporte du contenu uniquement accessible aux adultes." name="okcancelignore" notext="Fermer" yestext="Accéder à la Base de connaissances"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - Votre catégorie d'accès ne vous permet pas de pénétrer dans cette région. + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes. </notification> <notification name="RegionEntryAccessBlocked_Change"> - La catégorie de contenu définie dans vos préférences ne vous permet pas de pénétrer dans cette région. - -Pour cela, vous devez modifier votre paramètre de catégorie de contenu. Vous pourrez alors rechercher du contenu [REGIONMATURITY] et y accéder. Pour annuler vos modifications, accédez à Moi > Préférences > Général. + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences ou d'annuler l'action. Une fois vos préférences modifiées, vous pouvez réessayer d'accéder à la région. + <form name="form"> + <button name="OK" text="Modifier les préférences"/> + <button default="true" name="Cancel" text="Annuler"/> + <ignore name="ignore" text="Passage à une autre région : la région que vous essayez de visiter comporte du contenu dont le niveau est exclu de vos préférences actuelles."/> + </form> + </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + Nous rencontrons des difficultés techniques au niveau de votre téléportation car vos préférences ne sont pas synchronisées avec le serveur. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + La région que vous essayez de visiter comporte du contenu dont le niveau dépasse celui de vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi > Préférences > Général. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes. + <url name="url"> + http://community.secondlife.com/t5/Base-de-connaissances/Cat%C3%A9gories-niveaux-de-contenu/ta-p/700311 + </url> + <usetemplate ignoretext="Téléportation : la région que vous essayez de visiter comporte du contenu uniquement accessible aux adultes." name="okcancelignore" notext="Fermer" yestext="Accéder à la Base de connaissances"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences afin de poursuivre la téléportation ou d'annuler la téléportation. + <form name="form"> + <button name="OK" text="Modifier et continuer"/> + <button name="Cancel" text="Annuler"/> + <ignore name="ignore" text="Téléportation (redémarrage possible) : la région que vous essayez de visiter comporte du contenu dont le niveau est exclu de vos préférences."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences ou d'annuler la téléportation. Une fois vos préférences modifiées, vous devrez réessayer de vous téléporter. <form name="form"> <button name="OK" text="Modifier les préférences"/> - <button default="true" name="Cancel" text="Fermer"/> - <ignore name="ignore" text="La catégorie de contenu que j'ai choisie m'empêche de pénétrer dans une région"/> + <button name="Cancel" text="Annuler"/> + <ignore name="ignore" text="Téléportation (redémarrage impossible) : la région que vous essayez de visiter comporte du contenu dont le niveau est exclu de vos préférences."/> </form> </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + Nous rencontrons des difficultés techniques au niveau de votre téléportation car vos préférences ne sont pas synchronisées avec le serveur. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - Votre préférence de catégorie de contenu est désormais [RATING]. + Aucune autre notification vous informant que vous allez visiter une région au contenu [RATING] ne vous sera envoyée. Vous pouvez modifier vos préférences de contenu à l'avenir en accédant à Moi > Préférences > Général, à partir de la barre de menus. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + Impossible de modifier vos préférences afin d'afficher le contenu [PREFERRED_MATURITY] à l'heure actuelle. Le paramètre [ACTUAL_MATURITY] a été rétabli. Vous pouvez réessayer de modifier vos préférences en accédant à Moi > Préférences > Général, à partir de la barre de menus. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - Votre catégorie d'accès ne vous permet pas de réclamer cette région. Cela vient peut-être du fait qu'il manquait des informations pour valider votre âge. - -Vérifiez que vous avez la toute dernière version du client et consultez les pages d'aide pour savoir comment accéder aux zones ayant ce niveau d'accès. + Le niveau de contenu du terrain que vous essayez de revendiquer dépasse celui défini dans vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi > Préférences > Général. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - Votre catégorie d'accès ne vous permet pas de réclamer cette région. - -Souhaitez-vous en savoir plus sur les différentes catégories d'accès ? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + Seuls les adultes sont autorisés à revendiquer ce terrain. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/fr + http://community.secondlife.com/t5/Base-de-connaissances/Cat%C3%A9gories-niveaux-de-contenu/ta-p/700311 </url> - <usetemplate ignoretext="Je ne peux pas réclamer cette région car je n'ai pas accès à cette catégorie de contenu" name="okcancelignore" notext="Fermer" yestext="Consulter les pages d'aide"/> + <usetemplate ignoretext="Seuls les adultes sont autorisés à revendiquer ce terrain." name="okcancelignore" notext="Fermer" yestext="Accéder à la Base de connaissances"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - Votre catégorie d'accès ne vous autorise pas à réclamer cette région. + Le terrain que vous essayez de revendiquer comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + Le terrain que vous essayez de revendiquer comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes. </notification> <notification name="LandClaimAccessBlocked_Change"> - Votre catégorie d'accès ne vous permet pas de réclamer cette région. - -En cliquant sur Modifier les préférences, vous pourrez changer votre catégorie d'accès et pénétrer dans la région. À partir de maintenant, vous pouvez rechercher et accéder au contenu [REGIONMATURITY]. Vous pouvez modifier ce paramètre à partir du menu Moi > Préférences > Général. - <usetemplate ignoretext="La catégorie de contenu que j'ai choisie m'empêche de réclamer un terrain" name="okcancelignore" notext="Fermer" yestext="Modifier les Préférences"/> + Le terrain que vous essayez de revendiquer comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences, puis d'essayer de revendiquer ce terrain à nouveau. + <form name="form"> + <button name="OK" text="Modifier les préférences"/> + <button name="Cancel" text="Annuler"/> + <ignore name="ignore" text="Le terrain que vous essayez de revendiquer comporte du contenu dont le niveau est exclu de vos préférences."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - Votre catégorie d'accès ne vous permet pas d'acheter cette région. Cela vient peut-être du fait qu'il manquait des informations pour valider votre âge. - -Vérifiez que vous avez la toute dernière version du client et consultez les pages d'aide pour savoir comment accéder aux zones ayant ce niveau d'accès. + Le niveau de contenu du terrain que vous essayez d'acheter dépasse celui défini dans vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi > Préférences > Général. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - Votre catégorie d'accès ne vous permet pas d'acheter cette région. - -Souhaitez-vous en savoir plus sur les différentes catégories d'accès ? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Seuls les adultes sont autorisés à acheter ce terrain. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/fr + http://community.secondlife.com/t5/Base-de-connaissances/Cat%C3%A9gories-niveaux-de-contenu/ta-p/700311 </url> - <usetemplate ignoretext="Je ne peux pas acheter ce terrain car je n'ai pas accès à cette catégorie de contenu" name="okcancelignore" notext="Fermer" yestext="Consulter les pages d'aide"/> + <usetemplate ignoretext="Seuls les adultes sont autorisés à acheter ce terrain." name="okcancelignore" notext="Fermer" yestext="Accéder à la Base de connaissances"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - Votre catégorie d'accès ne vous permet pas d'acheter cette région. + Le terrain que vous essayez d'acheter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + Le terrain que vous essayez d'acheter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes. </notification> <notification name="LandBuyAccessBlocked_Change"> - Votre catégorie d'accès ne vous autorise pas à acheter cette région. - -En cliquant sur Modifier les préférences, vous pourrez changer votre catégorie d'accès et pénétrer dans la région. À partir de maintenant, vous pouvez rechercher et accéder au contenu [REGIONMATURITY]. Vous pouvez modifier ce paramètre à partir du menu Moi > Préférences > Général. - <usetemplate ignoretext="La catégorie de contenu que j'ai choisie m'empêche d'acheter un terrain" name="okcancelignore" notext="Fermer" yestext="Modifier les Préférences"/> + Le terrain que vous essayez d'acheter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences, puis d'essayer d'acheter ce terrain à nouveau. + <form name="form"> + <button name="OK" text="Modifier les préférences"/> + <button name="Cancel" text="Annuler"/> + <ignore name="ignore" text="Le terrain que vous essayez d'acheter comporte du contenu dont le niveau est exclu de vos préférences."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Vous avez sélectionné trop de prims. Veuillez sélectionner au maximum [MAX_PRIM_COUNT] prims et réessayer. @@ -1789,10 +1918,9 @@ Publier cette petite annonce maintenant pour [AMOUNT] L$ ? </form> </notification> <notification label="Catégorie de la région modifiée" name="RegionMaturityChange"> - Le niveau de maturité de cette région a été mis à jour. -Ce changement n'apparaîtra pas immédiatement sur la carte. - -Pour entrer dans les régions Adultes, le résident doit avoir vérifié son compte, que ce soit par vérification de l'âge ou du mode de paiement. + Le niveau de contenu de cette région a changé. +Il se peut que l'affichage de cette modification sur la carte prenne quelque temps. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="Versions de voix non compatibles" name="VoiceVersionMismatch"> Cette version de [APP_NAME] n'est pas compatible avec la fonctionnalité de chat vocal dans cette région. Vous devez mettre à jour [APP_NAME] pour que le chat vocal fonctionne correctement. @@ -1910,9 +2038,15 @@ Déplacer les objets de l'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'outils par défaut ? + Cette action rétablira vos boutons et barres d'outils par défaut. + +Vous ne pouvez pas l'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'outils seront vides. -Vous ne pouvez pas annuler cette action. +Vous ne pouvez pas l'annuler. <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> </notification> <notification name="DeleteItems"> @@ -2076,14 +2210,11 @@ Liez-la à partir d'une page web pour permettre aux autres résidents d&apo <usetemplate ignoretext="Porter automatiquement tout en modifiant mon apparence" name="okcancelignore" notext="Non" yestext="Oui"/> </notification> <notification name="NotAgeVerified"> - Vous devez avoir au moins 18 ans pour accéder au contenu et aux zones Adulte dans Second Life. Visitez la page de vérification de l'âge afin de confirmer que vous avez plus de 18 ans. -Cette opération lancera votre navigateur Web. - -[_URL] - <url name="url" option="0"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="Je n'ai pas procédé à la vérification de mon âge" name="okcancelignore" notext="Annuler" yestext="Accéder à la page de vérification de l'âge"/> + L'accès à l'endroit que vous essayez de visiter est limité aux résidents de plus de 18 ans. + <usetemplate ignoretext="Je n'ai pas l'âge requis pour visiter les zones d'accès limité en fonction de l'âge." name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + L'accès à cet endroit est limité aux plus de 18 ans. </notification> <notification name="Cannot enter parcel: no payment info on file"> Pour pouvoir pénétrer dans cette zone, vous devez avoir enregistré vos informations de paiement. Souhaitez-vous aller sur [SECOND_LIFE] et enregistrer vos informations de paiement ? @@ -2119,10 +2250,10 @@ Cette opération lancera votre navigateur Web. Sujet : [SUBJECT], Message : [MESSAGE] </notification> <notification name="FriendOnline"> - [NAME] est en ligne + <nolink>[NAME]</nolink> est en ligne </notification> <notification name="FriendOffline"> - [NAME] est hors ligne + <nolink>[NAME]</nolink> est hors ligne </notification> <notification name="AddSelfFriend"> Même si vous êtes extrêmement sympathique, vous ne pouvez pas devenir ami avec vous-même. @@ -2236,14 +2367,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'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'onglet Repères dans la fenêtre qui s'ouvre. Cliquez sur n'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'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 +2397,9 @@ Veuillez sélectionner un terrain plus petit. <notification name="PaymentSent"> [MESSAGE] </notification> + <notification name="PaymentFailure"> + [MESSAGE] + </notification> <notification name="EventNotification"> Avis d'événement : @@ -2340,6 +2476,23 @@ Vous ne pouvez pas voler ici. <notification name="NoBuild"> La construction est interdite dans cette zone. Vous ne pouvez pas construite ou rezzer d'objets ici. </notification> + <notification name="PathfindingDirty"> + Des modifications de recherche de chemin sont en attente concernant cette région. Si vous disposez de droits de construction, vous pouvez la figer de nouveau en cliquant sur le bouton Refiger la région. + </notification> + <notification name="DynamicPathfindingDisabled"> + La recherche de chemin dynamique n'est pas activée dans cette région. Il se peut que les objets scriptés utilisant des appels LSL de recherche de chemin ne fonctionnent pas comme prévu pour cette région. + </notification> + <notification name="PathfindingRebakeNavmesh"> + La modification de certains objets de cette région risque d'entraîner un comportement incorrect des autres objets mobiles. Pour que les objets mobiles se comportent correctement, cliquez sur Refiger la région. Pour plus d'informations, choisissez Aide. + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Aide" ignoretext="La modification de certains objets de cette région risque d'entraîner un comportement incorrect des autres objets mobiles." name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Une erreur est survenue. Un problème réseau ou serveur s'est peut-être produit ou vous ne disposez pas de droits de construction. Se déconnecter puis se reconnecter permet parfois de résoudre le problème. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> Cette parcelle masque les avatars et le chat écrit des autres parcelles. Vous ne pouvez pas voir les résidents qui se trouvent en dehors, et ceux qui se trouvent en dehors ne peuvent pas vous voir. Le chat écrit habituel sur le canal 0 est également bloqué. </notification> @@ -2358,9 +2511,7 @@ Aucun script ne marche ici à part ceux du propriétaire du terrain. Vous ne pouvez réclamer qu'un terrain public dans la région où vous vous trouvez actuellement. </notification> <notification name="RegionTPAccessBlocked"> - Votre catégorie d'accès ne vous autorise pas à pénétrer dans cette région. Vous devez sans doute procéder à la vérification de votre âge ou installer une version plus récente du client. - -Pour savoir comment accéder aux zones ayant un tel niveau d'accès, veuillez consulter les pages d'aide. + La région que vous essayez de visiter comporte du contenu dont le niveau dépasse celui de vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi > Préférences > Général. </notification> <notification name="URBannedFromRegion"> Vous avez été banni de cette région. @@ -2371,11 +2522,11 @@ Pour savoir comment accéder aux zones ayant un tel niveau d'accès, veuill <notification name="ImproperPaymentStatus"> Vous n'avez pas le statut de paiement approprié pour pénétrer dans cette région. </notification> - <notification name="MustGetAgeRgion"> - Pour pouvoir pénétrer dans cette région, vous devez avoir procédé à la vérification de votre âge. + <notification name="MustGetAgeRegion"> + Pour accéder à cette région, vous devez avoir au moins 18 ans. </notification> <notification name="MustGetAgeParcel"> - Pour pouvoir pénétrer sur cette parcelle, vous devez avoir procédé à la vérification de votre âge. + Pour accéder à cette parcelle, vous devez avoir au moins 18 ans. </notification> <notification name="NoDestRegion"> Région de destination introuvable. @@ -2477,12 +2628,33 @@ Veuillez réessayer dans quelques minutes. <notification name="TeleportOffered"> [NAME_SLURL] propose de vous téléporter à son emplacement : -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +« [MESSAGE] » +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="Téléporter"/> <button name="Cancel" text="Annuler"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] propose de vous téléporter à son emplacement : + +« [MESSAGE] » +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Cette région comporte du contenu [REGION_CONTENT_MATURITY] alors que vos préférences actuelles excluent tout contenu [REGION_CONTENT_MATURITY]. Il est possible de modifier vos préférences afin de poursuivre la téléportation ou d'annuler la téléportation. + <form name="form"> + <button name="Teleport" text="Modifier et continuer"/> + <button name="Cancel" text="Annuler"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] propose de vous téléporter à son emplacement : + +« [MESSAGE] » +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Toutefois, cette région comporte du contenu uniquement accessible aux adultes. + </notification> <notification name="TeleportOfferSent"> Offre de téléportation envoyée à [TO_NAME] </notification> @@ -2518,10 +2690,10 @@ Veuillez réessayer dans quelques minutes. </form> </notification> <notification name="FriendshipAccepted"> - [NAME] a accepté votre amitié. + <nolink>[NAME]</nolink> a accepté votre amitié. </notification> <notification name="FriendshipDeclined"> - [NAME] a refusé votre amitié. + <nolink>[NAME]</nolink> a refusé votre amitié. </notification> <notification name="FriendshipAcceptedByMe"> Amitié acceptée. @@ -2577,32 +2749,28 @@ Acceptez-vous ? </form> </notification> <notification name="ScriptQuestionCaution"> - Un objet nommé <nolink>[OBJECTNAME]</nolink>, appartenant à [NAME], aimerait : - -[QUESTIONS] -Si vous n'avez pas confiance en cet objet ni en son créateur, refusez cette requête. - -Accepter cette requête ? + Avertissement : l'objet <nolink>[OBJECTNAME]</nolink> souhaite un accès total à votre compte en Linden dollars. Si vous autorisez cet accès, il pourra supprimer des fonds de votre compte à tout moment ou le vider entièrement de façon continue sans avis préalable. + +Il est rare qu'une telle demande soit légitime. N'autorisez pas cet accès si vous ne comprenez pas entièrement pourquoi l'objet souhaite accéder à votre compte. <form name="form"> - <button name="Grant" text="Accepter"/> + <button name="Grant" text="Permettre un accès total"/> <button name="Deny" text="Refuser"/> - <button name="Details" text="Détails..."/> </form> </notification> <notification name="ScriptDialog"> <nolink>[TITLE]</nolink> de [NAME] [MESSAGE] <form name="form"> - <button name="Mute" text="Ignorer"/> - <button name="Ignore" text="Ignorer"/> + <button name="Client_Side_Mute" text="Bloquer"/> + <button name="Client_Side_Ignore" text="Ignorer"/> </form> </notification> <notification name="ScriptDialogGroup"> <nolink>[TITLE]</nolink> de [GROUPNAME] [MESSAGE] <form name="form"> - <button name="Mute" text="Ignorer"/> - <button name="Ignore" text="Ignorer"/> + <button name="Client_Side_Mute" text="Bloquer"/> + <button name="Client_Side_Ignore" text="Ignorer"/> </form> </notification> <notification name="BuyLindenDollarSuccess"> @@ -2798,6 +2966,18 @@ Voir le fichier journal pour plus de détails. avec les résidents suivants : [RESIDENTS] ? + <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> + </notification> + <notification name="ShareFolderConfirmation"> + Vous ne pouvez partager qu'un dossier à la fois. + +Voulez-vous vraiment partager les articles suivants : + +<nolink>[ITEMS]</nolink> + +avec les résidents suivants : + +[RESIDENTS] ? <usetemplate name="okcancelbuttons" notext="Annuler" yestext="Ok"/> </notification> <notification name="ItemsShared"> @@ -2878,6 +3058,10 @@ Texture figée de [RESOLUTION] chargée pour [BODYREGION] au bout de [TIME] seco ([EXISTENCE] secondes d'existence) Texture figée de [RESOLUTION] mise à jour localement pour [BODYREGION] au bout de [TIME] secondes. </notification> + <notification name="LivePreviewUnavailable"> + Impossible d'afficher un aperçu de cette texture car il s'agit d'une texture sans copie et/ou transfert. + <usetemplate ignoretext="M'avertir que le mode Aperçu en direct n'est pas disponible pour les textures sans copie et/ou transfert" name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> Voulez-vous vraiment quitter cet appel ? <usetemplate ignoretext="Confirmer avant de quitter l'appel" name="okcancelignore" notext="Non" yestext="Oui"/> @@ -2888,7 +3072,7 @@ Les résidents rejoignant l'appel ultérieurement seront également ignorés, même si vous quittez l'appel. Ignorer les autres ? - <usetemplate ignoretext="Confirmer avant d'ignorer les autres lors d'un appel de groupe" name="okcancelignore" notext="Annuler" yestext="Ok"/> + <usetemplate ignoretext="Confirmer avant d'ignorer les autres lors d'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. @@ -3046,8 +3230,64 @@ Cliquez sur un point dans le monde et faites glisser votre souris pour faire tou <usetemplate name="okcancelbuttons" notext="Ne pas quitter" yestext="Quitter"/> </notification> <notification label="" name="ConfirmHideUI"> - Cette action cachera tous les objets des menus et boutons. Pour les récupérer, cliquez de nouveau sur [SHORTCUT]. - <usetemplate ignoretext="Confimer avant de cacher l'interface" name="okcancelignore" notext="Annuler" yestext="OK"/> + Cette action masquera tous les boutons et articles de menu. Pour les récupérer, cliquez de nouveau sur [SHORTCUT]. + <usetemplate ignoretext="Confirmer avant de masquer l'interface" name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + L'indicateur Fantôme de certains groupes de liens sélectionnés basculera. + +Voulez-vous continuer ? + <usetemplate ignoretext="L'indicateur Fantôme de certains groupes de liens basculera." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison des restrictions d'autorisation les concernant. Ces groupes de liens seront définis sur [RESTRICTED_TYPE]. + +Voulez-vous continuer ? + <usetemplate ignoretext="Certains groupes de liens sélectionnés ne peuvent pas être définis en raison des restrictions d'autorisation les concernant." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison d'une forme non convexe. + +Voulez-vous continuer ? + <usetemplate ignoretext="Certains groupes de liens sélectionnés ne peuvent pas être définis en raison d'une forme non convexe." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + L'indicateur Fantôme de certains groupes de liens sélectionnés basculera. + +Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison des restrictions d'autorisation les concernant. Ces groupes de liens seront définis sur [RESTRICTED_TYPE]. + +Voulez-vous continuer ? + <usetemplate ignoretext="L'indicateur Fantôme de certains groupes de liens sélectionnés basculera et d'autres ne peuvent pas être définis en raison de restrictions d'autorisation sur les groupes de liens." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + L'indicateur Fantôme de certains groupes de liens sélectionnés basculera. + +Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison d'une forme non convexe. + +Voulez-vous continuer ? + <usetemplate ignoretext="L'indicateur Fantôme de certains groupes de liens sélectionnés basculera et d'autres ne peuvent pas être définis en raison d'une forme non convexe." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison des restrictions d'autorisation les concernant. Ces groupes de liens seront définis sur [RESTRICTED_TYPE]. + +Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison d'une forme non convexe. Les types d'usage de ces groupes de liens ne seront pas modifiés. + +Voulez-vous continuer ? + <usetemplate ignoretext="Certains groupes de liens sélectionnés ne peuvent pas être définis en raison des restrictions d'autorisation les concernant et d'une forme non convexe." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + L'indicateur Fantôme de certains groupes de liens sélectionnés basculera. + +Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison des restrictions d'autorisation les concernant. Ces groupes de liens seront définis sur [RESTRICTED_TYPE]. + +Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison d'une forme non convexe. Les types d'usage de ces groupes de liens ne seront pas modifiés. + +Voulez-vous continuer ? + <usetemplate ignoretext="L'indicateur Fantôme de certains groupes de liens sélectionnés basculera et d'autres ne peuvent pas être définis en raison de restrictions d'autorisation sur les groupes de liens et d'une forme non convexe." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + L'objet sélectionné affecte le maillage de navigation. Si vous le modifiez en Flexibilité, il sera supprimé de ce maillage. + <usetemplate ignoretext="L'objet sélectionné affecte le maillage de navigation. Si vous le modifiez en Flexibilité, il sera supprimé de ce maillage." name="okcancelignore" notext="Annuler" yestext="OK"/> </notification> <global name="UnsupportedGLRequirements"> Vous semblez ne pas avoir le matériel requis pour utiliser [APP_NAME]. [APP_NAME] requiert une carte graphique OpenGL avec une prise en charge du multitexturing. Si vous avez une telle carte, assurez-vous que vous avez aussi les pilotes les plus récents pour la carte, ainsi que les service packs et les patchs pour votre système d'exploitation. @@ -3073,4 +3313,23 @@ Sinon, consultez la carte et trouvez les " infohubs ". <global name="You died and have been teleported to your home location"> Vous êtes mort et avez été téléporté à votre domicile. </global> + <notification name="LocalBitmapsUpdateFileNotFound"> + Impossible de mettre à jour [FNAME] car le fichier est introuvable. +Désactivation des mises à jour futures de ce fichier... + </notification> + <notification name="LocalBitmapsUpdateFailedFinal"> + [NRETRIES] tentatives d'ouverture ou de décodage de [FNAME] ont échoué. Le fichier est désormais considéré comme endommagé. +Désactivation des mises à jour futures de ce fichier... + </notification> + <notification name="LocalBitmapsVerifyFail"> + Tentative d'ajout d'un fichier image [FNAME] non valide ou illisible n'ayant pas pu être ouvert ou décodé. Tentative annulée. + </notification> + <notification name="PathfindingReturnMultipleItems"> + Vous allez renvoyer [NUM_ITEMS] articles. Voulez-vous vraiment continuer ? + <usetemplate ignoretext="Voulez-vous vraiment renvoyer plusieurs articles ?" name="okcancelignore" notext="Non" yestext="Oui"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + Vous allez supprimer [NUM_ITEMS] articles. Voulez-vous vraiment continuer ? + <usetemplate ignoretext="Voulez-vous vraiment supprimer plusieurs articles ?" name="okcancelignore" notext="Non" yestext="Oui"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml index f54bed4fae..96add2a74b 100644 --- a/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml +++ b/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml @@ -5,6 +5,6 @@ </text> <scroll_list name="blocked" tool_tip="Liste des résidents actuellement ignorés"/> <button label="Ignorer une personne" label_selected="Ignorer le résident..." name="Block resident..." tool_tip="Choisir un résident à ignorer"/> - <button label="Ignorer l'objet par nom" label_selected="Ignorer l'objet par nom..." name="Block object by name..." tool_tip="Choisir un objet à ignorer par nom"/> + <button label="Ignorer un objet par son nom" label_selected="Ignorer un objet par son nom..." name="Block object by name..." tool_tip="Choisir un objet à ignorer par nom"/> <button label="Ne plus ignorer" label_selected="Ne plus ignorer" name="Unblock" tool_tip="Enlever le résident ou l'objet de la liste des ignorés"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_bottomtray.xml b/indra/newview/skins/default/xui/fr/panel_bottomtray.xml deleted file mode 100644 index c4537861e3..0000000000 --- a/indra/newview/skins/default/xui/fr/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Active/Désactive le micro"/> - <string name="VoiceControlBtnToolTip" value="Affiche/Masque le panneau de contrôle de la voix"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Parler" label_selected="Parler" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="Geste" name="Gesture" tool_tip="Affiche/Masque les gestes"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Bouger" name="movement_btn" tool_tip="Affiche/Masque le contrôle des déplacements"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Affichage" name="camera_btn" tool_tip="Affiche/Masque le contrôle de la caméra"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button label="" name="snapshots" tool_tip="Prendre une photo"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="Construire" name="build_btn" tool_tip="Affiche/Masque les outils pour la construction"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="Rechercher" name="search_btn" tool_tip="Affiche/Masque la recherche"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Carte" name="world_map_btn" tool_tip="Affiche/Masque la carte du monde"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Mini-carte" name="mini_map_btn" tool_tip="Affiche/Masque la mini-carte"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Conversations"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="Notifications"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> 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_group_invite.xml b/indra/newview/skins/default/xui/fr/panel_group_invite.xml index 53f7ac33c2..d792439220 100644 --- a/indra/newview/skins/default/xui/fr/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/fr/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> Certains résidents que vous avez choisis font déjà partie du groupe et l'invitation ne leur a donc pas été envoyée. </panel.string> + <panel.string name="invite_selection_too_large"> + Invitations de groupe non envoyées : trop de résidents sélectionnés. Les invitations de groupe sont limitées à 100 par demande. + </panel.string> <text name="help_text"> Vous pouvez inviter plusieurs résidents à la fois. Cliquez d'abord sur Choisir un résident. </text> diff --git a/indra/newview/skins/default/xui/fr/panel_login.xml b/indra/newview/skins/default/xui/fr/panel_login.xml index e54b36644c..c8a1fe8751 100644 --- a/indra/newview/skins/default/xui/fr/panel_login.xml +++ b/indra/newview/skins/default/xui/fr/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://fr.secondlife.com/registration/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php?lang=fr </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + CONNEXION + </text> <text name="username_text"> Nom d'utilisateur : </text> @@ -15,34 +15,32 @@ <text name="password_text"> Mot de passe : </text> - <check_box label="Enregistrer" name="remember_check"/> - <button label="Connexion" name="connect_btn"/> - <text name="mode_selection_text"> - Mode : - </text> - <combo_box name="mode_combo" tool_tip="Sélectionnez un mode. Pour une exploration facile et rapide avec chat, choisissez Basique. Pour accéder à plus de fonctionnalités, choisissez Avancé."> - <combo_box.item label="Basique" name="Basic"/> - <combo_box.item label="Avancé" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Lieu de départ : </text> <combo_box name="start_location_combo"> <combo_box.item label="Dernier emplacement" name="MyLastLocation"/> <combo_box.item label="Domicile" name="MyHome"/> - <combo_box.item label="<Saisir le nom de la région>" name="Typeregionname"/> + <combo_box.item label="<Nom de la région>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - S'inscrire + <layout_panel name="links_login_panel"> + <text name="login_help"> + Besoin d'aide ? </text> <text name="forgot_password_text"> Nom d'utilisateur ou mot de passe oublié ? </text> - <text name="login_help"> - Besoin d'aide ? + <button label="Connexion" name="connect_btn"/> + <check_box label="Enregistrer" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + CRÉER VOTRE COMPTE </text> + <button label="Commencer" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_my_profile.xml b/indra/newview/skins/default/xui/fr/panel_my_profile.xml deleted file mode 100644 index 5207c5a28e..0000000000 --- a/indra/newview/skins/default/xui/fr/panel_my_profile.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Profil" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=en - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=en - </string> - <string name="my_account_link_url" value="http://secondlife.com/account"/> - <string name="no_partner_text" value="Aucun"/> - <string name="no_group_text" value="Aucun"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="scroll_content_panel"> - <panel name="second_life_image_panel"> - <text name="display_name_descr_text"> - Nom d'utilisateur - </text> - <text name="name_descr_text"> - Nom d'affichage - </text> - <button label="Profil" name="see_profile_btn" tool_tip="Afficher le profil de cet avatar."/> - </panel> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> -</panel> 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..b02e53269b 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,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="nearby_chat"> - <check_box label="Traduction du chat" name="translate_chat_checkbox"/> + <layout_stack name="stack"> + <layout_panel name="translate_chat_checkbox_lp"> + <check_box label="Traduire le chat" name="translate_chat_checkbox"/> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml index 82cdf292ab..762dee01bb 100644 --- a/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="chat_bar"> +<panel name="nearby_chat"> <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/panel_notes.xml b/indra/newview/skins/default/xui/fr/panel_notes.xml deleted file mode 100644 index 1b44bc4b73..0000000000 --- a/indra/newview/skins/default/xui/fr/panel_notes.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Notes/Perso" name="panel_notes"> - <layout_stack name="layout"> - <layout_panel name="notes_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <text name="status_message" value="Mes notes perso :"/> - <text name="status_message2" value="Autoriser cette personne à :"/> - <check_box label="Afficher mon statut en ligne" name="status_check"/> - <check_box label="Me situer sur la carte" name="map_check"/> - <check_box label="Modifier, supprimer ou prendre mes objets" name="objects_check"/> - </panel> - </scroll_container> - </layout_panel> - <layout_panel name="notes_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Devenir amis" name="add_friend" tool_tip="Proposer à ce résident de devenir votre ami"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="Ouvrir une session IM"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Appeler" name="call" tool_tip="Appeler ce résident"/> - </layout_panel> - <layout_panel name="show_on_map_btn_lp"> - <button label="Carte" name="show_on_map_btn" tool_tip="Afficher le résident sur la carte"/> - </layout_panel> - <layout_panel name="teleport_btn_lp"> - <button label="Téléporter" name="teleport" tool_tip="Proposer une téléportation"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</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..945a5e0272 --- /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="Larg." name="postcard_snapshot_width"/> + <spinner label="Haut." 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é 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..550beb653e 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,7 @@ <check_box label="Chats IM" name="EnableIMChatPopups" tool_tip="Cocher cette case pour qu'un popup s'affiche à réception d'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..." name="ok_btn"/> + <button label="Rechercher/Remplacer..." name="autoreplace_showgui"/> + <button label="Orthographe..." name="spellcheck_showgui"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_move.xml b/indra/newview/skins/default/xui/fr/panel_preferences_move.xml index efb520bfd3..80aed90a2d 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_move.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_move.xml @@ -24,16 +24,16 @@ Clic simple sur le terrain : </text> <combo_box name="single_click_action_combo"> - <combo_box.item label="Pas d'action" name="0"/> - <combo_box.item label="Bouger vers le point cliqué" name="1"/> + <combo_box.item label="Aucune action" name="0"/> + <combo_box.item label="Déplacement vers le clic" name="1"/> </combo_box> <text name="double_click_action_lbl"> - Double-clic sur le terrain : + Double clic sur le terrain : </text> <combo_box name="double_click_action_combo"> - <combo_box.item label="Pas d'action" name="0"/> - <combo_box.item label="Bouger vers le point cliqué" name="1"/> - <combo_box.item label="Téléporter vers le point cliqué" name="2"/> + <combo_box.item label="Aucune action" name="0"/> + <combo_box.item label="Déplacement vers le double clic" name="1"/> + <combo_box.item label="Téléportation vers le double clic" name="2"/> </combo_box> <button label="Autres accessoires" name="joystick_setup_button"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml index b122db9502..cf1a374da6 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml @@ -20,7 +20,7 @@ <check_box label="Inclure la date et l'heure pour chaque ligne du journal de chat" name="show_timestamps_check_im"/> <check_box label="Inclure la date dans le nom du fichier journal" name="logfile_name_datestamp"/> <text name="log_path_desc"> - Emplacement des journaux : + Emplacement journaux : </text> <line_editor left="308" name="log_path_string" right="-20"/> <button label="Parcourir" label_selected="Parcourir" name="log_path_button" width="150"/> 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'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'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'aide, ouvrir des liens, etc. Ce navigateur s'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_prim_media_controls.xml b/indra/newview/skins/default/xui/fr/panel_prim_media_controls.xml index f16fcebd02..ad744b7760 100644 --- a/indra/newview/skins/default/xui/fr/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/fr/panel_prim_media_controls.xml @@ -13,10 +13,10 @@ </layout_stack> <layout_stack name="media_controls"> <layout_panel name="back"> - <button name="back_btn" tool_tip="Naviguer en arrière"/> + <button name="back_btn" tool_tip="Précédente"/> </layout_panel> <layout_panel name="fwd"> - <button name="fwd_btn" tool_tip="Naviguer vers l'avant"/> + <button name="fwd_btn" tool_tip="Suivante"/> </layout_panel> <layout_panel name="home"> <button name="home_btn" tool_tip="Page d'accueil"/> @@ -34,7 +34,7 @@ <button name="play_btn" tool_tip="Lire le média"/> </layout_panel> <layout_panel name="pause"> - <button name="pause_btn" tool_tip="Pauser le média"/> + <button name="pause_btn" tool_tip="Mettre le média sur pause"/> </layout_panel> <layout_panel name="media_address"> <line_editor name="media_address_url" tool_tip="URL du média"/> @@ -48,7 +48,7 @@ </layout_stack> </layout_panel> <layout_panel name="media_play_position"> - <slider_bar initial_value="0.5" name="media_play_slider" tool_tip="Progrès de la lecture du film"/> + <slider_bar initial_value="0.5" name="media_play_slider" tool_tip="Progression de la lecture du film"/> </layout_panel> <layout_panel name="skip_back"> <button name="skip_back_btn" tool_tip="Reculer"/> diff --git a/indra/newview/skins/default/xui/fr/panel_profile.xml b/indra/newview/skins/default/xui/fr/panel_profile.xml deleted file mode 100644 index 9aa6fe97a1..0000000000 --- a/indra/newview/skins/default/xui/fr/panel_profile.xml +++ /dev/null @@ -1,74 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Profil" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=fr-FR - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=fr - </string> - <string name="my_account_link_url" value="http://secondlife.com/my/account/index.php?lang=fr-FR"/> - <string name="no_partner_text" value="Aucun"/> - <string name="no_group_text" value="Aucun"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <panel name="second_life_image_panel"> - <text name="title_sl_descr_text" value="[SECOND_LIFE]:"/> - </panel> - <panel name="first_life_image_panel"> - <text name="title_rw_descr_text" value="Vie réelle :"/> - </panel> - <text name="title_member_text" value="Résident depuis :"/> - <text name="title_acc_status_text" value="Statut du compte :"/> - <text_editor name="acc_status_text"> - Résident. Aucune info de paiement enregistrée. - Linden. - </text_editor> - <text name="title_partner_text" value="Partenaire :"/> - <panel name="partner_data_panel"> - <text initial_value="(récupération en cours)" name="partner_text"/> - </panel> - <text name="title_groups_text" value="Groupes :"/> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> - <layout_stack name="layout_verb_buttons"> - <layout_panel name="profile_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Devenir amis" name="add_friend" tool_tip="Proposer à ce résident de devenir votre ami"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="Ouvrir une session IM"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Appeler" name="call" tool_tip="Appeler ce résident"/> - </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="Téléporter" name="teleport" tool_tip="Proposer une téléportation"/> - </layout_panel> - <layout_panel name="overflow_btn_lp"> - <menu_button label="â–¼" name="overflow_btn" tool_tip="Payer le résident ou partager l'inventaire avec lui"/> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="profile_me_buttons_panel"> - <button label="Modifier le profil" name="edit_profile_btn" tool_tip="Modifier vos informations personnelles"/> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_profile_view.xml b/indra/newview/skins/default/xui/fr/panel_profile_view.xml deleted file mode 100644 index 76ba44e899..0000000000 --- a/indra/newview/skins/default/xui/fr/panel_profile_view.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_target_profile"> - <string name="status_online"> - En ligne - </string> - <string name="status_offline"> - Hors ligne - </string> - <text name="display_name_label" value="Nom d'affichage :"/> - <text name="solo_username_label" value="Nom d'utilisateur :"/> - <text name="status" value="En ligne"/> - <text name="user_name_small" value="Jack oh look at me this is a super duper long name"/> - <button name="copy_to_clipboard" tool_tip="Copier dans le presse-papiers"/> - <text name="user_label" value="Nom d'utilisateur :"/> - <tab_container name="tabs"> - <panel label="PROFIL" name="panel_profile"/> - <panel label="FAVORIS" name="panel_picks"/> - <panel label="NOTES/PERSO" name="panel_notes"/> - </tab_container> -</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_region_debug.xml b/indra/newview/skins/default/xui/fr/panel_region_debug.xml index 733c3f9a22..98ae250215 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_debug.xml @@ -30,11 +30,11 @@ <check_box label="Sur le terrain d'un autre résident" name="return_other_land" tool_tip="Ne renvoyer que les objets se trouvant sur le terrain de quelqu'un d'autre"/> <check_box label="Dans toutes les régions de ce domaine" name="return_estate_wide" tool_tip="Renvoyer les objets dans toutes les régions qui constituent ce domaine"/> <button label="Renvoyer" name="return_btn"/> - <button label="Afficher les collisions les plus consommatrices..." name="top_colliders_btn" tool_tip="Liste des objets avec le plus de collisions potentielles" width="320"/> + <button label="Collisions les plus consommatrices" name="top_colliders_btn" tool_tip="Liste des objets avec le plus de collisions potentielles" width="320"/> <button label="?" left="337" name="top_colliders_help"/> - <button label="Afficher les objets scriptés les plus consommateurs..." name="top_scripts_btn" tool_tip="Liste des objets qui passent le plus de temps à exécuter des scripts" width="320"/> + <button label="Scripts les plus consommateurs" name="top_scripts_btn" tool_tip="Liste des objets passant le plus de temps à exécuter des scripts" width="320"/> <button label="?" left="337" name="top_scripts_help"/> <button label="Redémarrer la région" name="restart_btn" tool_tip="Redémarrer la région au bout de 2 minutes" width="160"/> <button label="?" left="177" name="restart_help"/> - <button label="Retarder le redémarrage" name="cancel_restart_btn" tool_tip="Retarder le redémarrage de la région d'une heure" width="160"/> + <button label="Annuler le redémarrage" name="cancel_restart_btn" tool_tip="Annuler le redémarrage de la région." width="160"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_region_environment.xml b/indra/newview/skins/default/xui/fr/panel_region_environment.xml index d18503db86..085a308786 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_environment.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_environment.xml @@ -15,7 +15,7 @@ <combo_box.item label="-Effectuer une sélection-" name="item0"/> </combo_box> <text name="sky_dayc_settings_title"> - Ciel / Cycle du jour + Ciel/Cycle du jour </text> <radio_group name="sky_dayc_settings_radio_group"> <radio_item label="Ciel fixe" name="my_sky_settings"/> diff --git a/indra/newview/skins/default/xui/fr/panel_region_estate.xml b/indra/newview/skins/default/xui/fr/panel_region_estate.xml index fb650ff646..be89020ac7 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_estate.xml @@ -18,10 +18,10 @@ domaine. (inconnu) </text> <text name="Only Allow"> - Limiter l'accès aux comptes vérifiés par : + Conditions d'accès des résidents : </text> - <check_box label="Infos de paiement enregistrées" name="limit_payment" tool_tip="Bannir les résidents non identifiés"/> - <check_box label="Vérification de l'âge" name="limit_age_verified" tool_tip="Bannir les résidents qui n'ont pas vérifié leur âge. Consultez la page [SUPPORT_SITE] pour plus d'informations."/> + <check_box label="Informations de paiement enregistrées" name="limit_payment" tool_tip="Pour pouvoir accéder à ce domaine, les résidents doivent avoir enregistré des informations de paiement. Consultez le [SUPPORT_SITE] pour plus d'informations."/> + <check_box label="Avoir plus de 18 ans" name="limit_age_verified" tool_tip="Pour accéder à ce domaine, les résidents doivent avoir au moins 18 ans. Consultez le [SUPPORT_SITE] pour plus d'informations."/> <check_box label="Autoriser les chats vocaux" name="voice_chat_check"/> <button label="?" name="voice_chat_help"/> <text name="abuse_email_text"> diff --git a/indra/newview/skins/default/xui/fr/panel_region_general.xml b/indra/newview/skins/default/xui/fr/panel_region_general.xml index b5795bebe2..234d316069 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_general.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_general.xml @@ -22,7 +22,7 @@ <check_box label="Interdire le vol" name="block_fly_check"/> <check_box label="Autoriser les dégâts" name="allow_damage_check"/> <check_box label="Interdire les bousculades" name="restrict_pushobject"/> - <check_box label="Autoriser la revente" name="allow_land_resell_check"/> + <check_box label="Autoriser la revente de terrain" name="allow_land_resell_check"/> <check_box label="Autoriser la fusion/division" name="allow_parcel_changes_check"/> <check_box label="Ne pas afficher dans la recherche" name="block_parcel_search_check" tool_tip="Afficher cette région et ses parcelles dans les résultats de recherche"/> <check_box label="Autoriser les objets de maillage" name="mesh_rez_enabled_check" tool_tip="Laisser les gens rezzer des objets de maillage dans cette région."/> diff --git a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml index d7e321d06d..97f486d3a3 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml @@ -55,8 +55,8 @@ du terrain" name="terrain_lower_spin"/> <spinner label="Bas" name="height_start_spin_2"/> <spinner label="Haut" name="height_range_spin_0"/> <spinner label="Haut" name="height_range_spin_2"/> - <button label="Télécharger le terrain au format RAW..." name="download_raw_btn" tool_tip="Réservé aux propriétaires de domaine, pas aux gérants" width="230"/> - <button label="Charger le terrain au format RAW..." name="upload_raw_btn" tool_tip="Réservé aux propriétaires de domaine, pas aux gérants" width="230"/> + <button label="Télécharger le terrain en RAW..." name="download_raw_btn" tool_tip="Réservé aux propriétaires de domaine, pas aux gérants" width="230"/> + <button label="Charger un terrain en RAW..." name="upload_raw_btn" tool_tip="Réservé aux propriétaires de domaine, pas aux gérants" width="230"/> <button label="Figer le terrain" name="bake_terrain_btn" tool_tip="Définir le terrain actuel comme point central pour les limites d'élévation/abaissement"/> <button label="Appliquer" name="apply_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_region_texture.xml b/indra/newview/skins/default/xui/fr/panel_region_texture.xml deleted file mode 100644 index c0b667137a..0000000000 --- a/indra/newview/skins/default/xui/fr/panel_region_texture.xml +++ /dev/null @@ -1,72 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Textures du sol" name="Textures"> - <text name="region_text_lbl"> - Région : - </text> - <text name="region_text"> - (inconnue) - </text> - <text name="base_texture_text"> - Textures de base (fichiers 128x128, 24 bit .tga) - </text> - <text name="height_text_lbl"> - 1 (faible) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (élevé) - </text> - <text name="detail_texture_text"> - Textures du terrain (fichiers.tga 512 x 512, 24 bit requis) - </text> - <text name="height_text_lbl5"> - Limites d'élévation de texture - </text> - <text name="height_text_lbl6"> - Nord-ouest - </text> - <text name="height_text_lbl7"> - Nord-est - </text> - <text name="height_text_lbl8"> - Sud-ouest - </text> - <text name="height_text_lbl9"> - Sud-est - </text> - <text name="height_text_lbl10" width="460"> - Ces valeurs représentent les limites de mélange pour les textures ci-dessus. - </text> - <text name="height_text_lbl11"> - En mètres, la valeur Bas correspond à la hauteur max. de la texture n°1 - </text> - <text name="height_text_lbl12"> - et la valeur Haut correspond à la hauteur min. de la texture n°4. - </text> - <text name="height_text_lbl13"> - Nord-est - </text> - <spinner label="Bas" name="height_start_spin_0"/> - <spinner label="Bas" name="height_start_spin_1"/> - <spinner label="Bas" name="height_start_spin_2"/> - <spinner label="Bas" name="height_start_spin_3"/> - <spinner label="Haut" name="height_range_spin_0"/> - <spinner label="Haut" name="height_range_spin_1"/> - <spinner label="Haut" name="height_range_spin_2"/> - <spinner label="Haut" name="height_range_spin_3"/> - <text name="height_text_lbl14"> - Ces valeurs représentent les limites de mélange pour les textures ci-dessus. - </text> - <text name="height_text_lbl15"> - La valeur Bas correspond à la hauteur max. de la Texture 1, - </text> - <text name="height_text_lbl16"> - et la valeur Haut correspond à la hauteur min. de la Texture 4. - </text> - <button label="Appliquer" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_script_ed.xml b/indra/newview/skins/default/xui/fr/panel_script_ed.xml index 2b08ae56c5..29fbe3c7e7 100644 --- a/indra/newview/skins/default/xui/fr/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/fr/panel_script_ed.xml @@ -22,6 +22,8 @@ <menu label="Fichier" name="File"> <menu_item_call label="Enregistrer" name="Save"/> <menu_item_call label="Annuler tous les changements" name="Revert All Changes"/> + <menu_item_call label="Charger depuis un fichier..." name="LoadFromFile"/> + <menu_item_call label="Enregistrer sous..." name="SaveToFile"/> </menu> <menu label="Modifier" name="Edit"> <menu_item_call label="Annuler" name="Undo"/> diff --git a/indra/newview/skins/default/xui/fr/panel_script_question_toast.xml b/indra/newview/skins/default/xui/fr/panel_script_question_toast.xml new file mode 100644 index 0000000000..a2d0237da0 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_script_question_toast.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel label="script_question_panel" name="panel_script_question_toast"> + <panel label="buttons_panel" name="buttons_panel"/> +</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_side_tray.xml b/indra/newview/skins/default/xui/fr/panel_side_tray.xml deleted file mode 100644 index 178ae4324b..0000000000 --- a/indra/newview/skins/default/xui/fr/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Activer/désactiver le panneau latéral." name="sidebar_openclose" tab_title="Activer/désactiver le panneau latéral"/> - <sidetray_tab description="Domicile." name="sidebar_home" tab_title="Accueil"> - <panel label="domicile" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Modifiez votre profil public et vos Favoris." name="sidebar_me" tab_title="Mon profil"> - <panel_container name="panel_container"> - <panel label="Moi" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Trouvez vos amis, vos contacts et les personnes se trouvant près de vous." name="sidebar_people" tab_title="Personnes"> - <panel_container name="panel_container"> - <panel label="Profil du groupe" name="panel_group_info_sidetray"/> - <panel label="Résidents et objets ignorés" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Trouvez de nouveaux lieux à découvrir et les lieux que vous connaissez déjà ." label="Lieux" name="sidebar_places" tab_title="Endroits"> - <panel label="Lieux" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="Parcourez votre inventaire." name="sidebar_inventory" tab_title="Mon inventaire"> - <panel label="Modifier l'inventaire" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Modifiez votre apparence actuelle." name="sidebar_appearance" tab_title="Mon apparence"> - <panel label="Changer d'apparence" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> 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..472c4a5e8f --- /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 l'inventaire + </text> + <text name="hint_lbl"> + L'enregistrement d'une image dans l'inventaire coûte [UPLOAD_COST] L$. Pour enregistrer votre image sous forme de texture, sélectionnez un format carré. + </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..97dc3e7e2b --- /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 l'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é 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'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..befe1b3bc6 --- /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="Enreg. dans l'inventaire ([AMOUNT] L$)" name="save_to_inventory_btn"/> + <button label="Enreg. sur l'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..82a4815144 --- /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"> + 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'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 e836c24a94..ba36a7d299 100644 --- a/indra/newview/skins/default/xui/fr/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/fr/panel_status_bar.xml @@ -15,14 +15,14 @@ <panel.string name="buycurrencylabel"> [AMT] L$ </panel.string> - <panel name="balance_bg"> + <panel left="-405" name="balance_bg" width="195"> <text name="balance" tool_tip="Cliquer sur ce bouton pour actualiser votre solde en L$." value="20 L$"/> - <button label="Achat de 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="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." width="75"/> </panel> <text name="TimeText" tool_tip="Heure actuelle (Pacifique)"> 00h00 PST </text> - <button name="media_toggle_btn" tool_tip="Arrêter tous les médias (musique, vidéo, pages web)"/> - <button name="volume_btn" tool_tip="Contrôle du volume global"/> + <button name="media_toggle_btn" tool_tip="Arrêter tous les médias (musique, vidéo, pages web)."/> + <button name="volume_btn" tool_tip="Régler le volume global."/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/fr/panel_volume_pulldown.xml new file mode 100644 index 0000000000..e05c93a4ac --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater"> + <slider label="Principal" name="System Volume"/> + <slider label="Boutons" name="UI Volume"/> + <slider label="Ambiant" name="Wind Volume"/> + <slider label="Sons" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="Activer les sons des gestes."/> + <slider label="Musique" name="Music Volume"/> + <check_box name="enable_music" tool_tip="Activer les flux de musique."/> + <slider label="Médias" name="Media Volume"/> + <check_box name="enable_media" tool_tip="Activer les flux de média."/> + <slider label="Voix" name="Voice Volume"/> + <check_box name="enable_voice_check" tool_tip="Activer le chat vocal."/> +</panel> diff --git a/indra/newview/skins/default/xui/fr/sidepanel_inventory.xml b/indra/newview/skins/default/xui/fr/sidepanel_inventory.xml index 969bd1ac44..1b9c832679 100644 --- a/indra/newview/skins/default/xui/fr/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/fr/sidepanel_inventory.xml @@ -2,47 +2,24 @@ <panel label="Choses" name="objects panel"> <panel label="" name="sidepanel__inventory_panel"> <layout_stack name="inventory_layout_stack"> - <layout_panel name="inbox_outbox_layout_panel"> - <layout_stack name="inbox_outbox_layout_stack"> - <layout_panel name="inbox_layout_panel"> - <panel label="" name="marketplace_inbox"> - <string name="InboxLabelWithArg"> - Articles reçus ([NUM]) - </string> - <string name="InboxLabelNoArg"> - Articles reçus - </string> - <button label="Articles reçus" name="inbox_btn"/> - <text name="inbox_fresh_new_count"> - [NUM] nouv. - </text> - <panel tool_tip="Drag and drop items to your inventory to manage and use them"> - <text name="inbox_inventory_placeholder"> - Ici seront livrés les achats effectués sur la Place du marché. - </text> - </panel> - </panel> - </layout_panel> - <layout_panel name="outbox_layout_panel"> - <panel label="" name="marketplace_outbox"> - <string name="OutboxLabelWithArg"> - Boîte d'envoi vendeur ([NUM]) - </string> - <string name="OutboxLabelNoArg"> - Boîte d'envoi vendeur - </string> - <button label="Boîte d'envoi vendeur" name="outbox_btn"/> - <button label="" name="outbox_sync_btn" tool_tip="Vers ma vitrine de la Place du marché"/> - <panel> - <panel name="outbox_inventory_placeholder_panel"> - <text name="outbox_inventory_placeholder_title"> - Chargement... - </text> - </panel> - </panel> - </panel> - </layout_panel> - </layout_stack> + <layout_panel name="inbox_layout_panel"> + <panel label="" name="marketplace_inbox"> + <string name="InboxLabelWithArg"> + Articles reçus ([NUM]) + </string> + <string name="InboxLabelNoArg"> + Articles reçus + </string> + <button label="Articles reçus" name="inbox_btn"/> + <text name="inbox_fresh_new_count"> + [NUM] nouv. + </text> + <panel name="inbox_inventory_placeholder_panel" tool_tip="Glisser-déposer des articles dans votre inventaire pour les utiliser."> + <text name="inbox_inventory_placeholder"> + Ici seront livrés les achats effectués sur la Place du marché. + </text> + </panel> + </panel> </layout_panel> </layout_stack> <panel name="button_panel"> diff --git a/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml b/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml index 95649d3934..e7fc7859c9 100644 --- a/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (inconnu) </panel.string> + <panel.string name="unknown_multiple"> + (valeur inconnue ou valeurs multiples) + </panel.string> <panel.string name="public"> (public) </panel.string> diff --git a/indra/newview/skins/default/xui/fr/sidepanel_task_info.xml b/indra/newview/skins/default/xui/fr/sidepanel_task_info.xml index bd8a39fe16..60027d41cb 100644 --- a/indra/newview/skins/default/xui/fr/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/fr/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> Vous ne pouvez pas modifier ces objets </panel.string> + <panel.string name="text modify info 5"> + Impossible de modifier cet objet au-delà de la frontière d'une région + </panel.string> + <panel.string name="text modify info 6"> + Impossible de modifier ces objets au-delà de la frontière d'une région + </panel.string> <panel.string name="text modify warning"> Cet objet comprend des parties liées </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Prix : L$" name="Edit Cost"/> <check_box label="Afficher avec la recherche" name="search_check" tool_tip="Permettre aux autres résidents de voir cet objet dans les résultats de recherche"/> + <text name="pathfinding_attributes_label"> + Attributs de recherche de chemin : + </text> <text name="B:"> B : </text> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index f9f3366f63..6a2a3f559a 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -137,7 +137,7 @@ Quitter </string> <string name="create_account_url"> - http://join.secondlife.com/index.php?lang=fr-FR + http://join.secondlife.com/index.php?lang=fr-FR&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> Le client que vous utilisez ne permet plus d'accéder à Second Life. Téléchargez un nouveau client à la page suivante : @@ -181,8 +181,8 @@ Consultez la page www.secondlife.com/status pour plus d'informations. </string> <string name="LoginFailedPremiumOnly"> Les connexions à Second Life sont temporairement limitées afin de s'assurer que l'expérience des utilisateurs présents dans le monde virtuel soit optimale. - -Les personnes disposant de comptes gratuits ne pourront pas accéder à Second Life pendant ce temps afin de permettre à celles qui ont payé pour pouvoir utiliser Second Life puissent le faire. + +Les personnes disposant de comptes gratuits ne pourront pas accéder à Second Life pendant ce temps afin de permettre à celles qui ont payé pour pouvoir utiliser Second Life de le faire. </string> <string name="LoginFailedComputerProhibited"> Impossible d'accéder à Second Life depuis cet ordinateur. @@ -339,17 +339,35 @@ Veuillez réessayer de vous connecter dans une minute. Impossible de faire glisser plus d'un objet ici </string> <string name="TooltipPrice" value="[AMOUNT] L$ :"/> + <string name="TooltipOutboxDragToWorld"> + Impossible de rezzer des articles dans la boîte d'envoi vendeur + </string> <string name="TooltipOutboxNoTransfer"> - Impossible de vendre ou de transférer un ou plusieurs de ces objets à un autre utilisateur. + Impossible de vendre ou de transférer un ou plusieurs de ces objets. + </string> + <string name="TooltipOutboxNotInInventory"> + La boîte d'envoi vendeur n'accepte que les articles directement issus de votre inventaire. </string> <string name="TooltipOutboxWorn"> - Vous portez un ou plusieurs de ces objets. Retirez-les de votre avatar, puis réessayez de les déplacer. + Impossible de placer des articles que vous portez dans votre boîte d'envoi vendeur + </string> + <string name="TooltipOutboxCallingCard"> + Impossible de placer des cartes de visite dans votre boîte d'envoi vendeur </string> <string name="TooltipOutboxFolderLevels"> - Trop de niveaux de sous-dossiers dans ce dossier. Réorganisez-le de sorte qu'un maximum de 4 niveaux soit utilisé (dossier racine contenant A contenant B contenant C). + Il existe plus de 3 niveaux de dossiers imbriqués. + </string> + <string name="TooltipOutboxTooManyFolders"> + Le dossier de niveau supérieur contient plus de 20 sous-dossiers. </string> <string name="TooltipOutboxTooManyObjects"> - Ce dossier contient plus de 200 objets. Regroupez une partie des articles dans un paquet afin de réduire le nombre d'objets. + Le dossier de niveau supérieur contient plus de 200 articles. + </string> + <string name="TooltipDragOntoOwnChild"> + Impossible de déplacer un dossier vers son enfant + </string> + <string name="TooltipDragOntoSelf"> + Impossible de déplacer un dossier vers lui-même </string> <string name="TooltipHttpUrl"> Cliquez pour afficher cette page web @@ -817,6 +835,9 @@ Veuillez réessayer de vous connecter dans une minute. <string name="anim_yes_head"> Oui </string> + <string name="multiple_textures"> + Multiples + </string> <string name="texture_loading"> Chargement... </string> @@ -865,6 +886,9 @@ Veuillez réessayer de vous connecter dans une minute. <string name="ScriptQuestionCautionChatDenied"> '[OBJECTNAME]', un objet appartenant à [OWNERNAME], situé dans [REGIONNAME] à [REGIONPOS], n'a pas reçu le droit de : [PERMISSIONS]. </string> + <string name="AdditionalPermissionsRequestHeader"> + Si vous autorisez un accès à votre compte, vous autorisez également l'objet à  : + </string> <string name="ScriptTakeMoney"> Débiter vos Linden dollars (L$) </string> @@ -898,6 +922,9 @@ Veuillez réessayer de vous connecter dans une minute. <string name="ControlYourCamera"> Contrôler votre caméra </string> + <string name="TeleportYourAgent"> + Vous téléporter + </string> <string name="NotConnected"> Pas connecté(e) </string> @@ -976,6 +1003,12 @@ Veuillez réessayer de vous connecter dans une minute. <string name="choose_the_directory"> Choisir le répertoire </string> + <string name="script_files"> + Scripts + </string> + <string name="dictionary_files"> + Dictionnaires + </string> <string name="AvatarSetNotAway"> Présent </string> @@ -1214,43 +1247,36 @@ Veuillez réessayer de vous connecter dans une minute. Vous n'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é. + Les achats que vous avez effectués sur la Place du marché s'affichent ici. Vous pouvez alors les faire glisser vers votre inventaire afin de les utiliser. </string> <string name="MarketplaceURL"> - http://marketplace.[DOMAIN_NAME] + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ </string> <string name="MarketplaceURL_CreateStore"> - http://marketplace.[DOMAIN_NAME]/create_store + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4 </string> - <string name="MarketplaceURL_LearnMore"> - http://marketplace.[DOMAIN_NAME]/learn_more + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard </string> - <string name="InventoryOutboxCreationErrorTitle"> - Configuration incorrecte de votre boîte d'envoi vendeur + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports </string> - <string name="InventoryOutboxCreationErrorTooltip"> - Erreur de configuration de la boîte d'envoi vendeur - </string> - <string name="InventoryOutboxCreationError"> - Veuillez contacter le service clientèle pour résoudre le problème. + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more </string> <string name="InventoryOutboxNotMerchantTitle"> - Tout le monde peut vendre des articles sur la Place du marché - </string> - <string name="InventoryOutboxNotMerchantTooltip"> - Devenez vendeur ! + Tout le monde peut vendre des articles sur la Place du marché. </string> + <string name="InventoryOutboxNotMerchantTooltip"/> <string name="InventoryOutboxNotMerchant"> - [[MARKETPLACE_URL] La Place du marché Second Life] comprend plus d'un million de produits virtuels à vendre, tous créés par des résidents. Vous aussi pouvez vendre les articles que vous créez, ainsi que certains articles que vous avez achetés. Le processus est simple et la configuration gratuite. [[LEARN_MORE_URL] En savoir plus] ou [[CREATE_STORE_URL] créer une boutique] sur la Place du marché pour démarrer + Pour devenir vendeur, vous devez [[MARKETPLACE_CREATE_STORE_URL] créer une boutique sur la Place du marché]. </string> <string name="InventoryOutboxNoItemsTitle"> - Un nouveau moyen d'envoyer des articles sur la Place du marché - </string> - <string name="InventoryOutboxNoItemsTooltip"> - Glisser-déposer des articles ici afin de les préparer à la vente sur la Place du marché. + Votre boîte d'envoi est vide. </string> + <string name="InventoryOutboxNoItemsTooltip"/> <string name="InventoryOutboxNoItems"> - Faites glisser les articles ou dossiers d'articles à vendre dans cette zone. Une copie de l'article s'affiche, sans que votre inventaire ne soit modifié, sauf si vous avez fait glisser un article pour lequel la copie est interdite. Une fois prêt à envoyer les articles vers la Place du marché, cliquez sur le bouton Charger. Les articles disparaissent de ce dossier lorsqu'ils ont été déplacés vers l'inventaire de la Place du marché. + Pour mettre des dossiers en vente sur la [[MARKETPLACE_DASHBOARD_URL] Place du marché], faites-les glisser vers cette zone et cliquez sur "Envoyer vers la Place du marché". </string> <string name="Marketplace Error None"> Aucune erreur @@ -1388,6 +1414,12 @@ Veuillez réessayer de vous connecter dans une minute. <string name="InvFolder favorite"> Mes Favoris </string> + <string name="InvFolder Favorites"> + Mes favoris + </string> + <string name="InvFolder favorites"> + Mes favoris + </string> <string name="InvFolder Current Outfit"> Tenue actuelle </string> @@ -1403,6 +1435,12 @@ Veuillez réessayer de vous connecter dans une minute. <string name="InvFolder Meshes"> Maillages </string> + <string name="InvFolder Received Items"> + Articles reçus + </string> + <string name="InvFolder Merchant Outbox"> + Boîte d'envoi vendeur + </string> <string name="InvFolder Friends"> Amis </string> @@ -1412,6 +1450,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 +1579,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'avatar + </string> <string name="Invalid Attachment"> Point d'attache non valide </string> @@ -3832,6 +3879,12 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. <string name="LocationCtrlSeeAVsTooltip"> Avatars visibles et chat autorisé en dehors de cette parcelle </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Les objets mobiles risquent de ne pas se comporter correctement dans cette région tant qu'elle n'est pas refigée. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + La recherche de chemin dynamique n'est pas activée dans cette région. + </string> <string name="UpdaterWindowTitle"> [APP_NAME] - Mise à jour </string> @@ -3898,6 +3951,9 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. <string name="Saved_message"> (Enregistrement : [LONG_TIMESTAMP]) </string> + <string name="IM_unblock_only_groups_friends"> + Pour afficher ce message, vous devez désactiver la case Seuls mes amis et groupes peuvent m'appeler ou m'envoyer un IM, sous Préférences/Confidentialité. + </string> <string name="answered_call"> Votre appel a fait l'objet d'une réponse </string> @@ -4030,6 +4086,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'article suivant : [ITEM] </string> @@ -4082,9 +4150,9 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. En ligne </string> <string name="uploading_abuse_report"> - Chargement en cours... + Chargement... -de l'infraction signalée +du rapport d'infraction </string> <string name="New Shape"> Nouvelle silhouette @@ -4351,7 +4419,7 @@ de l'infraction signalée <string name="server_is_down"> Malgré nos efforts, une erreur inattendue s'est produite. - Veuillez vous reporter à status.secondlifegrid.net afin de déterminer si un problème connu existe avec ce service. + Veuillez vous reporter à status.secondlifegrid.net afin de déterminer si un problème connu existe avec ce service. Si le problème persiste, vérifiez la configuration de votre réseau et de votre pare-feu. </string> <string name="dateTimeWeekdaysNames"> @@ -4440,6 +4508,12 @@ Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles <string name="ExternalEditorFailedToRun"> Échec d'exécution de l'éditeur externe. </string> + <string name="TranslationFailed"> + Échec de traduction : [REASON] + </string> + <string name="TranslationResponseParseError"> + Erreur lors de l'analyse de la réponse relative à la traduction. + </string> <string name="Esc"> Échap </string> @@ -4462,7 +4536,7 @@ Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles Backsp </string> <string name="Shift"> - Shift + Maj </string> <string name="Ctrl"> Ctrl @@ -4810,7 +4884,10 @@ Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles Mini-carte </string> <string name="Command_Move_Label"> - Bouger + Marcher / Courir / Voler + </string> + <string name="Command_Outbox_Label"> + Boîte d'envoi vendeur </string> <string name="Command_People_Label"> Personnes @@ -4837,10 +4914,10 @@ Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles Parler </string> <string name="Command_View_Label"> - Affichage + 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 @@ -4884,6 +4961,9 @@ Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles <string name="Command_Move_Tooltip"> Faire bouger votre avatar </string> + <string name="Command_Outbox_Tooltip"> + Transférer des articles vers votre place de marché afin de les vendre. + </string> <string name="Command_People_Tooltip"> Amis, groupes et personnes près de vous </string> @@ -4912,7 +4992,16 @@ Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles Changer l'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'outils du bas + </string> + <string name="Toolbar_Left_Tooltip"> + actuellement dans la barre d'outils de gauche + </string> + <string name="Toolbar_Right_Tooltip"> + actuellement dans la barre d'outils de droite </string> <string name="Retain%"> Garder% @@ -4938,4 +5027,40 @@ Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles <string name="Normal"> Normal </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Aucun + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Maillage de navigation affecté + </string> + <string name="Pathfinding_Object_Attr_Character"> + Personnage + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Multiple) + </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> + <string name="TeleportMaturityExceeded"> + Le résident ne peut pas visiter cette région. + </string> + <string name="UserDictionary"> + [User] + </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..6065fa2966 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'avez pas accès à cette destination. @@ -45,6 +45,9 @@ Pour répéter le didacticiel, veuillez aller sur Welcome Island Public. <message name="no_inventory_host"> L'inventaire est temporairement indisponible. </message> + <message name="MustGetAgeRegion"> + Pour accéder à cette région, vous devez avoir au moins 18 ans. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -80,5 +83,8 @@ Pour répéter le didacticiel, veuillez aller sur Welcome Island Public. <message name="requesting"> Demande de téléportation en cours... </message> + <message name="pending"> + En attente de téléportation... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml index 68d073a766..c672511fc5 100644 --- a/indra/newview/skins/default/xui/it/floater_about.xml +++ b/indra/newview/skins/default/xui/it/floater_about.xml @@ -66,33 +66,34 @@ Versione Server voice: [VOICE_VERSION] </panel> <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. + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion + APR Copyright (C) 2011 The Apache Software Foundation + Collada DOM Copyright 2006 Sony Computer Entertainment Inc. + cURL Copyright (C) 1996-2010, 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, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. + 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) 2002, Xiphophorus + OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. + PCRE Copyright (c) 1997-2012 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-2012 Jean-loup Gailly and Mark Adler. -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..fe3e59b0bd 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 > 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'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 'sicuro', 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: + Gli avatar su altri lotti possono vedere gli avatar su questo lotto e chattare con loro </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> @@ -466,12 +465,12 @@ Media: <text name="Limit access to this parcel to:"> Accesso a questo terreno </text> - <check_box label="Consenti l'accesso pubblico [MATURITY]" name="public_access"/> + <check_box label="Consenti l'accesso pubblico (se si rimuove la selezione vengono create linee di espulsione)" name="public_access"/> <text name="Only Allow"> - Consenti l'accesso soltanto ai residenti verificati tramite: + Consenti l'accesso solo ai Residenti che: </text> - <check_box label="Informazioni di pagamento in archivio [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Espelli i residenti non identificati."/> - <check_box label="Verifica dell'età [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Espelli i residenti che non hanno la loro età verificata. Vedi [SUPPORT_SITE] per maggiori informazioni."/> + <check_box label="Hanno informazioni di pagamento in archivio [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Per poter visitare questo lotto i Residenti devono aver fornito informazioni di pagamento a Linden Lab. Vedi [SUPPORT_SITE] per maggiori informazioni."/> + <check_box label="Hanno almeno 18 anni [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Per poter visitare questo lotto i Residenti devono avere almeno 18 anni. Vedi [SUPPORT_SITE] per maggiori informazioni."/> <check_box label="Permetti accesso al gruppo: [GROUP]" name="GroupCheck" tool_tip="Imposta il gruppo nel pannello generale."/> <check_box label="Vendi pass a:" name="PassCheck" tool_tip="Permetti in questo terreno l'accesso temporaneo"/> <combo_box name="pass_combo"> diff --git a/indra/newview/skins/default/xui/it/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/it/floater_animation_anim_preview.xml new file mode 100644 index 0000000000..a2bce00141 --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_animation_anim_preview.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Anim Preview" title="ANIMATION.ANIM"> + <text name="name_label"> + Nome: + </text> + <text name="description_label"> + Descrizione: + </text> + <button label="Carica ([AMOUNT] L$)" name="ok_btn"/> + <button label="Annulla" label_selected="Annulla" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_animation_preview.xml b/indra/newview/skins/default/xui/it/floater_animation_bvh_preview.xml index dc99d287b9..a4319f2e77 100644 --- a/indra/newview/skins/default/xui/it/floater_animation_preview.xml +++ b/indra/newview/skins/default/xui/it/floater_animation_bvh_preview.xml @@ -1,15 +1,15 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview" title=""> +<floater name="Animation Preview"> <floater.string name="failed_to_initialize"> - Impossibile inizializzare la sequenza + Movimento non inizializzato </floater.string> <floater.string name="anim_too_long"> - Il file dell'animazione è lungo [LENGTH] secondi. + La lunghezza del file di animazione è di [LENGTH] secondi. -La lunghezza massima è [MAX_LENGTH] secondi. +La lunghezza massima dell'animazione è [MAX_LENGTH] secondi. </floater.string> <floater.string name="failed_file_read"> - Impossibile leggere il file dell'animazione. + Impossibile leggere il file di animazione. [STATUS] </floater.string> @@ -116,16 +116,16 @@ La lunghezza massima è [MAX_LENGTH] secondi. Descrizione: </text> <spinner label="Priorità " name="priority" tool_tip="Definisce quali altre animazioni possono essere sostituite da questa animazione"/> - <check_box label="Ciclica" name="loop_check" tool_tip="Riproduce questa animazione in ripetizione"/> - <spinner label="In(%)" name="loop_in_point" tool_tip="Imposta il punto sul quale ritorna l'animazione"/> - <spinner label="Out(%)" name="loop_out_point" tool_tip="Imposta il punto sul quale termina l'animazione"/> + <check_box label="Ripetizione" name="loop_check" tool_tip="Riproduce questa animazione in ripetizione"/> + <spinner label="Dentro(%)" name="loop_in_point" tool_tip="Imposta il punto sul quale ritorna l'animazione"/> + <spinner label="Fuori(%)" name="loop_out_point" tool_tip="Imposta il punto sul quale termina l'animazione"/> <text name="hand_label"> - Postura della mano + Posa delle mani </text> <combo_box name="hand_pose_combo" tool_tip="Definisce ciò che fanno le mani durante l'animazione"> - <combo_box.item label="Stendi" name="Spread"/> - <combo_box.item label="Rilassato" name="Relaxed"/> - <combo_box.item label="Indica entrambi" name="PointBoth"/> + <combo_box.item label="Estese" name="Spread"/> + <combo_box.item label="Rilassate" name="Relaxed"/> + <combo_box.item label="Indicano entrambe" name="PointBoth"/> <combo_box.item label="Pugno" name="Fist"/> <combo_box.item label="Sinistra rilassata" name="RelaxedLeft"/> <combo_box.item label="Indica sinistra" name="PointLeft"/> @@ -141,7 +141,7 @@ La lunghezza massima è [MAX_LENGTH] secondi. Espressione </text> <combo_box name="emote_combo" tool_tip="Definisce ciò che fa il viso durante l'animazione"> - <item label="(Nessuno)" name="[None]" value=""/> + <item label="(Nulla)" name="[None]" value=""/> <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> <item label="Spavento" name="Afraid" value="Spavento"/> <item label="Arrabbiato" name="Angry" value="Arrabbiato"/> @@ -153,7 +153,7 @@ La lunghezza massima è [MAX_LENGTH] secondi. <item label="Accigliato" name="Frown" value="Accigliato"/> <item label="Bacio" name="Kiss" value="Bacio"/> <item label="Risata" name="Laugh" value="Risata"/> - <item label="Plllppt" name="Plllppt" value="Linguaccia"/> + <item label="Linguaccia" name="Plllppt" value="Linguaccia"/> <item label="Repulsione" name="Repulsed" value="Repulsione"/> <item label="Triste" name="Sad" value="Triste"/> <item label="Scrollata di spalle" name="Shrug" value="Scrollata di spalle"/> @@ -163,25 +163,24 @@ La lunghezza massima è [MAX_LENGTH] secondi. <item label="Preoccupato" name="Worry" value="Preoccupato"/> </combo_box> <text name="preview_label"> - Vedi anteprima mentre + Anteprima mentre </text> - <combo_box name="preview_base_anim" tool_tip="Da usarsi per controllare il comportamento dell'animazione mentre l'avatar svolge azioni abituali."> + <combo_box name="preview_base_anim" tool_tip="Prova il comportamento dell'animazione mentre l'avatar esegue attività comuni."> <item label="In piedi" name="Standing" value="In piedi"/> - <item label="Camminando" name="Walking" value="Cammina"/> + <item label="Camminare" name="Walking" value="Camminare"/> <item label="Seduto" name="Sitting" value="Seduto"/> - <item label="Volo" name="Flying" value="Volo"/> + <item label="Volare" name="Flying" value="Volare"/> </combo_box> - <spinner label="Avvio lento (sec)" name="ease_in_time" tool_tip="Durata (in secondi) della fusione in entrata delle animazioni"/> - <spinner label="Arresto lento (sec)" name="ease_out_time" tool_tip="Durata (in secondi) della fusione in uscita delle animazioni"/> + <spinner label="Transizione in ingresso (sec)" name="ease_in_time" tool_tip="Durata (in secondi) della fusione in entrata delle animazioni"/> + <spinner label="Transizione in uscita (sec)" name="ease_out_time" tool_tip="Durata (in secondi) della fusione in uscita delle animazioni"/> <button name="play_btn" tool_tip="Riproduci la tua animazione"/> <button name="pause_btn" tool_tip="Metti in pausa la tua animazione"/> - <button label="" name="stop_btn" tool_tip="Ferma la riproduzione dell'animazione"/> + <button name="stop_btn" tool_tip="Interrompi la riproduzione dell'animazione"/> <text name="bad_animation_text"> - Impossibile leggere il file dell'animazione. + Impossibile leggere il file di animazione. -Raccomandiamo file di tipo BVH esportati da -Poser 4. +Consigliamo file BVH esportati da Poser 4. </text> - <button label="Importa ([AMOUNT]L$)" name="ok_btn"/> + <button label="Carica ([AMOUNT] L$)" name="ok_btn"/> <button label="Annulla" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/it/floater_autoreplace.xml b/indra/newview/skins/default/xui/it/floater_autoreplace.xml new file mode 100644 index 0000000000..559a42cfae --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="Impostazioni sostituzione automatica"> + <check_box label="Attiva sostituzione automatica" name="autoreplace_enable" tool_tip="Quando inserisci testo nella chat, sostituisci le parole chiave inserite con l'elemento sostitutivo corrispondente."/> + <button label="Importa lista..." name="autoreplace_import_list" tool_tip="Carica da file una lista esportata in precedenza."/> + <button label="Esporta lista..." name="autoreplace_export_list" tool_tip="Salva la lista selezionata in un file per condividerla."/> + <button label="Nuova lista..." name="autoreplace_new_list" tool_tip="Crea una nuova lista"/> + <button label="Cancella lista" name="autoreplace_delete_list" tool_tip="Cancella la lista selezionata"/> + <button name="autoreplace_list_up" tool_tip="Aumenta la priorità di questa lista."/> + <button name="autoreplace_list_down" tool_tip="Diminuisci la priorità di questa lista."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Parola chiave" name="keyword"/> + <scroll_list.columns label="Sostituzione" name="replacement"/> + </scroll_list> + <button label="Aggiungi..." name="autoreplace_add_entry"/> + <button label="Rimuovi" name="autoreplace_delete_entry"/> + <button label="Salva elemento" name="autoreplace_save_entry" tool_tip="Salva questo elemento."/> + <button label="Salva modifiche" name="autoreplace_save_changes" tool_tip="Salva tutte le modifiche."/> + <button label="Annulla" name="autoreplace_cancel" tool_tip="Annulla tutte le modifiche."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </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'importo per vedere l'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 be4b8e210d..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'Inquadratura </floater.string> @@ -9,15 +9,6 @@ <floater.string name="move_tooltip"> Muovi la telecamera su e giù e a sinistra e destra </floater.string> - <floater.string name="camera_modes_title"> - Modalità della fotocamera - </floater.string> - <floater.string name="pan_mode_title"> - Ruota visuale - Ingrandisci - Panoramica - </floater.string> - <floater.string name="presets_mode_title"> - Visuali predefinite - </floater.string> <floater.string name="free_mode_title"> Vedi oggetto </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..b47e32ce90 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> +<floater name="nearby_chat" title="CHAT NEI DINTORNI"> + <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..edbbc354cf 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"> @@ -25,6 +25,10 @@ Attiva VBO: </text> <check_box initial_value="true" label="Attiva oggetti OpenGL Vertex Buffer" name="vbo" tool_tip="Attivandolo su un hardware moderno aumenta la performance. Ma, su un vecchio hardware, spesso l'implementazione dei VBO è scarsa e potresti avere dei crash quando è attivato."/> + <text name="tc label"> + Attiva S3TC: + </text> + <check_box initial_value="true" label="Attiva compressione texture (richiede riavvio)" name="texture compression" tool_tip="Comprime le texture nella memoria video, consentendo il caricamento di texture a risoluzione maggiore al prezzo di ua perdita di qualit' del colore."/> <slider label="Memoria texture (MB):" name="GraphicsCardTextureMemory" tool_tip="Spazio di memoria da ssegnare alle textures. Utilizza la memoria della scheda video come impostazione predefinita. La riduzione di questa impostazione potrebbe migliorare il rendimento ma potrebbe anche rendere le texture poco definite."/> <spinner label="Indice della distanza della nebbia:" name="fog"/> <button label="OK" label_selected="OK" name="OK"/> diff --git a/indra/newview/skins/default/xui/it/floater_inventory.xml b/indra/newview/skins/default/xui/it/floater_inventory.xml deleted file mode 100644 index 2aa6795988..0000000000 --- a/indra/newview/skins/default/xui/it/floater_inventory.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="IL MIO INVENTARIO"> - <floater.string name="Title"> - IL MIO INVENTARIO - </floater.string> - <floater.string name="TitleFetching"> - IL MIO INVENTARIO (recupero di [ITEM_COUNT] articoli...) [FILTER] - </floater.string> - <floater.string name="TitleCompleted"> - IL MIO INVENTARIO ([ITEM_COUNT] articoli) [FILTER] - </floater.string> - <floater.string name="Fetched"> - Completato - </floater.string> - <panel label="Pannello dell'Inventario" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/it/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/it/floater_merchant_outbox.xml new file mode 100644 index 0000000000..02f257d466 --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_merchant_outbox.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_merchant_outbox" title="CASELLA IN USCITA DEL RIVENDITORE"> + <string name="OutboxFolderCount1"> + 1 cartella + </string> + <string name="OutboxFolderCountN"> + [NUM] cartelle + </string> + <string name="OutboxImporting"> + Invio cartelle... + </string> + <string name="OutboxInitializing"> + Inizializzazione... + </string> + <panel label=""> + <panel> + <panel name="outbox_inventory_placeholder_panel"> + <text name="outbox_inventory_placeholder_title"> + Caricamento... + </text> + </panel> + </panel> + <panel> + <button label="Invia a Marketplace" name="outbox_import_btn" tool_tip="Push su negozio Marketplace"/> + </panel> + </panel> +</floater> 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..e8df4d2d4b 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> @@ -89,19 +92,54 @@ <text initial_value="Triangoli" name="triangles" value="Triangoli"/> <text initial_value="Vertici" name="vertices" value="Vertici"/> <text initial_value="Alto" name="high_label" value="Alto"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Carica da file"/> + <item name="Generate" value="Genera"/> + </combo_box> <button label="Sfoglia..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="Limite triangoli"/> + <item name="Error Threshold" value="Limite errori"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Medio" name="medium_label" value="Medio"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Carica da file"/> + <item name="Generate" value="Genera"/> + <item name="Use LoD above" value="Usa livello di dettaglio indicato in precedenza"/> + </combo_box> <button label="Sfoglia..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="Limite triangoli"/> + <item name="Error Threshold" value="Limite errori"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Basso" name="low_label" value="Basso"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Carica da file"/> + <item name="Generate" value="Genera"/> + <item name="Use LoD above" value="Usa livello di dettaglio indicato in precedenza"/> + </combo_box> <button label="Sfoglia..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="Limite triangoli"/> + <item name="Error Threshold" value="Limite errori"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="Bassissimo" name="lowest_label" value="Bassissimo"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Carica da file"/> + <item name="Generate" value="Genera"/> + <item name="Use LoD above" value="Usa livello di dettaglio indicato in precedenza"/> + </combo_box> <button label="Sfoglia..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="Limite triangoli"/> + <item name="Error Threshold" value="Limite errori"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Genera normali" name="gen_normals"/> diff --git a/indra/newview/skins/default/xui/it/floater_model_wizard.xml b/indra/newview/skins/default/xui/it/floater_model_wizard.xml deleted file mode 100644 index e6d0a7c4bc..0000000000 --- a/indra/newview/skins/default/xui/it/floater_model_wizard.xml +++ /dev/null @@ -1,205 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Model Wizard" title="PROCEDURA GUIDATA CARICA MODELLO"> - <button label="5. Carica sul server" name="upload_btn"/> - <button label="4. Rivedi" name="review_btn"/> - <button label="3. Fisica" name="physics_btn"/> - <button label="2. Ottimizza" name="optimize_btn"/> - <button label="1. Seleziona file" name="choose_file_btn"/> - <panel name="choose_file_panel"> - <panel name="header_panel"> - <text name="header_text"> - Seleziona file modello - </text> - </panel> - <panel name="content"> - <text name="advanced_users_text"> - Utenti avanzati: Gli utenti che hanno dimestichezza con gli strumenti di creazione 3D possono usare le opzioni di caricamento avanzate. - </text> - <button label="Passa a modalità avanzata" name="switch_to_advanced"/> - <text name="Cache location"> - Scegli il file del modello da caricare - </text> - <button label="Sfoglia..." label_selected="Sfoglia..." name="browse"/> - <text name="dimensions"> - X Y Z - </text> - <text name="warning_label"> - ATTENZIONE: - </text> - <text name="warning_text"> - Non sarà possibile completare il passaggio finale per il caricamento finale di questo modello sui server di Second Life. [secondlife:///app/floater/learn_more Scopri come] impostare l'account per il caricamento di modelli con reticolo. - </text> - </panel> - </panel> - <panel name="optimize_panel"> - <panel name="header_panel"> - <text name="header_text"> - Ottimizza modello - </text> - </panel> - <text name="description"> - Abbiamo ottimizzato il modello per migliorare le prestazioni. Se necessario, può essere regolato ulteriormente. - </text> - <panel name="content"> - <text name="high_detail_text"> - Genera livello di dettaglio: Alto - </text> - <text name="medium_detail_text"> - Genera livello di dettaglio: Medio - </text> - <text name="low_detail_text"> - Genera livello di dettaglio: Basso - </text> - <text name="lowest_detail_text"> - Genera livello di dettaglio: Bassissimo - </text> - </panel> - <panel name="content2"> - <button label="Ricalcola geometria" name="recalculate_geometry_btn"/> - <text name="lod_label"> - Anteprima geometria - </text> - <combo_box name="preview_lod_combo" tool_tip="Livello di dettaglio per anteprima rendering"> - <combo_item name="high"> - Molti dettagli - </combo_item> - <combo_item name="medium"> - Dettagli medi - </combo_item> - <combo_item name="low"> - Meno dettagli - </combo_item> - <combo_item name="lowest"> - Dettaglio minimo - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="physics_panel"> - <panel name="header_panel"> - <text name="header_text"> - Modifica fisica - </text> - </panel> - <text name="description"> - Verrà creata una forma per lo scafo esterno del modello. Regola il livello di dettaglio della forma in base al fine desiderato del modello. - </text> - <panel name="content"> - <button label="Ricalcola fisica" name="recalculate_physics_btn"/> - <button label="Ricalcolo in corso..." name="recalculating_physics_btn"/> - <text name="lod_label"> - Anteprima fisica - </text> - <combo_box name="preview_lod_combo2" tool_tip="Livello di dettaglio per anteprima rendering"> - <combo_item name="high"> - Molti dettagli - </combo_item> - <combo_item name="medium"> - Dettagli medi - </combo_item> - <combo_item name="low"> - Meno dettagli - </combo_item> - <combo_item name="lowest"> - Dettaglio minimo - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="review_panel"> - <panel name="header_panel"> - <text name="header_text"> - Rivedi - </text> - </panel> - <panel name="content"> - <text name="review_prim_equiv"> - Impatto sul lotto o sulla regione: [EQUIV] prim equivalenti - </text> - <text name="review_fee"> - All'account verrà accreditata una tariffa di caricamento pari a L$ [FEE]. - </text> - <text name="review_confirmation"> - Facendo clic sul pulsante Carica, confermi di possedere i diritti relativi ai materiali contenuti nel modello. - </text> - </panel> - </panel> - <panel name="upload_panel"> - <panel name="header_panel"> - <text name="header_text"> - Caricamento completato - </text> - </panel> - <text name="model_uploaded_text"> - Il modello è stato caricato. - </text> - <text name="inventory_text"> - Puoi trovarlo nella cartella Oggetti nel tuo inventario. - </text> - <text name="charged_fee"> - La somma di L$ [FEE] è stata addebitata sul tuo account. - </text> - </panel> - <button label="<< Indietro" name="back"/> - <button label="Avanti >>" name="next"/> - <button label="Calcolare pesi e tariffa >>" name="calculate"/> - <button label="Calcolo in corso..." name="calculating"/> - <button label="Carica" name="upload" tool_tip="Carica al simulatore"/> - <button label="Annulla" name="cancel"/> - <button label="Chiudi" name="close"/> - <spinner name="import_scale" value="1.0"/> - <string name="status_idle"> - Pausa - </string> - <string name="status_parse_error"> - Problema nell'elaborazione DAE - vedi il registro per informazioni al riguardo. - </string> - <string name="status_reading_file"> - Caricamento in corso... - </string> - <string name="status_generating_meshes"> - Generazione reticoli... - </string> - <string name="status_vertex_number_overflow"> - Errore: numero di vertici maggiore di 65534, annullato. - </string> - <string name="bad_element"> - Errore: elemento non valido - </string> - <string name="high"> - Alto - </string> - <string name="medium"> - Medio - </string> - <string name="low"> - Basso - </string> - <string name="lowest"> - Bassissimo - </string> - <string name="mesh_status_good"> - Invia! - </string> - <string name="mesh_status_na"> - N/D - </string> - <string name="mesh_status_none"> - Nessuno - </string> - <string name="mesh_status_submesh_mismatch"> - Ai vari livelli del dettaglio corrispondono numeri diversi di faccette con texture. - </string> - <string name="mesh_status_mesh_mismatch"> - Ai vari livelli del dettaglio corrispondono numeri diversi istanze di reticoli. - </string> - <string name="mesh_status_too_many_vertices"> - Troppi vertici per il livello di dettaglio. - </string> - <string name="mesh_status_missing_lod"> - Livello di dettaglio minimo mancante. - </string> - <string name="layer_all"> - Tutto - </string> -</floater> 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_nearby_chat.xml b/indra/newview/skins/default/xui/it/floater_nearby_chat.xml deleted file mode 100644 index 9e81899880..0000000000 --- a/indra/newview/skins/default/xui/it/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="CHAT NEI DINTORNI"> - <check_box label="Traduci chat" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/it/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/it/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..5122954edb --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="Personaggi con pathfinding"> + <floater.string name="messaging_get_inprogress"> + Ricerca personaggi con pathfinding in corso... + </floater.string> + <floater.string name="messaging_get_error"> + Errore rilevato durante la ricerca di personaggi con pathfinding. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Nessun personaggio con pathfinding. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] personaggi selezionati su [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + In questa regione non è attivata la funzione pathfinding + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Caricamento in corso] + </floater.string> + <floater.string name="character_owner_unknown"> + [Sconosciuto] + </floater.string> + <floater.string name="character_owner_group"> + [gruppo] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nome" name="name"/> + <scroll_list.columns label="Descrizione" name="description"/> + <scroll_list.columns label="Proprietario" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="Altitudine" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + Personaggi: + </text> + <button label="Aggiorna lista" name="refresh_objects_list"/> + <button label="Seleziona tutto" name="select_all_objects"/> + <button label="Non selezionare nessuno" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + Azioni per i personaggi selezionati: + </text> + <check_box label="Mostra marcatore" name="show_beacon"/> + <check_box label="Mostra capsula fisica" name="show_physics_capsule"/> + <button label="Prendi" name="take_objects"/> + <button label="Prendi copia" name="take_copy_objects"/> + <button label="Teletrasportami alla posizione" name="teleport_me_to_object" tool_tip="Attivato solo se viene selezionato un personaggio."/> + <button label="Restituisci" name="return_objects"/> + <button label="Elimina" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/it/floater_pathfinding_console.xml new file mode 100644 index 0000000000..77be220a2a --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="Visualizzazione / test pathfinding"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + Implementazione libreria percorsi non trovata. + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + In questa regione non è attivata la funzione pathfinding + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + Attendere il caricamento della regione. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Controllo stato navmesh + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Scaricamento navmesh in corso + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + Il navmesh è stato cambiato sul server. Scaricamento del navmesh più recente in corso + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + Il navmesh più recente è stato scaricato. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + Navmesh non scaricato correttamente. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + Il navmesh ha modifiche in sospeso. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + Costruzione navmesh in corso. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + Alcune regioni navmesh hanno modifiche in sospeso. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + La costruzione di alcune regioni navmesh è in corso. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + Alcune regioni navmesh hanno modifiche in sospeso e in altre la costruzione è in corso. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + Navmesh è aggiornato. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + Implementazione libreria percorsi non trovata. + </floater.string> + <floater.string name="pathing_region_not_enabled"> + In questa regione non è attivata la funzione pathfinding + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Seleziona punti iniziale e finale. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Seleziona punto iniziale. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Seleziona punto finale. + </floater.string> + <floater.string name="pathing_path_valid"> + Il percorso viene visualizzato con il colore arancione. + </floater.string> + <floater.string name="pathing_path_invalid"> + Nessun percorso trovato tra i punti selezionati. + </floater.string> + <floater.string name="pathing_error"> + Si è verificato un errore durante la generazione del percorso. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Visuale" name="view_panel"> + <text name="show_label"> + Mostra: + </text> + <check_box label="Mondo" name="show_world"/> + <check_box label="Solo elementi spostabili" name="show_world_movables_only"/> + <check_box label="Navmesh" name="show_navmesh"/> + <text name="show_walkability_label"> + Mostra mappa camminabilità : + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="Non mostrare" name="show_heatmap_mode_none"/> + <combo_box.item label="Personaggio tipo A" name="show_heatmap_mode_a"/> + <combo_box.item label="Personaggio tipo B" name="show_heatmap_mode_b"/> + <combo_box.item label="Personaggio tipo C" name="show_heatmap_mode_c"/> + <combo_box.item label="Personaggio tipo D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Camminabili" name="show_walkables"/> + <check_box label="Volumi materiali" name="show_material_volumes"/> + <check_box label="Ostacoli statici" name="show_static_obstacles"/> + <check_box label="Volumi esclusioni" name="show_exclusion_volumes"/> + <check_box label="Piano acqua" name="show_water_plane"/> + <check_box label="Con vista a raggi X" name="show_xray"/> + </panel> + <panel label="Percorso test" name="test_panel"> + <text name="ctrl_click_label"> + Seleziona il punto iniziale premendo Ctrl e facendo clic. + </text> + <text name="shift_click_label"> + Seleziona il punto finale premendo Maiusc e facendo clic. + </text> + <text name="character_width_label"> + Larghezza personaggio + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + Tipo personaggio + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Nessuno" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Cancella percorso" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/it/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..7edac3ff46 --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Set collegati pathfinding"> + <floater.string name="messaging_get_inprogress"> + Ricerca set collegati pathfinding in corso... + </floater.string> + <floater.string name="messaging_get_error"> + Errore rilevato durante la ricerca di set collegati pathfinding. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Modifica set collegati pathfinding selezionati in corso... + </floater.string> + <floater.string name="messaging_set_error"> + Errore rilevato durante la modifica dei set collegati pathfinding selezionati. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Nessun set collegato con pathfinding. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] set collegati selezionati su [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + In questa regione non è attivata la funzione pathfinding + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terreno] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Caricamento in corso] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Sconosciuto] + </floater.string> + <floater.string name="linkset_owner_group"> + [gruppo] + </floater.string> + <floater.string name="linkset_is_scripted"> + Sì + </floater.string> + <floater.string name="linkset_is_not_scripted"> + No + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + Sconosciuto + </floater.string> + <floater.string name="linkset_use_walkable"> + Camminabile + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Ostacolo statico + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Ostacolo mobile + </floater.string> + <floater.string name="linkset_use_material_volume"> + Volume materiale + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + Volume esclusione + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Oggetto fantasma mobile + </floater.string> + <floater.string name="linkset_is_terrain"> + [non modificabile] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [limitato] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [concavo] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [limitato,concavo] + </floater.string> + <floater.string name="linkset_choose_use"> + Seleziona uso set collegati... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="Filtra in base all'uso set collegati..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Camminabile" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Ostacolo statico" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Ostacolo mobile" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Volume materiale" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="Volume esclusione" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Oggetto fantasma mobile" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Applica" name="apply_filters"/> + <button label="Cancella" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nome (prim principale)" name="name"/> + <scroll_list.columns label="Descrizione (prim principale)" name="description"/> + <scroll_list.columns label="Proprietario" name="owner"/> + <scroll_list.columns label="Scriptato" name="scripted"/> + <scroll_list.columns label="Impatto" name="land_impact"/> + <scroll_list.columns label="Distanza" name="dist_from_you"/> + <scroll_list.columns label="Uso set collegati" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + Set collegati: + </text> + <button label="Aggiorna lista" name="refresh_objects_list"/> + <button label="Seleziona tutto" name="select_all_objects"/> + <button label="Non selezionare nessuno" name="select_none_objects"/> + </panel> + <panel> + <check_box label="Mostra marcatore" name="show_beacon"/> + <button label="Prendi" name="take_objects"/> + <button label="Prendi copia" name="take_copy_objects"/> + <button label="Teletrasportami alla posizione" name="teleport_me_to_object"/> + <button label="Restituisci" name="return_objects"/> + <button label="Elimina" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + Camminabilità : + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="Camminabilità per personaggi di tipo A. Umanoide è un esempio del tipo di personaggio."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="Camminabilità per personaggi di tipo B. Creatura è un esempio del tipo di personaggio."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="Camminabilità per personaggi di tipo C. Elemento meccanico è un esempio del tipo di personaggio."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="Camminabilità per personaggi di tipo D. Altro è un esempio del tipo di personaggio."/> + <button label="Applica modifiche" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Umanoide) + </text> + <text name="suggested_use_b_label"> + (Creatura) + </text> + <text name="suggested_use_c_label"> + (Elemento meccanico) + </text> + <text name="suggested_use_d_label"> + (Altro) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_postcard.xml b/indra/newview/skins/default/xui/it/floater_postcard.xml deleted file mode 100644 index cb2916268a..0000000000 --- a/indra/newview/skins/default/xui/it/floater_postcard.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="INVIA FOTO VIA E-MAIL"> - <text name="to_label" width="135"> - Email del destinatario: - </text> - <line_editor left="143" name="to_form" width="127"/> - <text name="from_label"> - La tua email: - </text> - <line_editor left="143" name="from_form" width="127"/> - <text name="name_label"> - Il tuo nome: - </text> - <line_editor left="143" name="name_form" width="127"/> - <text name="subject_label"> - Soggetto: - </text> - <line_editor left="143" name="subject_form" width="127"/> - <line_editor label="Scrivi il soggetto qui." name="subject_form"/> - <text name="msg_label"> - Messaggio: - </text> - <text_editor name="msg_form"> - Scrivi il messaggio qui. - </text_editor> - <text name="fine_print"> - Se il tuo destinatario si registrerà in [SECOND_LIFE], riceverai il relativo bonus. - </text> - <button label="Annulla" name="cancel_btn"/> - <button label="Invia" name="send_btn"/> - <string name="default_subject"> - Cartolina da [SECOND_LIFE]. - </string> - <string name="default_message"> - Vieni a vedere! - </string> - <string name="upload_message"> - Invio... - </string> -</floater> diff --git a/indra/newview/skins/default/xui/it/floater_preview_animation.xml b/indra/newview/skins/default/xui/it/floater_preview_animation.xml index 73082c9526..ed609c70fa 100644 --- a/indra/newview/skins/default/xui/it/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/it/floater_preview_animation.xml @@ -6,6 +6,6 @@ <text name="desc txt"> Descrizione: </text> - <button label="Riproduci in Second Life" label_selected="Ferma" left="20" name="Anim play btn" tool_tip="Riproduci questa animazione così che gli altri possano vederla" width="131"/> - <button label="Esegui localmente" label_selected="Ferma" left="162" name="Anim audition btn" tool_tip="Riproduci questa animazione così che solo tu possa vederla" width="125"/> + <button label="Riproduci in Second Life" label_selected="Ferma" name="Inworld" tool_tip="Riproduci questa animazione così che gli altri possano vederla"/> + <button label="Riproduci localmente" label_selected="Ferma" name="Locally" tool_tip="Riproduci questa animazione così che solo tu possa vederla"/> </floater> 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'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'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'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'immagine" name="image_quality_slider"/> - <text name="layer_type_label"> - Cattura: - </text> - <combo_box label="Layer dell'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'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_spellcheck.xml b/indra/newview/skins/default/xui/it/floater_spellcheck.xml new file mode 100644 index 0000000000..2a8557b0fc --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="Impostazioni controllo ortografico"> + <check_box label="Attiva controllo ortografico" name="spellcheck_enable"/> + <text name="spellcheck_main"> + Dizionario principale: + </text> + <text label="Registri:" name="spellcheck_additional"> + Dizionari aggiuntivi: + </text> + <text name="spellcheck_available"> + Disponibile + </text> + <text name="spellcheck_active"> + Attivato + </text> + <button label="Rimuovi" name="spellcheck_remove_btn"/> + <button label="Importa..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/it/floater_spellcheck_import.xml new file mode 100644 index 0000000000..c04fc249a7 --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Imposta dizionario"> + <button label="Sfoglia" label_selected="Sfoglia" name="dictionary_path_browse"/> + <button label="Importa" name="ok_btn"/> + <button label="Annulla" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_stats.xml b/indra/newview/skins/default/xui/it/floater_stats.xml index ad6ef6b54b..825b2ce57a 100644 --- a/indra/newview/skins/default/xui/it/floater_stats.xml +++ b/indra/newview/skins/default/xui/it/floater_stats.xml @@ -14,8 +14,11 @@ <stat_bar label="KTris disegnato per secondo" name="ktrissec"/> <stat_bar label="Totale oggetti" name="objs"/> <stat_bar label="Nuovi oggetti" name="newobjs"/> + <stat_bar label="Hit rate della cache per l'oggetto" name="object_cache_hits"/> </stat_view> <stat_view label="Texture" name="texture"> + <stat_bar label="Hit rate della cache" name="texture_cache_hits"/> + <stat_bar label="Latenza di lettura della cache" name="texture_cache_read_latency"/> <stat_bar label="Conteggio" name="numimagesstat"/> <stat_bar label="Conteggio grezzo" name="numrawimagesstat"/> <stat_bar label="Memoria GL" name="gltexmemstat"/> @@ -44,6 +47,12 @@ <stat_bar label="Oggetti a basso LOD" name="physicslodtasks"/> <stat_bar label="Memoria allocata" name="physicsmemoryallocated"/> </stat_view> + <stat_bar label="Script eseguiti" name="simpctscriptsrun"/> + <stat_view label="Pathfinding" name="simpathfinding"> + <stat_bar label="Tempo passaggio AI" name="simsimaistepmsec"/> + <stat_bar label="Passaggi silhouette saltati" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Personaggi aggiornati" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_view label="Tempo (ms)" name="simperf"> <stat_bar label="Tempo totale Frame" name="simframemsec"/> <stat_bar label="Tempo netto" name="simnetmsec"/> diff --git a/indra/newview/skins/default/xui/it/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/it/floater_test_layout_stacks.xml new file mode 100644 index 0000000000..b479d5f6d6 --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_test_layout_stacks.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="LAYOUTSTACK TESTS"/> diff --git a/indra/newview/skins/default/xui/it/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/it/floater_test_text_vertical_aligment.xml new file mode 100644 index 0000000000..23da6f7588 --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_test_text_vertical_aligment.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="FINESTRA DI TEST"/> diff --git a/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml index 7b77584ba0..c97a91bb3f 100644 --- a/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml @@ -1,23 +1,35 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="texture picker" title="PREFERITO: TEXTURE"> - <string name="choose_picture"> + <floater.string name="choose_picture"> Clicca per scegliere l'immagine - </string> + </floater.string> + <floater.string name="pick title"> + Scegli: + </floater.string> <text name="Multiple"> Texture multiple </text> + <radio_group name="mode_selection"> + <radio_item label="Inventario" name="inventory" value="0"/> + <radio_item label="Locale" name="local" value="1"/> + </radio_group> <text name="unknown"> Dimensioni: [DIMENSIONS] </text> <button label="Default" label_selected="Default" name="Default"/> - <button label="Niente" label_selected="Niente" name="None"/> <button label="Vuoto" label_selected="Vuoto" name="Blank"/> - <check_box label="Mostra cartelle" name="show_folders_check"/> - <search_editor label="Filtro texture" name="inventory search editor"/> - <check_box label="Applica adesso" name="apply_immediate_check"/> - <button label="Annulla" label_selected="Annulla" name="Cancel"/> + <button label="Niente" label_selected="Niente" name="None"/> + <check_box initial_value="true" label="Anteprima dal vivo" name="apply_immediate_check"/> + <text name="preview_disabled" value="Anteprima disattivata"/> + <filter_editor label="Filtro texture" name="inventory search editor"/> + <check_box initial_value="false" label="Mostra cartelle" name="show_folders_check"/> + <button label="Aggiungi" label_selected="Aggiungi" name="l_add_btn"/> + <button label="Rimuovi" label_selected="Rimuovi" name="l_rem_btn"/> + <button label="Carica" label_selected="Carica" name="l_upl_btn"/> + <scroll_list name="l_name_list"> + <column label="Nome" name="unit_name"/> + <column label="ID" name="unit_id_HIDDEN"/> + </scroll_list> <button label="OK" label_selected="OK" name="Select"/> - <string name="pick title"> - Scegli: - </string> + <button label="Annulla" label_selected="Annulla" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/it/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/it/floater_texture_fetch_debugger.xml new file mode 100644 index 0000000000..49b6453319 --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_texture_fetch_debugger.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="TexFetchDebugger" title="Debugger recupero texture"> + <text name="total_num_fetched_label"> + 1, Numero totale di texture recuperate: [NUM] + </text> + <text name="total_num_fetching_requests_label"> + 2, Numero totale di richieste di recupero: [NUM] + </text> + <text name="total_num_cache_hits_label"> + 3, Numero totale di recuperi dalla cache: [NUM] + </text> + <text name="total_num_visible_tex_label"> + 4, Numero totale di texture visibili: [NUM] + </text> + <text name="total_num_visible_tex_fetch_req_label"> + 5, Numero totale di richieste di fetching texture visibili: [NUM] + </text> + <text name="total_fetched_data_label"> + 6, Numero totale di fetching dati: [SIZE1] KB, Dati decodificati: [SIZE2] KB, [PIXEL] MPixel + </text> + <text name="total_fetched_vis_data_label"> + 7, Numero totale di dati visibili: [SIZE1] KB, Dati decodificati: [SIZE2] KB + </text> + <text name="total_fetched_rendered_data_label"> + 8, Numero totale di rendering dei dati: [SIZE1] KB, Dati decodificati: [SIZE2] KB, [PIXEL] MPixel + </text> + <text name="total_time_cache_read_label"> + 9, Tempo totale letture cache: [TIME] secondi + </text> + <text name="total_time_cache_write_label"> + 10, Tempo totale scrittura cache: [TIME] secondi + </text> + <text name="total_time_decode_label"> + 11, Tempo totale decodifica: [TIME] secondi + </text> + <text name="total_time_gl_label"> + 12, Tempo totale creazione texture gl: [TIME] secondi + </text> + <text name="total_time_http_label"> + 13, Tempo totale fetching HTTP: [TIME] secondi + </text> + <text name="total_time_fetch_label"> + 14, Tempo totale complessivo fetching: [TIME] secondi + </text> + <text name="total_time_refetch_vis_cache_label"> + 15, Nuovo fetching elementi visibili dalla cache, Tempo: [TIME] secondi, fetching: [SIZE] KB, [PIXEL] MPixels + </text> + <text name="total_time_refetch_all_cache_label"> + 16, Nuovo fetching di tutte le texture dalla cache, Tempo: [TIME] secondi, fetching: [SIZE] KB, [PIXEL] MPixels + </text> + <text name="total_time_refetch_vis_http_label"> + 17, Nuovo fetching elementi visibili da HTTP, Tempo: [TIME] secondi, fetching: [SIZE] KB, [PIXEL] MPixels + </text> + <text name="total_time_refetch_all_http_label"> + 18, Nuovo fetching di tutte le texture da HTTP, Tempo: [TIME] secondi, fetching: [SIZE] KB, [PIXEL] MPixels + </text> + <spinner label="19, Rapporto Texel/Pixel:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, Fonte texture: + </text> + <radio_group name="texture_source"> + <radio_item label="Cache + HTTP" name="0"/> + <radio_item label="Solo HTTP" name="1"/> + </radio_group> + <button label="Attiva" name="start_btn"/> + <button label="Reimposta" name="clear_btn"/> + <button label="Chiudi" name="close_btn"/> + <button label="Lettura cache" name="cacheread_btn"/> + <button label="Scrittura cache" name="cachewrite_btn"/> + <button label="HTTP" name="http_btn"/> + <button label="Decodifica" name="decode_btn"/> + <button label="Texture GL" name="gl_btn"/> + <button label="Nuovo fetch visibili cache" name="refetchviscache_btn"/> + <button label="Nuovo fetching di tutta la cache" name="refetchallcache_btn"/> + <button label="Nuovo fetch visibili HTTP" name="refetchvishttp_btn"/> + <button label="Nuovo fetching di tutto il contenuto HTTP" name="refetchallhttp_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_tools.xml b/indra/newview/skins/default/xui/it/floater_tools.xml index 0d981e2424..dd59035dd4 100644 --- a/indra/newview/skins/default/xui/it/floater_tools.xml +++ b/indra/newview/skins/default/xui/it/floater_tools.xml @@ -1,5 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="toolbox floater" short_title="STRUMENTI PER COSTRUZIONE"> + <floater.string name="grid_screen_text"> + Schermo + </floater.string> + <floater.string name="grid_local_text"> + Locale + </floater.string> + <floater.string name="grid_world_text"> + Mondo + </floater.string> + <floater.string name="grid_reference_text"> + Riferimento + </floater.string> + <floater.string name="grid_attachment_text"> + Allegato + </floater.string> <floater.string name="status_rotate"> Sposta le fasce colorate per ruotare l'oggetto </floater.string> @@ -63,7 +78,12 @@ </text> <check_box initial_value="true" label="Ridimensiona le texture" name="checkbox stretch textures"/> <check_box initial_value="true" label="Scatto" name="checkbox snap to grid"/> - <button label="Opzioni..." label_selected="Opzioni..." name="Options..." tool_tip="Vedi più opzioni della griglia"/> + <combo_box name="combobox grid mode" tool_tip="Scegli il tipo di righello per posizionare l'oggetto"> + <combo_box.item label="Mondo" name="World"/> + <combo_box.item label="Locale" name="Local"/> + <combo_box.item label="Riferimento" name="Reference"/> + </combo_box> + <button label="" label_selected="Opzioni..." name="Options..." tool_tip="Vedi più opzioni della griglia"/> <button label="" label_selected="" name="ToolCube" tool_tip="Cubo"/> <button label="" label_selected="" name="ToolPrism" tool_tip="Prisma"/> <button label="" label_selected="" name="ToolPyramid" tool_tip="Piramide"/> @@ -129,6 +149,12 @@ <panel.string name="text modify info 4"> Non puoi modificare questi oggetti </panel.string> + <panel.string name="text modify info 5"> + Questo oggetto non può essere modificato attraverso il confine di una regione + </panel.string> + <panel.string name="text modify info 6"> + Questi oggetti non possono essere modificati attraverso il confine di una regione + </panel.string> <panel.string name="text modify warning"> Devi selezionare tutto l'oggetto per impostare i permessi </panel.string> @@ -184,12 +210,12 @@ <combo_box.item label="Ingrandisci" name="Zoom"/> </combo_box> <check_box label="In vendita:" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Copia" name="Copy"/> <combo_box.item label="Contenuto" name="Contents"/> <combo_box.item label="Originale" name="Original"/> </combo_box> - <spinner label="Prezzo: L$" name="Edit Cost"/> <check_box label="Mostra nella ricerca" name="search_check" tool_tip="Permetti che l'oggetto sia visibile nella ricerca"/> <panel name="perms_build"> <text name="perm_modify"> @@ -225,6 +251,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Attributi pathfinding: + </text> + </panel> </panel> <panel label="Oggetto" name="Object"> <check_box label="Bloccato" name="checkbox locked" tool_tip="Previene lo spostamento o la cancellazione dell'oggetto. Spesso utile mentre si costruisce per evitare involontarie modifiche."/> diff --git a/indra/newview/skins/default/xui/it/floater_top_objects.xml b/indra/newview/skins/default/xui/it/floater_top_objects.xml index 7d062db23b..d8ca7f4438 100644 --- a/indra/newview/skins/default/xui/it/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/it/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> Ora </floater.string> - <floater.string name="scripts_mono_time_label"> - Ora 'Mono' - </floater.string> <floater.string name="top_colliders_title"> Oggetti con maggiori collisioni </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="Nome" name="name" width="84"/> <scroll_list.columns label="Proprietario" name="owner" width="84"/> <scroll_list.columns label="Ubicazione" name="location" width="84"/> + <scroll_list.columns label="Lotto" name="parcel"/> <scroll_list.columns label="Ora" name="time" width="84"/> - <scroll_list.columns label="Ora (Mono)" name="mono_time" width="84"/> <scroll_list.columns label="URL" name="URLs"/> + <scroll_list.columns label="Memoria (KB)" name="memory"/> </scroll_list> <text name="id_text"> ID oggetto: @@ -51,6 +49,10 @@ </text> <line_editor font="SansSerifSmall" left="90" name="owner_name_editor" width="280"/> <button label="Filtro" name="filter_owner_btn" width="150"/> + <text name="parcel_name_text"> + Lotto: + </text> + <button label="Filtra" name="filter_parcel_btn"/> <button label="Aggiorna" name="refresh_btn" width="150"/> <button label="Restituisci selezionato" name="return_selected_btn" width="150"/> <button label="Restituisci tutti" left="170" name="return_all_btn"/> 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/floater_voice_effect.xml b/indra/newview/skins/default/xui/it/floater_voice_effect.xml index a0e49525ea..c83b11f698 100644 --- a/indra/newview/skins/default/xui/it/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/it/floater_voice_effect.xml @@ -42,13 +42,16 @@ <string name="effect_Demon"> Demonio </string> + <string name="effect_Female Elf"> + Elfo donna + </string> <string name="effect_Flirty"> Civettuolo </string> <string name="effect_Foxy"> Scaltro </string> - <string name="effect_Halloween_2010_Bonus"> + <string name="effect_Halloween 2010 Bonus"> Halloween_2010_Bonus </string> <string name="effect_Helium"> @@ -57,9 +60,18 @@ <string name="effect_Husky"> Fusto </string> + <string name="effect_Husky Whisper"> + Sospiro rauco + </string> <string name="effect_Intercom"> Interfono </string> + <string name="effect_Julia"> + Julia + </string> + <string name="effect_Lo Lilt"> + Inflessione bassa + </string> <string name="effect_Macho"> Macho </string> @@ -69,6 +81,9 @@ <string name="effect_Mini"> Mini </string> + <string name="effect_Model"> + Modella + </string> <string name="effect_Nano"> Nano </string> @@ -90,6 +105,9 @@ <string name="effect_Roxanne"> Rosanna </string> + <string name="effect_Rumble"> + Rombo + </string> <string name="effect_Sabrina"> Sabrina </string> @@ -102,6 +120,9 @@ <string name="effect_Shorty"> Bassotto </string> + <string name="effect_Smaller"> + Più piccolo + </string> <string name="effect_Sneaky"> Vile </string> diff --git a/indra/newview/skins/default/xui/it/floater_window_size.xml b/indra/newview/skins/default/xui/it/floater_window_size.xml index 036b74b7d9..fef423aefe 100644 --- a/indra/newview/skins/default/xui/it/floater_window_size.xml +++ b/indra/newview/skins/default/xui/it/floater_window_size.xml @@ -7,10 +7,17 @@ Imposta dimensione finestra: </text> <combo_box name="window_size_combo" tool_tip="larghezza x altezza"> - <combo_box.item label="1000 x 700 (default)" name="item0"/> - <combo_box.item label="1024 x 768" name="item1"/> - <combo_box.item label="1280 x 720 (720p)" name="item2"/> - <combo_box.item label="1920 x 1080 (1080p)" name="item3"/> + <combo_box.item label="1000 x 700 (predefinito)" name="item1"/> + <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/> + <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/> + <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/> + <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/> + <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/> + <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/> + <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/> + <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/> + <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/> + <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/> </combo_box> <button label="Imposta" name="set_btn"/> <button label="Annulla" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/it/menu_bottomtray.xml b/indra/newview/skins/default/xui/it/menu_bottomtray.xml deleted file mode 100644 index ddd6909136..0000000000 --- a/indra/newview/skins/default/xui/it/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="Pulsante Parla" name="EnableVoiceChat"/> - <menu_item_check label="Tasto Gesture" name="ShowGestureButton"/> - <menu_item_check label="Tasto Movimento" name="ShowMoveButton"/> - <menu_item_check label="Tasto Visuale" name="ShowCameraButton"/> - <menu_item_check label="Tasto Foto" name="ShowSnapshotButton"/> - <menu_item_check label="Pulsante Costruisci" name="ShowBuildButton"/> - <menu_item_check label="Pulsante Cerca" name="ShowSearchButton"/> - <menu_item_check label="Pulsante Mappa" name="ShowWorldMapButton"/> - <menu_item_check label="Pulsante Mini mappa" name="ShowMiniMapButton"/> - <menu_item_call label="Taglia" name="NearbyChatBar_Cut"/> - <menu_item_call label="Copia" name="NearbyChatBar_Copy"/> - <menu_item_call label="Incolla" name="NearbyChatBar_Paste"/> - <menu_item_call label="Elimina" name="NearbyChatBar_Delete"/> - <menu_item_call label="Seleziona tutto" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/it/menu_im_well_button.xml b/indra/newview/skins/default/xui/it/menu_im_well_button.xml deleted file mode 100644 index 9e471b771c..0000000000 --- a/indra/newview/skins/default/xui/it/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<context_menu name="IM Well Button Context Menu"> - <menu_item_call label="Chiudi tutto" name="Close All"/> -</context_menu> diff --git a/indra/newview/skins/default/xui/it/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/it/menu_inspect_object_gear.xml index ede4a507c0..4740c9bf67 100644 --- a/indra/newview/skins/default/xui/it/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/it/menu_inspect_object_gear.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<menu name="Gear Menu"> +<toggleable_menu name="Gear Menu"> <menu_item_call label="Tocca" name="touch"/> <menu_item_call label="Siediti" name="sit"/> <menu_item_call label="Paga" name="pay"/> @@ -12,7 +12,8 @@ <menu_item_call label="Aggiungi" name="add"/> <menu_item_call label="Segnala" name="report"/> <menu_item_call label="Blocca" name="block"/> + <menu_item_call label="Sblocca" name="unblock"/> <menu_item_call label="Zoom avanti" name="zoom_in"/> <menu_item_call label="Rimuovi" name="remove"/> <menu_item_call label="Maggiori informazioni" name="more_info"/> -</menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/it/menu_inventory.xml b/indra/newview/skins/default/xui/it/menu_inventory.xml index 57aa4dc97d..b31e35771d 100644 --- a/indra/newview/skins/default/xui/it/menu_inventory.xml +++ b/indra/newview/skins/default/xui/it/menu_inventory.xml @@ -59,6 +59,7 @@ <menu_item_call label="Proprietà " name="Properties"/> <menu_item_call label="Rinomina" name="Rename"/> <menu_item_call label="Copia UUID dell'oggetto" name="Copy Asset UUID"/> + <menu_item_call label="Taglia" name="Cut"/> <menu_item_call label="Copia" name="Copy"/> <menu_item_call label="Incolla" name="Paste"/> <menu_item_call label="Incolla come link" name="Paste As Link"/> @@ -67,6 +68,7 @@ <menu_item_call label="Elimina la cartella di sistema" name="Delete System Folder"/> <menu_item_call label="Inizia la conferenza chat" name="Conference Chat Folder"/> <menu_item_call label="Esegui" name="Sound Play"/> + <menu_item_call label="Copia SLurl" name="url_copy"/> <menu_item_call label="Informazioni sul punto di riferimento" name="About Landmark"/> <menu_item_call label="Riproduci in Second Life" name="Animation Play"/> <menu_item_call label="Esegui localmente" name="Animation Audition"/> @@ -84,6 +86,6 @@ <menu_item_call label="Aggiungi" name="Wearable Add"/> <menu_item_call label="Togli" name="Take Off"/> <menu_item_call label="Copia nella casella venditore in uscita" name="Merchant Copy"/> - <menu_item_call label="Passa alla casella venditore in uscita" name="Merchant Move"/> + <menu_item_call label="Invia a Marketplace" name="Marketplace Send"/> <menu_item_call label="--nessuna opzione--" name="--no options--"/> </menu> diff --git a/indra/newview/skins/default/xui/it/menu_login.xml b/indra/newview/skins/default/xui/it/menu_login.xml index 834db974da..7b060e6565 100644 --- a/indra/newview/skins/default/xui/it/menu_login.xml +++ b/indra/newview/skins/default/xui/it/menu_login.xml @@ -16,8 +16,8 @@ <menu_item_call label="Imposta dimensioni della finestra..." name="Set Window Size..."/> <menu_item_call label="Mostra i Termini del servizio (TOS)" name="TOS"/> <menu_item_call label="Mostra messaggio critico" name="Critical"/> - <menu_item_call label="Test browser multimedia" name="Web Browser Test"/> <menu_item_call label="Test debug finestra contenuti Web" name="Web Content Floater Debug Test"/> + <menu label="Imposta livello di registrazione" name="Set Logging Level"/> <menu_item_check label="Mostra selettore griglia" name="Show Grid Picker"/> <menu_item_call label="Mostra Console notifiche" name="Show Notifications Console"/> </menu> diff --git a/indra/newview/skins/default/xui/it/menu_mode_change.xml b/indra/newview/skins/default/xui/it/menu_mode_change.xml deleted file mode 100644 index 499dcf1873..0000000000 --- a/indra/newview/skins/default/xui/it/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="Di base" name="BasicMode"/> - <menu_item_check label="Avanzata" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/it/menu_object.xml b/indra/newview/skins/default/xui/it/menu_object.xml index a172cf3b26..7f41e8937f 100644 --- a/indra/newview/skins/default/xui/it/menu_object.xml +++ b/indra/newview/skins/default/xui/it/menu_object.xml @@ -5,6 +5,8 @@ </menu_item_call> <menu_item_call label="Modifica" name="Edit..."/> <menu_item_call label="Costruisci" name="Build"/> + <menu_item_call label="Mostra nei set collegati" name="show_in_linksets"/> + <menu_item_call label="Mostra nei personaggi" name="show_in_characters"/> <menu_item_call label="Apri" name="Open"/> <menu_item_call label="Siediti qui" name="Object Sit"/> <menu_item_call label="Alzati" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/it/menu_text_editor.xml b/indra/newview/skins/default/xui/it/menu_text_editor.xml index 4636ce9929..5b61da914e 100644 --- a/indra/newview/skins/default/xui/it/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/it/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(sconosciuto)" name="Suggestion 1"/> + <menu_item_call label="(sconosciuto)" name="Suggestion 2"/> + <menu_item_call label="(sconosciuto)" name="Suggestion 3"/> + <menu_item_call label="(sconosciuto)" name="Suggestion 4"/> + <menu_item_call label="(sconosciuto)" name="Suggestion 5"/> + <menu_item_call label="Aggiungi al dizionario" name="Add to Dictionary"/> + <menu_item_call label="Aggiungi per ignorare" name="Add to Ignore"/> <menu_item_call label="Taglia" name="Cut"/> <menu_item_call label="Copia" name="Copy"/> <menu_item_call label="Incolla" name="Paste"/> 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 815f6f58ed..547c5a9b73 100644 --- a/indra/newview/skins/default/xui/it/menu_viewer.xml +++ b/indra/newview/skins/default/xui/it/menu_viewer.xml @@ -1,55 +1,62 @@ <?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"/> <menu_item_check label="Corri sempre" name="Always Run"/> <menu_item_call label="Ferma animazione" name="Stop Animating My Avatar"/> + <menu_item_call label="Cammina / corri / vola..." name="Walk / run / fly"/> </menu> <menu label="Stato" name="Status"> <menu_item_call label="Assente" name="Set Away"/> <menu_item_call label="Non disponibile" name="Set Busy"/> </menu> - <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="Acquista L$..." name="Buy and Sell L$"/> + <menu_item_call label="Casella venditore in uscita..." name="MerchantOutbox"/> + <menu_item_call label="Dashboard dell'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_check label="Mostra elementi HUD" name="Show HUD Attachments"/> <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_item_call label="Blocca lista" name="Block List"/> </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 +65,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 label="Sole" name="Sun"> <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> @@ -120,6 +126,11 @@ <menu_item_call label="Imposta gli script come in esecuzione" name="Set Scripts to Running"/> <menu_item_call label="Imposta script come non in esecuzione" name="Set Scripts to Not Running"/> </menu> + <menu label="Pathfinding" name="Pathfinding"> + <menu_item_call label="Set collegati..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="Personaggi..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="Visualizza / test..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Opzioni" name="Options"> <menu_item_check label="Mostra autorizzazioni avanzate" name="DebugPermissions"/> <menu_item_check label="Seleziona solo i miei oggetti" name="Select Only My Objects"/> @@ -140,11 +151,13 @@ <menu_item_call label="Animazione ([COST] L$)..." name="Upload Animation"/> <menu_item_call label="Modella..." name="Upload Model"/> <menu_item_call label="In blocco ([COST] L$ per file)..." name="Bulk Upload"/> + <menu_item_call label="Definisci diritti di caricamento predefiniti" name="perm prefs"/> </menu> <menu_item_call label="Annulla" name="Undo"/> <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"/> @@ -168,26 +181,25 @@ <menu_item_check label="Nascondi particelle" name="Hide Particles"/> <menu_item_check label="Nascondi selezionati" name="Hide Selected"/> <menu_item_check label="Evidenzia trasparenza" name="Highlight Transparent"/> - <menu_item_check label="Mostra elementi HUD" name="Show HUD Attachments"/> <menu_item_check label="Mostra mirino visuale soggettiva" name="ShowCrosshairs"/> </menu> <menu label="Modalità di rendering" name="Rendering Types"> - <menu_item_check label="Semplice" name="Simple"/> - <menu_item_check label="Alpha (Trasparenza)" name="Alpha"/> - <menu_item_check label="Albero" name="Tree"/> - <menu_item_check label="Avatar" name="Character"/> - <menu_item_check label="Superficie chiusa" name="Surface Patch"/> - <menu_item_check label="Cielo" name="Sky"/> - <menu_item_check label="Acqua" name="Water"/> - <menu_item_check label="Suolo" name="Ground"/> - <menu_item_check label="Volume" name="Volume"/> - <menu_item_check label="Erba" name="Grass"/> - <menu_item_check label="Nuvole" name="Clouds"/> - <menu_item_check label="Particelle" name="Particles"/> - <menu_item_check label="Urti" name="Bump"/> + <menu_item_check label="Semplice" name="Rendering Type Simple"/> + <menu_item_check label="Alpha (Trasparenza)" name="Rendering Type Alpha"/> + <menu_item_check label="Albero" name="Rendering Type Tree"/> + <menu_item_check label="Avatar" name="Rendering Type Character"/> + <menu_item_check label="Toppa superficie" name="Rendering Type Surface Patch"/> + <menu_item_check label="Cielo" name="Rendering Type Sky"/> + <menu_item_check label="Acqua" name="Rendering Type Water"/> + <menu_item_check label="Suolo" name="Rendering Type Ground"/> + <menu_item_check label="Volume" name="Rendering Type Volume"/> + <menu_item_check label="Erba" name="Rendering Type Grass"/> + <menu_item_check label="Nuvole" name="Rendering Type Clouds"/> + <menu_item_check label="Particelle" name="Rendering Type Particles"/> + <menu_item_check label="Urto" name="Rendering Type Bump"/> </menu> <menu label="Caratteristiche di rendering" name="Rendering Features"> - <menu_item_check label="Interfaccia utente" name="UI"/> + <menu_item_check label="Interfaccia utente" name="ToggleUI"/> <menu_item_check label="Selezionati" name="Selected"/> <menu_item_check label="Evidenziato" name="Highlighted"/> <menu_item_check label="Texture dinamiche" name="Dynamic Textures"/> @@ -198,11 +210,8 @@ <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'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"/> @@ -211,13 +220,6 @@ <menu_item_check label="Joystick Flycam" name="Joystick Flycam"/> <menu_item_call label="Reimposta vista" name="Reset View"/> <menu_item_call label="Guarda l'ultima conversazione" name="Look at Last Chatter"/> - <menu label="Seleziona strumento di costruzione" name="Select Tool"> - <menu_item_call label="Strumento Ingrandisci" name="Focus"/> - <menu_item_call label="Strumento Movimento" name="Move"/> - <menu_item_call label="Strumento Modifica" name="Edit"/> - <menu_item_call label="Strumento Crea" name="Create"/> - <menu_item_call label="Strumento Terreno" name="Land"/> - </menu> <menu_item_call label="Zoom avanti" name="Zoom In"/> <menu_item_call label="Zoom predefinito" name="Zoom Default"/> <menu_item_call label="Zoom indietro" name="Zoom Out"/> @@ -230,11 +232,10 @@ <menu_item_check label="Console texture" name="Texture Console"/> <menu_item_check label="Console di Debug" name="Debug Console"/> <menu_item_call label="Console notifiche" name="Notifications"/> - <menu_item_check label="Console dimensioni texture" name="Texture Size"/> - <menu_item_check label="Console categoria texture" name="Texture Category"/> <menu_item_check label="Timer veloci" name="Fast Timers"/> <menu_item_check label="Memoria" name="Memory"/> <menu_item_check label="Statistiche scena" name="Scene Statistics"/> + <menu_item_call label="Console di debug recupero texture" name="Texture Fetch Debug Console"/> <menu_item_call label="Informazioni regione sulla console di debug" name="Region Info to Debug Console"/> <menu_item_check label="Fotocamera" name="Camera"/> <menu_item_check label="Vento" name="Wind"/> @@ -271,8 +272,16 @@ <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="Byte collegamento" name="attachment bytes"/> <menu_item_check label="Scolpisci" name="Sculpt"/> + <menu label="Densità texture" name="Texture Density"> + <menu_item_check label="Nessuna" name="None"/> + <menu_item_check label="Attuale" name="Current"/> + <menu_item_check label="Desiderata" name="Desired"/> + <menu_item_check label="Completa" name="Full"/> + </menu> </menu> <menu label="Rendering" name="Rendering"> <menu_item_check label="Assi" name="Axes"/> @@ -280,7 +289,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"/> @@ -295,9 +303,8 @@ <menu_item_call label="Lascia un pacchetto" name="Drop a Packet"/> </menu> <menu_item_call label="Urti, spinte e contatti" name="Bumps, Pushes &amp; Hits"/> - <menu label="Mondo" name="World"> - <menu_item_check label="Esclusione al sole della regione" name="Sim Sun Override"/> - <menu_item_check label="Effetto marcatore lampeggiante" name="Cheesy Beacon"/> + <menu label="Mondo" name="DevelopWorld"> + <menu_item_check label="Esclusione al sole della simulazione" name="Sim Sun Override"/> <menu_item_check label="Clima fisso" name="Fixed Weather"/> <menu_item_call label="Dump della cache oggetti regione" name="Dump Region Object Cache"/> </menu> @@ -319,11 +326,11 @@ </menu> <menu label="Avatar" name="Character"> <menu label="Grab Baked Texture" name="Grab Baked Texture"> - <menu_item_call label="Iride" name="Iris"/> - <menu_item_call label="Testa" name="Head"/> - <menu_item_call label="Parte superiore del corpo" name="Upper Body"/> - <menu_item_call label="Parte inferiore del corpo" name="Lower Body"/> - <menu_item_call label="Gonna" name="Skirt"/> + <menu_item_call label="Iride" name="Grab Iris"/> + <menu_item_call label="Testa" name="Grab Head"/> + <menu_item_call label="Parte superiore del corpo" name="Grab Upper Body"/> + <menu_item_call label="Parte inferiore del corpo" name="Grab Lower Body"/> + <menu_item_call label="Gonna" name="Grab Skirt"/> </menu> <menu label="Test personaggio" name="Character Tests"> <menu_item_call label="Alterna la geometria dei personaggi" name="Toggle Character Geometry"/> @@ -339,18 +346,27 @@ </menu> <menu_item_check label="Texture HTTP" name="HTTP Textures"/> <menu_item_check label="Inventario HTTP" name="HTTP Inventory"/> + <menu_item_call label="Attiva Visual Leak Detector" name="Enable Visual Leak Detector"/> <menu_item_check label="Finestra Console al prossimo lancio" name="Console Window"/> + <menu label="Imposta livello di registrazione" name="Set Logging Level"> + <menu_item_check label="Debug" name="Debug"/> + <menu_item_check label="Informazioni" name="Info"/> + <menu_item_check label="Attenzione" name="Warning"/> + <menu_item_check label="Errore" name="Error"/> + <menu_item_check label="Nessuno" name="None"/> + </menu> <menu_item_call label="Richiedi diritti Admin" name="Request Admin Options"/> <menu_item_call label="Lascia stato Admin" name="Leave Admin Options"/> <menu_item_check label="Mostra menu Admin" name="View Admin Options"/> </menu> <menu label="Admin" name="Admin"> - <menu label="Object"> - <menu_item_call label="Prendi copia" name="Take Copy"/> + <menu label="Oggetto" name="AdminObject"> + <menu_item_call label="Prendi copia" name="Admin Take Copy"/> <menu_item_call label="Rendimi proprietario" name="Force Owner To Me"/> <menu_item_call label="Forza permesso proprietario" name="Force Owner Permissive"/> <menu_item_call label="Elimina" name="Delete"/> <menu_item_call label="Blocca" name="Lock"/> + <menu_item_call label="Ottieni ID asset" name="Get Assets IDs"/> </menu> <menu label="Lotto" name="Parcel"> <menu_item_call label="Rendimi proprietario" name="Owner To Me"/> @@ -367,5 +383,16 @@ <menu label="Take Off Clothing" name="Take Off Clothing"> <menu_item_call label="Fisica" name="Physics"/> </menu> + <menu label="Guida" name="DeprecatedHelp"> + <menu_item_call label="Blog ufficiale Linden" name="Official Linden Blog"/> + <menu_item_call label="Portale script" name="Scripting Portal"/> + <menu label="Segnalazione bug" name="Bug Reporting"> + <menu_item_call label="Monitoraggio problemi pubblici" name="Public Issue Tracker"/> + <menu_item_call label="Guida Monitoraggio problemi pubblici" name="Publc Issue Tracker Help"/> + <menu_item_call label="Guida alla segnalazione di bug" name="Bug Reporing 101"/> + <menu_item_call label="Problemi sicurezza" name="Security Issues"/> + <menu_item_call label="Wiki domande e risposte" name="QA Wiki"/> + </menu> + </menu> </menu> </menu_bar> diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index e19b84912a..d5fdde4e7d 100644 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -86,17 +92,38 @@ Accertati che la tua connessione Internet stia funzionando correttamente. <usetemplate canceltext="Annulla" name="yesnocancelbuttons" notext="Non salvare" yestext="Salva"/> </notification> <notification name="ConfirmNoCopyToOutbox"> - Non hai l'autorizzazione necessaria per copiare questo oggetto nella casella in uscita di Marketplace. Sei sicuro di volere spostare gli oggetti seguenti? - [ITEM_NAME] - <usetemplate name="okcancelbuttons" notext="No" yestext="Sì"/> + Non hai l'autorizzazione necessaria per copiare almeno uno di questi elementi nella casella in uscita del rivenditore. Puoi spostarli o lasciarli indietro. + <usetemplate name="okcancelbuttons" notext="Non spostare gli oggetti" yestext="Sposta oggetti"/> </notification> - <notification name="OutboxUploadComplete"> - Caricamento di Marketplace completato. - <usetemplate name="okbutton" yestext="Ottimo!"/> + <notification name="OutboxFolderCreated"> + Una nuova cartella è stata creata per ciascun elemento trasferito nel livello superiore della casella in uscita del rivenditore. + <usetemplate ignoretext="Una nuova cartella è stata creata nella casella in uscita del rivenditore" name="okignore" yestext="OK"/> + </notification> + <notification name="OutboxImportComplete"> + Successo + +Tutte le cartelle sono state inviate a Marketplace correttamente. + <usetemplate ignoretext="Tutte le cartelle inviate a Marketplace" name="okignore" yestext="OK"/> </notification> - <notification name="OutboxUploadHadErrors"> - Caricamento di Marketplace completato senza errori. Correggi i problemi nella casella in uscita e riprova. Grazie. - <usetemplate name="okbutton" yestext="Riprova"/> + <notification name="OutboxImportHadErrors"> + Alcune cartelle non sono state trasferite + +Si sono verificati degli errori durante l'invio di alcune cartelle a Marketplace. Tali cartelle sono ancora nella casella in uscita del rivenditore. + +Per ulteriori informazioni consulta il [[MARKETPLACE_IMPORTS_URL] registro errori]. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="OutboxImportFailed"> + Trasferimento non riuscito + +Nessuna cartella è stata inviata a Marketplace, a causa di un errore di sistema o di rete. Riprova più tardi. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="OutboxInitFailed"> + Inizializzazione Marketplace non riuscita + +L'inizializzazione con il Marketplace non ha avuto successo a causa di un errore di sistema o di rete. Riprova più tardi. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CompileQueueSaveText"> C'è stato un problema importando il testo di uno script per la seguente ragione: [REASON]. Riprova più tardi. @@ -339,13 +366,19 @@ Inserisci il Nome utente del tuo avatar. Devi avere un account per entrare in [SECOND_LIFE]. Vuoi crearne uno adesso? <url name="url"> - https://join.secondlife.com/index.php?lang=it-IT + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Riprova" yestext="Crea un nuovo account"/> </notification> <notification name="InvalidCredentialFormat"> Immetti il nome utente oppure sia il nome che il cognome del tuo avatar nel campo del nome utente, quindi effettua nuovamente l'accesso. </notification> + <notification name="InvalidGrid"> + '[GRID]' non è un identificatore di griglia valido. + </notification> + <notification name="InvalidLocationSLURL"> + La tua posizione iniziale non ha specificato una griglia valida. + </notification> <notification name="DeleteClassified"> Cancella annuncio '[NAME]'? Non ci sono rimborsi per la tariffa pagata. @@ -471,6 +504,15 @@ Visitare [_URL] per ulteriori informazioni? </url> <usetemplate ignoretext="L'hardware di questo computer non è compatibile" name="okcancelignore" notext="No" yestext="Si"/> </notification> + <notification name="IntelOldDriver"> + È probabile che ci sia un driver aggiornato per il processore grafico. L'aggiornamento dei driver della grafica può migliorare le prestazioni in maniera significativa. + + Visitare [_URL] per cercare un aggiornamento del driver? + <url name="url"> + http://www.intel.com/p/it_IT/support/detect/graphics + </url> + <usetemplate ignoretext="Driver grafica obsoleto" name="okcancelignore" notext="No" yestext="Sì"/> + </notification> <notification name="UnknownGPU"> Il tuo sistema utilizza una scheda grafica che [APP_NAME] non riconosce. Questo succede spesso con un nuovo hardware che non è stato ancora testato con [APP_NAME]. Probabilmente tutto andrà bene, ma devi riconfigurare le tue impostazioni grafiche. @@ -568,6 +610,9 @@ Puoi unire al massimo [MAX] oggetti. Accertati che nessuno sia bloccato e che li possiedi tutti. </notification> + <notification name="CannotLinkPermanent"> + Gli oggetti non possono essere collegati attraverso i confini. + </notification> <notification name="CannotLinkDifferentOwners"> Impossibile unire perche non tutti gli oggetti hanno lo stesso proprietario. @@ -647,7 +692,7 @@ Attese [VALIDS] Impossibile creare il file in uscita: [FILE] </notification> <notification name="DoNotSupportBulkAnimationUpload"> - [APP_NAME] non supporta ancora il caricamento in blocco di file di animazione. + [APP_NAME] non supporta ancora il caricamento in blocco di file di animazione in formato BVH. </notification> <notification name="CannotUploadReason"> Impossibile importare il file [FILE] a causa del seguente motivo: [REASON] @@ -947,6 +992,41 @@ Offri l'amicizia a [NAME]? <button name="Cancel" text="Annulla"/> </form> </notification> + <notification label="Aggiungi lista di sostituzione automatica" name="AddAutoReplaceList"> + Nome per la nuova lista: + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="Rinomina lista di sostituzione automatica" name="RenameAutoReplaceList"> + Il nome '[DUPNAME]' è già in uso + Inserisci un nuovo nome univoco: + <form name="form"> + <button name="ReplaceList" text="Sostituisci lista corrente"/> + <button name="SetName" text="Usa nuovo nome"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + La parola chiave deve essere una sola parola e la sostituzione non può essere vuota. + </notification> + <notification name="InvalidAutoReplaceList"> + L'elenco di sostituzione non è valido. + </notification> + <notification name="SpellingDictImportRequired"> + Devi specificare un file, un nome e una lingua. + </notification> + <notification name="SpellingDictIsSecondary"> + Sembra che il dizionario [DIC_NAME] non includa un file "aff"; ciò indica che di tratta di un dizionario "secondario". +Può essere usato come dizionario aggiuntivo, ma non come dizionario principale. + +Vedi https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + Copia non eseguita da + [FROM_NAME] + a + [TO_NAME] + </notification> <notification label="Salva vestiario" name="SaveOutfitAs"> Salva gli abiti che indosso come nuovo vestiario: <form name="form"> @@ -978,7 +1058,7 @@ Offri l'amicizia a [NAME]? </form> </notification> <notification name="RemoveFromFriends"> - Vuoi rimuovere [NAME] dalla lista dei tuoi amici? + Vuoi rimuovere <nolink>[NAME]</nolink> dalla lista dei tuoi amici? <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> </notification> <notification name="RemoveMultipleFromFriends"> @@ -1110,8 +1190,13 @@ Cedere questi [AREA] m² di terreno al gruppo '[GROUP_NAME]'? <notification name="DisplaySetToSafe"> Le impostazioni dello schermo sono state impostate a valori di sicurezza perchè hai specificato l'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 '[LAST_GPU]' +a '[THIS_GPU]' + </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] @@ -1122,7 +1207,7 @@ Cedere questi [AREA] m² di terreno al gruppo '[GROUP_NAME]'? Sei stato trasferito in una regione vicina. </notification> <notification name="AvatarMovedLast"> - La tua ultima posizione non è al momento disponibile. + La posizione richiesta non è al momento disponibile. Sei stato trasferito in una regione vicina. </notification> <notification name="AvatarMovedHome"> @@ -1141,8 +1226,7 @@ Puoi comunque usare [SECOND_LIFE] normalmente e gli altri residenti ti vedranno L'installazione di [APP_NAME] è terminata. Se questa è la prima volta che usi [SECOND_LIFE], devi creare un account prima che tu possa effettuare l'accesso. -Vuoi tornare a [http://join.secondlife.com secondlife.com] per creare un nuovo account? - <usetemplate name="okcancelbuttons" notext="Continua" yestext="Nuovo Account..."/> + <usetemplate name="okcancelbuttons" notext="Continua" yestext="Crea account..."/> </notification> <notification name="LoginPacketNeverReceived"> Ci sono problemi di connessione. È possibile che ci siano problemi con la tua connessione Internet oppure sulla [SECOND_LIFE_GRID]. @@ -1432,8 +1516,8 @@ Per installare l'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]. -Vuoi lasciare il gruppo? + Attualmente sei un membro del gruppo <nolink>[GROUP]</nolink>. +Lasciare il gruppo? <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> </notification> <notification name="ConfirmKick"> @@ -1663,83 +1747,128 @@ Cambierà migliaia di regioni e produrrà seri problemi ai vari server. <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> </notification> <notification name="RegionEntryAccessBlocked"> - Non sei ammesso in questa regione a causa della tua categoria di accesso. Questo può risultare da una mancanza di informazioni necessarie per convalidare la tua età . - -Verifica di avere installato l'ultima versione del programma e vai alla Knowledge Base per ulteriori informazioni su come accedere nelle zone con tale categoria di accesso. + La regione che cerchi di visitare include contenuti che non corripondono al livello selezionato nelle preferenze. Per cambiare le preferenze seleziona Io > Preferenze > Generale. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - Non sei ammesso in questa regione a causa della tua categoria d'accesso. - -Vuoi andare alla Knowledge Base per ulteriori informazioni sulle categorie di accesso? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY] accessibili solo ad adulti. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/it + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Non posso entrare in questa regione a causa delle restrizioni della categoria di accesso" name="okcancelignore" notext="Chiudi" yestext="Vai alla Knowledge Base"/> + <usetemplate ignoretext="Attraversamento regione: la regione che cerchi di visitare include contenuti accessibili solo ad adulti." name="okcancelignore" notext="Chiudi" yestext="Passa alla Base conoscenze"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - Non sei ammesso in questa regione a causa della tua categoria d'accesso. + La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY] accessibili solo ad adulti. </notification> <notification name="RegionEntryAccessBlocked_Change"> - Non ti è consentito entrare in quella regione a causa della categoria di accesso impostata nelle preferenze. - -Per entrare nella regione, dovrai modificare la tua categoria di accesso. Ciò ti consentirà inoltre di effettuare ricerche di contenuti di categoria [REGIONMATURITY]. Per annullare le modifiche in un secondo momento, vai a Io > Preferenze > Generali. + La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le tue preferenze o annullare. Dopo aver modificato le preferenze, prova nuovamente ad entrare nella regione. <form name="form"> - <button name="OK" text="Cambia preferenza"/> - <button default="true" name="Cancel" text="Chiudi"/> - <ignore name="ignore" text="La categoria di accesso impostata mi impedisce di entrare in una regione"/> + <button name="OK" text="Modifica preferenze"/> + <button default="true" name="Cancel" text="Annulla"/> + <ignore name="ignore" text="Attraversamento regione: La regione che cerchi di visitare include contenuti esclusi nelle preferenze."/> </form> </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + Si è verificato un problema con il teleport a causa di un errore di sincronizzazione delle preferenze con il server. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + La regione che cerchi di visitare include contenuti che non corripondono al livello selezionato nelle preferenze. Per cambiare le preferenze seleziona Io > Preferenze > Generale. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY] accessibili solo ad adulti. + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="Teleport: la regione che cerchi di visitare include contenuti accessibili solo ad adulti." name="okcancelignore" notext="Chiudi" yestext="Passa alla Base conoscenze"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY] accessibili solo ad adulti. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le preferenze e continuare con il teleport oppure annullarlo. + <form name="form"> + <button name="OK" text="Modifica e continua"/> + <button name="Cancel" text="Annulla"/> + <ignore name="ignore" text="Teleport (riavviabile): La regione che cerchi di visitare include contenuti esclusi nelle preferenze."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le tue preferenze o annullare il teleport. Dopo aver modificato le preferenze, prova nuovamente a teletrasportarti nella regione. + <form name="form"> + <button name="OK" text="Modifica preferenze"/> + <button name="Cancel" text="Annulla"/> + <ignore name="ignore" text="Teleport (non riavviabile): La regione che cerchi di visitare include contenuti esclusi nelle preferenze."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + Si è verificato un problema con il teleport a causa di un errore di sincronizzazione delle preferenze con il server. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - La tua categoria di accesso attuale è [RATING]. + Non riceverai più notifiche se stai per visitare una regione con contenuti [RATING]. In futuro potrai modificare le preferenze relative ai contenuti selezionando Io > Preferenze > Generale nella barra del menu. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + Non è stato possibile modificare le preferenze per visualizzare contenuti [PREFERRED_MATURITY]. le preferenze sono state ripristinate per consentire la visualizzazione di contenuti [ACTUAL_MATURITY]. Puoi cercare di modificare nuovamente le preferenze selezionando Io > Preferenze > Generale nella barra del menu. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - Non puoi prendere possesso di questo terreno a causa della tua categoria di accesso. Questo può essere dovuto ad una mancanza di informazioni valide che confermino la tua età . - -Verifica di avere installato l'ultima versione del programma e vai alla Knowledge Base per informazioni sull'accesso ad aree con queste categorie di accesso. + Il terreno che desideri richiedere ha una categoria di accesso maggiore di quella indicata nelle preferenze. Per cambiare le preferenze seleziona Io > Preferenze > Generale. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - Non puoi prendere possesso di questa terra a causa delle preferenze sulle categorie di accesso. - -Vuoi andare alla Knowledge Base per maggiori informazioni sulle categorie di accesso? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + Solo gli adulti possono richiedere questo terreno. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/it + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Non posso richiedere questo terreno a causa delle restrizioni della categoria di accesso" name="okcancelignore" notext="Chiudi" yestext="Vai alla Knowledge Base"/> + <usetemplate ignoretext="Solo gli adulti possono richiedere questo terreno." name="okcancelignore" notext="Chiudi" yestext="Passa alla Base conoscenze"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - Non puoi prendere possesso di questa terra a causa della tua categoria di accesso. + Il terreno che desideri richiedere include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + Il terreno che cerchi di richiedere include contenuti [REGIONMATURITY], accessibili solo ad adulti. </notification> <notification name="LandClaimAccessBlocked_Change"> - Non puoi richiedere questo terreno a causa della tua categoria di accesso. - -Puoi cliccare su Cambia preferenze per modificare la categoria di accesso e quindi riuscire ad entrare. Da adesso potrai accedere ai contenuti [REGIONMATURITY] ed effettuare ricerche in questa categoria. Se in seguito tu volessi cambiare di nuovo le tue impostazioni, apri la finestra di dialogo da Io > Preferenze > Generale. - <usetemplate ignoretext="Le mie preferenze di categoria di accesso mi impediscono di richiedere terreno" name="okcancelignore" notext="Chiudi" yestext="Cambia le preferenze"/> + Il terreno che desideri richiedere include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le preferenze e quindi cercare di richiedere nuovamente il terreno. + <form name="form"> + <button name="OK" text="Modifica preferenze"/> + <button name="Cancel" text="Annulla"/> + <ignore name="ignore" text="Il terreno che cerchi di richiedere include contenuti esclusi nelle preferenze."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - Non puoi acquistare questo terreno a causa della tua categoria di accesso. Questo può essere dovuto ad una mancanza di informazioni valide che confermino la tua età . - -Verifica di avere installato l'ultima versione del programma e vai alla Knowledge Base per informazioni sull'accesso ad aree con queste categorie di accesso. + Il terreno che desideri acquistare ha una categoria di accesso maggiore di quella indicata nelle preferenze. Per cambiare le preferenze seleziona Io > Preferenze > Generale. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - Non puoi acquistare questo terreno a causa della tua categoria di accesso. - -Vuoi andare alla Knowledge Base per maggiori informazioni sulle categorie di accesso? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Solo gli adulti possono acquistare questo terreno. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/it + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Non posso acquistare questo terreno a causa delle restrizioni della categoria di accesso" name="okcancelignore" notext="Chiudi" yestext="Vai alla Knowledge Base"/> + <usetemplate ignoretext="Solo gli adulti possono acquistare questo terreno." name="okcancelignore" notext="Chiudi" yestext="Passa alla Base conoscenze"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - Non puoi acquistare questa land a causa della tua categoria di accesso. + Il terreno che cerchi di acquistare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + Il terreno che cerchi di acquistare include contenuti [REGIONMATURITY], accessibili solo ad adulti. </notification> <notification name="LandBuyAccessBlocked_Change"> - Non puoi acquistare questo terreno a causa della tua categoria di accesso. - -Puoi cliccare su Cambia preferenze per modificare la categoria di accesso e quindi riuscire ad entrare. Da adesso potrai accedere ai contenuti [REGIONMATURITY] ed effettuare ricerche in questa categoria. Se in seguito tu volessi cambiare di nuovo le tue impostazioni, apri la finestra di dialogo da Io > Preferenze > Generale. - <usetemplate ignoretext="Le mie Preferenze di accesso mi impediscono di acquistare terreno" name="okcancelignore" notext="Chiudi" yestext="Cambia le preferenze"/> + Il terreno che cerchi di acquistare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le preferenze e quindi cercare di acquistare nuovamente il terreno. + <form name="form"> + <button name="OK" text="Modifica preferenze"/> + <button name="Cancel" text="Annulla"/> + <ignore name="ignore" text="Il terreno che cerchi di acquistare include contenuti esclusi nelle preferenze."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Hai selezionato troppi prim. Seleziona non più di [MAX_PRIM_COUNT] prim e riprova @@ -1794,10 +1923,9 @@ Pubblica questo annuncio adesso per [AMOUNT]L$? </form> </notification> <notification label="Cambiato il contenuto Moderato" name="RegionMaturityChange"> - La classificazione di questa regione è stata aggiornata. -Un periodo di tempo è necessario prima che la modifica venga integrata nella mappa. - -Per accedere a regioni per adulti, i residenti devono avere un Account verificato, mediante verifica dell'età oppure mediante verifica della modalità di pagamento. + La classificazione di questa regione è stata modificata. +Prima che questa modifica venga integrata nella mappa potrebbe essere necessario un po' di tempo. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="Versione voice non compatibile" name="VoiceVersionMismatch"> Questa versione di [APP_NAME] non è compatibile con la funzionalità di chat vocale in questa regione. Affinché la chat vocale funzioni correttamente, dovrai aggiornare [APP_NAME]. @@ -1916,7 +2044,13 @@ Trasferisci gli elementi nell'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"/> @@ -2082,14 +2216,11 @@ Inseriscilo in una pagina web per dare ad altri un accesso facile a questa ubica <usetemplate ignoretext="Indossare gli abiti che creo mentre modifico il mio aspetto" name="okcancelignore" notext="No" yestext="Si"/> </notification> <notification name="NotAgeVerified"> - Per accedere ai contenuti e alle aree per adulti in Second Life devi avere almeno 18 anni. Visita la pagina di verifica dell'età per confermare di avere almeno 18 anni. -Verrà avviato il browser Web. - -[_URL] - <url name="url" option="0"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="Non ho verificato la mia età " name="okcancelignore" notext="Annulla" yestext="Passa alla verifica dell'età "/> + Il luogo che desideri visitare è limitato a persone di almeno 18 anni di età . + <usetemplate ignoretext="Non ho l'età necessaria per visitare aree limitate." name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + Posizione limitata a persone maggiori di 18 anni di età . </notification> <notification name="Cannot enter parcel: no payment info on file"> Per poter visitare questa zona devi avere devi aver fornito informazioni di pagamento a Linden Lab. Vuoi andare sul sito di [SECOND_LIFE] ed impostarle? @@ -2125,10 +2256,10 @@ Verrà avviato il browser Web. Oggetto: [SUBJECT], Messaggio: [MESSAGE] </notification> <notification name="FriendOnline"> - [NAME] è Online + <nolink>[NAME]</nolink> è online </notification> <notification name="FriendOffline"> - [NAME] è Offline + <nolink>[NAME]</nolink> è offline </notification> <notification name="AddSelfFriend"> Anche se sei molto simpatico, non puoi aggiungere te stesso all'elenco degli amici. @@ -2241,14 +2372,16 @@ Seleziona solo un oggetto. Il tuo biglietto da visita non è stato accettato. </notification> <notification name="TeleportToLandmark"> - Puoi teleportarti alle ubicazioni come '[NAME]' 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 '[NAME]', clicca sul pulsante "Luoghi", + 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 '[NAME]' aprendo il pannello Persone nel lato destro del tuo schermo. -Seleziona il residente dall'elenco, clicca su 'IM' in basso nel pannello. -(Puoi anche fare doppio clic sul nome nell'elenco oppure fare clic con il pulsante destro del mouse e selezionare 'IM'). + Per contattare Residenti come '[NAME]', clicca sul pulsante "Persone", seleziona un Residente nel pannello che viene aperto, quindi clicca su 'IM' in + basso nel pannello. + (Puoi anche fare doppio clic sul nome nell'elenco oppure fare clic con il pulsante destro del mouse e selezionare 'IM'). </notification> <notification name="CantSelectLandFromMultipleRegions"> Non è possibile selezionare il terreno attraverso i confini del server. @@ -2269,6 +2402,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: @@ -2345,6 +2481,23 @@ Qui non puoi volare. <notification name="NoBuild"> In questa zona è proibita la costruzione. Qui non puoi costruire né rezzare oggetti. </notification> + <notification name="PathfindingDirty"> + La regione ha modifiche di pathfinding in sospeso. Se hai le autorizzazioni necessarie per la costruzione puoi eseguire il rebake facendo clic sul pulsante “Rebake regioneâ€. + </notification> + <notification name="DynamicPathfindingDisabled"> + Il pathfinding dinamico non è attivato in questa regione. Gli oggetti scriptati che usano chiamate LSL di pathfinding potrebbero non funzionare come previsto in questa regione. + </notification> + <notification name="PathfindingRebakeNavmesh"> + Se modifichi alcuni oggetti in questa regione, ciò potrebbe causare il comportamento errato di altri oggetti in movimento. Per fare in modo che gli oggetti in movimento si comportino correttamente, fai clic sul pulsante "Rebake regione". Per maggiori informazioni, seleziona la guida + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Guida" ignoretext="Se modifichi alcuni oggetti in questa regione, ciò potrebbe causare il comportamento errato di altri oggetti in movimento." name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Si è verificato un errore. Potrebbe trattarsi di un problema di rete o del server, oppure potresti non avere le autorizzazioni necessarie per la costruzione. A volte il problema viene risolto uscendo ed eseguendo nuovamente l'accesso. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> In questo lotto non si possono vedere avatar e chat di testo presenti in altri lotti. Non puoi vedere altri residenti fuori dal lotto e loro non possono vederti. Viene bloccata anche la normale chat di testo sul canale 0. </notification> @@ -2363,9 +2516,7 @@ Qui funzionano soltanto gli script del proprietario del terreno. Puoi solo richiedere terreni pubblici nella regione in cui sei posizionato. </notification> <notification name="RegionTPAccessBlocked"> - Non puoi entrare in quella regione a causa della tua categoria di accesso. Può essere necessario validare l'età e/o installare l'ultima versione del programma. - -Visita la Knowledge Base per informazioni sull'accesso alle aree con queste categorie di accesso. + La regione che cerchi di visitare include contenuti che non corripondono al livello selezionato nelle preferenze. Per cambiare le preferenze seleziona Io > Preferenze > Generale. </notification> <notification name="URBannedFromRegion"> Tu hai l'accesso bloccato a questa regione. @@ -2376,8 +2527,11 @@ Visita la Knowledge Base per informazioni sull'accesso alle aree con queste <notification name="ImproperPaymentStatus"> Non hai una impostazioni di pagamento corrette per entrare in questa regione. </notification> + <notification name="MustGetAgeRegion"> + Per poter entrare in questa regione devi avere almeno 18 anni. + </notification> <notification name="MustGetAgeParcel"> - Devi essere di età verificata per entrare in questa terra. + Per poter entrare in questo lotto devi avere almeno 18 anni. </notification> <notification name="NoDestRegion"> Non è stata trovata nessuna regione di destinazione. @@ -2479,12 +2633,33 @@ Riprova tra qualche istante. <notification name="TeleportOffered"> [NAME_SLURL] ti ha offerto il teleport alla sua ubicazione: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="Teleport"/> <button name="Cancel" text="Cancella"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] ti ha offerto il teleport alla sua ubicazione: + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Questa regione include contenuti [REGION_CONTENT_MATURITY], ma le tue preferenze attuali escludono i contenuti [REGION_CONTENT_MATURITY]. Puoi modificare le preferenze e continuare con il teleport oppure annullarlo. + <form name="form"> + <button name="Teleport" text="Modifica e continua"/> + <button name="Cancel" text="Annulla"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] ti ha offerto il teleport alla sua ubicazione: + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Questa regione include però contenuti accessibili solo agli adulti. + </notification> <notification name="TeleportOfferSent"> Offerta di Teleport inviata a [TO_NAME] </notification> @@ -2520,10 +2695,10 @@ Riprova tra qualche istante. </form> </notification> <notification name="FriendshipAccepted"> - [NAME] ha accettato la tua offerta di amicizia. + <nolink>[NAME]</nolink> ha accettato la tua richiesta di amicizia. </notification> <notification name="FriendshipDeclined"> - [NAME] ha rifiutato la tua offerta di amicizia. + <nolink>[NAME]</nolink> ha rifiutato la tua richiesta di amicizia. </notification> <notification name="FriendshipAcceptedByMe"> Offerta di amicizia accettata. @@ -2579,32 +2754,28 @@ OK? </form> </notification> <notification name="ScriptQuestionCaution"> - Un oggetto di nome '<nolink>[OBJECTNAME]</nolink>', posseduto da '[NAME]' vorrebbe: - -[QUESTIONS] -Se non ti fidi di questo oggetto e del suo ideatore, dovresti rifiutare la richiesta. - -Concedi questa richiesta? + Attenzione: L'oggetto '<nolink>[OBJECTNAME]</nolink>' ha richiesto accesso completo al tuo account in Dollari Linden. Se consenti l'accesso, potrà rimuovere fondi dal tuo account in qalunque momento e anche svuotare completamente l'account, per un periodo illimitato e senza ulteriori avvisi. + +Raramente questo tipo di richiesta è legittima. Non consentire l'accesso se non comprendi perfettamente il motivo per cui desidera accedere al tuo account. <form name="form"> - <button name="Grant" text="Accetta"/> + <button name="Grant" text="Consenti accesso totale"/> <button name="Deny" text="Nega"/> - <button name="Details" text="Dettagli..."/> </form> </notification> <notification name="ScriptDialog"> '<nolink>[TITLE]</nolink>' di [NAME] [MESSAGE] <form name="form"> - <button name="Mute" text="Blocca"/> - <button name="Ignore" text="Ignora"/> + <button name="Client_Side_Mute" text="Blocca"/> + <button name="Client_Side_Ignore" text="Ignora"/> </form> </notification> <notification name="ScriptDialogGroup"> '<nolink>[TITLE]</nolink>' di [GROUPNAME] [MESSAGE] <form name="form"> - <button name="Mute" text="Blocca"/> - <button name="Ignore" text="Ignora"/> + <button name="Client_Side_Mute" text="Blocca"/> + <button name="Client_Side_Ignore" text="Ignora"/> </form> </notification> <notification name="BuyLindenDollarSuccess"> @@ -2800,6 +2971,18 @@ Per informazioni dettagliate, vedi il file del registro. Con i seguenti residenti? [RESIDENTS] + <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> + </notification> + <notification name="ShareFolderConfirmation"> + Si può condividere solo una cartella alla volta. + +Sei sicuro di volere condividere gli oggetti seguenti: + +<nolink>[ITEMS]</nolink> + +Con i seguenti residenti: + +[RESIDENTS] <usetemplate name="okcancelbuttons" notext="Annulla" yestext="Ok"/> </notification> <notification name="ItemsShared"> @@ -2880,6 +3063,10 @@ Hai caricato una texture [RESOLUTION] completata per '[BODYREGION]' do ( In esistenza da [EXISTENCE] secondi) Hai aggiornato localmente una texture [RESOLUTION] completata per '[BODYREGION]' dopo [TIME] secondi. </notification> + <notification name="LivePreviewUnavailable"> + Non possiamo mostrare un'anteprima di questa texture perché non ne è consentita la copia e/o il trasferimento. + <usetemplate ignoretext="Avvisami se la modalità Anteprima dal vivo non è disponibile per texture per cui non è consentita la copia e/o il trasferimento." name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> Sei sicuro di volere uscire dalla chiamata? <usetemplate ignoretext="Conferma prima di uscire dalla chiamata" name="okcancelignore" notext="No" yestext="Sì"/> @@ -2890,7 +3077,7 @@ In questo modo verrà disattivato l'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'audio di tutti i partecipanti alla chiamata di gruppo" name="okcancelignore" notext="Annulla" yestext="Ok"/> + <usetemplate ignoretext="Conferma prima di disattivare l'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. @@ -3051,6 +3238,62 @@ Clicca e trascina dovunque nel mondo per ruotare la visuale Questa azione cancellerà tutte le voci di menu e i pulsanti. Per visualizzarli nuovamente cliccare ancora [SHORTCUT]. <usetemplate ignoretext="Conferma prima di nascondere l'interfaccia" name="okcancelignore" notext="Annulla" yestext="OK"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + L'indicatore oggetto fantasma di alcuni set collegati verrà commutato. + +Vuoi continuare? + <usetemplate ignoretext="L'indicatore oggetto fantasma di alcuni set collegati verrà commutato." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Alcuni set collegati selezionati non possono essere impostati su '[REQUESTED_TYPE]' a causa di limitazioni nelle autorizzazioni per i set collegati. Questi set collegati verranno invece impostati su '[RESTRICTED_TYPE]'. + +Vuoi continuare? + <usetemplate ignoretext="Alcuni set collegati selezionati non possono essere impostati a causa di limitazioni nelle autorizzazioni per i set collegati." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Alcuni set collegati selezionati non possono essere impostati a '[REQUESTED_TYPE]' perché la forma è non-convessa. + +Vuoi continuare? + <usetemplate ignoretext="Alcuni set collegati selezionati non possono essere impostati perché la forma è non-convessa." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + L'indicatore oggetto fantasma di alcuni set collegati verrà commutato. + +Alcuni set collegati selezionati non possono essere impostati su '[REQUESTED_TYPE]' a causa di limitazioni nelle autorizzazioni per i set collegati. Questi set collegati verranno invece impostati su '[RESTRICTED_TYPE]'. + +Vuoi continuare? + <usetemplate ignoretext="L'indicatore oggetto fantasma per alcuni set collegati selezionati verrà commutato, mentre quello degli altri non può essere impostato a causa di limitazioni nelle autorizzazioni per i set collegati." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + L'indicatore oggetto fantasma di alcuni set collegati verrà commutato. + +Alcuni set collegati selezionati non possono essere impostati a '[REQUESTED_TYPE]' perché la forma è non-convessa. + +Vuoi continuare? + <usetemplate ignoretext="L'indicatore oggetto fantasma per alcuni set collegati selezionati verrà commutato, mentre quello degli altri non può essere impostato perché la forma è non-convessa." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Alcuni set collegati selezionati non possono essere impostati su '[REQUESTED_TYPE]' a causa di limitazioni nelle autorizzazioni per i set collegati. Questi set collegati verranno invece impostati su '[RESTRICTED_TYPE]'. + +Alcuni set collegati selezionati non possono essere impostati a '[REQUESTED_TYPE]' perché la forma è non-convessa. Il tipo di utilizzo di questi set collegati non cambierà . + +Vuoi continuare? + <usetemplate ignoretext="Alcuni set collegati selezionati non possono essere impostati a causa delle limitazioni nelle autorizzazioni per il set collegato e perché la forma è non-convessa." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + L'indicatore oggetto fantasma di alcuni set collegati verrà commutato. + +Alcuni set collegati selezionati non possono essere impostati su '[REQUESTED_TYPE]' a causa di limitazioni nelle autorizzazioni per i set collegati. Questi set collegati verranno invece impostati su '[RESTRICTED_TYPE]'. + +Alcuni set collegati selezionati non possono essere impostati a '[REQUESTED_TYPE]' perché la forma è non-convessa. Il tipo di utilizzo di questi set collegati non cambierà . + +Vuoi continuare? + <usetemplate ignoretext="L'indicatore oggetto fantasma per alcuni set collegati selezionati verrà commutato, mentre quello degli altri non può essere impostato a causa delle limitazioni nelle autorizzazioni per il set collegato e perché la forma è non-convessa." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + L'oggetto selezionato influenza il navmesh. Se lo si trasforma in un percorso flessibile verrà rimosso dal navmesh. + <usetemplate ignoretext="L'oggetto selezionato influenza il navmesh. Se lo si trasforma in un percorso flessibile verrà rimosso dal navmesh." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> <global name="UnsupportedGLRequirements"> Non sembra che tu abbia i requisiti hardware adeguati per [APP_NAME]. [APP_NAME] richiede una scheda grafica OpenGL con supporto multitexture. Se ne hai una in dotazione, accertati di avere i driver, i service pack e i patch più recenti per la scheda grafica e per il sistema operativo. @@ -3075,4 +3318,24 @@ In alternativa, puoi guardare sulla mappa e trovare luoghi segnalati come " <global name="You died and have been teleported to your home location"> Sei deceduto e sei stato teleportato a casa tua. </global> + <notification name="LocalBitmapsUpdateFileNotFound"> + [FNAME] non è stato aggiornato perché il file non è stato più trovato. +Gli aggiornamenti futuri per questo file sono disattivati. + </notification> + <notification name="LocalBitmapsUpdateFailedFinal"> + [FNAME] non è stato aperto o decodificato dopo [NRETRIES] tentativi, viene considerato danneggiato. +Gli aggiornamenti futuri per questo file sono disattivati. + </notification> + <notification name="LocalBitmapsVerifyFail"> + Tentativo di aggiungere un file immagine [FNAME] non valido o non leggibile che non è stato possibile aprire o decodificare. +Tentativo annullato. + </notification> + <notification name="PathfindingReturnMultipleItems"> + Stai per restituire [NUM_ITEMS] elementi. Vuoi continuare? + <usetemplate ignoretext="Sei sicuro di volere restituire più oggetti?" name="okcancelignore" notext="No" yestext="Sì"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + Stai per cancellare [NUM_ITEMS] elementi. Vuoi continuare? + <usetemplate ignoretext="Sei sicuro di volere eliminare più oggetti?" name="okcancelignore" notext="No" yestext="Sì"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/it/panel_bottomtray.xml b/indra/newview/skins/default/xui/it/panel_bottomtray.xml deleted file mode 100644 index 3d12473c87..0000000000 --- a/indra/newview/skins/default/xui/it/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Accende o spegne il microfono"/> - <string name="VoiceControlBtnToolTip" value="Mostra o nasconde il pannello di regolazione voce"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Parla" label_selected="Parla" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="Gesture" name="Gesture" tool_tip="Mostra o nasconde le gesture"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Sposta" name="movement_btn" tool_tip="Mostra o nasconde i comandi del movimento"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Visuale" name="camera_btn" tool_tip="Mostra o nasconde le regolazioni della visuale"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button label="" name="snapshots" tool_tip="Scatta una foto"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="Costruisci" name="build_btn" tool_tip="Mostra o nasconde gli strumenti di costruzione"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="Cerca" name="search_btn" tool_tip="Mostra o nasconde la ricerca"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Mappa" name="world_map_btn" tool_tip="Mostra o nasconde la mappa del mondo"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Mini mappa" name="mini_map_btn" tool_tip="Mostra o nasconde la mini mappa"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Conversazioni"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="Notifiche"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> 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_group_invite.xml b/indra/newview/skins/default/xui/it/panel_group_invite.xml index e3cb3c1092..1b57eba3f0 100644 --- a/indra/newview/skins/default/xui/it/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/it/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> Alcuni dei residenti selezionati sono già nel gruppo, pertanto l'invito non verrà loro spedito. </panel.string> + <panel.string name="invite_selection_too_large"> + Invito di gruppo non inviato: troppi residenti selezionati Gli inviti di gruppo possono essere inviati a un massimo di 100 persone per ciascuna richiesta. + </panel.string> <text name="help_text"> Puoi selezionare più residenti da invitare nel tuo gruppo. Per iniziare, clicca su Apri il selettore di residenti. </text> diff --git a/indra/newview/skins/default/xui/it/panel_login.xml b/indra/newview/skins/default/xui/it/panel_login.xml index f88230ed11..2afde40940 100644 --- a/indra/newview/skins/default/xui/it/panel_login.xml +++ b/indra/newview/skins/default/xui/it/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php?lang=it </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + ACCEDI + </text> <text name="username_text"> Nome utente: </text> @@ -15,15 +15,8 @@ <text name="password_text"> Password: </text> - <check_box label="Ricorda password" name="remember_check"/> - <button label="Accedi" name="connect_btn"/> - <text name="mode_selection_text"> - Modalità : - </text> - <combo_box name="mode_combo" tool_tip="Seleziona la modalità . Seleziona Di base per esplorare facilmente e rapidamente e per la chat. Seleziona Avanzata per accedere ad altre funzionalità ."> - <combo_box.item label="Di base" name="Basic"/> - <combo_box.item label="Avanzate" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Inizia da: </text> @@ -33,16 +26,21 @@ <combo_box.item label="<Scrivi nome regione>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Iscriviti + <layout_panel name="links_login_panel"> + <text name="login_help"> + Ti serve aiuto con la fase di accesso? </text> <text name="forgot_password_text"> Hai dimenticato il nome utente o la password? </text> - <text name="login_help"> - Ti serve aiuto con la fase di accesso? + <button label="Accedi" name="connect_btn"/> + <check_box label="Ricorda password" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + CREA IL TUO ACCOUNT </text> + <button label="Inizia adesso" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_my_profile.xml b/indra/newview/skins/default/xui/it/panel_my_profile.xml deleted file mode 100644 index 094b97962f..0000000000 --- a/indra/newview/skins/default/xui/it/panel_my_profile.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Profilo" name="panel_profile"> - <string name="no_partner_text" value="Nessuno"/> - <string name="no_group_text" value="Nessuno"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="scroll_content_panel"> - <panel name="second_life_image_panel"> - <text name="display_name_descr_text"> - Nome utente - </text> - <text name="name_descr_text"> - Nome visualizzato - </text> - <button label="Profilo" name="see_profile_btn" tool_tip="Visualizza profilo per questo avatar"/> - </panel> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/it/panel_nearby_chat.xml b/indra/newview/skins/default/xui/it/panel_nearby_chat.xml index 1b529e2737..d46a15c735 100644 --- a/indra/newview/skins/default/xui/it/panel_nearby_chat.xml +++ b/indra/newview/skins/default/xui/it/panel_nearby_chat.xml @@ -1,4 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="nearby_chat"> - <check_box label="Traduci chat" name="translate_chat_checkbox"/> + <layout_stack name="stack"> + <layout_panel name="translate_chat_checkbox_lp"> + <check_box label="Traduci chat" name="translate_chat_checkbox"/> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml index 6317d3192e..1fef88870a 100644 --- a/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="chat_bar"> +<panel name="nearby_chat"> <string name="min_width"> 192 </string> diff --git a/indra/newview/skins/default/xui/it/panel_notes.xml b/indra/newview/skins/default/xui/it/panel_notes.xml deleted file mode 100644 index e127138277..0000000000 --- a/indra/newview/skins/default/xui/it/panel_notes.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Note e Privacy" name="panel_notes"> - <layout_stack name="layout"> - <layout_panel name="notes_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <text name="status_message" value="Le mie note private:"/> - <text name="status_message2" value="Consenti a questa persona di:"/> - <check_box label="Vedere se sono online" name="status_check"/> - <check_box label="Vedermi sulla mappa" name="map_check"/> - <check_box label="Modificare, eliminare o prendere i miei oggetti" name="objects_check"/> - </panel> - </scroll_container> - </layout_panel> - <layout_panel name="notes_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Aggiungi come amico" name="add_friend" tool_tip="Offri amicizia a questo residente"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="Apri una sessione messaggio istantaneo"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Chiama" name="call" tool_tip="Chiama questo residente"/> - </layout_panel> - <layout_panel name="show_on_map_btn_lp"> - <button label="Mappa" name="show_on_map_btn" tool_tip="Mostra il residente sulla mappa"/> - </layout_panel> - <layout_panel name="teleport_btn_lp"> - <button label="Teleport" name="teleport" tool_tip="Offri teleport"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> 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'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'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..0c9c4027e5 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,7 @@ <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="Traduzione..." name="ok_btn"/> + <button label="Sostituzione automatica..." name="autoreplace_showgui"/> + <button label="Correzione ortografica..." name="spellcheck_showgui"/> </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'aiuto, per i link Web e così via. Sconsigliato durante l'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'aiuto, per i link Web e così via. Sconsigliato durante l'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'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_profile.xml b/indra/newview/skins/default/xui/it/panel_profile.xml deleted file mode 100644 index 309937c5a0..0000000000 --- a/indra/newview/skins/default/xui/it/panel_profile.xml +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Profilo" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=it-IT - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=it - </string> - <string name="my_account_link_url" value="http://secondlife.com/my/account/index.php?lang=it-IT"/> - <string name="no_partner_text" value="Nessuno"/> - <string name="no_group_text" value="Nessuno"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <panel name="second_life_image_panel"> - <text name="title_sl_descr_text" value="[SECOND_LIFE]:"/> - </panel> - <panel name="first_life_image_panel"> - <text name="title_rw_descr_text" value="Mondo reale:"/> - </panel> - <text name="title_member_text" value="Residente dal:"/> - <text name="title_acc_status_text" value="Stato account:"/> - <text name="title_partner_text" value="Partner:"/> - <panel name="partner_data_panel"> - <text initial_value="(recupero)" name="partner_text"/> - </panel> - <text name="title_groups_text" value="Gruppi:"/> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> - <layout_stack name="layout_verb_buttons"> - <layout_panel name="profile_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Aggiungi come amico" name="add_friend" tool_tip="Offri amicizia a questo residente"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="Apri una sessione messaggio istantaneo"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Chiama" name="call" tool_tip="Chiama questo residente"/> - </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="Teleport" name="teleport" tool_tip="Offri teleport"/> - </layout_panel> - <layout_panel name="overflow_btn_lp"> - <menu_button label="â–¼" name="overflow_btn" tool_tip="Paga del denaro o condividi qualcosa dall'inventario con il residente"/> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="profile_me_buttons_panel"> - <button label="Modifica profilo" name="edit_profile_btn" tool_tip="Modifica le tue informazioni personali"/> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/it/panel_profile_view.xml b/indra/newview/skins/default/xui/it/panel_profile_view.xml deleted file mode 100644 index 409eb5d1f4..0000000000 --- a/indra/newview/skins/default/xui/it/panel_profile_view.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_target_profile"> - <string name="status_online"> - Online - </string> - <string name="status_offline"> - Offline - </string> - <text name="display_name_label" value="Nome visualizzato:"/> - <text name="solo_username_label" value="Nome utente:"/> - <text name="status" value="Online"/> - <text name="user_name_small" value="Jack guarda quanto è lungo questo splendido nome"/> - <text name="user_name" value="Jack Linden"/> - <button name="copy_to_clipboard" tool_tip="Copia negli appunti"/> - <text name="user_label" value="Nome utente:"/> - <text name="user_slid" value="jack.linden"/> - <tab_container name="tabs"> - <panel label="PROFILO" name="panel_profile"/> - <panel label="LUOGHI CONSIGLIATI" name="panel_picks"/> - <panel label="NOTE E PRIVACY" name="panel_notes"/> - </tab_container> -</panel> diff --git a/indra/newview/skins/default/xui/it/panel_region_debug.xml b/indra/newview/skins/default/xui/it/panel_region_debug.xml index 45b3a016f4..aba60d03aa 100644 --- a/indra/newview/skins/default/xui/it/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/it/panel_region_debug.xml @@ -36,5 +36,5 @@ <button label="?" left="297" name="top_scripts_help"/> <button label="Riavvia la regione" name="restart_btn" tool_tip="Dai 2 minuti di tempo massimo e fai riavviare la regione"/> <button label="?" name="restart_help"/> - <button label="Ritarda il riavvio" name="cancel_restart_btn" tool_tip="Ritarda il riavvio della regione di un'ora"/> + <button label="Annulla riavvio" name="cancel_restart_btn" tool_tip="Annulla riavvio regione"/> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_region_estate.xml b/indra/newview/skins/default/xui/it/panel_region_estate.xml index 61e3f31024..98d9b86cfc 100644 --- a/indra/newview/skins/default/xui/it/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/it/panel_region_estate.xml @@ -23,10 +23,10 @@ <check_box label="Permetti accesso pubblico" name="externally_visible_check"/> <button label="?" name="externally_visible_help"/> <text name="Only Allow"> - Limita l'accesso agli account verificati con: + Consenti l'accesso solo ai Residenti che: </text> - <check_box label="Informazioni di pagamento in archivio" name="limit_payment" tool_tip="Espelli i residenti non identificati"/> - <check_box label="Verifica età " name="limit_age_verified" tool_tip="Espelli i residenti che non hanno la loro età verificata. Vedi [SUPPORT_SITE] per maggiori informazioni."/> + <check_box label="Hanno memorizzato le informazioni per l'addebito" name="limit_payment" tool_tip="Per poter visitare questa proprietà immobiliare i Residenti devono aver fornito informazioni di pagamento a Linden Lab. Vedi [SUPPORT_SITE] per maggiori informazioni."/> + <check_box label="Hanno almeno 18 anni" name="limit_age_verified" tool_tip="Per poter visitare questa proprietà immobiliare i Residenti devono avere almeno 18 anni. Vedi [SUPPORT_SITE] per maggiori informazioni."/> <check_box label="Permetti la chat voice" name="voice_chat_check"/> <button label="?" name="voice_chat_help"/> <check_box label="Permetti teleport diretto" name="allow_direct_teleport"/> diff --git a/indra/newview/skins/default/xui/it/panel_region_texture.xml b/indra/newview/skins/default/xui/it/panel_region_texture.xml deleted file mode 100644 index 1337ed18ca..0000000000 --- a/indra/newview/skins/default/xui/it/panel_region_texture.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Texture del terreno" name="Textures"> - <text name="region_text_lbl"> - Regione: - </text> - <text name="region_text"> - sconosciuto - </text> - <text name="detail_texture_text" width="380"> - Texture del terreno (è necessario siano 512x512, 24 bit .tga files) - </text> - <text name="height_text_lbl"> - 1 (Bassa) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (Alta) - </text> - <text name="height_text_lbl5"> - Range di elevazione della texture - </text> - <text name="height_text_lbl6"> - Nordovest - </text> - <text name="height_text_lbl7"> - Nordest - </text> - <text name="height_text_lbl8"> - Sudovest - </text> - <text name="height_text_lbl9"> - Sudest - </text> - <spinner label="Bassa" name="height_start_spin_0"/> - <spinner label="Bassa" name="height_start_spin_1"/> - <spinner label="Bassa" name="height_start_spin_2"/> - <spinner label="Bassa" name="height_start_spin_3"/> - <spinner label="Alta" name="height_range_spin_0"/> - <spinner label="Alta" name="height_range_spin_1"/> - <spinner label="Alta" name="height_range_spin_2"/> - <spinner label="Alta" name="height_range_spin_3"/> - <text name="height_text_lbl10"> - Questi valori indicano la gamma di miscele per le texture di cui sopra. - </text> - <text name="height_text_lbl11"> - Misurato in metri, il valore BASSO è la MASSIMA altezza della texture n. 1, e il valore ALTO è l'altezza MINIMA della texture n. 4. - </text> - <text name="height_text_lbl12"> - Texture #1, e il valore più ALTO all'altezza MINIMA della Texture #4. - </text> - <button label="Applica" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/it/panel_script_ed.xml b/indra/newview/skins/default/xui/it/panel_script_ed.xml index 950dfacf3a..d7ee8230b3 100644 --- a/indra/newview/skins/default/xui/it/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/it/panel_script_ed.xml @@ -22,6 +22,8 @@ <menu label="File" name="File"> <menu_item_call label="Salva" name="Save"/> <menu_item_call label="Annulla tutte le modifiche" name="Revert All Changes"/> + <menu_item_call label="Carica da file..." name="LoadFromFile"/> + <menu_item_call label="Salva su file..." name="SaveToFile"/> </menu> <menu label="Modifica" name="Edit"> <menu_item_call label="Annulla" name="Undo"/> diff --git a/indra/newview/skins/default/xui/it/panel_script_question_toast.xml b/indra/newview/skins/default/xui/it/panel_script_question_toast.xml new file mode 100644 index 0000000000..a2d0237da0 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_script_question_toast.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel label="script_question_panel" name="panel_script_question_toast"> + <panel label="buttons_panel" name="buttons_panel"/> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_side_tray.xml b/indra/newview/skins/default/xui/it/panel_side_tray.xml deleted file mode 100644 index e0143088a5..0000000000 --- a/indra/newview/skins/default/xui/it/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Apri/chiudi la barra laterale." name="sidebar_openclose" tab_title="Apri/chiudi la barra laterale"/> - <sidetray_tab description="Casa." name="sidebar_home" tab_title="Home"> - <panel label="casa" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Modifica il tuo profilo pubblico e i preferiti." name="sidebar_me" tab_title="Il mio profilo"> - <panel_container name="panel_container"> - <panel label="Io" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Trova amici, contatti e persone nelle vicinanze." name="sidebar_people" tab_title="Persone"> - <panel_container name="panel_container"> - <panel label="Profilo del gruppo" name="panel_group_info_sidetray"/> - <panel label="Residenti e oggetti bloccati" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Trova luoghi dove andare e luoghi già visitati." label="Luoghi" name="sidebar_places" tab_title="Luoghi"> - <panel label="Luoghi" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="Sfoglia il tuo inventario." name="sidebar_inventory" tab_title="Il mio inventario"> - <panel label="Modifica inventario" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Cambia il tuo aspetto ed il tuo look attuale." name="sidebar_appearance" tab_title="Il mio aspetto"> - <panel label="Modifica aspetto fisico" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> 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'inventario + </text> + <text name="hint_lbl"> + Salvare un'immagine nell'inventario costa L$[UPLOAD_COST]. Per salvare l'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'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'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'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..0aaf89d8c8 100644 --- a/indra/newview/skins/default/xui/it/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/it/panel_status_bar.xml @@ -15,10 +15,10 @@ <panel.string name="buycurrencylabel"> L$ [AMT] </panel.string> - <panel name="balance_bg"> + <panel left="-405" name="balance_bg" width="195"> <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/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/it/panel_volume_pulldown.xml new file mode 100644 index 0000000000..bc17fc0c89 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_volume_pulldown.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater" width="220"> + <button left="197" name="prefs_btn"/> + <slider label="Principale" label_width="60" name="System Volume" width="160"/> + <slider label="Pulsanti" label_width="60" name="UI Volume" width="160"/> + <slider label="Ambiente" label_width="60" name="Wind Volume" width="160"/> + <slider label="Suoni" label_width="60" name="SFX Volume" width="160"/> + <check_box name="gesture_audio_play_btn" tool_tip="Attiva suoni dai gesti"/> + <slider label="Musica" label_width="60" name="Music Volume" width="160"/> + <check_box name="enable_music" tool_tip="Attiva streaming musica"/> + <slider label="Multimedia" label_width="60" name="Media Volume" width="160"/> + <check_box name="enable_media" tool_tip="Attiva streaming multimediale"/> + <slider label="Voce" label_width="60" name="Voice Volume" width="160"/> + <check_box name="enable_voice_check" tool_tip="Attiva chat vocale"/> +</panel> diff --git a/indra/newview/skins/default/xui/it/sidepanel_inventory.xml b/indra/newview/skins/default/xui/it/sidepanel_inventory.xml index 5d6c7681f9..5ac0961bd7 100644 --- a/indra/newview/skins/default/xui/it/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/it/sidepanel_inventory.xml @@ -2,47 +2,24 @@ <panel label="Cose" name="objects panel"> <panel label="" name="sidepanel__inventory_panel"> <layout_stack name="inventory_layout_stack"> - <layout_panel name="inbox_outbox_layout_panel"> - <layout_stack name="inbox_outbox_layout_stack"> - <layout_panel name="inbox_layout_panel"> - <panel label="" name="marketplace_inbox"> - <string name="InboxLabelWithArg"> - Oggetti ricevuti ([NUM]) - </string> - <string name="InboxLabelNoArg"> - Oggetti ricevuti - </string> - <button label="Oggetti ricevuti" name="inbox_btn"/> - <text name="inbox_fresh_new_count"> - [NUM] nuovi - </text> - <panel tool_tip="Drag and drop items to your inventory to manage and use them"> - <text name="inbox_inventory_placeholder"> - Gli acquisti dal mercato verranno consegnati qui. - </text> - </panel> - </panel> - </layout_panel> - <layout_panel name="outbox_layout_panel"> - <panel label="" name="marketplace_outbox"> - <string name="OutboxLabelWithArg"> - Casella venditore in uscita ([NUM]) - </string> - <string name="OutboxLabelNoArg"> - Casella venditore in uscita - </string> - <button label="Casella venditore in uscita" name="outbox_btn"/> - <button label="" name="outbox_sync_btn" tool_tip="Push su negozio Marketplace"/> - <panel> - <panel name="outbox_inventory_placeholder_panel"> - <text name="outbox_inventory_placeholder_title"> - Caricamento in corso... - </text> - </panel> - </panel> - </panel> - </layout_panel> - </layout_stack> + <layout_panel name="inbox_layout_panel"> + <panel label="" name="marketplace_inbox"> + <string name="InboxLabelWithArg"> + Oggetti ricevuti ([NUM]) + </string> + <string name="InboxLabelNoArg"> + Oggetti ricevuti + </string> + <button label="Oggetti ricevuti" name="inbox_btn"/> + <text name="inbox_fresh_new_count"> + [NUM] nuovi + </text> + <panel name="inbox_inventory_placeholder_panel" tool_tip="Trascina gli elementi nell'inventario per usarli"> + <text name="inbox_inventory_placeholder"> + Gli acquisti dal mercato verranno consegnati qui. + </text> + </panel> + </panel> </layout_panel> </layout_stack> <panel name="button_panel"> diff --git a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml index 900a65956b..2b3ea0fb83 100644 --- a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (sconosciuto) </panel.string> + <panel.string name="unknown_multiple"> + (sconosciuto / multiplo) + </panel.string> <panel.string name="public"> (pubblico) </panel.string> diff --git a/indra/newview/skins/default/xui/it/sidepanel_task_info.xml b/indra/newview/skins/default/xui/it/sidepanel_task_info.xml index cfabdc81b0..8a0f93e650 100644 --- a/indra/newview/skins/default/xui/it/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/it/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> Non puoi modificare questi oggetti </panel.string> + <panel.string name="text modify info 5"> + Questo oggetto non può essere modificato attraverso il confine di una regione + </panel.string> + <panel.string name="text modify info 6"> + Questi oggetti non possono essere modificati attraverso il confine di una regione + </panel.string> <panel.string name="text modify warning"> Questo oggetto ha parti collegate </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Prezzo: L$" name="Edit Cost"/> <check_box label="Mostra nella ricerca" name="search_check" tool_tip="Permetti alle persone di vedere questo oggetto nei risultati della ricerca"/> + <text name="pathfinding_attributes_label"> + Attributi pathfinding: + </text> <text name="B:"> B: </text> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index e58ce0cd70..fb1e387468 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -134,7 +134,7 @@ Esci </string> <string name="create_account_url"> - http://join.secondlife.com/index.php?lang=it-IT + http://join.secondlife.com/index.php?lang=it-IT&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> Il viewer utilizzato non è più in grado di accedere a Second Life. Visita la parina seguente per scaricare un nuovo viewer: @@ -178,8 +178,8 @@ Visita www.secondlife.com/status per aggiornamenti. </string> <string name="LoginFailedPremiumOnly"> L'accesso a Second Life è temporaneamente limitato per garantire che chi è nel mondo virtuale abbia la migliore esperienza possibile. - -Le persona con account gratuiti non potrenno accedere a Second Life durante questo periodo, per lasciare spazio alle persone che hanno pagato per Second Life. + +Le persone con account gratuiti non potranno accedere a Second Life durante questo periodo, per lasciare spazio alle persone che hanno pagato per Second Life. </string> <string name="LoginFailedComputerProhibited"> Non si può accedere a Second Life da questo computer. @@ -336,17 +336,35 @@ Prova ad accedere nuovamente tra un minuto. Solo un singolo oggetto può essere creato qui </string> <string name="TooltipPrice" value="L$ [AMOUNT]:"/> + <string name="TooltipOutboxDragToWorld"> + Non puoi rezzare elementi nella tua casella in uscita del rivenditore + </string> <string name="TooltipOutboxNoTransfer"> - Almeno un oggetto non può essere venduto o trasferito a un altro utente. + Almeno uno di questi oggetti non può essere venduto o trasferito. + </string> + <string name="TooltipOutboxNotInInventory"> + La tua casella in uscita del rivenditore può accettare solo elementi provenienti dal tuo inventario </string> <string name="TooltipOutboxWorn"> - Stai indossando almeno uno degli oggetti. Rimuovili dall'avatar e prova nuovamente a spostarli. + Non puoi mettere gli elementi che indossi nella casella in uscita del rivenditore + </string> + <string name="TooltipOutboxCallingCard"> + Non puoi inserire il tuo biglietto da visita nella tua casella in uscita del rivenditore </string> <string name="TooltipOutboxFolderLevels"> - Questa cartella contiene troppi livelli di cartelle nidificate. Riordina le cartelle interne in modo che non ci siano più di 4 livelli (cartella principale che contiene la cartella A, che contiene la cartella B, che contiene la cartella C). + La profondità delle caselle nidificate è maggiore di 3 + </string> + <string name="TooltipOutboxTooManyFolders"> + Il numero di sottocartelle nella cartella al livello più alto è maggiore di 20 </string> <string name="TooltipOutboxTooManyObjects"> - Questa cartella contiene più di 200 oggetti. Inserisci alcuni oggetti in scatole per ridurne il numero. + Il numero di elementi nella cartella al livello più alto è maggiore di 200 + </string> + <string name="TooltipDragOntoOwnChild"> + Non puoi spostare una cartella nella relativa cartella secondaria + </string> + <string name="TooltipDragOntoSelf"> + Non puoi spostare una cartella in se stessa </string> <string name="TooltipHttpUrl"> Clicca per visitare questa pagina web @@ -592,6 +610,9 @@ Prova ad accedere nuovamente tra un minuto. <string name="mesh"> reticolo </string> + <string name="AvatarEditingAppearance"> + (Modifica Aspetto) + </string> <string name="AvatarAway"> Assente </string> @@ -808,6 +829,9 @@ Prova ad accedere nuovamente tra un minuto. <string name="anim_yes_head"> Si </string> + <string name="multiple_textures"> + Multiple + </string> <string name="texture_loading"> Caricamento in corso... </string> @@ -856,6 +880,9 @@ Prova ad accedere nuovamente tra un minuto. <string name="ScriptQuestionCautionChatDenied"> A '[OBJECTNAME]', un oggetto di proprietà di '[OWNERNAME]', situato in [REGIONNAME] [REGIONPOS], è stato negato il permesso di: [PERMISSIONS]. </string> + <string name="AdditionalPermissionsRequestHeader"> + Se consenti l'accesso al tuo account, consentirai anche all'oggetto di: + </string> <string name="ScriptTakeMoney"> Prendere dollari Linden (L$) da te </string> @@ -889,6 +916,9 @@ Prova ad accedere nuovamente tra un minuto. <string name="ControlYourCamera"> Controllare la tua fotocamera </string> + <string name="TeleportYourAgent"> + Teleportarti + </string> <string name="SIM_ACCESS_PG"> Generale </string> @@ -964,6 +994,12 @@ Prova ad accedere nuovamente tra un minuto. <string name="choose_the_directory"> Scegli la cartella </string> + <string name="script_files"> + Script + </string> + <string name="dictionary_files"> + Dizionari + </string> <string name="AvatarSetNotAway"> Imposta come non assente </string> @@ -1202,43 +1238,36 @@ 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 + Gli acquissti dal mercato verranno mostrati qui. Potrai quindi trascinarli nel tuo inventario per usarli. </string> <string name="MarketplaceURL"> - http://marketplace.[DOMAIN_NAME]/learn_more + https://marketplace.[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 + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4 </string> - <string name="InventoryOutboxCreationErrorTitle"> - La casella in uscita del rivenditore non è configurata correttamente + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard </string> - <string name="InventoryOutboxCreationErrorTooltip"> - Errore di configurazione della casella in uscita del rivenditore + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports </string> - <string name="InventoryOutboxCreationError"> - Contatta l'Assistenza clienti per correggere il problema. + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more </string> <string name="InventoryOutboxNotMerchantTitle"> - Chiunque può vendere oggetti nel Marketplace - </string> - <string name="InventoryOutboxNotMerchantTooltip"> - Diventa un rivenditore! + Chiunque può vendere oggetti nel Marketplace. </string> + <string name="InventoryOutboxNotMerchantTooltip"/> <string name="InventoryOutboxNotMerchant"> - [[MARKETPLACE_URL] Second Life Marketplace] offre in vendita più di un milione di prodotti virtuali, tutti creati da Residenti. Anche tu puoi vendere gli oggetti che crei, oltre ad alcuni degli oggetti che hai acquistato. È facile da usare e l'impostazione è gratuita. [[LEARN_MORE_URL] Leggi ulteriori informazioni] oppure [[CREATE_STORE_URL] crea un negozio] sul Marketplace per cominciare. + Per diventare un venditore, devi [[MARKETPLACE_CREATE_STORE_URL] creare un negozio nel Marketplace]. </string> <string name="InventoryOutboxNoItemsTitle"> - Un nuovo modo di inviare oggetti al Marketplace - </string> - <string name="InventoryOutboxNoItemsTooltip"> - Trascina gli oggetti qui per prepararli per la vendita nel Marketplace + La tua casella in uscita è vuota. </string> + <string name="InventoryOutboxNoItemsTooltip"/> <string name="InventoryOutboxNoItems"> - Trascina elementi o cartelle che desideri vendere in quest'area. Verrà visualizzata una copia dell'elemento, senza che venga modificato l'inventario, tranne nel caso in cui venga trascinato un oggetto per cui non è permessa la copia. Clicca sul pulsante Carica per caricare gli elementi su Marketplace. Dopo aver spostato gli elementi nell'inventario di Marketplace, non saranno più visibili in questa cartella. + Trascina le cartelle in questa area e clicca su "Invia a Marketplace" per metterle in vendita su [[MARKETPLACE_DASHBOARD_URL] Marketplace]. </string> <string name="Marketplace Error None"> Nessun errore @@ -1250,7 +1279,7 @@ Prova ad accedere nuovamente tra un minuto. Errore: questa cartella non include alcun contenuto. </string> <string name="Marketplace Error Unassociated Products"> - Errore: Oggetto non caricato perché il tuo account venditore ha troppi oggetti che non sono associati con dei prodotti. Per risolvere questo errore, esegui l'accesso al sito di Marketplace e riduci il numero di oggetti non associati. + Errore: Oggetto non caricato perché il tuo account venditore ha troppi oggetti che non sono associati con dei prodotti. Per risolvere questo errore, esegui l'accesso al sito di Marketplace e riduci il numero di oggetti non associati. </string> <string name="Marketplace Error Object Limit"> Errore: questo elemento contiene troppi oggetti. Per risolvere questo problema, inserisci più oggetti insieme in una scatola per ridurre a meno di 200 il numero totale di oggetti. @@ -1370,6 +1399,12 @@ Prova ad accedere nuovamente tra un minuto. <string name="InvFolder favorite"> I miei preferiti </string> + <string name="InvFolder Favorites"> + I miei preferiti + </string> + <string name="InvFolder favorites"> + I miei preferiti + </string> <string name="InvFolder Current Outfit"> Abbigliamento attuale </string> @@ -1385,6 +1420,12 @@ Prova ad accedere nuovamente tra un minuto. <string name="InvFolder Meshes"> Reticoli </string> + <string name="InvFolder Received Items"> + Oggetti ricevuti + </string> + <string name="InvFolder Merchant Outbox"> + Casella venditore in uscita + </string> <string name="InvFolder Friends"> Amici </string> @@ -1394,6 +1435,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> @@ -1520,6 +1564,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> @@ -3751,6 +3801,12 @@ Se il messaggio persiste, contatta [SUPPORT_SITE]. <string name="LocationCtrlSeeAVsTooltip"> Avatar visibili e chat consentita fuori di questo lotto </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Gli oggetti che si muovono potrebbero non comportarsi correttamente in questa regione fino a quando non viene eseguito il rebake della regione. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + Il pathfinding dinamico non è attivato in questa regione. + </string> <string name="UpdaterWindowTitle"> Aggiornamento [APP_NAME] </string> @@ -3817,6 +3873,9 @@ Se il messaggio persiste, contatta [SUPPORT_SITE]. <string name="Saved_message"> (Salvato [LONG_TIMESTAMP]) </string> + <string name="IM_unblock_only_groups_friends"> + Per vedere questo messaggio, devi deselezionare 'Solo amici e gruppi possono chiamarmi o mandarmi IM' in Preferenze/Privacy. + </string> <string name="answered_call"> Risposto alla chiamata </string> @@ -3937,6 +3996,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> @@ -3990,7 +4061,7 @@ Se il messaggio persiste, contatta [SUPPORT_SITE]. </string> <string name="uploading_abuse_report"> Caricamento in corso... - + Segnala abuso </string> <string name="New Shape"> @@ -4258,7 +4329,7 @@ Segnala abuso <string name="server_is_down"> Nonostante i nostri tentativi, si è verificato un errore imprevisto. - Consulta la pagina status.secondlifegrid.net per determinare se si sia verificato un problema noto con il servizio. + Consulta la pagina status.secondlifegrid.net per determinare se si sia verificato un problema noto con il servizio. Se il problema continua, ti consigliamo di controllare le tue impostazioni di rete e della firewall. </string> <string name="dateTimeWeekdaysNames"> @@ -4347,6 +4418,12 @@ Prova a racchiudere il percorso dell'editor in doppie virgolette. <string name="ExternalEditorFailedToRun"> L'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> @@ -4717,7 +4794,10 @@ Prova a racchiudere il percorso dell'editor in doppie virgolette. Mini mappa </string> <string name="Command_Move_Label"> - Movimento + Cammina / corri / vola + </string> + <string name="Command_Outbox_Label"> + Casella in uscita del rivenditore </string> <string name="Command_People_Label"> Persone @@ -4744,10 +4824,10 @@ Prova a racchiudere il percorso dell'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 @@ -4791,6 +4871,9 @@ Prova a racchiudere il percorso dell'editor in doppie virgolette. <string name="Command_Move_Tooltip"> Movimento avatar </string> + <string name="Command_Outbox_Tooltip"> + Trasferisci elementi al tuo mercato per la vendita + </string> <string name="Command_People_Tooltip"> Amici, gruppi e persone vicine </string> @@ -4819,7 +4902,16 @@ Prova a racchiudere il percorso dell'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% @@ -4845,4 +4937,40 @@ Prova a racchiudere il percorso dell'editor in doppie virgolette. <string name="Normal"> Normale </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Nessuno + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Influenza il navmesh + </string> + <string name="Pathfinding_Object_Attr_Character"> + Personaggio + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Multiple) + </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> + <string name="TeleportMaturityExceeded"> + Il Residente non può visitare questa regione. + </string> + <string name="UserDictionary"> + [User] + </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..bd967ebcc4 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'Welcome Island. -Vai alla 'Welcome Island Public' per ripetere il tutorial. + Non puoi teleportarti nuovamente a Welcome Island. +Per ripetere l'esercitazione, visita 'Welcome Island Public'. </message> <message name="noaccess_tport"> Spiacenti, ma non hai accesso nel luogo di destinazione richiesto. @@ -43,6 +43,9 @@ Vai alla 'Welcome Island Public' per ripetere il tutorial. <message name="no_inventory_host"> L'inventario è temporaneamente inaccessibile. </message> + <message name="MustGetAgeRegion"> + Per poter entrare in questa regione devi avere almeno 18 anni. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -78,5 +81,8 @@ Vai alla 'Welcome Island Public' per ripetere il tutorial. <message name="requesting"> Avvio teletrasporto.... </message> + <message name="pending"> + Teleport in sospeso... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml index c628ade43e..6d5df75645 100644 --- a/indra/newview/skins/default/xui/ja/floater_about.xml +++ b/indra/newview/skins/default/xui/ja/floater_about.xml @@ -66,30 +66,31 @@ Qt Webkit ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š [QT_WEBKIT_VERSION] </panel> <panel label="ライセンス" 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) + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion +APR Copyright (C) 2011 The Apache Software Foundation +Collada DOM Copyright 2006 Sony Computer Entertainment Inc. +cURL Copyright (C) 1996-2010, 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). +FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. 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 +ogg/vorbis Copyright (C) 2002, Xiphophorus +OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. +PCRE Copyright (c) 1997-2012 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. +zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. 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..3b4b5ed070 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> @@ -460,12 +459,12 @@ <text name="Limit access to this parcel to:"> ã“ã®åŒºç”»ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ </text> - <check_box label="パブリックアクセスを許å¯ã™ã‚‹ [MATURITY]" name="public_access"/> + <check_box label="パブリックアクセスを許å¯ï¼ˆã“ã®ã‚ªãƒ—ションをオフã«ã™ã‚‹ã¨ç«‹å…¥ç¦æ¢ãƒ©ã‚¤ãƒ³ãŒä½œæˆã•れã¾ã™ï¼‰" name="public_access"/> <text name="Only Allow"> - 次ã®ä½äººã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ï¼š + 次ã®ä½äººã«ã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ï¼š </text> - <check_box label="æ”¯æ‰•æƒ…å ±ç™»éŒ²æ¸ˆ [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="未確èªã®ä½äººã®ç«‹å…¥ã‚’ç¦æ¢ã—ã¾ã™ã€‚"/> - <check_box label="å¹´é½¢ç¢ºèª [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="年齢確èªã‚’済ã¾ã›ã¦ã„ãªã„ä½äººã®ç«‹å…¥ã‚’ç¦æ¢ã—ã¾ã™ã€‚ 詳ã—ã„æƒ…å ±ã¯ [SUPPORT_SITE] ã‚’ã”覧下ã•ã„。"/> + <check_box label="æ”¯æ‰•æƒ…æƒ…å ±ãŒç™»éŒ²ã•れã¦ã„ã‚‹ [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="æ”¯æ‰•æƒ…å ±ãŒç™»éŒ²ã•れã¦ã„ãªã„ã¨ã€ã“ã®åŒºç”»ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。詳細ã«ã¤ã„ã¦ã¯ã€[SUPPORT_SITE] ã‚’ã”覧ãã ã•ã„。"/> + <check_box label="18 æ‰ä»¥ä¸Šã§ã™ [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="ã“ã®åŒºç”»ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ã€18 æ‰ä»¥ä¸Šã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。詳細ã«ã¤ã„ã¦ã¯ã€[SUPPORT_SITE] ã‚’ã”覧ãã ã•ã„。"/> <check_box label="グループã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ï¼š[GROUP]" name="GroupCheck" tool_tip="「一般ã€ã‚¿ãƒ–ã§ã€ã‚°ãƒ«ãƒ¼ãƒ—ã‚’é¸æŠžã—ã¦ãã ã•ã„。"/> <check_box label="å…¥å ´è¨±å¯ã‚’販売:" name="PassCheck" tool_tip="ã“ã®åŒºç”»ã¸ã®ä¸€æ™‚çš„ãªã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ã—ã¾ã™ã€‚"/> <combo_box name="pass_combo"> diff --git a/indra/newview/skins/default/xui/ja/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/ja/floater_animation_anim_preview.xml new file mode 100644 index 0000000000..2bada303ae --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_animation_anim_preview.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Anim Preview" title="ANIMATION.ANIM"> + <text name="name_label"> + åå‰ï¼š + </text> + <text name="description_label"> + 説明: + </text> + <button label="アップãƒãƒ¼ãƒ‰ï¼ˆL$[AMOUNT])" name="ok_btn"/> + <button label="å–り消ã—" label_selected="å–り消ã—" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_animation_preview.xml b/indra/newview/skins/default/xui/ja/floater_animation_bvh_preview.xml index 548d24097f..f74bab3598 100644 --- a/indra/newview/skins/default/xui/ja/floater_animation_preview.xml +++ b/indra/newview/skins/default/xui/ja/floater_animation_bvh_preview.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview" title=""> +<floater name="Animation Preview"> <floater.string name="failed_to_initialize"> - ãƒ¢ãƒ¼ã‚·ãƒ§ãƒ³ã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—㟠+ å‹•ãã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—㟠</floater.string> <floater.string name="anim_too_long"> - アニメーションファイルã®é•·ã•ã¯[LENGTH]ç§’ã§ã™ã€‚ + アニメーションファイルã®é•·ã•㯠[LENGTH] ç§’ã§ã™ã€‚ -ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®æœ€å¤§ã®é•·ã•ã¯[MAX_LENGTH]ç§’ã§ã™ã€‚ +ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®æœ€å¤§é•·ã¯ [MAX_LENGTH] ç§’ã§ã™ã€‚ </floater.string> <floater.string name="failed_file_read"> アニメーションファイルをèªã¿å–れã¾ã›ã‚“。 @@ -17,22 +17,22 @@ Ok </floater.string> <floater.string name="E_ST_EOF"> - ä¸å®Œå…¨ãªãƒ•ァイル。 + ファイルã®çµ‚端ãŒä¸å®Œå…¨ã§ã™ã€‚ </floater.string> <floater.string name="E_ST_NO_CONSTRAINT"> - 制約定義をèªã¿ã¨ã‚Œã¾ã›ã‚“。 + 制約定義をèªã¿å–れã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_FILE"> BVH ファイルを開ã‘ã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_HIER"> - 無効㪠HIERARCHY ヘッダーã§ã™ã€‚. + HIERARCHY ヘッダーãŒç„¡åйã§ã™ã€‚ </floater.string> <floater.string name="E_ST_NO_JOINT"> ROOT ã¾ãŸã¯ JOINT ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_NAME"> - JOINT ãƒãƒ¼ãƒ ã‚’å–å¾—ã§ãã¾ã›ã‚“。 + JOINT åã‚’å–å¾—ã§ãã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_OFFSET"> OFFSET ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。 @@ -53,34 +53,34 @@ フレーム数をå–å¾—ã§ãã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_FRAME_TIME"> - フレームタイムをå–å¾—ã§ãã¾ã›ã‚“。 + フレーム時間をå–å¾—ã§ãã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_POS"> - ãƒã‚¸ã‚·ãƒ§ãƒ³å€¤ã‚’å–å¾—ã§ãã¾ã›ã‚“。 + ä½ç½®ã®å€¤ã‚’å–å¾—ã§ãã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_ROT"> 回転値をå–å¾—ã§ãã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_XLT_FILE"> - ファイルを開ã‘ã¾ã›ã‚“。 + 変æ›ãƒ•ァイルを開ã‘ã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_XLT_HEADER"> - èªã¿ã¨ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 + 変æ›ãƒ˜ãƒƒãƒ€ãƒ¼ã‚’èªã¿å–れã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_XLT_NAME"> - èªã¿ã¨ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 + 変æ›åã‚’èªã¿å–れã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_XLT_IGNORE"> - èªã¿ã¨ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 + 変æ›ç„¡è¦–値をèªã¿å–れã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_XLT_RELATIVE"> - èªã¿ã¨ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 + 変æ›ç›¸å¯¾å€¤ã‚’èªã¿å–れã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_XLT_OUTNAME"> - èªã¿ã¨ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 + å¤‰æ› outname 値をèªã¿å–れã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_XLT_MATRIX"> - èªã¿ã¨ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 + 変æ›è¡Œåˆ—ã‚’èªã¿å–れã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_XLT_MERGECHILD"> Mergechild åã‚’å–å¾—ã§ãã¾ã›ã‚“。 @@ -89,10 +89,10 @@ Mergeparent åã‚’å–å¾—ã§ãã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_XLT_PRIORITY"> - プãƒãƒ‘ティ値をå–å¾—ã§ãã¾ã›ã‚“。 + priority 値をå–å¾—ã§ãã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_XLT_LOOP"> - ループ値をå–å¾—ã§ãã¾ã›ã‚“。 + loop 値をå–å¾—ã§ãã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_XLT_EASEIN"> easeln 値をå–å¾—ã§ãã¾ã›ã‚“。 @@ -104,10 +104,10 @@ Hand morph 値をå–å¾—ã§ãã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_NO_XLT_EMOTE"> - エモートåã‚’èªã¿ã¨ã‚Œã¾ã›ã‚“。 + emote åã‚’èªã¿ã¨ã‚Œã¾ã›ã‚“。 </floater.string> <floater.string name="E_ST_BAD_ROOT"> - ルートジョイントåãŒç„¡åйã§ã™ã€‚「hipã€ã‚’使用ã—ã¦ãã ã•ã„。 + ルートジョイントåãŒä¸æ£ã§ã™ã€‚「hipã€ã‚’使用ã—ã¦ãã ã•ã„。 </floater.string> <text name="name_label"> åå‰ï¼š @@ -115,14 +115,14 @@ <text name="description_label"> 説明: </text> - <spinner label="å„ªå…ˆé †ä½" name="priority" tool_tip="ã“ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ãŒã©ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’上書ãã™ã‚‹ã‹ã‚’決ã‚ã¾ã™"/> - <check_box label="ループ" name="loop_check" tool_tip="ã“ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ループå†ç”Ÿã—ã¾ã™"/> - <spinner label="イン(ï¼…)" label_width="45" left="60" name="loop_in_point" tool_tip="アニメーションã®ãƒ«ãƒ¼ãƒ—復帰点をè¨å®šã—ã¾ã™" width="100"/> - <spinner label="アウト(ï¼…)" label_width="50" left="170" name="loop_out_point" tool_tip="アニメーションã®ãƒ«ãƒ¼ãƒ—終了点をè¨å®šã—ã¾ã™" width="100"/> + <spinner label="優先度" name="priority" tool_tip="ã“ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã§ã©ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’上書ãã§ãã‚‹ã‹ã‚’決ã‚ã¾ã™"/> + <check_box label="ループ" name="loop_check" tool_tip="ã“ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ループå†ç”Ÿã«ã—ã¾ã™"/> + <spinner label="イン(%)" name="loop_in_point" tool_tip="アニメーションã®ãƒ«ãƒ¼ãƒ—復帰点をè¨å®šã—ã¾ã™"/> + <spinner label="アウト(%)" name="loop_out_point" tool_tip="アニメーションã®ãƒ«ãƒ¼ãƒ—終了点をè¨å®šã—ã¾ã™"/> <text name="hand_label"> - 手ã®å‹•ã + 手ã®ãƒãƒ¼ã‚º </text> - <combo_box label="" name="hand_pose_combo" tool_tip="アニメーションå†ç”Ÿä¸ã®æ‰‹ã®å‹•ãを決ã‚ã¾ã™"> + <combo_box name="hand_pose_combo" tool_tip="アニメーションå†ç”Ÿä¸ã®æ‰‹ã®å‹•ãを決ã‚ã¾ã™"> <combo_box.item label="広ã’ã‚‹" name="Spread"/> <combo_box.item label="リラックス" name="Relaxed"/> <combo_box.item label="指を指ã™ãƒ»ä¸¡æ‰‹" name="PointBoth"/> @@ -138,9 +138,9 @@ <combo_box.item label="ピース・å³" name="PeaceRight"/> </combo_box> <text name="emote_label"> - è¡¨ç¾ + 表情 </text> - <combo_box label="" name="emote_combo" tool_tip="アニメーションå†ç”Ÿä¸ã®é¡”ã®è¡¨æƒ…を決ã‚ã¾ã™"> + <combo_box name="emote_combo" tool_tip="アニメーションå†ç”Ÿä¸ã®é¡”ã®è¡¨æƒ…を決ã‚ã¾ã™"> <item label="(ãªã—)" name="[None]" value=""/> <item label="アーーーーー" name="Aaaaah" value="アーーーーー"/> <item label="æã‚Œã‚‹" name="Afraid" value="æã‚Œã‚‹"/> @@ -148,12 +148,12 @@ <item label="満é¢ã®ç¬‘ã¿" name="BigSmile" value="満é¢ã®ç¬‘ã¿"/> <item label="退屈" name="Bored" value="退屈"/> <item label="æ³£ã" name="Cry" value="æ³£ã"/> - <item label="侮辱" name="Disdain" value="侮辱"/> + <item label="軽蔑" name="Disdain" value="軽蔑"/> <item label="æ¥ãšã‹ã—ãŒã‚‹" name="Embarrassed" value="æ¥ãšã‹ã—ãŒã‚‹"/> <item label="ã—ã‹ã‚ã£é¢" name="Frown" value="ã—ã‹ã‚ã£é¢"/> <item label="ã‚ス" name="Kiss" value="ã‚ス"/> <item label="笑ã†" name="Laugh" value="笑ã†"/> - <item label="Plllppt" name="Plllppt" value="Plllppt"/> + <item label="ã‚€ã‹ã¤ã" name="Plllppt" value="ã‚€ã‹ã¤ã"/> <item label="嫌悪感" name="Repulsed" value="嫌悪感"/> <item label="悲ã—ã„" name="Sad" value="悲ã—ã„"/> <item label="è‚©ã‚’ã™ãã‚ã‚‹" name="Shrug" value="è‚©ã‚’ã™ãã‚ã‚‹"/> @@ -163,25 +163,24 @@ <item label="心é…ã™ã‚‹" name="Worry" value="心é…ã™ã‚‹"/> </combo_box> <text name="preview_label"> - åŒæ™‚進行行動 + プレビューä¸ã®å‹•作 </text> - <combo_box label="" name="preview_base_anim" tool_tip="ã‚¢ãƒã‚¿ãƒ¼ãŒæ™®é€šã®è¡Œå‹•ã‚’ã™ã‚‹ã¨ãã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®å‹•ãをテストã™ã‚‹ãŸã‚ã«ã“れを使ã„ã¾ã™ã€‚"> + <combo_box name="preview_base_anim" tool_tip="ã“れを使用ã—ã¦ã€ã‚¢ãƒã‚¿ãƒ¼ãŒä¸€èˆ¬çš„ãªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’実行ã—ã¦ã„ã‚‹é–“ã«ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®å‹•作をテストã—ã¾ã™ã€‚"> <item label="ç«‹ã¤" name="Standing" value="ç«‹ã¤"/> <item label="æ©ã" name="Walking" value="æ©ã"/> <item label="座る" name="Sitting" value="座る"/> <item label="飛ã¶" name="Flying" value="飛ã¶"/> </combo_box> - <spinner label="イーズイン(ç§’)" name="ease_in_time" tool_tip="アニメーションã®ãƒ–レンドイン時間(秒)"/> - <spinner label="イーズアウト(ç§’)" name="ease_out_time" tool_tip="アニメーションã®ãƒ–レンドアウト時間(秒)"/> - <button label="" name="play_btn" tool_tip="アニメーションをå†ç”Ÿã™ã‚‹"/> + <spinner label="イーズイン(秒)" name="ease_in_time" tool_tip="アニメーションã®ãƒ–レンドイン時間(秒)"/> + <spinner label="イーズアウト(秒)" name="ease_out_time" tool_tip="アニメーションã®ãƒ–レンドアウト時間(秒)"/> + <button name="play_btn" tool_tip="アニメーションをå†ç”Ÿã™ã‚‹"/> <button name="pause_btn" tool_tip="ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ä¸€æ™‚åœæ¢ã™ã‚‹"/> - <button label="" name="stop_btn" tool_tip="アニメーションã®å†ç”Ÿã‚’åœæ¢"/> - <slider label="" name="playback_slider"/> + <button name="stop_btn" tool_tip="アニメーションã®å†ç”Ÿã‚’åœæ¢ã™ã‚‹"/> <text name="bad_animation_text"> - アニメーションファイルをèªã¿è¾¼ã‚ã¾ã›ã‚“。 - - Poser 4ã‹ã‚‰ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã•れãŸBVHファイルを推奨ã—ã¾ã™ã€‚ + アニメーションファイルをèªã¿å–れã¾ã›ã‚“。 + +Poser 4 ã‹ã‚‰ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã—㟠BVH ファイルをãŠå‹§ã‚ã—ã¾ã™ã€‚ </text> - <button label="アップãƒãƒ¼ãƒ‰L$[AMOUNT]" name="ok_btn"/> + <button label="アップãƒãƒ¼ãƒ‰ï¼ˆL$[AMOUNT])" name="ok_btn"/> <button label="å–り消ã—" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/ja/floater_autoreplace.xml b/indra/newview/skins/default/xui/ja/floater_autoreplace.xml new file mode 100644 index 0000000000..21abf59160 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="自動置æ›è¨å®š"> + <check_box label="自動置æ›ã‚’有効ã«ã™ã‚‹" name="autoreplace_enable" tool_tip="ãƒãƒ£ãƒƒãƒˆãƒ†ã‚ストを入力ã™ã‚‹ã«ã¤ã‚Œã¦ã€å…¥åŠ›ã—ãŸã‚ーワードを対応ã™ã‚‹ç½®æ›ã‚ーワードã«ç½®ãæ›ãˆã¾ã™"/> + <button label="リストをインãƒãƒ¼ãƒˆ..." name="autoreplace_import_list" tool_tip="以å‰ã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã—ãŸãƒªã‚¹ãƒˆã‚’ファイルã‹ã‚‰ãƒãƒ¼ãƒ‰ã—ã¾ã™ã€‚"/> + <button label="リストをエクスãƒãƒ¼ãƒˆ..." name="autoreplace_export_list" tool_tip="é¸æŠžã—ãŸãƒªã‚¹ãƒˆã‚’ファイルã«ä¿å˜ã—ã¦ã€å…±æœ‰ã§ãるよã†ã«ã—ã¾ã™ã€‚"/> + <button label="æ–°è¦ãƒªã‚¹ãƒˆ..." name="autoreplace_new_list" tool_tip="æ–°è¦ãƒªã‚¹ãƒˆã‚’作æˆã—ã¾ã™ã€‚"/> + <button label="リストを削除" name="autoreplace_delete_list" tool_tip="é¸æŠžã—ãŸãƒªã‚¹ãƒˆã‚’削除ã—ã¾ã™ã€‚"/> + <button name="autoreplace_list_up" tool_tip="ã“ã®ãƒªã‚¹ãƒˆã®å„ªå…ˆåº¦ã‚’上ã’ã¾ã™ã€‚"/> + <button name="autoreplace_list_down" tool_tip="ã“ã®ãƒªã‚¹ãƒˆã®å„ªå…ˆåº¦ã‚’下ã’ã¾ã™ã€‚"/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="ã‚ーワード" name="keyword"/> + <scroll_list.columns label="ç½®æ›" name="replacement"/> + </scroll_list> + <button label="è¿½åŠ ..." name="autoreplace_add_entry"/> + <button label="削除" name="autoreplace_delete_entry"/> + <button label="エントリをä¿å˜" name="autoreplace_save_entry" tool_tip="ã“ã®ã‚¨ãƒ³ãƒˆãƒªã‚’ä¿å˜ã—ã¾ã™ã€‚"/> + <button label="変更をä¿å˜" name="autoreplace_save_changes" tool_tip="変更をã™ã¹ã¦ä¿å˜ã—ã¾ã™ã€‚"/> + <button label="å–り消ã—" name="autoreplace_cancel" tool_tip="変更をã™ã¹ã¦ç ´æ£„ã—ã¾ã™ã€‚"/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </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 5d3a048975..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> @@ -9,15 +9,6 @@ <floater.string name="move_tooltip"> カメラを上下左å³ã«ç§»å‹• </floater.string> - <floater.string name="camera_modes_title"> - カメラモード - </floater.string> - <floater.string name="pan_mode_title"> - 旋回 - ズーム- 水平・垂直移動 - </floater.string> - <floater.string name="presets_mode_title"> - 事å‰è¨å®šã®è¦–野 - </floater.string> <floater.string name="free_mode_title"> オブジェクトを見る </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..9f5df6fb85 100644 --- a/indra/newview/skins/default/xui/ja/floater_chat_bar.xml +++ b/indra/newview/skins/default/xui/ja/floater_chat_bar.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="chat_bar" title="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆ"> - <panel> +<floater name="nearby_chat" title="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆ"> + <panel name="bottom_panel"> <line_editor label="ã“ã“をクリックã—ã¦ãƒãƒ£ãƒƒãƒˆã‚’é–‹å§‹ã—ã¾ã™ã€‚" name="chat_box" tool_tip="Enter ã‚ーを押ã—ã¦è©±ã—ã€Ctrl + Enter ã‚ーã§å«ã³ã¾ã™ã€‚"/> - <button name="show_nearby_chat" tool_tip="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆãƒã‚°ã‚’表示・éžè¡¨ç¤º"/> + <button name="show_nearby_chat" tool_tip="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆãƒã‚°ã‚’表示ï¼éžè¡¨ç¤º"/> </panel> </floater> 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..c8b8e918e0 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"/> @@ -25,6 +25,10 @@ VBO を有効化: </text> <check_box initial_value="true" label="OpenGL Vertex Buffer Objectsを有効化" name="vbo" tool_tip="最新ã®ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã§ã“ã®è¨å®šã‚’有効ã«ã™ã‚‹ã¨ã€ãƒ‘フォーマンスãŒå‘上ã—ã¾ã™ã€‚ ã—ã‹ã—ã€æ—§åž‹ã®ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã§ã¯ VBO ã®å®Ÿè£…ãŒè²§å¼±ãªå ´åˆãŒå¤šãã€ã“ã®è¨å®šã‚’有効ã«ã™ã‚‹ã“ã¨ã§ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã«ã¤ãªãŒã‚‹ãŠãれãŒã‚りã¾ã™ã€‚"/> + <text name="tc label"> + S3TC を有効ã«ã™ã‚‹ï¼š + </text> + <check_box initial_value="true" label="テクスãƒãƒ£åœ§ç¸®ã‚’有効ã«ã™ã‚‹ï¼ˆå†èµ·å‹•ãŒå¿…è¦ï¼‰" name="texture compression" tool_tip="ビデオメモリ内ã§ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’圧縮ã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€è‰²ã®è³ªã‚’å¤šå°‘çŠ ç‰²ã«ã—ãªãŒã‚‰ã€ã‚ˆã‚Šé«˜è§£åƒåº¦ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’èªã¿è¾¼ã‚るよã†ã«ã—ã¾ã™ã€‚"/> <slider label="テクスãƒãƒ£ãƒ¡ãƒ¢ãƒªï¼ˆMB):" name="GraphicsCardTextureMemory" tool_tip="テクスãƒãƒ£ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸãƒ¡ãƒ¢ãƒªã®é‡ã€‚ ビデオカードã®ãƒ¡ãƒ¢ãƒªã«æ—¢å®šã€‚ 数値を下ã’ã‚‹ã¨ãƒ‘フォーマンスãŒå‘上ã—ã¾ã™ãŒã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®ç²¾åº¦ãŒè½ã¡ã‚‹ã“ã¨ãŒã‚りã¾ã™ã€‚"/> <spinner label="フォグã®è·é›¢æ¯”率:" name="fog"/> <button label="OK" label_selected="OK" name="OK"/> diff --git a/indra/newview/skins/default/xui/ja/floater_inventory.xml b/indra/newview/skins/default/xui/ja/floater_inventory.xml deleted file mode 100644 index b113fde94a..0000000000 --- a/indra/newview/skins/default/xui/ja/floater_inventory.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="æŒã¡ç‰©"> - <floater.string name="Title"> - æŒã¡ç‰© - </floater.string> - <floater.string name="TitleFetching"> - æŒã¡ç‰© ( [ITEM_COUNT] アイテムをå–å¾—ä¸...) [FILTER] - </floater.string> - <floater.string name="TitleCompleted"> - æŒã¡ç‰© ( [ITEM_COUNT] アイテム) [FILTER] - </floater.string> - <floater.string name="Fetched"> - å–得済 - </floater.string> - <panel label="æŒã¡ç‰©ãƒ‘ãƒãƒ«" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml index 725214086a..c01c46211e 100644 --- a/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml +++ b/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="item properties" title="æŒã¡ç‰©ã‚¢ã‚¤ãƒ†ãƒ ã®ãƒ—ãƒãƒ‘ティ"> +<floater name="item properties" title="インベントリアイテムã®ãƒ—ãƒãƒ‘ティ"> <floater.string name="unknown"> (䏿˜Žï¼‰ </floater.string> @@ -24,11 +24,11 @@ <text name="LabelCreatorTitle"> クリエーター </text> - <button label="æƒ…å ±" label_selected="" name="BtnCreator"/> + <button label="プãƒãƒ•ィール..." label_selected="" name="BtnCreator"/> <text name="LabelOwnerTitle"> オーナー: </text> - <button label="æƒ…å ±" label_selected="" name="BtnOwner"/> + <button label="プãƒãƒ•ィール..." label_selected="" name="BtnOwner"/> <text name="LabelAcquiredTitle"> 入手日時: </text> diff --git a/indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml index 47d57da031..af96edda79 100644 --- a/indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml +++ b/indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory Finder" title="最近å–å¾—ã—ãŸæŒã¡ç‰©ã‚¢ã‚¤ãƒ†ãƒ "> +<floater name="Inventory Finder" title="インベントリ最近å–å¾—ã—ãŸã‚¢ã‚¤ãƒ†ãƒ "> <check_box label="アニメーション" name="check_animation"/> <check_box label="コーリング・カード" name="check_calling_card"/> <check_box label="æœ" name="check_clothing"/> diff --git a/indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml new file mode 100644 index 0000000000..c59a3dc0ab --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_merchant_outbox" title="マーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹"> + <string name="OutboxFolderCount1"> + 1 個ã®ãƒ•ォルダ + </string> + <string name="OutboxFolderCountN"> + [NUM] 個ã®ãƒ•ォルダ + </string> + <string name="OutboxImporting"> + フォルダをé€ä¿¡ä¸... + </string> + <string name="OutboxInitializing"> + åˆæœŸåŒ–ä¸... + </string> + <panel label=""> + <panel> + <panel name="outbox_inventory_placeholder_panel"> + <text name="outbox_inventory_placeholder_title"> + ãƒãƒ¼ãƒ‰ä¸... + </text> + </panel> + </panel> + <panel> + <button label="マーケットプレイスã«é€ä¿¡" name="outbox_import_btn" tool_tip="自分ã®ãƒžãƒ¼ã‚±ãƒƒãƒˆãƒ—レイス店é ã«ç§»å‹•"/> + </panel> + </panel> +</floater> 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..942cc91317 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> @@ -89,19 +92,54 @@ <text initial_value="三角形" name="triangles" value="三角形"/> <text initial_value="é ‚ç‚¹" name="vertices" value="é ‚ç‚¹"/> <text initial_value="高" name="high_label" value="高"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="ファイルã‹ã‚‰ãƒãƒ¼ãƒ‰"/> + <item name="Generate" value="生æˆ"/> + </combo_box> <button label="å‚ç…§" name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="三角形ã®é™åº¦æ•°"/> + <item name="Error Threshold" value="エラーã—ãã„値"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="ä¸" name="medium_label" value="ä¸"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="ファイルã‹ã‚‰ãƒãƒ¼ãƒ‰"/> + <item name="Generate" value="生æˆ"/> + <item name="Use LoD above" value="上記㮠LoD を使用"/> + </combo_box> <button label="å‚ç…§" name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="三角形ã®é™åº¦æ•°"/> + <item name="Error Threshold" value="エラーã—ãã„値"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="低" name="low_label" value="低"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="ファイルã‹ã‚‰ãƒãƒ¼ãƒ‰"/> + <item name="Generate" value="生æˆ"/> + <item name="Use LoD above" value="上記㮠LoD を使用"/> + </combo_box> <button label="å‚ç…§" name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="三角形ã®é™åº¦æ•°"/> + <item name="Error Threshold" value="エラーã—ãã„値"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="最低" name="lowest_label" value="最低"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="ファイルã‹ã‚‰ãƒãƒ¼ãƒ‰"/> + <item name="Generate" value="生æˆ"/> + <item name="Use LoD above" value="上記㮠LoD を使用"/> + </combo_box> <button label="å‚ç…§" name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="三角形ã®é™åº¦æ•°"/> + <item name="Error Threshold" value="エラーã—ãã„値"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="ノーマルã®ä½œæˆ" name="gen_normals"/> diff --git a/indra/newview/skins/default/xui/ja/floater_model_wizard.xml b/indra/newview/skins/default/xui/ja/floater_model_wizard.xml deleted file mode 100644 index 915b37557f..0000000000 --- a/indra/newview/skins/default/xui/ja/floater_model_wizard.xml +++ /dev/null @@ -1,205 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Model Wizard" title="モデルウィザードをアップãƒãƒ¼ãƒ‰"> - <button label="5. アップãƒãƒ¼ãƒ‰" name="upload_btn"/> - <button label="4. 確èª" name="review_btn"/> - <button label="3. 物ç†åŠ¹æžœ" name="physics_btn"/> - <button label="2. 最é©åŒ–" name="optimize_btn"/> - <button label="1. ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž" name="choose_file_btn"/> - <panel name="choose_file_panel"> - <panel name="header_panel"> - <text name="header_text"> - ãƒ¢ãƒ‡ãƒ«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž - </text> - </panel> - <panel name="content"> - <text name="advanced_users_text"> - 上級ユーザーã®å ´åˆï¼š3D コンテンツã®åˆ¶ä½œãƒ„ãƒ¼ãƒ«ã‚’ä½¿ã„æ…£ã‚ŒãŸæ–¹ã¯ã€é«˜åº¦ãªã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ€ãƒ¼ã‚‚ãŠè©¦ã—ãã ã•ã„。 - </text> - <button label="アドãƒãƒ³ã‚¹ãƒ¢ãƒ¼ãƒ‰ã«åˆ‡ã‚Šæ›¿ãˆã‚‹" name="switch_to_advanced"/> - <text name="Cache location"> - アップãƒãƒ¼ãƒ‰ã™ã‚‹ãƒ¢ãƒ‡ãƒ«ãƒ•ァイルã®é¸æŠž - </text> - <button label="å‚ç…§" label_selected="å‚ç…§" name="browse"/> - <text name="dimensions"> - X Y Z - </text> - <text name="warning_label"> - è¦å‘Šï¼š - </text> - <text name="warning_text"> - ã“ã®ãƒ¢ãƒ‡ãƒ«ã‚’ Second Life サーãƒãƒ¼ã«ã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰ã™ã‚‹ãŸã‚ã®æœ€çµ‚æ‰‹é †ã‚’å®Ÿè¡Œã§ãã¾ã›ã‚“。[secondlife:///app/floater/learn_more ã“ã¡ã‚‰ã‚’å‚ç…§ã—ã¦]ã€ãƒ¡ãƒƒã‚·ãƒ¥ãƒ¢ãƒ‡ãƒ«ã‚’アップãƒãƒ¼ãƒ‰ã§ãるよã†ã«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’è¨å®šã—ã¦ãã ã•ã„。 - </text> - </panel> - </panel> - <panel name="optimize_panel"> - <panel name="header_panel"> - <text name="header_text"> - モデルを最é©åŒ– - </text> - </panel> - <text name="description"> - パフォーマンスをé‡è¦–ã—ã¦ãƒ¢ãƒ‡ãƒ«ã‚’最é©åŒ–ã—ã¾ã—ãŸã€‚å¿…è¦ã«å¿œã˜ã¦èª¿æ•´ã—ã¦ãã ã•ã„。 - </text> - <panel name="content"> - <text name="high_detail_text"> - æ¬¡ã®æç”»è©³ç´°åº¦ã‚’ä½œæˆï¼šé«˜ - </text> - <text name="medium_detail_text"> - æ¬¡ã®æç”»è©³ç´°åº¦ã‚’ä½œæˆï¼šä¸ - </text> - <text name="low_detail_text"> - æ¬¡ã®æç”»è©³ç´°åº¦ã‚’ä½œæˆï¼šä½Ž - </text> - <text name="lowest_detail_text"> - æ¬¡ã®æç”»è©³ç´°åº¦ã‚’ä½œæˆï¼šæœ€ä½Ž - </text> - </panel> - <panel name="content2"> - <button label="ジオメトリをå†è¨ˆç®—" name="recalculate_geometry_btn"/> - <text name="lod_label"> - ジオメトリã®ãƒ—レビュー - </text> - <combo_box name="preview_lod_combo" tool_tip="プレビュー表示㮠LOD è¨å®š"> - <combo_item name="high"> - 高ã„詳細度 - </combo_item> - <combo_item name="medium"> - ä¸ã®è©³ç´°åº¦ - </combo_item> - <combo_item name="low"> - 低ã„詳細度 - </combo_item> - <combo_item name="lowest"> - 最低ã®è©³ç´°åº¦ - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="physics_panel"> - <panel name="header_panel"> - <text name="header_text"> - 物ç†ä½œç”¨ã®èª¿æ•´ - </text> - </panel> - <text name="description"> - モデルã®å¤–æ®»æ§‹é€ ã®ã‚·ã‚§ã‚¤ãƒ—ã¯å¼Šç¤¾ãŒä½œæˆã—ã¾ã™ã€‚モデルã®ç›®çš„ã«å¿œã˜ã¦ã‚·ã‚§ã‚¤ãƒ—ã®è©³ç´°åº¦ã‚’調整ã—ã¦ãã ã•ã„。 - </text> - <panel name="content"> - <button label="ç‰©ç†æ¼”算ウェイトをå†è¨ˆç®—" name="recalculate_physics_btn"/> - <button label="å†è¨ˆç®—ä¸..." name="recalculating_physics_btn"/> - <text name="lod_label"> - 物ç†ä½œç”¨ã®ãƒ—レビュー - </text> - <combo_box name="preview_lod_combo2" tool_tip="プレビュー表示㮠LOD è¨å®š"> - <combo_item name="high"> - 高ã„詳細度 - </combo_item> - <combo_item name="medium"> - ä¸ã®è©³ç´°åº¦ - </combo_item> - <combo_item name="low"> - 低ã„詳細度 - </combo_item> - <combo_item name="lowest"> - 最低ã®è©³ç´°åº¦ - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="review_panel"> - <panel name="header_panel"> - <text name="header_text"> - ç¢ºèª - </text> - </panel> - <panel name="content"> - <text name="review_prim_equiv"> - 区画/リージョンã¸ã®è² è·ï¼š[EQUIV] プリムæ›ç®—値 - </text> - <text name="review_fee"> - L$ [FEE] ã®ã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰æ–™é‡‘ãŒã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«è«‹æ±‚ã•れã¾ã™ã€‚ - </text> - <text name="review_confirmation"> - アップãƒãƒ¼ãƒ‰ãƒœã‚¿ãƒ³ã‚’クリックã™ã‚‹ã¨ã€ãƒ¢ãƒ‡ãƒ«ã«å«ã¾ã‚Œã‚‹ãƒžãƒ†ãƒªã‚¢ãƒ«ã®æ‰€æœ‰æ¨©ã‚„使用許å¯ã‚’所æŒã™ã‚‹ã“ã¨ã‚’èªã‚ãŸã“ã¨ã«ãªã‚Šã¾ã™ã€‚ - </text> - </panel> - </panel> - <panel name="upload_panel"> - <panel name="header_panel"> - <text name="header_text"> - アップãƒãƒ¼ãƒ‰å®Œäº† - </text> - </panel> - <text name="model_uploaded_text"> - モデルãŒã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰ã•れã¾ã—ãŸã€‚ - </text> - <text name="inventory_text"> - ãã‚Œã¯æŒã¡ç‰©ã®ã€Œã‚ªãƒ–ジェクトã€ãƒ•ォルダã«ã‚りã¾ã™ã€‚ - </text> - <text name="charged_fee"> - ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã« L$ [FEE] ãŒè«‹æ±‚ã•れã¾ã—ãŸã€‚ - </text> - </panel> - <button label="<< 戻る" name="back"/> - <button label="次ã¸>>" name="next"/> - <button label="ã‚¦ã‚§ã‚¤ãƒˆã¨æ–™é‡‘ã®è¨ˆç®— >>" name="calculate"/> - <button label="計算ä¸..." name="calculating"/> - <button label="アップãƒãƒ¼ãƒ‰" name="upload" tool_tip="シミュレーターã«ã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰"/> - <button label="å–り消ã—" name="cancel"/> - <button label="é–‰ã˜ã‚‹" name="close"/> - <spinner name="import_scale" value="1.0"/> - <string name="status_idle"> - 待機状態 - </string> - <string name="status_parse_error"> - Dae ã«å•題ãŒè¦‹ã¤ã‹ã‚Šã¾ã—㟠- 詳細ã«ã¤ã„ã¦ã¯ãƒã‚°ã‚’ã”å‚ç…§ãã ã•ã„。 - </string> - <string name="status_reading_file"> - ãƒãƒ¼ãƒ‡ã‚£ãƒ³ã‚°... - </string> - <string name="status_generating_meshes"> - メッシュを作æˆä¸ - </string> - <string name="status_vertex_number_overflow"> - ã‚¨ãƒ©ãƒ¼ï¼šé ‚ç‚¹ã®æ•°ãŒ65534ã‚’è¶…éŽã—ãŸã®ã§ä¸æ¢ã•れã¾ã—ãŸã€‚ - </string> - <string name="bad_element"> - エラー:è¦ç´ ãŒç„¡åйã§ã™ - </string> - <string name="high"> - 高 - </string> - <string name="medium"> - ä¸ - </string> - <string name="low"> - 低 - </string> - <string name="lowest"> - 最低 - </string> - <string name="mesh_status_good"> - ç™ºé€ - </string> - <string name="mesh_status_na"> - 該当ãªã— - </string> - <string name="mesh_status_none"> - ãªã— - </string> - <string name="mesh_status_submesh_mismatch"> - テクスãƒãƒ£ç·¨é›†å¯èƒ½ãªé¢ã®æ•°ã¯æç”»è©³ç´°åº¦ã«å¿œã˜ã¦ç•°ãªã‚Šã¾ã™ã€‚ - </string> - <string name="mesh_status_mesh_mismatch"> - ãƒ¡ãƒƒã‚·ãƒ¥ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã®æ•°ã¯æç”»è©³ç´°åº¦ã«å¿œã˜ã¦ç•°ãªã‚Šã¾ã™ã€‚ - </string> - <string name="mesh_status_too_many_vertices"> - æç”»è©³ç´°åº¦ã«å¯¾ã—ã¦é ‚ç‚¹ã®æ•°ãŒå¤šã™ãŽã¾ã™ã€‚ - </string> - <string name="mesh_status_missing_lod"> - å¿…è¦ãªæç”»è©³ç´°åº¦ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。 - </string> - <string name="layer_all"> - 全㦠- </string> -</floater> 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_my_inventory.xml b/indra/newview/skins/default/xui/ja/floater_my_inventory.xml index c6a789b63b..d708fc3dec 100644 --- a/indra/newview/skins/default/xui/ja/floater_my_inventory.xml +++ b/indra/newview/skins/default/xui/ja/floater_my_inventory.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_my_inventory" title="æŒã¡ç‰©"/> +<floater name="floater_my_inventory" title="インベントリ"/> diff --git a/indra/newview/skins/default/xui/ja/floater_nearby_chat.xml b/indra/newview/skins/default/xui/ja/floater_nearby_chat.xml deleted file mode 100644 index bcddcc6907..0000000000 --- a/indra/newview/skins/default/xui/ja/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆ"> - <check_box label="ãƒãƒ£ãƒƒãƒˆã‚’翻訳" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_object_weights.xml b/indra/newview/skins/default/xui/ja/floater_object_weights.xml index 3bd9b6b069..d727a268fb 100644 --- a/indra/newview/skins/default/xui/ja/floater_object_weights.xml +++ b/indra/newview/skins/default/xui/ja/floater_object_weights.xml @@ -6,7 +6,7 @@ <text name="objects_label" value="オブジェクト"/> <text name="prims" value="--"/> <text name="prims_label" value="プリム"/> - <text name="weights_of_selected_text" value="é¸æŠžæ¸ˆã¿é …ç›®ã®ã‚¦ã‚¨ã‚¤ãƒˆ"/> + <text name="weights_of_selected_text" value="é¸æŠžæ¸ˆã¿ã‚¢ã‚¤ãƒ†ãƒ ã®ã‚¦ã‚¨ã‚¤ãƒˆ"/> <text name="download" value="--"/> <text name="download_label" value="ダウンãƒãƒ¼ãƒ‰"/> <text name="physics" value="--"/> diff --git a/indra/newview/skins/default/xui/ja/floater_openobject.xml b/indra/newview/skins/default/xui/ja/floater_openobject.xml index bd1b650f98..af02ffedda 100644 --- a/indra/newview/skins/default/xui/ja/floater_openobject.xml +++ b/indra/newview/skins/default/xui/ja/floater_openobject.xml @@ -3,6 +3,6 @@ <text name="object_name"> [DESC]: </text> - <button label="æŒã¡ç‰©ã«ã‚³ãƒ”ー" label_selected="æŒã¡ç‰©ã«ã‚³ãƒ”ー" name="copy_to_inventory_button"/> + <button label="インベントリã«ã‚³ãƒ”ー" label_selected="インベントリã«ã‚³ãƒ”ー" name="copy_to_inventory_button"/> <button label="コピーã—ã¦è£…ç€" label_selected="コピーã—ã¦è£…ç€" name="copy_and_wear_button"/> </floater> diff --git a/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..ada96b5b62 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="パスファインディングã‚ャラクター"> + <floater.string name="messaging_get_inprogress"> + パスファインディングã‚ャラクターを照会ä¸... + </floater.string> + <floater.string name="messaging_get_error"> + パスファインディングã‚ャラクターã®ç…§ä¼šä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ + </floater.string> + <floater.string name="messaging_complete_none_found"> + パスファインディングã‚ャラクターãŒã‚りã¾ã›ã‚“。 + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_TOTAL] ã‚ãƒ£ãƒ©ã‚¯ã‚¿ãƒ¼ä¸ [NUM_SELECTED] ã‚ャラクターãŒé¸æŠžã•れã¾ã—ãŸã€‚ + </floater.string> + <floater.string name="messaging_not_enabled"> + ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã¯ãƒ‘スファインディングã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。 + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Loading] + </floater.string> + <floater.string name="character_owner_unknown"> + [Unknown] + </floater.string> + <floater.string name="character_owner_group"> + [group] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="åå‰" name="name"/> + <scroll_list.columns label="説明" name="description"/> + <scroll_list.columns label="所有者" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="高度" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + ã‚ャラクター: + </text> + <button label="リストを更新" name="refresh_objects_list"/> + <button label="ã™ã¹ã¦é¸æŠž" name="select_all_objects"/> + <button label="ä½•ã‚‚é¸æŠžã—ãªã„" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + é¸æŠžã—ãŸã‚ャラクターã«å¯¾ã™ã‚‹ã‚¢ã‚¯ã‚·ãƒ§ãƒ³: + </text> + <check_box label="ビーコンを表示" name="show_beacon"/> + <check_box label="物ç†åŠ¹æžœã‚«ãƒ—ã‚»ãƒ«ã‚’è¡¨ç¤º" name="show_physics_capsule"/> + <button label="å–ã‚‹" name="take_objects"/> + <button label="コピーをå–ã‚‹" name="take_copy_objects"/> + <button label="ç§ã‚’ãã“ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã™ã‚‹" name="teleport_me_to_object" tool_tip="1 ã¤ã®ã‚ャラクターãŒé¸æŠžã•れãŸå ´åˆã«ã®ã¿æœ‰åйã§ã™ã€‚"/> + <button label="è¿”å´" name="return_objects"/> + <button label="削除" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml new file mode 100644 index 0000000000..ec107f3e6b --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="パスファインディングã®è¡¨ç¤º/テスト"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + パスファインディングライブラリã®å®Ÿè£…ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。 + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã¯ãƒ‘スファインディングã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。 + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + 地域(リージョン)ã®èªã¿è¾¼ã¿ã‚’待機ã—ã¦ã„ã¾ã™ã€‚ + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + ナビメッシュã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’確èªã—ã¦ã„ã¾ã™ã€‚ + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + ナビメッシュをダウンãƒãƒ¼ãƒ‰ã—ã¦ã„ã¾ã™ã€‚ + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + サーãƒãƒ¼ä¸Šã§ãƒŠãƒ“メッシュãŒå¤‰ã‚りã¾ã—ãŸã€‚最新ã®ãƒŠãƒ“メッシュをダウンãƒãƒ¼ãƒ‰ã—ã¦ã„ã¾ã™ã€‚ + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + 最新ã®ãƒŠãƒ“メッシュãŒãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã•れã¾ã—ãŸã€‚ + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + ナビメッシュをæ£ã—ãダウンãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“。 + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + ナビメッシュã«ä¿ç•™ä¸ã®å¤‰æ›´ãŒã‚りã¾ã™ã€‚ + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + ナビメッシュを作æˆã—ã¦ã„ã¾ã™ã€‚ + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + ナビメッシュã®ä¸€éƒ¨ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ä¿ç•™ä¸ã®å¤‰æ›´ãŒã‚りã¾ã™ã€‚ + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + 一部ã®ãƒŠãƒ“メッシュ地域(リージョン)を構築ã—ã¦ã„ã¾ã™ã€‚ + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + ナビメッシュã®ä¸€éƒ¨ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ä¿ç•™ä¸ã®å¤‰æ›´ãŒã‚りã€ãã®ä»–ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã¯æ§‹ç¯‰ä¸ã§ã™ã€‚ + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + ãƒŠãƒ“ãƒ¡ãƒƒã‚·ãƒ¥ã¯æœ€æ–°ã§ã™ã€‚ + </floater.string> + <floater.string name="pathing_library_not_implemented"> + パスファインディングライブラリã®å®Ÿè£…ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。 + </floater.string> + <floater.string name="pathing_region_not_enabled"> + ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã¯ãƒ‘スファインディングã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。 + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + 開始点ã¨çµ‚äº†ç‚¹ã‚’é¸æŠžã—ã¦ãã ã•ã„。 + </floater.string> + <floater.string name="pathing_choose_start_point"> + é–‹å§‹ç‚¹ã‚’é¸æŠžã—ã¦ãã ã•ã„。 + </floater.string> + <floater.string name="pathing_choose_end_point"> + çµ‚äº†ç‚¹ã‚’é¸æŠžã—ã¦ãã ã•ã„。 + </floater.string> + <floater.string name="pathing_path_valid"> + パスã¯ã‚ªãƒ¬ãƒ³ã‚¸è‰²ã§è¡¨ç¤ºã•れã¦ã„ã¾ã™ã€‚ + </floater.string> + <floater.string name="pathing_path_invalid"> + é¸æŠžã—㟠2 点間ã®ãƒ‘スãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。 + </floater.string> + <floater.string name="pathing_error"> + パスã®ç”Ÿæˆä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="表示" name="view_panel"> + <text name="show_label"> + 表示: + </text> + <check_box label="世界" name="show_world"/> + <check_box label="å¯å‹•物ã®ã¿" name="show_world_movables_only"/> + <check_box label="ナビメッシュ" name="show_navmesh"/> + <text name="show_walkability_label"> + æ©è¡Œå¯èƒ½ãƒžãƒƒãƒ—を表示: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="表示ã—ãªã„" name="show_heatmap_mode_none"/> + <combo_box.item label="ã‚ャラクター タイプ A" name="show_heatmap_mode_a"/> + <combo_box.item label="ã‚ャラクター タイプ B" name="show_heatmap_mode_b"/> + <combo_box.item label="ã‚ャラクター タイプ C" name="show_heatmap_mode_c"/> + <combo_box.item label="ã‚ャラクター タイプ D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="æ©è¡Œå¯èƒ½" name="show_walkables"/> + <check_box label="ç´ æãƒœãƒªãƒ¥ãƒ¼ãƒ " name="show_material_volumes"/> + <check_box label="é™çš„障害物" name="show_static_obstacles"/> + <check_box label="除外ボリューム" name="show_exclusion_volumes"/> + <check_box label="水上飛行機" name="show_water_plane"/> + <check_box label="X 線表示ã«ã‚ˆã‚‹" name="show_xray"/> + </panel> + <panel label="パスをテスト" name="test_panel"> + <text name="ctrl_click_label"> + Ctrl ã‚ーを押ã—ãªãŒã‚‰ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€é–‹å§‹ç‚¹ã‚’é¸æŠžã—ã¾ã™ã€‚ + </text> + <text name="shift_click_label"> + Shift ã‚ーを押ã—ãªãŒã‚‰ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€çµ‚äº†ç‚¹ã‚’é¸æŠžã—ã¾ã™ã€‚ + </text> + <text name="character_width_label"> + ã‚ャラクターã®å¹… + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + ã‚ャラクタータイプ + </text> + <combo_box name="path_character_type"> + <combo_box.item label="ãªã—" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="パスをクリア" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..4441d5e738 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="パスファインディングリンクセット"> + <floater.string name="messaging_get_inprogress"> + パスファインディングリンクセットを照会ä¸... + </floater.string> + <floater.string name="messaging_get_error"> + パスファインディングリンクセットã®ç…§ä¼šä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ + </floater.string> + <floater.string name="messaging_set_inprogress"> + é¸æŠžã—ãŸãƒ‘スファインディングリンクセットを修æ£ä¸... + </floater.string> + <floater.string name="messaging_set_error"> + é¸æŠžã—ãŸãƒ‘スファインディングリンクセットã®ä¿®æ£ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ + </floater.string> + <floater.string name="messaging_complete_none_found"> + パスファインディングリンクセットãŒã‚りã¾ã›ã‚“。 + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_TOTAL] ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆä¸ [NUM_SELECTED] リンクセットãŒé¸æŠžã•れã¾ã—ãŸã€‚ + </floater.string> + <floater.string name="messaging_not_enabled"> + ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã¯ãƒ‘スファインディングã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。 + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terrain] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Loading] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Unknown] + </floater.string> + <floater.string name="linkset_owner_group"> + [group] + </floater.string> + <floater.string name="linkset_is_scripted"> + ã¯ã„ + </floater.string> + <floater.string name="linkset_is_not_scripted"> + ã„ã„㈠+ </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + 䏿˜Ž + </floater.string> + <floater.string name="linkset_use_walkable"> + æ©è¡Œå¯èƒ½ + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + é™çš„障害物 + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + å¯å‹•障害物 + </floater.string> + <floater.string name="linkset_use_material_volume"> + ç´ æãƒœãƒªãƒ¥ãƒ¼ãƒ + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + 除外ボリューム+ </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + å¯å‹•ボリューム+ </floater.string> + <floater.string name="linkset_is_terrain"> + [unmodifiable] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [restricted] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [concave] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [restricted,concave] + </floater.string> + <floater.string name="linkset_choose_use"> + リンクセットã®ç”¨é€”ã‚’é¸æŠž... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="リンクセットã®ç”¨é€”ã§ãƒ•ィルター..." name="filter_by_linkset_use_none"/> + <combo_box.item label="æ©è¡Œå¯èƒ½" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="é™çš„障害物" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="å¯å‹•障害物" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="ç´ æãƒœãƒªãƒ¥ãƒ¼ãƒ " name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="除外ボリューム" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="å¯å‹•ボリューム" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="é©ç”¨" name="apply_filters"/> + <button label="クリア" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="åå‰ï¼ˆãƒ«ãƒ¼ãƒˆãƒ—リム)" name="name"/> + <scroll_list.columns label="説明(ルートプリム)" name="description"/> + <scroll_list.columns label="所有者" name="owner"/> + <scroll_list.columns label="スクリプト" name="scripted"/> + <scroll_list.columns label="è² è·" name="land_impact"/> + <scroll_list.columns label="è·é›¢" name="dist_from_you"/> + <scroll_list.columns label="リンクセットã®ç”¨é€”" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + リンクセット: + </text> + <button label="リスト更新" name="refresh_objects_list"/> + <button label="ã™ã¹ã¦é¸æŠž" name="select_all_objects"/> + <button label="ä½•ã‚‚é¸æŠžã—ãªã„" name="select_none_objects"/> + </panel> + <panel> + <check_box label="ビーコンを表示" name="show_beacon"/> + <button label="å–ã‚‹" name="take_objects"/> + <button label="コピーをå–ã‚‹" name="take_copy_objects"/> + <button label="ç§ã‚’ãã“ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã™ã‚‹" name="teleport_me_to_object"/> + <button label="è¿”å´" name="return_objects"/> + <button label="削除" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + æ©è¡Œå¯èƒ½æ€§: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="タイプ A ã®ã‚ãƒ£ãƒ©ã‚¯ã‚¿ãƒ¼ã®æ©è¡Œå¯èƒ½æ€§ã€‚ã‚ャラクタータイプã®ä¾‹ã¯ãƒ’ューマノイドã§ã™ã€‚"/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="タイプ B ã®ã‚ãƒ£ãƒ©ã‚¯ã‚¿ãƒ¼ã®æ©è¡Œå¯èƒ½æ€§ã€‚ã‚ャラクタータイプã®ä¾‹ã¯ã‚¯ãƒªãƒ¼ãƒãƒ£ãƒ¼ã§ã™ã€‚"/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="タイプ C ã®ã‚ãƒ£ãƒ©ã‚¯ã‚¿ãƒ¼ã®æ©è¡Œå¯èƒ½æ€§ã€‚ã‚ャラクタータイプã®ä¾‹ã¯ãƒ¡ã‚«ãƒ‹ã‚«ãƒ«ã§ã™ã€‚"/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="タイプ D ã®ã‚ãƒ£ãƒ©ã‚¯ã‚¿ãƒ¼ã®æ©è¡Œå¯èƒ½æ€§ã€‚ã‚ャラクタータイプã®ä¾‹ã¯ãã®ä»–ã§ã™ã€‚"/> + <button label="変更をé©ç”¨" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (ヒューマノイド) + </text> + <text name="suggested_use_b_label"> + (クリーãƒãƒ£ãƒ¼) + </text> + <text name="suggested_use_c_label"> + (メカニカル) + </text> + <text name="suggested_use_d_label"> + (ãã®ä»–) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_people.xml b/indra/newview/skins/default/xui/ja/floater_people.xml index 08bee88103..b180658ab7 100644 --- a/indra/newview/skins/default/xui/ja/floater_people.xml +++ b/indra/newview/skins/default/xui/ja/floater_people.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="floater_people" title="人"> <panel_container name="main_panel"> - <panel label="ã‚°ãƒ«ãƒ¼ãƒ—æƒ…å ±" name="panel_group_info_sidetray"/> + <panel label="グループプãƒãƒ•ィール" name="panel_group_info_sidetray"/> <panel label="ブãƒãƒƒã‚¯ã•れãŸä½äººã¨ã‚ªãƒ–ジェクト" name="panel_block_list_sidetray"/> </panel_container> </floater> diff --git a/indra/newview/skins/default/xui/ja/floater_postcard.xml b/indra/newview/skins/default/xui/ja/floater_postcard.xml deleted file mode 100644 index 9d9b59fa51..0000000000 --- a/indra/newview/skins/default/xui/ja/floater_postcard.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="スナップショットをEメールã§é€ä¿¡"> - <text name="to_label"> - å—ä¿¡å…ˆã®Eメール: - </text> - <line_editor left="145" name="to_form" width="125"/> - <text name="from_label"> - ã‚ãªãŸã®Eメール: - </text> - <line_editor left="145" name="from_form" width="125"/> - <text name="name_label"> - ã‚ãªãŸã®åå‰ï¼š - </text> - <line_editor left="145" name="name_form" width="125"/> - <text name="subject_label"> - ä»¶å: - </text> - <line_editor label="ä»¶åを入力ã—ã¦ãã ã•ã„" left="145" name="subject_form" width="125"/> - <text name="msg_label"> - メッセージ: - </text> - <text_editor bottom_delta="-120" height="110" name="msg_form"> - メッセージをã“ã“ã«å…¥åŠ›ã—ã¦ãã ã•ã„。 - </text_editor> - <check_box label="Web上ã§å…¬é–‹" name="allow_publish_check" tool_tip="ã“ã®ãƒã‚¹ãƒˆã‚«ãƒ¼ãƒ‰ã‚’Web上ã§å…¬é–‹ã—ã¾ã™ã€‚"/> - <check_box label="æˆäººå‘ã‘コンテンツ" name="mature_check" tool_tip="ã“ã®ãƒã‚¹ãƒˆã‚«ãƒ¼ãƒ‰ã«ã¯æˆäººå‘ã‘内容ãŒå«ã¾ã‚Œã¾ã™ã€‚"/> - <button label="?" left="300" name="publish_help_btn"/> - <text name="fine_print"> - ã“ã®å—信者ãŒSLã«å‚åŠ ã™ã‚‹ã¨ã€ã‚ãªãŸã«ç´¹ä»‹ãƒœãƒ¼ãƒŠã‚¹ãŒå…¥ã‚Šã¾ã™ - </text> - <button bottom_delta="-52" label="å–り消ã—" name="cancel_btn"/> - <button label="é€ä¿¡" name="send_btn"/> - <text name="default_subject"> - [SECOND_LIFE] ã‹ã‚‰ã®ãƒã‚¹ãƒˆã‚«ãƒ¼ãƒ‰ã§ã™ã€‚ - </text> - <text name="default_message"> - ã“れã¯çµ¶å¯¾ãƒã‚§ãƒƒã‚¯ï¼ - </text> - <string name="upload_message"> - é€ä¿¡ä¸... - </string> -</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_preview_animation.xml b/indra/newview/skins/default/xui/ja/floater_preview_animation.xml index 4fc59e16d3..a3042f66ea 100644 --- a/indra/newview/skins/default/xui/ja/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/ja/floater_preview_animation.xml @@ -6,6 +6,6 @@ <text name="desc txt"> 説明: </text> - <button label="インワールドã§å†ç”Ÿ" label_selected="åœæ¢" name="Anim play btn" tool_tip="他人ã«ã‚‚見ãˆã‚‹ã‚ˆã†ã«å†ç”Ÿã—ã¾ã™"/> - <button label="ãƒãƒ¼ã‚«ãƒ«å†ç”Ÿ" label_selected="åœæ¢" name="Anim audition btn" tool_tip="自分ã ã‘ãŒè¦‹ãˆã‚‹ã‚ˆã†ã«å†ç”Ÿã—ã¾ã™"/> + <button label="インワールドã§å†ç”Ÿ" label_selected="åœæ¢" name="Inworld" tool_tip="他人ã«è¦‹ãˆã‚‹ã‚ˆã†ã«å†ç”Ÿ"/> + <button label="ãƒãƒ¼ã‚«ãƒ«å†ç”Ÿ" label_selected="åœæ¢" name="Locally" tool_tip="自分ã ã‘ãŒè¦‹ãˆã‚‹ã‚ˆã†ã«å†ç”Ÿ"/> </floater> diff --git a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml index 6ea1d79cfc..4617fd1d92 100644 --- a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml @@ -4,7 +4,7 @@ テクスãƒãƒ£ï¼š [NAME] </floater.string> <floater.string name="Copy"> - æŒã¡ç‰©ã«ã‚³ãƒ”ー + インベントリã«ã‚³ãƒ”ー </floater.string> <text name="desc txt"> 説明: diff --git a/indra/newview/skins/default/xui/ja/floater_snapshot.xml b/indra/newview/skins/default/xui/ja/floater_snapshot.xml index 05a10f9f6d..f145a2e8b8 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_spellcheck.xml b/indra/newview/skins/default/xui/ja/floater_spellcheck.xml new file mode 100644 index 0000000000..31fbef9bcf --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="スペルãƒã‚§ãƒƒã‚«ãƒ¼ã®è¨å®š"> + <check_box label="スペルãƒã‚§ãƒƒã‚«ãƒ¼ã‚’有効ã«ã™ã‚‹" name="spellcheck_enable"/> + <text name="spellcheck_main"> + メイン辞書: + </text> + <text label="ãƒã‚°ï¼š" name="spellcheck_additional"> + ãã®ä»–ã®è¾žæ›¸ï¼š + </text> + <text name="spellcheck_available"> + å…¥æ‰‹å¯ + </text> + <text name="spellcheck_active"> + 有効 + </text> + <button label="削除" name="spellcheck_remove_btn"/> + <button label="インãƒãƒ¼ãƒˆ..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/ja/floater_spellcheck_import.xml new file mode 100644 index 0000000000..febe153d25 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="辞書をインãƒãƒ¼ãƒˆ"> + <button label="å‚ç…§" label_selected="å‚ç…§" name="dictionary_path_browse"/> + <button label="インãƒãƒ¼ãƒˆ" name="ok_btn"/> + <button label="å–り消ã—" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_stats.xml b/indra/newview/skins/default/xui/ja/floater_stats.xml index 6a1f34cfd8..1922e4841a 100644 --- a/indra/newview/skins/default/xui/ja/floater_stats.xml +++ b/indra/newview/skins/default/xui/ja/floater_stats.xml @@ -14,8 +14,11 @@ <stat_bar label="ç§’ã”ã¨ã® KTris æç”»" name="ktrissec"/> <stat_bar label="オブジェクトåˆè¨ˆ" name="objs"/> <stat_bar label="æ–°è¦ã‚ªãƒ–ジェクト" name="newobjs"/> + <stat_bar label="オブジェクトã‚ャッシュヒット率" name="object_cache_hits"/> </stat_view> <stat_view label="テクスãƒãƒ£" name="texture"> + <stat_bar label="ã‚ャッシュヒット率" name="texture_cache_hits"/> + <stat_bar label="ã‚ャッシュèªã¿å–りé…å»¶" name="texture_cache_read_latency"/> <stat_bar label="カウント" name="numimagesstat"/> <stat_bar label="Raw カウント" name="numrawimagesstat"/> <stat_bar label="GL メモリ" name="gltexmemstat"/> @@ -50,7 +53,13 @@ <stat_bar label="オブジェクト" name="simobjects"/> <stat_bar label="アクティブãªã‚ªãƒ–ジェクト" name="simactiveobjects"/> <stat_bar label="アクティブãªã‚¹ã‚¯ãƒªãƒ—ト" name="simactivescripts"/> + <stat_bar label="スクリプト実行" name="simpctscriptsrun"/> <stat_bar label="スクリプトイベント" name="simscripteps"/> + <stat_view label="パスファインディング" name="simpathfinding"> + <stat_bar label="AIステップ時間" name="simsimaistepmsec"/> + <stat_bar label="スã‚ップã•れãŸã‚·ãƒ«ã‚¨ãƒƒãƒˆã‚¹ãƒ†ãƒƒãƒ—" name="simsimskippedsilhouettesteps"/> + <stat_bar label="æ›´æ–°ã•れãŸã‚ャラクター" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_bar label="パケットイン" name="siminpps"/> <stat_bar label="パケットアウト" name="simoutpps"/> <stat_bar label="ä¿ç•™ä¸ã®ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰" name="simpendingdownloads"/> diff --git a/indra/newview/skins/default/xui/ja/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/ja/floater_test_layout_stacks.xml new file mode 100644 index 0000000000..31b5bbd3bf --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_test_layout_stacks.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="レイアウトスタックテスト"/> diff --git a/indra/newview/skins/default/xui/ja/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/ja/floater_test_text_vertical_aligment.xml new file mode 100644 index 0000000000..40fd8e9f93 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_test_text_vertical_aligment.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="テスト用ウィンドウ"/> diff --git a/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml index 399cffcce5..3773812bb6 100644 --- a/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml @@ -1,24 +1,36 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="texture picker" title="テクスãƒãƒ£ã®é¸æŠž"> - <string name="choose_picture"> + <floater.string name="choose_picture"> クリックã—ã¦å†™çœŸã‚’é¸æŠž - </string> + </floater.string> + <floater.string name="pick title"> + ピック: + </floater.string> <text name="Multiple"> 複数ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ </text> + <radio_group name="mode_selection"> + <radio_item label="インベントリ" name="inventory" value="0"/> + <radio_item label="ãƒãƒ¼ã‚«ãƒ«" name="local" value="1"/> + </radio_group> <text name="unknown"> サイズ: [DIMENSIONS] </text> <button label="デフォルト" label_selected="デフォルト" name="Default"/> - <button label="ãªã—" label_selected="ãªã—" name="None"/> <button label="ブランク" label_selected="ブランク" name="Blank"/> - <check_box label="フォルダを表示" name="show_folders_check"/> - <search_editor label="テクスãƒãƒ£ã‚’フィルター" name="inventory search editor"/> - <check_box label="ã™ãé©ç”¨" name="apply_immediate_check"/> + <button label="ãªã—" label_selected="ãªã—" name="None"/> <button label="" label_selected="" name="Pipette"/> - <button label="å–り消ã—" label_selected="å–り消ã—" name="Cancel"/> + <check_box initial_value="true" label="ライブプレビュー" name="apply_immediate_check"/> + <text name="preview_disabled" value="プレビュー無効"/> + <filter_editor label="テクスãƒãƒ£ã‚’フィルター" name="inventory search editor"/> + <check_box initial_value="false" label="フォルダを表示" name="show_folders_check"/> + <button label="è¿½åŠ " label_selected="è¿½åŠ " name="l_add_btn"/> + <button label="削除" label_selected="削除" name="l_rem_btn"/> + <button label="アップãƒãƒ¼ãƒ‰" label_selected="アップãƒãƒ¼ãƒ‰" name="l_upl_btn"/> + <scroll_list name="l_name_list"> + <column label="åå‰" name="unit_name"/> + <column label="ID" name="unit_id_HIDDEN"/> + </scroll_list> <button label="OK" label_selected="OK" name="Select"/> - <text name="pick title"> - ピック: - </text> + <button label="å–り消ã—" label_selected="å–り消ã—" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/ja/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/ja/floater_texture_fetch_debugger.xml new file mode 100644 index 0000000000..adc35137b5 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_texture_fetch_debugger.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="TexFetchDebugger" title="テクスãƒãƒ£å–得デãƒãƒƒã‚¬"> + <text name="total_num_fetched_label"> + 1, å–å¾—ã—ãŸãƒ†ã‚¯ã‚¹ãƒãƒ£ã®åˆè¨ˆæ•°ï¼š[NUM] + </text> + <text name="total_num_fetching_requests_label"> + 2, å–得リクエストã®åˆè¨ˆæ•°ï¼š[NUM] + </text> + <text name="total_num_cache_hits_label"> + 3, ã‚ャッシュヒットã®åˆè¨ˆæ•°ï¼š[NUM] + </text> + <text name="total_num_visible_tex_label"> + 4, 表示テクスãƒãƒ£ã®åˆè¨ˆæ•°ï¼š[NUM] + </text> + <text name="total_num_visible_tex_fetch_req_label"> + 5, 表示テクスãƒãƒ£å–得リクエストã®åˆè¨ˆæ•°ï¼š[NUM] + </text> + <text name="total_fetched_data_label"> + 6, å–å¾—ã—ãŸãƒ‡ãƒ¼ã‚¿ã®åˆè¨ˆæ•°ï¼š[SIZE1]KBã€ãƒ‡ã‚³ãƒ¼ãƒ‰ã•れãŸãƒ‡ãƒ¼ã‚¿ï¼š[SIZE2]KBã€[PIXEL]メガピクセル + </text> + <text name="total_fetched_vis_data_label"> + 7, 表示データã®åˆè¨ˆæ•°ï¼š[SIZE1]KBã€ãƒ‡ã‚³ãƒ¼ãƒ‰ã•れãŸãƒ‡ãƒ¼ã‚¿ï¼š[SIZE2]KB + </text> + <text name="total_fetched_rendered_data_label"> + 8, レンダリングã•れãŸãƒ‡ãƒ¼ã‚¿ã®åˆè¨ˆæ•°ï¼š[SIZE1]KBã€ãƒ‡ã‚³ãƒ¼ãƒ‰ã•れãŸãƒ‡ãƒ¼ã‚¿ï¼š[SIZE2]KBã€[PIXEL]メガピクセル + </text> + <text name="total_time_cache_read_label"> + 9, ã‚ャッシュèªã¿å–りã®åˆè¨ˆæ™‚間:[TIME] ç§’ + </text> + <text name="total_time_cache_write_label"> + 10, ã‚ャッシュ書ãè¾¼ã¿ã®åˆè¨ˆæ™‚間:[TIME] ç§’ + </text> + <text name="total_time_decode_label"> + 11, デコードã®åˆè¨ˆæ™‚間:[TIME] ç§’ + </text> + <text name="total_time_gl_label"> + 12, glテクスãƒãƒ£ä½œæˆã®åˆè¨ˆæ™‚間:[TIME] ç§’ + </text> + <text name="total_time_http_label"> + 13, HTTP å–å¾—ã®åˆè¨ˆæ™‚間:[TIME] ç§’ + </text> + <text name="total_time_fetch_label"> + 14, å–得全体ã®åˆè¨ˆæ™‚間:[TIME] ç§’ + </text> + <text name="total_time_refetch_vis_cache_label"> + 15, ã‚ャッシュã‹ã‚‰è¡¨ç¤ºãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’å†å–å¾—ã€æ™‚間:[TIME] ç§’ã€å–得:[SIZE]KBã€[PIXEL]メガピクセル + </text> + <text name="total_time_refetch_all_cache_label"> + 16ã€ã‚ャッシュã‹ã‚‰ã™ã¹ã¦ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’å†ãƒ•ェッãƒä¸ã€æ™‚é–“: [TIME] ç§’ã€ãƒ•ã‚§ãƒƒãƒæ¸ˆã¿: [SIZE]KBã€[PIXEL]メガピクセル + </text> + <text name="total_time_refetch_vis_http_label"> + 17ã€HTTP ã‹ã‚‰å¯è¦–ファイルをå†ãƒ•ェッãƒä¸ã€æ™‚é–“: [TIME] ç§’ã€ãƒ•ã‚§ãƒƒãƒæ¸ˆã¿: [SIZE]KBã€[PIXEL]メガピクセル + </text> + <text name="total_time_refetch_all_http_label"> + 18ã€HTTP ã‹ã‚‰ã™ã¹ã¦ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’å†ãƒ•ェッãƒä¸ã€æ™‚é–“: [TIME] ç§’ã€ãƒ•ã‚§ãƒƒãƒæ¸ˆã¿: [SIZE]KBã€[PIXEL]メガピクセル + </text> + <spinner label="19ã€ãƒ†ã‚»ãƒ«/ピクセル比:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ ソース: + </text> + <radio_group name="texture_source"> + <radio_item label="ã‚ャッシュ + HTTP" name="0"/> + <radio_item label="HTTP ã®ã¿" name="1"/> + </radio_group> + <button label="é–‹å§‹" name="start_btn"/> + <button label="リセット" name="clear_btn"/> + <button label="é–‰ã˜ã‚‹" name="close_btn"/> + <button label="ã‚ャッシュèªã¿å–り" name="cacheread_btn"/> + <button label="ã‚ャッシュ書ãè¾¼ã¿" name="cachewrite_btn"/> + <button label="HTTP" name="http_btn"/> + <button label="デコード" name="decode_btn"/> + <button label="GL テクスãƒãƒ£" name="gl_btn"/> + <button label="ã‚ャッシュ表示テクスãƒãƒ£å†å–å¾—" name="refetchviscache_btn"/> + <button label="ã™ã¹ã¦ã®ã‚ャッシュをå†ãƒ•ェッãƒ" name="refetchallcache_btn"/> + <button label="HTTP表示テクスãƒãƒ£å†å–å¾—" name="refetchvishttp_btn"/> + <button label="ã™ã¹ã¦ã® HTTP ã‚’å†ãƒ•ェッãƒ" name="refetchallhttp_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_tools.xml b/indra/newview/skins/default/xui/ja/floater_tools.xml index 8eddf55a44..4bd6439ad2 100644 --- a/indra/newview/skins/default/xui/ja/floater_tools.xml +++ b/indra/newview/skins/default/xui/ja/floater_tools.xml @@ -1,5 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="toolbox floater" short_title="制作ツール" title=""> + <floater.string name="grid_screen_text"> + ç”»é¢ + </floater.string> + <floater.string name="grid_local_text"> + ãƒãƒ¼ã‚«ãƒ« + </floater.string> + <floater.string name="grid_world_text"> + 世界 + </floater.string> + <floater.string name="grid_reference_text"> + リファレンス + </floater.string> + <floater.string name="grid_attachment_text"> + アタッãƒãƒ¡ãƒ³ãƒˆ + </floater.string> <floater.string name="status_rotate"> 色ã®ä»˜ã„ãŸãƒãƒ³ãƒ‰ã‚’ドラッグã—ã¦ã‚ªãƒ–ジェクトを回転 </floater.string> @@ -63,7 +78,12 @@ </text> <check_box initial_value="true" label="テクスãƒãƒ£ã‚’引ãå»¶ã°ã™" name="checkbox stretch textures"/> <check_box initial_value="true" label="スナップ" name="checkbox snap to grid"/> - <button label="オプション..." label_selected="オプション" name="Options..." tool_tip="グリッドオプションを表示ã—ã¾ã™"/> + <combo_box name="combobox grid mode" tool_tip="オブジェクトã®é…ç½®ã«ä½¿ã†ã‚°ãƒªãƒƒãƒ‰ãƒ«ãƒ¼ãƒ©ã®ç¨®é¡žã‚’é¸æŠž"> + <combo_box.item label="世界" name="World"/> + <combo_box.item label="ãƒãƒ¼ã‚«ãƒ«" name="Local"/> + <combo_box.item label="リファレンス" name="Reference"/> + </combo_box> + <button label="" label_selected="オプション" name="Options..." tool_tip="グリッドオプションを表示ã—ã¾ã™"/> <button label="" label_selected="" name="ToolCube" tool_tip="ã‚ューブ"/> <button label="" label_selected="" name="ToolPrism" tool_tip="プリズム"/> <button label="" label_selected="" name="ToolPyramid" tool_tip="ピラミッド"/> @@ -128,6 +148,12 @@ <panel.string name="text modify info 4"> ã“れらã®ã‚ªãƒ–ジェクトを修æ£ã§ãã¾ã›ã‚“ </panel.string> + <panel.string name="text modify info 5"> + 地域(リージョン)ã®å¢ƒç•Œã‚’è¶Šãˆã¦ã“ã®ã‚ªãƒ–ジェクトを修æ£ã§ãã¾ã›ã‚“ + </panel.string> + <panel.string name="text modify info 6"> + 地域(リージョン)ã®å¢ƒç•Œã‚’è¶Šãˆã¦ã“れらã®ã‚ªãƒ–ジェクトを修æ£ã§ãã¾ã›ã‚“ + </panel.string> <panel.string name="text modify warning"> ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆå…¨ä½“ã‚’é¸æŠžã—ã¦æ¨©é™ã®è¨å®šã‚’行ã£ã¦ãã ã•ã„。 </panel.string> @@ -183,12 +209,12 @@ <combo_box.item label="ズームã™ã‚‹" name="Zoom"/> </combo_box> <check_box label="販売対象:" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="コピー" name="Copy"/> <combo_box.item label="ä¸èº«" name="Contents"/> <combo_box.item label="オリジナル" name="Original"/> </combo_box> - <spinner label="ä¾¡æ ¼ï¼š L$" name="Edit Cost"/> <check_box label="検索ã«è¡¨ç¤º" name="search_check" tool_tip="æ¤œç´¢çµæžœã«ã“ã®ã‚ªãƒ–ジェクトを表示ã—ã¾ã™"/> <panel name="perms_build"> <text name="perm_modify"> @@ -224,6 +250,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + パスファインディング属性: + </text> + </panel> </panel> <panel label="形状" name="Object"> <check_box label="ãƒãƒƒã‚¯" name="checkbox locked" tool_tip="オブジェクトã®ç§»å‹•ã¨å‰Šé™¤ã‚’ç¦æ¢ã—ã¾ã™ã€‚ ã“ã®æ©Ÿèƒ½ã‚’使ã†ã¨ã€åˆ¶ä½œä¸ã®æ„図ã›ã¬ç·¨é›†ã‚’防ãã“ã¨ãŒã§ãã¾ã™"/> diff --git a/indra/newview/skins/default/xui/ja/floater_top_objects.xml b/indra/newview/skins/default/xui/ja/floater_top_objects.xml index bfc93e5624..c44f409d4e 100644 --- a/indra/newview/skins/default/xui/ja/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/ja/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> 時間 </floater.string> - <floater.string name="scripts_mono_time_label"> - Monoタイム- </floater.string> <floater.string name="top_colliders_title"> 上部コライダー </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="åå‰" name="name"/> <scroll_list.columns label="所有者" name="owner"/> <scroll_list.columns label="ãƒã‚±ãƒ¼ã‚·ãƒ§ãƒ³" name="location"/> + <scroll_list.columns label="区画" name="parcel"/> <scroll_list.columns label="時間" name="time"/> - <scroll_list.columns label="Monoタイム" name="mono_time"/> <scroll_list.columns label="URL" name="URLs"/> + <scroll_list.columns label="メモリ(KB)" name="memory"/> </scroll_list> <text name="id_text"> 物体ID: @@ -48,6 +46,10 @@ 所有者: </text> <button label="フィルタ" name="filter_owner_btn"/> + <text name="parcel_name_text"> + 区画: + </text> + <button label="フィルター" name="filter_parcel_btn"/> <button label="æ›´æ–°" name="refresh_btn"/> <button label="é¸æŠžå†…å®¹ã‚’è¿”å´" name="return_selected_btn"/> <button label="ã™ã¹ã¦è¿”å´" name="return_all_btn"/> 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/floater_voice_effect.xml b/indra/newview/skins/default/xui/ja/floater_voice_effect.xml index 801b7a9db0..ee675e143b 100644 --- a/indra/newview/skins/default/xui/ja/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/ja/floater_voice_effect.xml @@ -42,13 +42,16 @@ <string name="effect_Demon"> デーモン </string> + <string name="effect_Female Elf"> + 女性ã®ã‚¨ãƒ«ãƒ• + </string> <string name="effect_Flirty"> æ°—ã®ã‚りãã†ãª </string> <string name="effect_Foxy"> é…æƒ‘çš„ </string> - <string name="effect_Halloween_2010_Bonus"> + <string name="effect_Halloween 2010 Bonus"> ãƒãƒã‚¦ã‚£ãƒ³_2010_ボーナス </string> <string name="effect_Helium"> @@ -57,9 +60,18 @@ <string name="effect_Husky"> ãƒã‚¹ã‚ー </string> + <string name="effect_Husky Whisper"> + スモーã‚ーウィスパー + </string> <string name="effect_Intercom"> インターホン </string> + <string name="effect_Julia"> + ジュリア + </string> + <string name="effect_Lo Lilt"> + 軽快 + </string> <string name="effect_Macho"> マッãƒãƒ§ </string> @@ -69,6 +81,9 @@ <string name="effect_Mini"> ミニ </string> + <string name="effect_Model"> + モデル + </string> <string name="effect_Nano"> ナノ </string> @@ -90,6 +105,9 @@ <string name="effect_Roxanne"> ãƒã‚¯ã‚µãƒ³ </string> + <string name="effect_Rumble"> + ランブル + </string> <string name="effect_Sabrina"> サブリナ </string> @@ -102,6 +120,9 @@ <string name="effect_Shorty"> ãƒãƒ“ </string> + <string name="effect_Smaller"> + å°ã•ã‚ + </string> <string name="effect_Sneaky"> コソコソ </string> diff --git a/indra/newview/skins/default/xui/ja/floater_window_size.xml b/indra/newview/skins/default/xui/ja/floater_window_size.xml index 152a5f4806..416813d6cc 100644 --- a/indra/newview/skins/default/xui/ja/floater_window_size.xml +++ b/indra/newview/skins/default/xui/ja/floater_window_size.xml @@ -7,10 +7,17 @@ ウィンドウã®ã‚µã‚¤ã‚ºã‚’è¨å®šï¼š </text> <combo_box name="window_size_combo" tool_tip="横幅 x 高ã•"> - <combo_box.item label="1000 x 700 (標準)" name="item0"/> - <combo_box.item label="1024 x 768" name="item1"/> - <combo_box.item label="1280 x 720 (720p)" name="item2"/> - <combo_box.item label="1920 x 1080 (1080p)" name="item3"/> + <combo_box.item label="1000 x 700 (デフォルト)" name="item1"/> + <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/> + <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/> + <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/> + <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/> + <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/> + <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/> + <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/> + <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/> + <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/> + <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/> </combo_box> <button label="è¨å®š" name="set_btn"/> <button label="ã‚ャンセル" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/ja/menu_bottomtray.xml b/indra/newview/skins/default/xui/ja/menu_bottomtray.xml deleted file mode 100644 index 7f106c1ab5..0000000000 --- a/indra/newview/skins/default/xui/ja/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="スピーカーボタン" name="EnableVoiceChat"/> - <menu_item_check label="ジェスãƒãƒ£ãƒ¼ãƒœã‚¿ãƒ³" name="ShowGestureButton"/> - <menu_item_check label="移動ボタン" name="ShowMoveButton"/> - <menu_item_check label="視界ボタン" name="ShowCameraButton"/> - <menu_item_check label="スナップショットボタン" name="ShowSnapshotButton"/> - <menu_item_check label="制作ボタン" name="ShowBuildButton"/> - <menu_item_check label="検索ボタン" name="ShowSearchButton"/> - <menu_item_check label="地図ボタン" name="ShowWorldMapButton"/> - <menu_item_check label="ミニマップボタン" name="ShowMiniMapButton"/> - <menu_item_call label="切りå–り" name="NearbyChatBar_Cut"/> - <menu_item_call label="コピー" name="NearbyChatBar_Copy"/> - <menu_item_call label="貼り付ã‘" name="NearbyChatBar_Paste"/> - <menu_item_call label="削除" name="NearbyChatBar_Delete"/> - <menu_item_call label="ã™ã¹ã¦é¸æŠž" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/ja/menu_im_well_button.xml b/indra/newview/skins/default/xui/ja/menu_im_well_button.xml deleted file mode 100644 index 3397004bd7..0000000000 --- a/indra/newview/skins/default/xui/ja/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<context_menu name="IM Well Button Context Menu"> - <menu_item_call label="ã™ã¹ã¦é–‰ã˜ã‚‹" name="Close All"/> -</context_menu> diff --git a/indra/newview/skins/default/xui/ja/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/ja/menu_inspect_object_gear.xml index 2edade70bf..5a0519ba19 100644 --- a/indra/newview/skins/default/xui/ja/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/ja/menu_inspect_object_gear.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<menu name="Gear Menu"> +<toggleable_menu name="Gear Menu"> <menu_item_call label="触る" name="touch"/> <menu_item_call label="座る" name="sit"/> <menu_item_call label="支払ã†" name="pay"/> @@ -12,7 +12,8 @@ <menu_item_call label="è¿½åŠ " name="add"/> <menu_item_call label="å ±å‘Š" name="report"/> <menu_item_call label="ブãƒãƒƒã‚¯" name="block"/> + <menu_item_call label="ブãƒãƒƒã‚¯è§£é™¤" name="unblock"/> <menu_item_call label="ズームイン" name="zoom_in"/> <menu_item_call label="削除" name="remove"/> <menu_item_call label="詳細" name="more_info"/> -</menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/ja/menu_inventory.xml b/indra/newview/skins/default/xui/ja/menu_inventory.xml index 9449e61274..106b09453a 100644 --- a/indra/newview/skins/default/xui/ja/menu_inventory.xml +++ b/indra/newview/skins/default/xui/ja/menu_inventory.xml @@ -59,6 +59,7 @@ <menu_item_call label="プãƒãƒ‘ティ" name="Properties"/> <menu_item_call label="åå‰ã‚’変更ã™ã‚‹" name="Rename"/> <menu_item_call label="UUID をコピーã™ã‚‹" name="Copy Asset UUID"/> + <menu_item_call label="カット" name="Cut"/> <menu_item_call label="コピー" name="Copy"/> <menu_item_call label="貼り付ã‘" name="Paste"/> <menu_item_call label="リンクを貼り付ã‘ã‚‹" name="Paste As Link"/> @@ -67,6 +68,7 @@ <menu_item_call label="システムフォルダを削除ã™ã‚‹" name="Delete System Folder"/> <menu_item_call label="コンファレンスãƒãƒ£ãƒƒãƒˆã‚’é–‹å§‹ã™ã‚‹" name="Conference Chat Folder"/> <menu_item_call label="å†ç”Ÿã™ã‚‹" name="Sound Play"/> + <menu_item_call label="SLurl をコピー" name="url_copy"/> <menu_item_call label="ãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã®æƒ…å ±" name="About Landmark"/> <menu_item_call label="インワールドã§å†ç”Ÿã™ã‚‹" name="Animation Play"/> <menu_item_call label="ãƒãƒ¼ã‚«ãƒ«ã§å†ç”Ÿã™ã‚‹" name="Animation Audition"/> @@ -84,6 +86,6 @@ <menu_item_call label="è¿½åŠ " name="Wearable Add"/> <menu_item_call label="å–り外ã™" name="Take Off"/> <menu_item_call label="マーãƒãƒ£ãƒ³ãƒˆã®ã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ã«ã‚³ãƒ”ー" name="Merchant Copy"/> - <menu_item_call label="マーãƒãƒ£ãƒ³ãƒˆã®ã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ã«ç§»å‹•" name="Merchant Move"/> + <menu_item_call label="マーケットプレイスã«é€ä¿¡" name="Marketplace Send"/> <menu_item_call label="ï¼ï¼ã‚ªãƒ—ションãªã—ï¼ï¼" name="--no options--"/> </menu> diff --git a/indra/newview/skins/default/xui/ja/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/ja/menu_inventory_gear_default.xml index 1f425df83c..f38dbc71a8 100644 --- a/indra/newview/skins/default/xui/ja/menu_inventory_gear_default.xml +++ b/indra/newview/skins/default/xui/ja/menu_inventory_gear_default.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <toggleable_menu name="menu_gear_default"> - <menu_item_call label="æ–°ã—ã„æŒã¡ç‰©ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦" name="new_window"/> + <menu_item_call label="æ–°ã—ã„インベントリウィンドウ" name="new_window"/> <menu_item_check label="åå‰ã§ä¸¦ã¹æ›¿ãˆ" name="sort_by_name"/> <menu_item_check label="æ–°ã—ã„é †ã«ä¸¦ã¹æ›¿ãˆ" name="sort_by_recent"/> <menu_item_check label="フォルダを常ã«åå‰é †ã«ä¸¦ã¹ã‚‹" name="sort_folders_by_name"/> diff --git a/indra/newview/skins/default/xui/ja/menu_login.xml b/indra/newview/skins/default/xui/ja/menu_login.xml index 4c88f17f3d..ab6d9e3546 100644 --- a/indra/newview/skins/default/xui/ja/menu_login.xml +++ b/indra/newview/skins/default/xui/ja/menu_login.xml @@ -17,8 +17,8 @@ <menu_item_call label="ウィンドウã®ã‚µã‚¤ã‚ºã‚’è¨å®š..." name="Set Window Size..."/> <menu_item_call label="利用è¦ç´„を表示" name="TOS"/> <menu_item_call label="クリティカルメッセージを表示" name="Critical"/> - <menu_item_call label="メディアブラウザã®ãƒ†ã‚¹ãƒˆ" name="Web Browser Test"/> <menu_item_call label="Web コンテンツフãƒãƒ¼ã‚¿ãƒ¼ã®ãƒ‡ãƒãƒƒã‚°ãƒ†ã‚¹ãƒˆ" name="Web Content Floater Debug Test"/> + <menu label="ãƒã‚°ãƒ¬ãƒ™ãƒ«ã‚’è¨å®š" name="Set Logging Level"/> <menu_item_check label="グリッドピッカーを表示ã™ã‚‹" name="Show Grid Picker"/> <menu_item_call label="通知コンソールを表示ã™ã‚‹" name="Show Notifications Console"/> </menu> diff --git a/indra/newview/skins/default/xui/ja/menu_mode_change.xml b/indra/newview/skins/default/xui/ja/menu_mode_change.xml deleted file mode 100644 index dff3392bd5..0000000000 --- a/indra/newview/skins/default/xui/ja/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="ベーシック" name="BasicMode"/> - <menu_item_check label="アドãƒãƒ³ã‚¹" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/ja/menu_object.xml b/indra/newview/skins/default/xui/ja/menu_object.xml index 4cee8089ee..01436ad12b 100644 --- a/indra/newview/skins/default/xui/ja/menu_object.xml +++ b/indra/newview/skins/default/xui/ja/menu_object.xml @@ -5,6 +5,8 @@ </menu_item_call> <menu_item_call label="編集" name="Edit..."/> <menu_item_call label="制作" name="Build"/> + <menu_item_call label="リンクセットã§è¡¨ç¤º" name="show_in_linksets"/> + <menu_item_call label="ã‚ャラクターã§è¡¨ç¤º" name="show_in_characters"/> <menu_item_call label="é–‹ã" name="Open"/> <menu_item_call label="ã“ã“ã«åº§ã‚‹" name="Object Sit"/> <menu_item_call label="ç«‹ã¡ä¸ŠãŒã‚‹" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/ja/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/ja/menu_places_gear_folder.xml index e64f97fda5..c455204722 100644 --- a/indra/newview/skins/default/xui/ja/menu_places_gear_folder.xml +++ b/indra/newview/skins/default/xui/ja/menu_places_gear_folder.xml @@ -1,8 +1,8 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <toggleable_menu name="menu_folder_gear"> <menu_item_call label="ãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã‚’è¿½åŠ " name="add_landmark"/> <menu_item_call label="ãƒ•ã‚©ãƒ«ãƒ€ã‚’è¿½åŠ " name="add_folder"/> - <menu_item_call label="商å“を復元" name="restore_item"/> + <menu_item_call label="アイテムを復元" name="restore_item"/> <menu_item_call label="切りå–り" name="cut"/> <menu_item_call label="コピー" name="copy_folder"/> <menu_item_call label="貼り付ã‘" name="paste"/> diff --git a/indra/newview/skins/default/xui/ja/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/ja/menu_places_gear_landmark.xml index f416b5b1f6..579f2c2cbd 100644 --- a/indra/newview/skins/default/xui/ja/menu_places_gear_landmark.xml +++ b/indra/newview/skins/default/xui/ja/menu_places_gear_landmark.xml @@ -1,11 +1,11 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <toggleable_menu name="menu_ladmark_gear"> <menu_item_call label="テレãƒãƒ¼ãƒˆ" name="teleport"/> <menu_item_call label="ã‚‚ã£ã¨è©³ã—ã" name="more_info"/> <menu_item_call label="地図ã«è¡¨ç¤º" name="show_on_map"/> <menu_item_call label="ãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã‚’è¿½åŠ " name="add_landmark"/> <menu_item_call label="ãƒ•ã‚©ãƒ«ãƒ€ã‚’è¿½åŠ " name="add_folder"/> - <menu_item_call label="商å“を復元" name="restore_item"/> + <menu_item_call label="アイテムを復元" name="restore_item"/> <menu_item_call label="切りå–り" name="cut"/> <menu_item_call label="ランドマークをコピー" name="copy_landmark"/> <menu_item_call label="SLurl をコピー" name="copy_slurl"/> diff --git a/indra/newview/skins/default/xui/ja/menu_text_editor.xml b/indra/newview/skins/default/xui/ja/menu_text_editor.xml index fcb1038a6a..eda973c888 100644 --- a/indra/newview/skins/default/xui/ja/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/ja/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="ï¼ˆä¸æ˜Žï¼‰" name="Suggestion 1"/> + <menu_item_call label="ï¼ˆä¸æ˜Žï¼‰" name="Suggestion 2"/> + <menu_item_call label="ï¼ˆä¸æ˜Žï¼‰" name="Suggestion 3"/> + <menu_item_call label="ï¼ˆä¸æ˜Žï¼‰" name="Suggestion 4"/> + <menu_item_call label="ï¼ˆä¸æ˜Žï¼‰" name="Suggestion 5"/> + <menu_item_call label="辞書ã«è¿½åŠ " name="Add to Dictionary"/> + <menu_item_call label="無視ã«è¿½åŠ " name="Add to Ignore"/> <menu_item_call label="切りå–り" name="Cut"/> <menu_item_call label="コピー" name="Copy"/> <menu_item_call label="貼り付ã‘" name="Paste"/> 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_url_inventory.xml b/indra/newview/skins/default/xui/ja/menu_url_inventory.xml index 7af2f9e2cd..147ab44a1b 100644 --- a/indra/newview/skins/default/xui/ja/menu_url_inventory.xml +++ b/indra/newview/skins/default/xui/ja/menu_url_inventory.xml @@ -1,6 +1,6 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Url Popup"> - <menu_item_call label="æŒã¡ç‰©ã‚¢ã‚¤ãƒ†ãƒ を表示" name="show_item"/> + <menu_item_call label="インベントリアイテムを表示" name="show_item"/> <menu_item_call label="åå‰ã‚’クリップボードã«ã‚³ãƒ”ー" name="url_copy_label"/> <menu_item_call label="SLurl をクリップボードã«ã‚³ãƒ”ー" name="url_copy"/> </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 b9dbb81c0a..e60e6781c6 100644 --- a/indra/newview/skins/default/xui/ja/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml @@ -1,55 +1,62 @@ <?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_check label="æŒã¡ç‰©..." name="Inventory"/> - <menu_item_check label="ジェスãƒãƒ£ãƒ¼..." name="Gestures"/> - <menu_item_check label="ボイス..." name="ShowVoice"/> + <menu_item_call label="ã‚¢ãƒã‚¿ãƒ¼ã‚’é¸æŠž..." name="Avatar Picker"/> + <menu_item_check label="インベントリ..." name="Inventory"/> + <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"/> <menu_item_check label="常ã«èµ°ã‚‹" name="Always Run"/> <menu_item_call label="ç§ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’åœæ¢ã™ã‚‹" name="Stop Animating My Avatar"/> + <menu_item_call label="æ©è¡Œï¼èµ°è¡Œï¼é£›è¡Œ..." name="Walk / run / fly"/> </menu> <menu label="ãƒã‚°ã‚¤ãƒ³" name="Status"> <menu_item_call label="一時退å¸ä¸" name="Set Away"/> <menu_item_call label="å–り込ã¿ä¸" name="Set Busy"/> </menu> - <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="L$ ã®è³¼å…¥..." name="Buy and Sell L$"/> + <menu_item_call label="マーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹..." name="MerchantOutbox"/> + <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_check label="HUD を表示" name="Show HUD Attachments"/> <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_item_call label="リストをブãƒãƒƒã‚¯" name="Block List"/> </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 +65,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 label="太陽" name="Sun"> <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="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"/> @@ -109,7 +115,7 @@ <menu_item_call label="è²·ã†" name="Menu Object Buy"/> <menu_item_call label="å–ã‚‹" name="Menu Object Take"/> <menu_item_call label="コピーをå–ã‚‹" name="Take Copy"/> - <menu_item_call label="「æŒã¡ç‰©ã€ã«ä¿å˜" name="Save Object Back to My Inventory"/> + <menu_item_call label="マイインベントリã«ä¿å˜" name="Save Object Back to My Inventory"/> <menu_item_call label="オブジェクトã®ä¸èº«ã«ä¿å˜" name="Save Object Back to Object Contents"/> <menu_item_call label="オブジェクトを返å´ã™ã‚‹" name="Return Object back to Owner"/> </menu> @@ -120,6 +126,11 @@ <menu_item_call label="スクリプトを実行ä¸ã«ã™ã‚‹" name="Set Scripts to Running"/> <menu_item_call label="ã‚¹ã‚¯ãƒªãƒ—ãƒˆã‚’å®Ÿè¡Œåœæ¢ã«ã™ã‚‹" name="Set Scripts to Not Running"/> </menu> + <menu label="パスファインディング" name="Pathfinding"> + <menu_item_call label="リンクセット..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="ã‚ャラクター..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="表示/テスト..." name="pathfinding_console_menu_item"/> + </menu> <menu label="オプション" name="Options"> <menu_item_check label="権é™ã®è©³ç´°ã‚’表示ã™ã‚‹" name="DebugPermissions"/> <menu_item_check label="ç§ã®ã‚ªãƒ–ジェクトã ã‘ã‚’é¸æŠžã™ã‚‹" name="Select Only My Objects"/> @@ -140,11 +151,13 @@ <menu_item_call label="アニメーション(L$[COST])..." name="Upload Animation"/> <menu_item_call label="モデル" name="Upload Model"/> <menu_item_call label="一括 (ファイルã«ã¤ãL$[COST])..." name="Bulk Upload"/> + <menu_item_call label="デフォルトã®ã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰æ¨©é™ã‚’è¨å®š" name="perm prefs"/> </menu> <menu_item_call label="å…ƒã«æˆ»ã™" name="Undo"/> <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"/> @@ -168,26 +181,25 @@ <menu_item_check label="パーティクルをéžè¡¨ç¤ºã«ã™ã‚‹" name="Hide Particles"/> <menu_item_check label="é¸æŠžã—ãŸã‚‚ã®ã‚’éžè¡¨ç¤ºã«ã™ã‚‹" name="Hide Selected"/> <menu_item_check label="逿˜Žéƒ¨åˆ†ã‚’ãƒã‚¤ãƒ©ã‚¤ãƒˆã™ã‚‹" name="Highlight Transparent"/> - <menu_item_check label="HUD を表示ã™ã‚‹" name="Show HUD Attachments"/> <menu_item_check label="一人称視点ã®ã¨ãã«åå—線を表示ã™ã‚‹" name="ShowCrosshairs"/> </menu> <menu label="レンダリング(種類)" 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="Surface Patch"/> - <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="レンダリング(機能)" name="Rendering Features"> - <menu_item_check label="UI" name="UI"/> + <menu_item_check label="UI" name="ToggleUI"/> <menu_item_check label="é¸æŠžæ¸ˆ" name="Selected"/> <menu_item_check label="ãƒã‚¤ãƒ©ã‚¤ãƒˆ" name="Highlighted"/> <menu_item_check label="ダイナミックテクスãƒãƒ£" name="Dynamic Textures"/> @@ -199,11 +211,8 @@ <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"/> @@ -212,13 +221,6 @@ <menu_item_check label="ジョイスティックフライカム" 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="ズームイン" name="Zoom In"/> <menu_item_call label="ズーム(デフォルト)" name="Zoom Default"/> <menu_item_call label="ズームアウト" name="Zoom Out"/> @@ -231,11 +233,10 @@ <menu_item_check label="テクスãƒãƒ£ã®ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Texture Console"/> <menu_item_check label="デãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Debug Console"/> <menu_item_call label="通知コンソール" name="Notifications"/> - <menu_item_check label="テクスãƒãƒ£ã‚µã‚¤ã‚ºã®ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Texture Size"/> - <menu_item_check label="テクスãƒãƒ£ã‚«ãƒ†ã‚´ãƒªã®ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Texture Category"/> <menu_item_check label="ファーストタイマー" name="Fast Timers"/> <menu_item_check label="メモリ" name="Memory"/> <menu_item_check label="風景ã®çµ±è¨ˆ" name="Scene Statistics"/> + <menu_item_call label="テクスãƒãƒ£å–得デãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Texture Fetch Debug Console"/> <menu_item_call label="ãƒªãƒ¼ã‚¸ãƒ§ãƒ³æƒ…å ±ã‚’ãƒ‡ãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã¸" name="Region Info to Debug Console"/> <menu_item_call label="ã‚°ãƒ«ãƒ¼ãƒ—æƒ…å ±ã‚’ãƒ‡ãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã¸" name="Group Info to Debug Console"/> <menu_item_call label="æ€§èƒ½æƒ…å ±ã‚’ãƒ‡ãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã¸" name="Capabilities Info to Debug Console"/> @@ -289,8 +290,16 @@ <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="attachment bytes"/> <menu_item_check label="スカルプト" name="Sculpt"/> + <menu label="テクスãƒãƒ£ã®å¯†åº¦" name="Texture Density"> + <menu_item_check label="ãªã—" name="None"/> + <menu_item_check label="ç¾åœ¨" name="Current"/> + <menu_item_check label="望ã¾ã—ã„" name="Desired"/> + <menu_item_check label="フル" name="Full"/> + </menu> </menu> <menu label="レンダリング" name="Rendering"> <menu_item_check label="軸" name="Axes"/> @@ -301,7 +310,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)"/> @@ -309,7 +317,6 @@ <menu_item_check label="アニメーションテクスãƒãƒ£" name="Animation Textures"/> <menu_item_check label="テクスãƒãƒ£ã‚’無効ã«ã™ã‚‹" name="Disable Textures"/> <menu_item_check label="フル解åƒåº¦ãƒ†ã‚¯ã‚¹ãƒãƒ£" name="Rull Res Textures"/> - <menu_item_check label="テクスãƒãƒ£ã®æ¤œæŸ»" name="Audit Textures"/> <menu_item_check label="テクスãƒãƒ£ã‚¢ãƒˆãƒ©ã‚¹ï¼ˆè©¦é¨“段階)" name="Texture Atlas"/> <menu_item_check label="装ç€ã•れãŸå…‰æºã‚’æç”»ã™ã‚‹" name="Render Attached Lights"/> <menu_item_check label="å–り付ã‘られãŸãƒ‘ーティクルをæç”»ã™ã‚‹" name="Render Attached Particles"/> @@ -332,17 +339,16 @@ <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="ビーコンを強調表示ã™ã‚‹" name="Cheesy Beacon"/> <menu_item_check label="固定ã•れãŸå¤©æ°—" name="Fixed Weather"/> - <menu_item_call label="リージョンオブジェクトã®ã‚ャッシュをダンプã™ã‚‹" name="Dump Region Object Cache"/> + <menu_item_call label="リージョンオブジェクトã®ã‚ャッシュをダンプ" name="Dump Region Object Cache"/> </menu> <menu label="UI" name="UI"> <menu_item_call label="メディアブラウザã®ãƒ†ã‚¹ãƒˆ" name="Web Browser Test"/> <menu_item_call label="Web コンテンツブラウザ" name="Web Content Browser"/> <menu_item_call label="SelectMgr をダンプ" name="Dump SelectMgr"/> - <menu_item_call label="æŒã¡ç‰©ã®å‡ºåŠ›" name="Dump Inventory"/> + <menu_item_call label="インベントリã®å‡ºåŠ›" name="Dump Inventory"/> <menu_item_call label="タイマーをダンプ" name="Dump Timers"/> <menu_item_call label="フォーカスホールダーをダンプ" name="Dump Focus Holder"/> <menu_item_call label="é¸æŠžã—ãŸã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆæƒ…å ±ã‚’ãƒ—ãƒªãƒ³ãƒˆ" name="Print Selected Object Info"/> @@ -366,18 +372,17 @@ </menu> <menu label="ã‚¢ãƒã‚¿ãƒ¼" name="Character"> <menu label="ベークドテクスãƒãƒ£ã‚’å–å¾—ã™ã‚‹" name="Grab Baked Texture"> - <menu_item_call label="çž³" name="Iris"/> - <menu_item_call label="é " name="Head"/> - <menu_item_call label="上åŠèº«" name="Upper Body"/> - <menu_item_call label="下åŠèº«" name="Lower Body"/> - <menu_item_call label="スカート" name="Skirt"/> + <menu_item_call label="çž³" name="Grab Iris"/> + <menu_item_call label="é " name="Grab Head"/> + <menu_item_call label="上åŠèº«" name="Grab Upper Body"/> + <menu_item_call label="下åŠèº«" name="Grab Lower Body"/> + <menu_item_call label="スカート" name="Grab Skirt"/> </menu> <menu label="ã‚ャラクターテスト" name="Character Tests"> <menu_item_call label="容姿を XML ã«ä¿å˜ã™ã‚‹" name="Appearance To XML"/> <menu_item_call label="ã‚ャラクタジオメトリã®åˆ‡ã‚Šæ›¿ãˆ" name="Toggle Character Geometry"/> <menu_item_call label="男性アãƒã‚¿ãƒ¼ã®ãƒ†ã‚¹ãƒˆ" name="Test Male"/> <menu_item_call label="女性アãƒã‚¿ãƒ¼ã®ãƒ†ã‚¹ãƒˆ" name="Test Female"/> - <menu_item_call label="PG ã®ãƒˆã‚°ãƒ«" name="Toggle PG"/> <menu_item_check label="é¸æŠžã‚¢ãƒã‚¿ãƒ¼è¨±å¯" name="Allow Select Avatar"/> </menu> <menu_item_call label="パラメータを強制的ã«ãƒ‡ãƒ•ォルトã«ã™ã‚‹" name="Force Params to Default"/> @@ -396,22 +401,30 @@ <menu_item_call label="ãƒãƒ¼ã‚«ãƒ«ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’ダンプ" name="Dump Local Textures"/> </menu> <menu_item_check label="HTTP Texture" name="HTTP Textures"/> - <menu_item_check label="HTTP æŒã¡ç‰©" name="HTTP Inventory"/> + <menu_item_check label="HTTP インベントリ" name="HTTP Inventory"/> <menu_item_call label="圧縮画åƒ" name="Compress Images"/> + <menu_item_call label="Visual Leak Detector を有効ã«ã™ã‚‹" name="Enable Visual Leak Detector"/> <menu_item_check label="デãƒãƒƒã‚°ç”¨ã®ãƒŸãƒ‹ãƒ€ãƒ³ãƒ—を出力ã™ã‚‹" name="Output Debug Minidump"/> <menu_item_check label="次回ã®èµ·å‹•時ã«ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’表示ã™ã‚‹" name="Console Window"/> + <menu label="ãƒã‚°ãƒ¬ãƒ™ãƒ«ã‚’è¨å®š" name="Set Logging Level"> + <menu_item_check label="デãƒãƒƒã‚°" name="Debug"/> + <menu_item_check label="æƒ…å ±" name="Info"/> + <menu_item_check label="è¦å‘Š" name="Warning"/> + <menu_item_check label="エラー" name="Error"/> + <menu_item_check label="ãªã—" name="None"/> + </menu> <menu_item_call label="管ç†è€…ステータスã®å‘¼ã³å‡ºã—" name="Request Admin Options"/> <menu_item_call label="管ç†è€…ステータス解除" name="Leave Admin Options"/> <menu_item_check label="管ç†è€…メニューを表示ã™ã‚‹" name="View Admin Options"/> </menu> <menu label="管ç†è€…" name="Admin"> - <menu label="Object"> - <menu_item_call label="コピーをå–ã‚‹" name="Take Copy"/> + <menu label="オブジェクト" name="AdminObject"> + <menu_item_call label="コピーをå–ã‚‹" name="Admin Take Copy"/> <menu_item_call label="ç§ã‚’所有者ã«ã™ã‚‹" name="Force Owner To Me"/> - <menu_item_call label="所有者権é™ã‚’実行ã™ã‚‹" name="Force Owner Permissive"/> + <menu_item_call label="所有者権é™ã®å®Ÿè¡Œ" name="Force Owner Permissive"/> <menu_item_call label="削除" name="Delete"/> <menu_item_call label="ãƒãƒƒã‚¯" name="Lock"/> - <menu_item_call label="アセット ID ã‚’å–å¾—ã™ã‚‹" name="Get Assets IDs"/> + <menu_item_call label="アセット ID ã‚’å–å¾—" name="Get Assets IDs"/> </menu> <menu label="区画" name="Parcel"> <menu_item_call label="ç§ã‚’所有者ã«ã™ã‚‹" name="Owner To Me"/> @@ -442,7 +455,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="スクリプトãƒãƒ¼ã‚¿ãƒ«" name="Scripting Portal"/> <menu label="ãƒã‚°ã®å ±å‘Š" name="Bug Reporting"> diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index 85f09b4500..d5cff18a24 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -85,17 +91,38 @@ <usetemplate canceltext="ã‚ャンセル" name="yesnocancelbuttons" notext="ä¿å˜ã—ãªã„" yestext="ä¿å˜"/> </notification> <notification name="ConfirmNoCopyToOutbox"> - マーãƒãƒ£ãƒ³ãƒˆã®ã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ã«ã“れをコピーã™ã‚‹æ¨©é™ãŒã‚りã¾ã™ã€‚次ã®ã‚¢ã‚¤ãƒ†ãƒ を移動ã—ã¾ã™ã‹ï¼Ÿ -[ITEM_NAME] - <usetemplate name="okcancelbuttons" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> + ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã® 1 ã¤ã¾ãŸã¯è¤‡æ•°ã‚’マーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ã«ã‚³ãƒ”ーã™ã‚‹è¨±å¯ãŒã‚りã¾ã›ã‚“。移動ã™ã‚‹ã‹ã€ç½®ã去りã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã™ã€‚ + <usetemplate name="okcancelbuttons" notext="アイテムを移動ã—ãªã„" yestext="アイテムを移動"/> + </notification> + <notification name="OutboxFolderCreated"> + マーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ã®æœ€ä¸Šä½ã«è»¢é€ã—ãŸå„アイテムã«ã¤ãã€ãれãžã‚Œ 1 ã¤ã®æ–°ã—ã„フォルダãŒä½œæˆã•れã¾ã—ãŸã€‚ + <usetemplate ignoretext="æ–°ã—ã„フォルダãŒãƒžãƒ¼ãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹å†…ã«ä½œæˆã•れã¾ã—ãŸ" name="okignore" yestext="OK"/> + </notification> + <notification name="OutboxImportComplete"> + æˆåŠŸ + +ãƒžãƒ¼ã‚±ãƒƒãƒˆãƒ—ãƒ¬ã‚¤ã‚¹ã«æ£å¸¸ã«é€ä¿¡ã•れãŸã™ã¹ã¦ã®ãƒ•ォルダ + <usetemplate ignoretext="マーケットプレイスã«é€ä¿¡ã•れãŸã™ã¹ã¦ã®ãƒ•ォルダ" name="okignore" yestext="OK"/> + </notification> + <notification name="OutboxImportHadErrors"> + 一部ã®ãƒ•ォルダã¯è»¢é€ã•れã¾ã›ã‚“ã§ã—㟠+ +一部ã®ãƒ•ォルダãŒãƒžãƒ¼ã‚±ãƒƒãƒˆãƒ—レイスã«é€ä¿¡ã•れãŸã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã“れらã®ãƒ•ォルダã¯ã¾ã マーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹å†…ã«ã‚りã¾ã™ã€‚ + +詳細ã«ã¤ã„ã¦ã¯ã€[[MARKETPLACE_IMPORTS_URL] エラーãƒã‚°]ã‚’ã”覧ãã ã•ã„。 + <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="OutboxUploadComplete"> - マーケットプレイスã¸ã®ã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰ãŒå®Œäº†ã—ã¾ã—ãŸã€‚ - <usetemplate name="okbutton" yestext="ã‚„ã£ãŸã‚ï¼"/> + <notification name="OutboxImportFailed"> + 転é€ã«å¤±æ•— + +システムã¾ãŸã¯ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã®ã‚¨ãƒ©ãƒ¼ã®ãŸã‚ã€ãƒ•ォルダã¯ãƒžãƒ¼ã‚±ãƒƒãƒˆãƒ—レイスã«é€ä¿¡ã•れã¾ã›ã‚“ã§ã—ãŸã€‚後ã§ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。 + <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="OutboxUploadHadErrors"> - マーケットプレイスã¸ã®ã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰ã®å®Œäº†æ™‚ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚アウトボックスã®å•題を解決ã—ã¦ã€ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。ã‚りãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚ - <usetemplate name="okbutton" yestext="å†ãƒˆãƒ©ã‚¤ï¼"/> + <notification name="OutboxInitFailed"> + マーケットプレイスã®åˆæœŸåŒ–ã«å¤±æ•— + +システムã¾ãŸã¯ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã®ã‚¨ãƒ©ãƒ¼ã®ãŸã‚ã€ãƒžãƒ¼ã‚±ãƒƒãƒˆãƒ—レイスã®åˆæœŸåŒ–ã«å¤±æ•—ã—ã¾ã—ãŸã€‚後ã§ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。 + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CompileQueueSaveText"> 次ã®ç†ç”±ã§ã€ã‚¹ã‚¯ãƒªãƒ—ト用テã‚ストã®ã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰æ™‚ã«å•題ãŒèµ·ã“りã¾ã—ãŸã€‚ @@ -243,7 +270,7 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ãã <usetemplate name="okcancelbuttons" notext="ã‚ャンセル" yestext="OK"/> </notification> <notification name="ReturnObjectsDeededToGroup"> - ã“ã®åŒºç”»ã®ã‚°ãƒ«ãƒ¼ãƒ— [NAME] 共有ã®ã™ã¹ã¦ã®ã‚ªãƒ–ジェクトをã€ä»¥å‰ã®æ‰€æœ‰è€…ã®ã€ŒæŒã¡ç‰©ã€ã«æˆ»ãã†ã¨ã—ã¦ã„ã¾ã™ã€‚ + ã“ã®åŒºç”»ã®ã‚°ãƒ«ãƒ¼ãƒ— [NAME] 共有ã®ã™ã¹ã¦ã®ã‚ªãƒ–ジェクトをã€ä»¥å‰ã®æ‰€æœ‰è€…ã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«æˆ»ãã†ã¨ã—ã¦ã„ã¾ã™ã€‚ æ“作を続行ã—ã¾ã™ã‹ï¼Ÿ *è¦å‘Š* ã“れã«ã‚ˆã‚Šã€ @@ -254,21 +281,21 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ãã <notification name="ReturnObjectsOwnedByUser"> ã“ã®åŒºç”»ã§ã€ ä½äºº [NAME] ãŒæ‰€æœ‰ã™ã‚‹å…¨ã¦ã®ã‚ªãƒ–ジェクトを -本人ã®ã€ŒæŒã¡ç‰©ã€ã«æœ¬å½“ã«è¿”å´ã—ã¦ã‚‚よã„ã§ã™ã‹ï¼Ÿ +本人ã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«æœ¬å½“ã«è¿”å´ã—ã¦ã‚‚よã„ã§ã™ã‹ï¼Ÿ オブジェクト: [N] <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> <notification name="ReturnObjectsOwnedBySelf"> ã“ã®åœŸåœ°åŒºç”»å†…ã«ã‚ã‚‹ã€ã‚ãªãŸãŒæ‰€æœ‰ã™ã‚‹ã™ã¹ã¦ã®ã‚ªãƒ–ジェクトを〠-ã‚ãªãŸã®ã€ŒæŒã¡ç‰©ã€ã«æˆ»ãã†ã¨ã—ã¦ã„ã¾ã™ã€‚ç¶šã‘ã¾ã™ã‹ï¼Ÿ +ã‚ãªãŸã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«æˆ»ãã†ã¨ã—ã¦ã„ã¾ã™ã€‚ç¶šã‘ã¾ã™ã‹ï¼Ÿ オブジェクト: [N] <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> <notification name="ReturnObjectsNotOwnedBySelf"> ã“ã®åœŸåœ°åŒºç”»å†…ã«ã‚ã‚‹ã€ã‚ãªãŸä»¥å¤–ãŒæ‰€æœ‰ã™ã‚‹ã™ã¹ã¦ã®ã‚ªãƒ–ジェクトを〠-ãれãžã‚Œã®æ‰€æœ‰è€…ã®ã€ŒæŒã¡ç‰©ã€ã«æˆ»ãã†ã¨ã—ã¦ã„ã¾ã™ã€‚ +ãれãžã‚Œã®æ‰€æœ‰è€…ã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«æˆ»ãã†ã¨ã—ã¦ã„ã¾ã™ã€‚ æ“作を続行ã—ã¾ã™ã‹ï¼Ÿ グループã«è²æ¸¡ã•れãŸã€Œå†è²©ãƒ»ãƒ—レゼントå¯ã€ã®ã‚ªãƒ–ジェクトã¯ã€ä»¥å‰ã®æ‰€æœ‰è€…ã«è¿”å´ã•れã¾ã™ã€‚ @@ -279,7 +306,7 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ãã </notification> <notification name="ReturnObjectsNotOwnedByUser"> ã“ã®åœŸåœ°åŒºç”»å†…ã«ã‚る〠-[NAME]以外ã«ã‚ˆã‚‹æ‰€æœ‰ã®ã‚ªãƒ–ジェクトをã™ã¹ã¦ãれãžã‚Œã®æ‰€æœ‰è€…ã®ã€ŒæŒã¡ç‰©ã€ã«è¿”å´ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ +[NAME]以外ã«ã‚ˆã‚‹æ‰€æœ‰ã®ã‚ªãƒ–ジェクトをã™ã¹ã¦ãれãžã‚Œã®æ‰€æœ‰è€…ã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«è¿”å´ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ æ“作を続行ã—ã¾ã™ã‹ï¼Ÿã‚°ãƒ«ãƒ¼ãƒ—ã«è²æ¸¡ã•れãŸã€Œå†è²©ãƒ»ãƒ—レゼントå¯ã€ã®ã‚ªãƒ–ジェクトã¯ã€ä»¥å‰ã®æ‰€æœ‰è€…ã«è¿”å´ã•れã¾ã™ã€‚ *è¦å‘Š* ã“れã«ã‚ˆã‚Šã€ @@ -361,13 +388,19 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ãã [SECOND_LIFE] ã«å…¥ã‚‹ã«ã¯ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¿…è¦ã§ã™ã€‚今ã™ãアカウントを作æˆã—ã¾ã™ã‹ï¼Ÿ <url name="url"> - https://join.secondlife.com/index.php?lang=ja-JP + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="ã‚‚ã†ä¸€åº¦è©¦ã™" yestext="æ–°ã—ã„アカウントを作æˆ"/> </notification> <notification name="InvalidCredentialFormat"> ユーザーåã®ãƒ•ィールドã«ã‚¢ãƒã‚¿ãƒ¼ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼åã‚‚ã—ãã¯æ°åを入力ã—ã¦ã‹ã‚‰ã€å†åº¦ãƒã‚°ã‚¤ãƒ³ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ </notification> + <notification name="InvalidGrid"> + '[GRID]' ã¯æœ‰åйãªã‚°ãƒªãƒƒãƒ‰ ID ã§ã¯ã‚りã¾ã›ã‚“。 + </notification> + <notification name="InvalidLocationSLURL"> + ãƒã‚°ã‚¤ãƒ³ä½ç½®ã§æœ‰åйãªã‚°ãƒªãƒƒãƒ‰ãŒæŒ‡å®šã•れã¾ã›ã‚“ã§ã—ãŸã€‚ + </notification> <notification name="DeleteClassified"> クラシファイド広告 [NAME] を削除ã—ã¾ã™ã‹ï¼Ÿ æ”¯æ‰•ã„æ¸ˆã¿ã®æ–™é‡‘ã¯è¿”金ã•れã¾ã›ã‚“。 @@ -443,14 +476,14 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ãã ジェスãƒãƒ£ãƒ¼ã®ä¿å˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚å°‘ã—å¾…ã£ã¦ã‹ã‚‰ã‚‚ã†ä¸€åº¦è©¦ã—ã¦ãã ã•ã„。 </notification> <notification name="GestureSaveFailedObjectNotFound"> - ジェスãƒãƒ£ãƒ¼ã®ä¿å˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚オブジェクトã€ã¾ãŸã¯é–¢é€£ã™ã‚‹ã‚ªãƒ–ジェクトæŒã¡ç‰©ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。 + ジェスãƒãƒ£ãƒ¼ã®ä¿å˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚オブジェクトã€ã¾ãŸã¯é–¢é€£ã™ã‚‹ã‚ªãƒ–ジェクトインベントリãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。 オブジェクトãŒç¯„囲内ã«å˜åœ¨ã—ãªã„ã‹ã€ã¾ãŸã¯å‰Šé™¤ã•れãŸå¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚ </notification> <notification name="GestureSaveFailedReason"> 次ã®ç†ç”±ã§ã€ã‚¸ã‚§ã‚¹ãƒãƒ£ãƒ¼ã®ä¿å˜æ™‚ã«å•題ãŒèµ·ã“りã¾ã—ãŸã€‚ [REASON]。 後ã§ã‚‚ã†ä¸€åº¦è©¦ã—ã¦ãã ã•ã„。 </notification> <notification name="SaveNotecardFailObjectNotFound"> - ノートカードã®ä¿å˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚オブジェクトã€ã¾ãŸã¯é–¢é€£ã™ã‚‹ã‚ªãƒ–ジェクトæŒã¡ç‰©ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。 + ノートカードã®ä¿å˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚オブジェクトã€ã¾ãŸã¯é–¢é€£ã™ã‚‹ã‚ªãƒ–ジェクトインベントリãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。 オブジェクトãŒç¯„囲内ã«å˜åœ¨ã—ãªã„ã‹ã€ã¾ãŸã¯å‰Šé™¤ã•れãŸå¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚ </notification> <notification name="SaveNotecardFailReason"> @@ -474,7 +507,7 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ãã </notification> <notification name="StartRegionEmpty"> ãƒã‚°ã‚¤ãƒ³ä½ç½®ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“。 -ãƒã‚°ã‚¤ãƒ³ä½ç½®ã®æ¬„ã«ãƒªãƒ¼ã‚¸ãƒ§ãƒ³åを入力ã™ã‚‹ã‹ã€ã€Œæœ€å¾Œã«ãƒã‚°ã‚¢ã‚¦ãƒˆã—ãŸå ´æ‰€ã€ã‹ã€Œãƒ›ãƒ¼ãƒ ã€ã‚’é¸æŠžã—ã¦ãã ã•ã„。 +ãƒã‚°ã‚¤ãƒ³ä½ç½®ã®æ¬„ã«ãƒªãƒ¼ã‚¸ãƒ§ãƒ³åを入力ã™ã‚‹ã‹ã€ã€Œæœ€å¾Œã«ãƒã‚°ã‚¢ã‚¦ãƒˆã—ãŸå ´æ‰€ã€ã‹ã€Œè‡ªå®…(ホーム)ã€ã‚’é¸æŠžã—ã¦ãã ã•ã„。 <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CouldNotStartStopScript"> @@ -496,6 +529,15 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ãã </url> <usetemplate ignoretext="使用ä¸ã®ã‚³ãƒ³ãƒ”ューターã®ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ãªã„ã¨ã" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> </notification> + <notification name="IntelOldDriver"> + ãŠãらããŠä½¿ã„ã®ã‚°ãƒ©ãƒ•ィックãƒãƒƒãƒ—ç”¨ã®æ–°ã—ã„ドライãƒãŒå…¥æ‰‹å¯èƒ½ã§ã™ã€‚グラフィックドライãƒã‚’æ›´æ–°ã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€ãƒ‘フォーマンスãŒå¤§å¹…ã«å‘上ã™ã‚‹å ´åˆãŒã‚りã¾ã™ã€‚ + +[_URL] ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦æ›´æ–°ç‰ˆã®ãƒ‰ãƒ©ã‚¤ãƒãŒã‚ã‚‹ã‹ã©ã†ã‹ã‚’確èªã—ã¾ã™ã‹ï¼Ÿ + <url name="url"> + http://www.intel.com/p/ja_JP/support/detect/graphics + </url> + <usetemplate ignoretext="使用ã—ã¦ã„るグラフィックドライãƒãŒå¤ã„å ´åˆ" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> + </notification> <notification name="UnknownGPU"> ãŠä½¿ã„ã®ã‚·ã‚¹ãƒ†ãƒ ã«ã¯ã€[APP_NAME] ãŒèªè˜ã§ããªã„ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ã‚«ãƒ¼ãƒ‰ãŒæè¼‰ã•れã¦ã„ã¾ã™ã€‚ [APP_NAME] ã§ã¾ã テストã•れã¦ã„ãªã„最新ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã®ãŸã‚ã ã¨è€ƒãˆã‚‰ã‚Œã¾ã™ã€‚ å•題ãªã„ã¨ã¯æ€ã„ã¾ã™ãŒã€ã‚°ãƒ©ãƒ•ィックã®è¨å®šã‚’調整ã™ã‚‹å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。 @@ -514,11 +556,11 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ãã [REGION] ã§ã¯ã€åœ°å½¢ã®å¤‰æ›´ãŒã§ãã¾ã›ã‚“。 </notification> <notification name="CannotCopyWarning"> - ã‚ãªãŸã«ã¯[ITEMS]ã¨ã„ã†ã‚¢ã‚¤ãƒ†ãƒ をコピーã™ã‚‹è¨±å¯ãŒã‚りã¾ã›ã‚“。他ã®ä½äººã«æä¾›ã™ã‚‹ã¨ã€ãã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ã‚ãªãŸã®ã€ŒæŒã¡ç‰©ã€ã‹ã‚‰å‰Šé™¤ã•れã¾ã™ã€‚本当ã«ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’è²ã‚Šã¾ã™ã‹ï¼Ÿ + ã‚ãªãŸã«ã¯[ITEMS]ã¨ã„ã†ã‚¢ã‚¤ãƒ†ãƒ をコピーã™ã‚‹è¨±å¯ãŒã‚りã¾ã›ã‚“。他ã®ä½äººã«æä¾›ã™ã‚‹ã¨ã€ãã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ã‚ãªãŸã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‹ã‚‰å‰Šé™¤ã•れã¾ã™ã€‚本当ã«ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’è²ã‚Šã¾ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> </notification> <notification name="CannotGiveItem"> - æŒã¡ç‰©ã®ã‚¢ã‚¤ãƒ†ãƒ を渡ã›ã¾ã›ã‚“。 + インベントリã®ã‚¢ã‚¤ãƒ†ãƒ を渡ã›ã¾ã›ã‚“。 </notification> <notification name="TransactionCancelled"> å–引ãŒã‚ャンセルã•れã¾ã—ãŸã€‚ @@ -531,7 +573,7 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ãã </notification> <notification name="CannotCopyCountItems"> ã‚ãªãŸã¯é¸æŠžã—㟠[COUNT] 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã®ã®ã‚³ãƒ”ーを許ã•れã¦ã„ã¾ã›ã‚“。 -ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ã‚ãªãŸã®ã€ŒæŒã¡ç‰©ã€ã‹ã‚‰å¤±ã‚れã¾ã™ã€‚ +ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ã‚ãªãŸã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‹ã‚‰å¤±ã‚れã¾ã™ã€‚ 本当ã«ã‚¢ã‚¤ãƒ†ãƒ を渡ã—ãŸã„ã§ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> </notification> @@ -593,6 +635,9 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ãã ã©ã®ã‚ªãƒ–ジェクトもãƒãƒƒã‚¯ã•れã¦ãŠã‚‰ãšã€ã‚ãªãŸã®ã‚‚ã®ã§ã‚ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。 </notification> + <notification name="CannotLinkPermanent"> + 地域(リージョン)ã®å¢ƒç•Œã‚’è¶Šãˆã¦ã‚ªãƒ–ジェクトをリンクã§ãã¾ã›ã‚“。 + </notification> <notification name="CannotLinkDifferentOwners"> 所有者ãŒç•°ãªã‚‹ãŸã‚ã€ã‚ªãƒ–ジェクトをリンクã§ãã¾ã›ã‚“。 @@ -672,7 +717,7 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ãã 出力ファイルを作æˆã§ãã¾ã›ã‚“: [FILE] </notification> <notification name="DoNotSupportBulkAnimationUpload"> - ç¾åœ¨ [APP_NAME] ã§ã¯ã€ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®ä¸€æ‹¬ã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。 + ç¾åœ¨ [APP_NAME] ã§ã¯ã€BVH å½¢å¼ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ãƒ•ァイルã®ä¸€æ‹¬ã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。 </notification> <notification name="CannotUploadReason"> 次ã®ç†ç”±ã§ã€ã€Œ [FILE] ã€ã‚’アップãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“: [REASON] @@ -775,7 +820,7 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ãã テレãƒãƒ¼ãƒˆç›®çš„地を見ã¤ã‘られã¾ã›ã‚“。目的地ãŒä¸€æ™‚çš„ã«åˆ©ç”¨ã§ããªã„状態ã‹ã€ã™ã§ã«æ¶ˆæ»…ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚数分後ã«ã‚„り直ã—ã¦ãã ã•ã„。 </notification> <notification name="no_inventory_host"> - æŒã¡ç‰©ã‚·ã‚¹ãƒ†ãƒ ã¯ç¾åœ¨åˆ©ç”¨ã§ãã¾ã›ã‚“。 + インベントリシステムã¯ç¾åœ¨åˆ©ç”¨ã§ãã¾ã›ã‚“。 </notification> <notification name="CannotSetLandOwnerNothingSelected"> 土地所有者è¨å®šãŒã§ãã¾ã›ã‚“: @@ -938,7 +983,7 @@ L$ ã¯è¿”金ã•れã¾ã›ã‚“。 <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> <notification name="ConfirmItemCopy"> - ã“ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’ã‚ãªãŸã®æŒã¡ç‰©ã«ã‚³ãƒ”ーã—ã¾ã™ã‹ï¼Ÿ + ã“ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’ã‚ãªãŸã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«ã‚³ãƒ”ーã—ã¾ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="コピー"/> </notification> <notification name="ResolutionSwitchFail"> @@ -979,6 +1024,40 @@ L$ ã¯è¿”金ã•れã¾ã›ã‚“。 <button name="Cancel" text="ã‚ャンセル"/> </form> </notification> + <notification label="自動置æ›ãƒªã‚¹ãƒˆã‚’è¿½åŠ " name="AddAutoReplaceList"> + æ–°ã—ã„リストã®åå‰: + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="自動置æ›ãƒªã‚¹ãƒˆã®åå‰ã‚’変更" name="RenameAutoReplaceList"> + åå‰ '[DUPNAME]' ã¯æ—¢ã«ä½¿ã‚れã¦ã„ã¾ã™ +一æ„ã®åå‰ã‚’入力ã—ã¦ãã ã•ã„: + <form name="form"> + <button name="ReplaceList" text="ç€ç”¨ä¸ã®ãƒªã‚¹ãƒˆã‚’入れ替ãˆã‚‹"/> + <button name="SetName" text="æ–°ã—ã„åå‰ã‚’使用"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + ã‚ーワードã¯ä¸€èªžã§ãªã‘れã°ãªã‚‰ãšã€ç½®æ›ã¯ç©ºã«ã§ãã¾ã›ã‚“。 + </notification> + <notification name="InvalidAutoReplaceList"> + ãã®ç½®æ›ãƒªã‚¹ãƒˆã¯ç„¡åйã§ã™ã€‚ + </notification> + <notification name="SpellingDictImportRequired"> + ファイルã€åå‰ãŠã‚ˆã³è¨€èªžã‚’指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ + </notification> + <notification name="SpellingDictIsSecondary"> + 辞書 [DIC_NAME] ã«ã€Œaffã€ãƒ•ァイルãŒãªã„よã†ã§ã™ã€‚ã“れã¯ã“ã®è¾žæ›¸ãŒã€Œã‚»ã‚«ãƒ³ãƒ€ãƒªã€è¾žæ›¸ã§ã‚ã‚‹ã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚ +ã“ã®è¾žæ›¸ã¯è¿½åŠ è¾žæ›¸ã¨ã—ã¦ä½¿ç”¨ã§ãã¾ã™ãŒã€ãƒ¡ã‚¤ãƒ³è¾žæ›¸ã¨ã—ã¦ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。 + +https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries ã‚’å‚ç…§ã—ã¦ãã ã•ã„。 + </notification> + <notification name="SpellingDictImportFailed"> + [FROM_NAME] ã‹ã‚‰ + +[TO_NAME] ã¸ã‚³ãƒ”ーã§ãã¾ã›ã‚“ + </notification> <notification label="アウトフィットをä¿å˜ã™ã‚‹" name="SaveOutfitAs"> ç€ç”¨ä¸ã®ã‚¢ã‚¦ãƒˆãƒ•ィットを新ã—ã„アウトフットã¨ã—ã¦ä¿å˜ï¼š <form name="form"> @@ -990,7 +1069,7 @@ L$ ã¯è¿”金ã•れã¾ã›ã‚“。 </form> </notification> <notification label="ç€ç”¨ç‰©ã‚’ä¿å˜" name="SaveWearableAs"> - アイテムを別åã§æŒã¡ç‰©ã«ä¿å˜ï¼š + アイテムを別åã§ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«ä¿å˜ï¼š <form name="form"> <input name="message"> [DESC](新è¦ï¼‰ @@ -1010,7 +1089,7 @@ L$ ã¯è¿”金ã•れã¾ã›ã‚“。 </form> </notification> <notification name="RemoveFromFriends"> - フレンドリストã‹ã‚‰ [NAME] を削除ã—ã¾ã™ã‹ï¼Ÿ + フレンドリストã‹ã‚‰ <nolink>[NAME]</nolink> を削除ã—ã¾ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> <notification name="RemoveMultipleFromFriends"> @@ -1144,8 +1223,13 @@ L$ ã¯è¿”金ã•れã¾ã›ã‚“。 -safe オプションを指定ã—ãŸã®ã§ã€ 表示è¨å®šã¯ã‚»ãƒ¼ãƒ•レベルã«è¨å®šã•れã¦ã„ã¾ã™ã€‚ </notification> - <notification name="DisplaySetToRecommended"> - 表示è¨å®šã¯ã€ã‚ãªãŸã®ã‚·ã‚¹ãƒ†ãƒ æ§‹æˆã«åŸºã¥ã„ã¦æŽ¨å¥¨ã•れãŸãƒ¬ãƒ™ãƒ«ã«è¨å®šã•れã¦ã„ã¾ã™ã€‚ + <notification name="DisplaySetToRecommendedGPUChange"> + グラフィックã®å¤‰æ›´ã«ã‚ˆã‚Šã€ç”»é¢è¨å®šã¯æŽ¨å¥¨ãƒ¬ãƒ™ãƒ«ã«è¨å®šã•れã¾ã—ãŸã€‚ +'[LAST_GPU]' ã‹ã‚‰ +'[THIS_GPU]' ã¾ã§ + </notification> + <notification name="DisplaySetToRecommendedFeatureChange"> + レンダリングサブシステムã®å¤‰æ›´ã«ã‚ˆã‚Šã€ç”»é¢è¨å®šã¯æŽ¨å¥¨ãƒ¬ãƒ™ãƒ«ã«è¨å®šã•れã¾ã—ãŸã€‚ </notification> <notification name="ErrorMessage"> [ERROR_MESSAGE] @@ -1156,7 +1240,7 @@ L$ ã¯è¿”金ã•れã¾ã›ã‚“。 è¿‘ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ç§»å‹•ã—ã¾ã—ãŸã€‚ </notification> <notification name="AvatarMovedLast"> - å‰å›žã„ãŸå ´æ‰€ã¯ç¾åœ¨ã”利用ã„ãŸã ã‘ã¾ã›ã‚“。 + リクエストã•れãŸå ´æ‰€ã¯ç¾åœ¨ã”利用ã„ãŸã ã‘ã¾ã›ã‚“。 è¿‘ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ç§»å‹•ã—ã¾ã—ãŸã€‚ </notification> <notification name="AvatarMovedHome"> @@ -1175,8 +1259,7 @@ L$ ã¯è¿”金ã•れã¾ã›ã‚“。 [APP_NAME] ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå®Œäº†ã—ã¾ã—ãŸã€‚ [SECOND_LIFE] を使ã£ãŸã“ã¨ãŒãªã„å ´åˆã¯ã€ãƒã‚°ã‚¤ãƒ³ã™ã‚‹å‰ã«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ä½œæˆã‚’行ã£ã¦ãã ã•ã„。 -[http://join.secondlife.com/?lang=ja-JP] ã§æ–°ã—ã„アカウントを作æˆã—ã¾ã™ã‹ï¼Ÿ - <usetemplate name="okcancelbuttons" notext="続行" yestext="æ–°è¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆ..."/> + <usetemplate name="okcancelbuttons" notext="続行" yestext="アカウントを作æˆ..."/> </notification> <notification name="LoginPacketNeverReceived"> 接続ãŒãªã‹ãªã‹ã§ãã¾ã›ã‚“。 ãŠä½¿ã„ã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒƒãƒˆæŽ¥ç¶šã‹ã€[SECOND_LIFE_GRID] ã®å•題ã¨è€ƒãˆã‚‰ã‚Œã¾ã™ã€‚ @@ -1467,8 +1550,8 @@ http://secondlife.com/download ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã <usetemplate ignoretext="オブジェクトを所有者ã«è¿”å´ã™ã‚‹å‰ã®ç¢ºèª" name="okcancelignore" notext="å–り消ã—" yestext="OK"/> </notification> <notification name="GroupLeaveConfirmMember"> - ç¾åœ¨ã‚ãªãŸã¯ [GROUP] ã®ãƒ¡ãƒ³ãƒãƒ¼ã§ã™ã€‚ -ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—を抜ã‘ã¾ã™ã‹ï¼Ÿ + ç¾åœ¨ã€ã‚ãªãŸã¯ <nolink>[GROUP]</nolink> グループã®ãƒ¡ãƒ³ãƒãƒ¼ã§ã™ã€‚ +グループã‹ã‚‰è„±é€€ã—ã¾ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> <notification name="ConfirmKick"> @@ -1698,83 +1781,128 @@ http://wiki.secondlife.com/wiki/Setting_your_display_name ã‚’å‚ç…§ã—ã¦ãã ã <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> <notification name="RegionEntryAccessBlocked"> - ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼ˆåœ°åŸŸï¼‰ã¸ã¯å…¥ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 年齢を確èªã™ã‚‹éš›ã®æƒ…å ±ã«ä¸è¶³ãŒã‚ã£ãŸãŸã‚ã¨è€ƒãˆã‚‰ã‚Œã¾ã™ã€‚ - -最新ビューワãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã‚‹ã‹ã‚’ã”確èªãã ã•ã„。ã“ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã§ã®ã‚¢ã‚¯ã‚»ã‚¹ã«é–¢ã™ã‚‹è©³ç´°ã¯ãƒŠãƒ¬ãƒƒã‚¸ãƒ™ãƒ¼ã‚¹ã‚’ã”覧ãã ã•ã„。 + 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨å®šã‚’è¶…ãˆã‚‹ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚「ミー〠> 「環境è¨å®šã€ > 「一般ã€ã‚’é¸æŠžã—ã¦ã€ç’°å¢ƒè¨å®šã‚’変更ã§ãã¾ã™ã€‚ <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼ˆåœ°åŸŸï¼‰ã¸ã¯å…¥ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 - -ナレッジベースを開ãレーティング区分ã«ã¤ã„ã¦å¦ã³ã¾ã™ã‹ï¼Ÿ + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/ja + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="レーティング区分ã®åˆ¶é™ã®ãŸã‚ã€ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«å…¥ã‚‹ã“ã¨ãŒã§ããªã„ã¨ã" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/> + <usetemplate ignoretext="ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼ˆåœ°åŸŸï¼‰ã®æ¨ªæ–:訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãるコンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼ˆåœ°åŸŸï¼‰ã¸ã¯å…¥ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 + 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨å®šã¯ [REGIONMATURITY] コンテンツ除外ã™ã‚‹ã‚ˆã†ã«è¨å®šã•れã¦ã„ã¾ã™ã€‚ + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ </notification> <notification name="RegionEntryAccessBlocked_Change"> - レーティング区分ã«é–¢ã™ã‚‹è¨å®šã«ã‚ˆã‚Šã€ãã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ã¯ç«‹ã¡å…¥ã‚Œã¾ã›ã‚“。 - -ãã®åœ°åŸŸã«å…¥ã‚‹ã«ã¯ã€ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã®è¨å®šã‚’変更ã—ã¦ãã ã•ã„。変更ã™ã‚‹ã¨ã€[REGIONMATURITY]ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã®æ¤œç´¢ã‚„アクセスãŒå¯èƒ½ã«ãªã‚Šã¾ã™ã€‚å¤‰æ›´å†…å®¹ã‚’å…ƒã«æˆ»ã™ã«ã¯ã€ãƒŸãƒ¼ > 環境è¨å®š > ä¸€èˆ¬ã‚’é¸æŠžã—ã¦ãã ã•ã„。 + 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨å®šã•れã¦ã„ã¾ã™ã€‚環境è¨å®šã‚’変更ã™ã‚‹ã‹ã€å–り消ã™ã“ã¨ãŒã§ãã¾ã™ã€‚環境è¨å®šã‚’変更ã—ãŸå¾Œã€ã‚‚ã†ä¸€åº¦ã€åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«å…¥ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ <form name="form"> <button name="OK" text="環境è¨å®šã®å¤‰æ›´"/> - <button default="true" name="Cancel" text="é–‰ã˜ã‚‹"/> - <ignore name="ignore" text="é¸æŠžã—ãŸãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒåŽŸå› ã§ã€ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«å…¥ã‚Œãªã„ã¨ã"/> + <button default="true" name="Cancel" text="å–り消ã—"/> + <ignore name="ignore" text="ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼ˆåœ°åŸŸï¼‰ã®æ¨ªæ–:訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨å®šã«ã‚ˆã‚Šé™¤å¤–ã•れãŸã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"/> </form> </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + ã‚ãªãŸã®ç’°å¢ƒè¨å®šãŒã‚µãƒ¼ãƒãƒ¼ã¨åŒæœŸã—ã¦ã„ãªã„ãŸã‚ã€ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã«æŠ€è¡“çš„ãªå•題ãŒç™ºç”Ÿã—ã¦ã„ã¾ã™ã€‚ + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨å®šã‚’è¶…ãˆã‚‹ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚「ミー〠> 「環境è¨å®šã€ > 「一般ã€ã‚’é¸æŠžã—ã¦ã€ç’°å¢ƒè¨å®šã‚’変更ã§ãã¾ã™ã€‚ + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="テレãƒãƒ¼ãƒˆï¼šè¨ªå•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãるコンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨å®šã•れã¦ã„ã¾ã™ã€‚ + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨å®šã•れã¦ã„ã¾ã™ã€‚環境è¨å®šã‚’変更ã—ã¦ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’ç¶šã‘ã‚‹ã‹ã€ã“ã®ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’å–り消ã™ã“ã¨ãŒã§ãã¾ã™ã€‚ + <form name="form"> + <button name="OK" text="変更ã—ã¦ç¶šã‘ã‚‹"/> + <button name="Cancel" text="å–り消ã—"/> + <ignore name="ignore" text="テレãƒãƒ¼ãƒˆï¼ˆå†èµ·å‹•å¯èƒ½ï¼‰ï¼šè¨ªå•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨å®šã«ã‚ˆã‚Šé™¤å¤–ã•れãŸã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨å®šã•れã¦ã„ã¾ã™ã€‚環境è¨å®šã‚’変更ã™ã‚‹ã‹ã€ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’å–り消ã™ã“ã¨ãŒã§ãã¾ã™ã€‚環境è¨å®šã‚’変更ã—ãŸå¾Œã€ã‚‚ã†ä¸€åº¦ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’実行ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ + <form name="form"> + <button name="OK" text="環境è¨å®šã®å¤‰æ›´"/> + <button name="Cancel" text="å–り消ã—"/> + <ignore name="ignore" text="テレãƒãƒ¼ãƒˆï¼ˆå†èµ·å‹•ä¸å¯ï¼‰ï¼šè¨ªå•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨å®šã«ã‚ˆã‚Šé™¤å¤–ã•れãŸã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + ã‚ãªãŸã®ç’°å¢ƒè¨å®šãŒã‚µãƒ¼ãƒãƒ¼ã¨åŒæœŸã—ã¦ã„ãªã„ãŸã‚ã€ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã«æŠ€è¡“çš„ãªå•題ãŒç™ºç”Ÿã—ã¦ã„ã¾ã™ã€‚ + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†è¨å®šã¯ç¾åœ¨ [RATING] ã§ã™ã€‚ + 今後ã€[RATING] コンテンツ付ãã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã‚’訪å•ã—よã†ã¨ã—ã¦ã„ã‚‹ã¨ã„ã†é€šçŸ¥ã‚’å—ã‘å–りã¾ã›ã‚“。後ã§ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãƒãƒ¼ã®ã€ŒãƒŸãƒ¼ã€ > 「環境è¨å®šã€ > 「一般ã€ã‚’使用ã—ã¦ã€ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã®ç’°å¢ƒè¨å®šã‚’変更ã§ãã¾ã™ã€‚ + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + ç¾åœ¨ã€[PREFERRED_MATURITY] コンテンツを表示ã™ã‚‹ã‚ˆã†ã«ç’°å¢ƒè¨å®šã‚’変更ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚ãªãŸã®ç’°å¢ƒè¨å®šã¯ã€[ACTUAL_MATURITY] コンテンツを表示ã™ã‚‹ã‚ˆã†ã«ãƒªã‚»ãƒƒãƒˆã•れã¾ã—ãŸã€‚メニューãƒãƒ¼ã®ã€ŒãƒŸãƒ¼ã€ > 「環境è¨å®šã€ > 「一般ã€ã‚’使用ã—ã¦ã€ã‚‚ã†ä¸€åº¦ç’°å¢ƒè¨å®šã‚’変更ã§ãã¾ã™ã€‚ + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’å–å¾—ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 年齢を確èªã™ã‚‹éš›ã®æƒ…å ±ã«ä¸è¶³ãŒã‚ã£ãŸãŸã‚ã¨è€ƒãˆã‚‰ã‚Œã¾ã™ã€‚ - -最新ビューワãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã‚‹ã‹ã‚’ã”確èªãã ã•ã„。ã“ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã§ã®ã‚¢ã‚¯ã‚»ã‚¹ã«é–¢ã™ã‚‹è©³ç´°ã¯ãƒŠãƒ¬ãƒƒã‚¸ãƒ™ãƒ¼ã‚¹ã‚’ã”覧ãã ã•ã„。 + å–å¾—ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨å®šã‚’è¶…ãˆã‚‹ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚「ミー〠> 「環境è¨å®šã€ > 「一般ã€ã‚’é¸æŠžã—ã¦ã€ç’°å¢ƒè¨å®šã‚’変更ã§ãã¾ã™ã€‚ <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’å–å¾—ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 - -ナレッジベースを開ãレーティング区分ã«ã¤ã„ã¦å¦ã³ã¾ã™ã‹ï¼Ÿ + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + ã“ã®åœŸåœ°ã‚’購入ã§ãã‚‹ã®ã¯ã€æˆäººã ã‘ã§ã™ã€‚ <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/ja + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="レーティング区分ã®åˆ¶é™ã®ãŸã‚ã€ã“ã®åœŸåœ°ã‚’å–å¾—ã§ãã¾ã›ã‚“" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/> + <usetemplate ignoretext="ã“ã®åœŸåœ°ã‚’購入ã§ãã‚‹ã®ã¯ã€æˆäººã ã‘ã§ã™ã€‚" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’å–å¾—ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 + å–å¾—ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨å®šã•れã¦ã„ã¾ã™ã€‚ + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + å–å¾—ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ </notification> <notification name="LandClaimAccessBlocked_Change"> - ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†è¨å®šã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’å–å¾—ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 - -「è¨å®šã‚’変更ã€ã‚’クリックã—ã¦ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã‚’上ã’ã‚‹ã¨ã€å…¥ã‚Œã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚ ã‚ãªãŸã¯ä»Šå¾Œ [REGIONMATURITY] ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã®æ¤œç´¢åŠã³ã‚¢ã‚¯ã‚»ã‚¹ãŒå¯èƒ½ã¨ãªã‚Šã¾ã™ã€‚ ã‚ã¨ã§è¨å®šã‚’å…ƒã«æˆ»ã—ãŸã„å ´åˆã¯ã€ã€Œç·¨é›†ã€ï¼žã€Œç’°å¢ƒè¨å®šã€ã‚’ã”覧ãã ã•ã„。 - <usetemplate ignoretext="é¸æŠžã—ãŸãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒåŽŸå› ã§ã€åœŸåœ°ã‚’å–å¾—ã§ããªã„ã¨ã" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="è¨å®šã®å¤‰æ›´"/> + å–å¾—ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨å®šã•れã¦ã„ã¾ã™ã€‚環境è¨å®šã‚’変更ã—ã¦ã€ã‚‚ã†ä¸€åº¦åœŸåœ°ã®å–得を試ã¿ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ + <form name="form"> + <button name="OK" text="環境è¨å®šã®å¤‰æ›´"/> + <button name="Cancel" text="å–り消ã—"/> + <ignore name="ignore" text="å–å¾—ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨å®šã«ã‚ˆã‚Šé™¤å¤–ã•れãŸã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’購入ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 年齢を確èªã™ã‚‹éš›ã®æƒ…å ±ã«ä¸è¶³ãŒã‚ã£ãŸãŸã‚ã¨è€ƒãˆã‚‰ã‚Œã¾ã™ã€‚ - -最新ビューワãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã‚‹ã‹ã‚’ã”確èªãã ã•ã„。ã“ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã§ã®ã‚¢ã‚¯ã‚»ã‚¹ã«é–¢ã™ã‚‹è©³ç´°ã¯ãƒŠãƒ¬ãƒƒã‚¸ãƒ™ãƒ¼ã‚¹ã‚’ã”覧ãã ã•ã„。 + 購入ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨å®šã‚’è¶…ãˆã‚‹ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚「ミー〠> 「環境è¨å®šã€ > 「一般ã€ã‚’é¸æŠžã—ã¦ã€ç’°å¢ƒè¨å®šã‚’変更ã§ãã¾ã™ã€‚ <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’購入ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 - -ナレッジベースを開ãレーティング区分ã«ã¤ã„ã¦å¦ã³ã¾ã™ã‹ï¼Ÿ + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + ã“ã®åœŸåœ°ã‚’å–å¾—ã§ãã‚‹ã®ã¯ã€æˆäººã ã‘ã§ã™ã€‚ <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/ja + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="レーティング区分ã®åˆ¶é™ã®ãŸã‚ã€ã“ã®åœŸåœ°ã‚’購入ã§ãã¾ã›ã‚“" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/> + <usetemplate ignoretext="ã“ã®åœŸåœ°ã‚’å–å¾—ã§ãã‚‹ã®ã¯ã€æˆäººã ã‘ã§ã™ã€‚" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’購入ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 + 購入ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨å®šã•れã¦ã„ã¾ã™ã€‚ + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + 購入ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ </notification> <notification name="LandBuyAccessBlocked_Change"> - ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†è¨å®šã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’購入ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 - -「è¨å®šã‚’変更ã€ã‚’クリックã—ã¦ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã‚’上ã’ã‚‹ã¨ã€å…¥ã‚Œã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚ ã‚ãªãŸã¯ä»Šå¾Œ [REGIONMATURITY] ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã®æ¤œç´¢åŠã³ã‚¢ã‚¯ã‚»ã‚¹ãŒå¯èƒ½ã¨ãªã‚Šã¾ã™ã€‚ ã‚ã¨ã§è¨å®šã‚’å…ƒã«æˆ»ã—ãŸã„å ´åˆã¯ã€ã€Œç·¨é›†ã€ï¼žã€Œç’°å¢ƒè¨å®šã€ã‚’ã”覧ãã ã•ã„。 - <usetemplate ignoretext="é¸æŠžã—ãŸãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒåŽŸå› ã§ã€åœŸåœ°ã‚’購入ã§ããªã„ã¨ã" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="è¨å®šã®å¤‰æ›´"/> + 購入ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨å®šã•れã¦ã„ã¾ã™ã€‚環境è¨å®šã‚’変更ã—ã¦ã€ã‚‚ã†ä¸€åº¦åœŸåœ°ã®è³¼å…¥ã‚’試ã¿ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ + <form name="form"> + <button name="OK" text="環境è¨å®šã®å¤‰æ›´"/> + <button name="Cancel" text="å–り消ã—"/> + <ignore name="ignore" text="購入ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨å®šã«ã‚ˆã‚Šé™¤å¤–ã•れãŸã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"/> + </form> </notification> <notification name="TooManyPrimsSelected"> é¸æŠžã—ãŸãƒ—リムãŒå¤šã™ãŽã¾ã™ã€‚ [MAX_PRIM_COUNT] å€‹é¸æŠžã™ã‚‹ã‹ã€ãƒ—リム数を減らã—ã¦ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。 @@ -1832,10 +1960,9 @@ L$ [AMOUNT] ã§ã€ã“ã®ã‚¯ãƒ©ã‚·ãƒ•ァイド広告を今ã™ã公開ã—ã¾ã™ã </form> </notification> <notification label="地域ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†æŒ‡å®šå¤‰æ›´æ¸ˆã¿" name="RegionMaturityChange"> - ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼ˆåœ°åŸŸï¼‰ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒã‚¢ãƒƒãƒ—デートã•れã¾ã—ãŸã€‚ -地図ã«å¤‰æ›´ãŒåæ˜ ã•れるã¾ã§æ•°åˆ†ã‹ã‹ã‚‹ã“ã¨ãŒã‚りã¾ã™ã€‚ - -Adult 専用リージョンã«å…¥ã‚‹ã«ã¯ã€ä½äººã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¹´é½¢ç¢ºèªã‹æ”¯æ‰•方法ã®ã„ãšã‚Œã‹ã§ã€Œç¢ºèªæ¸ˆã¿ã€ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。 + ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒå¤‰æ›´ã•れã¾ã—ãŸã€‚ +地図ã«ã“ã®å¤‰æ›´ãŒåæ˜ ã™ã‚‹ã«ã¯æ•°åˆ†ã‹ã‹ã‚‹ã“ã¨ãŒã‚りã¾ã™ã€‚ + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="ボイスãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ä¸ä¸€è‡´" name="VoiceVersionMismatch"> [APP_NAME] ã®ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã€ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ãŠã‘るボイスãƒãƒ£ãƒƒãƒˆã®äº’æ›æ€§ãŒã‚りã¾ã›ã‚“。 ボイスãƒãƒ£ãƒƒãƒˆã‚’æ£å¸¸ã«è¡Œã†ãŸã‚ã«ã¯ã€[APP_NAME] ã®ã‚¢ãƒƒãƒ—デートãŒå¿…è¦ã§ã™ã€‚ @@ -1870,7 +1997,7 @@ Adult 専用リージョンã«å…¥ã‚‹ã«ã¯ã€ä½äººã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¹´é½¢ç¢ </notification> <notification name="BuyCopy"> コピーを [OWNER] ã‹ã‚‰ L$ [PRICE] ã§è³¼å…¥ã—ã¾ã™ã‹ï¼Ÿ -購入ã—ãŸã‚ªãƒ–ジェクトã¯ã€ã‚ãªãŸã®ã€ŒæŒã¡ç‰©ã€ã«ã‚³ãƒ”ーã•れã¾ã™ã€‚ +購入ã—ãŸã‚ªãƒ–ジェクトã¯ã€ã‚ãªãŸã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«ã‚³ãƒ”ーã•れã¾ã™ã€‚ å¯èƒ½ãªæ“作ã¯ã€ ä¿®æ£ï¼š[MODIFYPERM]ã€ã‚³ãƒ”ー:[COPYPERM]〠å†è²©ãƒ»ãƒ—レゼント:[RESELLPERM] ã§ã™ã€‚ @@ -1878,7 +2005,7 @@ Adult 専用リージョンã«å…¥ã‚‹ã«ã¯ã€ä½äººã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¹´é½¢ç¢ </notification> <notification name="BuyCopyNoOwner"> L$ [PRICE] ã§ã‚³ãƒ”ーを購入ã—ã¾ã™ã‹ï¼Ÿ -購入ã—ãŸã‚ªãƒ–ジェクトã¯ã€ã‚ãªãŸã®ã€ŒæŒã¡ç‰©ã€ã«ã‚³ãƒ”ーã•れã¾ã™ã€‚ +購入ã—ãŸã‚ªãƒ–ジェクトã¯ã€ã‚ãªãŸã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«ã‚³ãƒ”ーã•れã¾ã™ã€‚ å¯èƒ½ãªæ“作ã¯ã€ ä¿®æ£ï¼š[MODIFYPERM]ã€ã‚³ãƒ”ー:[COPYPERM]〠å†è²©ãƒ»ãƒ—レゼント:[RESELLPERM] ã§ã™ã€‚ @@ -1886,12 +2013,12 @@ Adult 専用リージョンã«å…¥ã‚‹ã«ã¯ã€ä½äººã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¹´é½¢ç¢ </notification> <notification name="BuyContents"> ä¸èº«ã‚’ [OWNER] ã‹ã‚‰ L$ [PRICE] ã§è³¼å…¥ã—ã¾ã™ã‹ï¼Ÿ -購入ã—ãŸä¸èº«ã¯ã€ã‚ãªãŸã®ã€ŒæŒã¡ç‰©ã€ã«ã‚³ãƒ”ーã•れã¾ã™ã€‚ +購入ã—ãŸä¸èº«ã¯ã€ã‚ãªãŸã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«ã‚³ãƒ”ーã•れã¾ã™ã€‚ <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> <notification name="BuyContentsNoOwner"> L$ [PRICE] ã§ä¸èº«ã‚’購入ã—ã¾ã™ã‹ï¼Ÿ -購入ã—ãŸä¸èº«ã¯ã€ã‚ãªãŸã®ã€ŒæŒã¡ç‰©ã€ã«ã‚³ãƒ”ーã•れã¾ã™ã€‚ +購入ã—ãŸä¸èº«ã¯ã€ã‚ãªãŸã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«ã‚³ãƒ”ーã•れã¾ã™ã€‚ <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> <notification name="ConfirmPurchase"> @@ -1920,20 +2047,20 @@ Adult 専用リージョンã«å…¥ã‚‹ã«ã¯ã€ä½äººã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¹´é½¢ç¢ <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="MoveInventoryFromObject"> - 「コピーä¸å¯ã€ã®æŒã¡ç‰©ã‚¢ã‚¤ãƒ†ãƒ ã‚’é¸æŠžã—ã¾ã—ãŸã€‚ -ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ã‚³ãƒ”ーã•れãªã„ã¾ã¾ã€ã‚ãªãŸã®ã€ŒæŒã¡ç‰©ã€ã«ç§»å‹•ã•れã¾ã™ã€‚ + 「コピーä¸å¯ã€ã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‚¢ã‚¤ãƒ†ãƒ ã‚’é¸æŠžã—ã¾ã—ãŸã€‚ +ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ã‚³ãƒ”ーã•れãªã„ã¾ã¾ã€ã‚ãªãŸã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«ç§»å‹•ã•れã¾ã™ã€‚ アイテムを動ã‹ã—ã¾ã™ã‹ï¼Ÿ <usetemplate ignoretext="「コピーä¸å¯ã€ã®ã‚¢ã‚¤ãƒ†ãƒ をオブジェクトã‹ã‚‰å‹•ã‹ã™å‰ã®è¦å‘Š" name="okcancelignore" notext="ã‚ャンセル" yestext="OK"/> </notification> <notification name="MoveInventoryFromScriptedObject"> - 「コピーä¸å¯ã€ã®æŒã¡ç‰©ã‚¢ã‚¤ãƒ†ãƒ ã‚’é¸æŠžã—ã¾ã—ãŸã€‚ -ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ã‚³ãƒ”ーã•れãšã«ã€ã‚ãªãŸã®ã€ŒæŒã¡ç‰©ã€ã«ç§»å‹•ã•れã¾ã™ã€‚ -ã“ã®ã‚ªãƒ–ジェクトã¯ã‚¹ã‚¯ãƒªãƒ—ト付ããªã®ã§ã€ã€ŒæŒã¡ç‰©ã€ã«ç§»å‹•ã•ã›ã‚‹ã¨ + 「コピーä¸å¯ã€ã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‚¢ã‚¤ãƒ†ãƒ ã‚’é¸æŠžã—ã¾ã—ãŸã€‚ +ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ã‚³ãƒ”ーã•れãšã«ã€ã‚ãªãŸã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«ç§»å‹•ã•れã¾ã™ã€‚ +ã“ã®ã‚ªãƒ–ジェクトã¯ã‚¹ã‚¯ãƒªãƒ—ト付ããªã®ã§ã€ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«ç§»å‹•ã•ã›ã‚‹ã¨ スクリプトã«èª¤å‹•作ãŒèµ·ãã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚ -æŒã¡ç‰©ã‚¢ã‚¤ãƒ†ãƒ を移動ã—ã¾ã™ã‹ï¼Ÿ +インベントリアイテムを移動ã—ã¾ã™ã‹ï¼Ÿ <usetemplate ignoretext="スクリプト入りã®ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã‚’å£Šã™æã‚Œã®ã‚る「コピーä¸å¯ã€ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’å‹•ã‹ã™å‰ã®è¦å‘Š" name="okcancelignore" notext="ã‚ャンセル" yestext="OK"/> </notification> <notification name="ClickActionNotPayable"> @@ -1954,7 +2081,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"/> @@ -2036,7 +2169,7 @@ Linden Lab </notification> <notification name="ConfirmEmptyTrash"> ã”ã¿ç®±ã®ä¸èº«ã‚’ã™ã¹ã¦å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ - <usetemplate ignoretext="æŒã¡ç‰©ã®ã”ã¿ç®±ãƒ•ォルダを空ã«ã™ã‚‹å‰ã®ç¢ºèª" name="okcancelignore" notext="ã‚ャンセル" yestext="OK"/> + <usetemplate ignoretext="インベントリã®ã”ã¿ç®±ãƒ•ォルダを空ã«ã™ã‚‹å‰ã®ç¢ºèª" name="okcancelignore" notext="ã‚ャンセル" yestext="OK"/> </notification> <notification name="ConfirmClearBrowserCache"> トラベルã€Webã€æ¤œç´¢ã®å±¥æ´ã‚’ã™ã¹ã¦å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ @@ -2124,14 +2257,11 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã <usetemplate ignoretext="「容姿ã€ã‚’編集ä¸ã«ã€ä½œæˆã™ã‚‹è¡£é¡žã‚’装ç€ã™ã‚‹ã¨ã" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> </notification> <notification name="NotAgeVerified"> - Second Life ã§ Adult 指定ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã‚„é ˜åŸŸã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ã®ã¯ 18 æ³ä»¥ä¸Šã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ã¿ã§ã™ã€‚年齢確èªãƒšãƒ¼ã‚¸ã§ 18 æ³ä»¥ä¸Šã§ã‚ã‚‹ã“ã¨ã‚’証明ã—ã¦ãã ã•ã„。 -ã“れをクリックã™ã‚‹ã¨ã‚¦ã‚§ãƒ–ブラウザãŒé–‹ãã¾ã™ã€‚ - -[_URL] - <url name="url" option="0"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="å¹´é½¢ã®ç¢ºèªã‚’済ã¾ã›ã¦ã„ãªã„ã¨ã" name="okcancelignore" notext="å–り消ã—" yestext="年齢確èªãƒšãƒ¼ã‚¸ã‚’é–‹ã"/> + 訪å•ã—よã†ã¨ã—ã¦ã„ã‚‹ãƒã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã¯ã€18 æ‰ä»¥ä¸Šã®ä½äººã«åˆ¶é™ã•れã¦ã„ã¾ã™ã€‚ + <usetemplate ignoretext="年齢制é™ä»˜ãã®ã‚¨ãƒªã‚¢ã‚’訪å•ã™ã‚‹å¹´é½¢ã«é”ã—ã¦ã„ã¾ã›ã‚“。" name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + ãƒã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã¯ 18 æ‰ä»¥ä¸Šã«åˆ¶é™ã•れã¦ã„ã¾ã™ã€‚ </notification> <notification name="Cannot enter parcel: no payment info on file"> æ”¯æ‰•æƒ…å ±ãŒç™»éŒ²ã•れã¦ã„ãªã„ã¨ã“ã®ã‚¨ãƒªã‚¢ã‚’訪れるã“ã¨ãŒã§ãã¾ã›ã‚“。 [SECOND_LIFE] サイトã§ç™»éŒ²ã‚’行ã„ã¾ã™ã‹ï¼Ÿ @@ -2167,10 +2297,10 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã ä»¶å: [SUBJECT]ã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ï¼š [MESSAGE] </notification> <notification name="FriendOnline"> - [NAME] ã¯ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ä¸ã§ã™ + <nolink>[NAME]</nolink> ã¯ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã§ã™ </notification> <notification name="FriendOffline"> - [NAME] ã¯ã‚ªãƒ•ラインä¸ã§ã™ + <nolink>[NAME]</nolink> ã¯ã‚ªãƒ•ラインã§ã™ </notification> <notification name="AddSelfFriend"> 残念ãªãŒã‚‰è‡ªåˆ†è‡ªèº«ã‚’フレンド登録ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 @@ -2220,7 +2350,7 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã 親エステート間ã§ã¯ IM ã‚’é€ä¿¡ã§ãã¾ã›ã‚“。 </notification> <notification name="TransferInventoryAcrossParentEstates"> - è¦ªã‚¨ã‚¹ãƒ†ãƒ¼ãƒˆé–“ã§æŒã¡ç‰©ã‚’移動ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 + 親エステート間ã§ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‚’移動ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 </notification> <notification name="UnableToLoadNotecard"> ノートカードをèªã¿è¾¼ã‚ã¾ã›ã‚“。ã‚ã¨ã§å†åº¦ãŠè©¦ã—ãã ã•ã„。 @@ -2272,7 +2402,7 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã [NAME] ã¯ã€ã‚ãªãŸãŒæ¸¡ã—ãŸã‚¢ã‚¤ãƒ†ãƒ ã‚’å—ã‘å–りã¾ã—ãŸã€‚ </notification> <notification name="InventoryDeclined"> - [NAME] ã¯ã€æŒã¡ç‰©ã®æä¾›ã‚’æ–りã¾ã—ãŸã€‚ + [NAME] ã¯ã€ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã®æä¾›ã‚’æ–りã¾ã—ãŸã€‚ </notification> <notification name="ObjectMessage"> [NAME]: [MESSAGE] @@ -2284,13 +2414,15 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã ã‚³ãƒ¼ãƒªãƒ³ã‚°ã‚«ãƒ¼ãƒ‰ãŒæ‹’å¦ã•れã¾ã—ãŸã€‚ </notification> <notification name="TeleportToLandmark"> - ç”»é¢å³ã®ã€Œå ´æ‰€ã€ãƒ‘ãƒãƒ«ã‚’é–‹ã„ã¦ã€ã€Œãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã€ã‚¿ãƒ–ã‚’é¸ã¶ã¨ã€[NAME] ã¨ã„ã£ãŸå ´æ‰€ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã§ãã¾ã™ã€‚ -好ããªãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã‚’クリックã—ã¦é¸ã³ã€æ¬¡ã«ãƒ‘ãƒãƒ«ä¸‹ã®ã€Œãƒ†ãƒ¬ãƒãƒ¼ãƒˆã€ã‚’クリックã—ã¾ã™ã€‚ -(ランドマークをダブルクリックã€ã¾ãŸã¯å³ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€Œãƒ†ãƒ¬ãƒãƒ¼ãƒˆã€ã‚’é¸ã‚“ã§ã‚‚åŒã˜ã§ã™ã€‚) + [NAME] ãªã©ã®å ´æ‰€ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã™ã‚‹ã«ã¯ã€ã€Œå ´æ‰€ã€ãƒœã‚¿ãƒ³ã‚’クリックã—ã¦ã‹ã‚‰ã€ +表示ã•れãŸã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã§ã€Œãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã€ã‚¿ãƒ–ã‚’é¸æŠžã—ã¾ã™ã€‚ランドマークを +ã„ãšã‚Œã‹ 1 ã¤é¸æŠžã—ã¦ã‹ã‚‰ã€ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ä¸‹éƒ¨ã«ã‚る「テレãƒãƒ¼ãƒˆã€ã‚’クリックã—ã¾ã™ã€‚ +(ã“ã®æ“作ã¯ã€ãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã‚’ダブルクリックã™ã‚‹ã‹ã€å³ã‚¯ãƒªãƒƒã‚¯ã—㦠+「テレãƒãƒ¼ãƒˆã€ã‚’é¸æŠžã—ã¦å®Ÿè¡Œã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚) </notification> <notification name="TeleportToPerson"> - ç”»é¢å³ã®ã€Œäººã€ãƒ‘ãƒãƒ«ã‚’é–‹ã„ã¦ã€[NAME] ã¨ã„ã£ãŸä½äººã«é€£çµ¡ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ -リストã‹ã‚‰ä½äººã‚’é¸æŠžã—ã¦ã€ãƒ‘ãƒãƒ«ä¸‹ã®ã€ŒIMã€ã‚’クリックã—ã¾ã™ã€‚ + [NAME] ã®ã‚ˆã†ãªä½äººã«é€£çµ¡ã‚’ã¨ã‚‹ã«ã¯ã€ã€Œäººã€ãƒœã‚¿ãƒ³ã‚’クリックã—ã€è¡¨ç¤ºã•れるウィンドウã§ã€Œä½äººã€ã‚’é¸æŠžã—ã¦ã‹ã‚‰ã€ +ウィンドウ下部ã«ã‚る「IMã€ã‚’クリックã—ã¾ã™ã€‚ (リストã®åå‰ã‚’ダブルクリックã€ã¾ãŸã¯å³ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€ŒIMã€ã‚’é¸ã‚“ã§ã‚‚åŒã˜ã§ã™ã€‚) </notification> <notification name="CantSelectLandFromMultipleRegions"> @@ -2312,6 +2444,9 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã <notification name="PaymentSent"> [MESSAGE] </notification> + <notification name="PaymentFailure"> + [MESSAGE] + </notification> <notification name="EventNotification"> イベント通知: @@ -2352,16 +2487,16 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã </form> </notification> <notification name="OwnedObjectsReturned"> - é¸æŠžã—ãŸåœŸåœ°ã®åŒºç”»ä¸Šã«ã‚ã£ãŸã‚ãªãŸã®ã‚ªãƒ–ジェクトã¯ã€ã™ã¹ã¦ã‚ãªãŸã®ã€ŒæŒã¡ç‰©ã€ã«è¿”å´ã•れã¾ã—ãŸã€‚ + é¸æŠžã—ãŸåœŸåœ°ã®åŒºç”»ä¸Šã«ã‚ã£ãŸã‚ãªãŸã®ã‚ªãƒ–ジェクトã¯ã€ã™ã¹ã¦ã‚ãªãŸã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«è¿”å´ã•れã¾ã—ãŸã€‚ </notification> <notification name="OtherObjectsReturned"> - [NAME] ãŒæ‰€æœ‰ã™ã‚‹ã€é¸æŠžã—ãŸåŒºç”»ã«ã‚るオブジェクトã¯ã€æ‰€æœ‰è€…ã®æŒã¡ç‰©ã«è¿”å´ã•れã¾ã—ãŸã€‚ + [NAME] ãŒæ‰€æœ‰ã™ã‚‹ã€é¸æŠžã—ãŸåŒºç”»ã«ã‚るオブジェクトã¯ã€æ‰€æœ‰è€…ã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«è¿”å´ã•れã¾ã—ãŸã€‚ </notification> <notification name="OtherObjectsReturned2"> 「 [NAME] ã€ã¨ã„ã†åå‰ã®ä½äººãŒæ‰€æœ‰ã™ã‚‹ã€é¸æŠžã—ãŸåŒºç”»ä¸Šã®ã‚ªãƒ–ジェクトã¯ã€æœ¬äººã«è¿”å´ã•れã¾ã—ãŸã€‚ </notification> <notification name="GroupObjectsReturned"> - é¸æŠžã—ãŸåŒºç”»ä¸Šã®ã€[GROUPNAME] ã¨ã„ã†ã‚°ãƒ«ãƒ¼ãƒ—ã¨å…±æœ‰ã—ã¦ã„ãŸã‚ªãƒ–ジェクトã¯ã€ãれãžã‚Œã®æ‰€æœ‰è€…ã®ã€ŒæŒã¡ç‰©ã€ã«è¿”å´ã•れã¾ã—ãŸã€‚ + é¸æŠžã—ãŸåŒºç”»ä¸Šã®ã€[GROUPNAME] ã¨ã„ã†ã‚°ãƒ«ãƒ¼ãƒ—ã¨å…±æœ‰ã—ã¦ã„ãŸã‚ªãƒ–ジェクトã¯ã€ãれãžã‚Œã®æ‰€æœ‰è€…ã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«è¿”å´ã•れã¾ã—ãŸã€‚ è²æ¸¡ã•れã¦ã„ãŸã€Œå†è²©ãƒ»ãƒ—レゼントå¯ã€ã®ã‚ªãƒ–ジェクトã¯ã€ä»¥å‰ã®æ‰€æœ‰è€…ã«è¿”å´ã•れã¾ã—ãŸã€‚ グループã«è²æ¸¡ã•れã¦ã„ãŸã€Œå†è²©ãƒ»ãƒ—レゼントä¸å¯ã€ã®ã‚ªãƒ–ジェクトã¯ã€å‰Šé™¤ã•れã¾ã—ãŸã€‚ </notification> @@ -2389,6 +2524,23 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã <notification name="NoBuild"> ã“ã®ã‚¨ãƒªã‚¢ã§ã¯åˆ¶ä½œãŒç¦æ¢ã•れã¦ã„ã¾ã™ã€‚ オブジェクトを制作ã—ãŸã‚Š Rez ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 </notification> + <notification name="PathfindingDirty"> + ã“ã®å€¤åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ã¯ã€ä¿ç•™ä¸ã®ãƒ‘スファインディングã®å¤‰æ›´ãŒã‚りã¾ã™ã€‚制作権ãŒã‚ã‚‹å ´åˆã¯ã€ã€Œåœ°åŸŸã®å†æ§‹ç¯‰ã€ãƒœã‚¿ãƒ³ã‚’クリックã—ã¦ã€åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã‚’冿§‹ç¯‰ã§ãã¾ã™ã€‚ + </notification> + <notification name="DynamicPathfindingDisabled"> + ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã§ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ‘ã‚¹ãƒ•ã‚¡ã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ãŒæœ‰åйã«ãªã£ã¦ã„ã¾ã›ã‚“。パスファインディング LSL 呼ã³å‡ºã—を使用ã™ã‚‹ã‚¹ã‚¯ãƒªãƒ—ト化ã•れãŸã‚ªãƒ–ジェクトãŒã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã§ã¯å‹•作ã§ãã¾ã›ã‚“。 + </notification> + <notification name="PathfindingRebakeNavmesh"> + ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã®ã‚ªãƒ–ジェクトを変更ã™ã‚‹ã¨ã€ä»–ã®ç§»å‹•ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæ£ã—ã動作ã—ãªããªã‚‹æã‚ŒãŒã‚りã¾ã™ã€‚移動オブジェクトをæ£ã—ã動作ã•ã›ã‚‹ã«ã¯ã€ã€Œåœ°åŸŸã®å†æ§‹ç¯‰ã€ãƒœã‚¿ãƒ³ã‚’クリックã—ã¾ã™ã€‚詳ã—ã„æƒ…å ±ã¯è¦‹ã‚‹ã«ã¯ã€Œãƒ˜ãƒ«ãƒ—ã€ã‚’é¸æŠžã—ã¦ãã ã•ã„。 + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="ヘルプ" ignoretext="ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã®ã‚ªãƒ–ジェクトを変更ã™ã‚‹ã¨ã€ä»–ã®ç§»å‹•ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæ£ã—ã動作ã—ãªããªã‚‹æã‚ŒãŒã‚りã¾ã™ã€‚" name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã¾ãŸã¯ã‚µãƒ¼ãƒãƒ¼ã«å•題ãŒã‚ã‚‹ã‹ã€åˆ¶ä½œæ¨©ãŒãªã„å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚ã“ã®å•題ã¯ã€ä¸€åº¦ãƒã‚°ã‚¢ã‚¦ãƒˆã—ã¦ã‹ã‚‰ã€ãƒã‚°ã‚¤ãƒ³ã—ç›´ã™ã¨è§£æ±ºã•ã‚Œã‚‹å ´åˆãŒã‚りã¾ã™ã€‚ + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> ã“ã®åŒºç”»ã«ã„ã‚‹ã‚¢ãƒã‚¿ãƒ¼ã‚„ã“ã®åŒºç”»å†…ã§è¡Œã‚れる文å—ãƒãƒ£ãƒƒãƒˆã¯ã€ä»–ã®åŒºç”»ã‹ã‚‰è¦‹ãˆã¾ã›ã‚“。ã‚ãªãŸã«ã¯ã€ã“ã®åŒºç”»å¤–ã«ã„ã‚‹ä½äººãŒè¦‹ãˆãšã€å¤–ã®ä½äººã«ã¯ã‚ãªãŸã®å§¿ãŒè¦‹ãˆã¾ã›ã‚“。ãƒãƒ£ãƒ³ãƒãƒ« 0 ã§ã®é€šå¸¸ã®æ–‡å—ãƒãƒ£ãƒƒãƒˆã‚‚ブãƒãƒƒã‚¯ã•れã¾ã™ã€‚ </notification> @@ -2407,9 +2559,7 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ã„ãªã„ã¨å…¬å…±ã®åœŸåœ°ã‚’å–å¾—ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 </notification> <notification name="RegionTPAccessBlocked"> - ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã¸ã¯å…¥ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 年齢確èªã‚’行ã†ã‹ã€æœ€æ–°ãƒ“ューワをインストールã—ã¦ãã ã•ã„。 - -ç¾åœ¨ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã§ã‚¢ã‚¯ã‚»ã‚¹å¯èƒ½ãªã‚¨ãƒªã‚¢ã«é–¢ã™ã‚‹è©³ç´°ã¯ãƒŠãƒ¬ãƒƒã‚¸ãƒ™ãƒ¼ã‚¹ã‚’å‚ç…§ã—ã¦ãã ã•ã„。 + 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨å®šã‚’è¶…ãˆã‚‹ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚「ミー〠> 「環境è¨å®šã€ > 「一般ã€ã‚’é¸æŠžã—ã¦ã€ç’°å¢ƒè¨å®šã‚’変更ã§ãã¾ã™ã€‚ </notification> <notification name="URBannedFromRegion"> ã‚ãªãŸã¯ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã¸ã®ç«‹å…¥ãŒç¦æ¢ã•れã¦ã„ã¾ã™ã€‚ @@ -2420,11 +2570,11 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã <notification name="ImproperPaymentStatus"> ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«å…¥ã‚‹ãŸã‚ã«é©ã—ãŸæ”¯æ‰•ã„ステータスãŒã‚りã¾ã›ã‚“。 </notification> - <notification name="MustGetAgeRgion"> - ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«å…¥ã‚‹ãŸã‚ã«ã¯ã€å¹´é½¢ç¢ºèªã‚’済ã¾ã›ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ + <notification name="MustGetAgeRegion"> + ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«å…¥ã‚‹ã«ã¯ 18 æ‰ä»¥ä¸Šã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ </notification> <notification name="MustGetAgeParcel"> - ã“ã®åŒºç”»ã«å…¥ã‚‹ãŸã‚ã«ã¯ã€å¹´é½¢ç¢ºèªã‚’済ã¾ã›ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ + ã“ã®åŒºç”»ã«å…¥ã‚‹ã«ã¯ 18 æ‰ä»¥ä¸Šã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ </notification> <notification name="NoDestRegion"> 目的地ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚ @@ -2526,12 +2676,33 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã <notification name="TeleportOffered"> [NAME_SLURL] ã¯ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã§ã‚ãªãŸã‚’呼んã§ã„ã¾ã™ã€‚ -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="テレãƒãƒ¼ãƒˆ"/> <button name="Cancel" text="å–り消ã—"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] ã¯ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã§ã‚ãªãŸã‚’呼んã§ã„ã¾ã™ã€‚ + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ã¯ [REGION_CONTENT_MATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨å®šã¯ [REGION_CONTENT_MATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨å®šã•れã¦ã„ã¾ã™ã€‚環境è¨å®šã‚’変更ã—ã¦ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’ç¶šã‘ã‚‹ã‹ã€ã“ã®ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’å–り消ã™ã“ã¨ãŒã§ãã¾ã™ã€‚ + <form name="form"> + <button name="Teleport" text="変更ã—ã¦ç¶šã‘ã‚‹"/> + <button name="Cancel" text="å–り消ã—"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] ã¯ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã§ã‚ãªãŸã‚’呼んã§ã„ã¾ã™ã€‚ + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +ãŸã ã—ã€ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ã¯æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãるコンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ + </notification> <notification name="TeleportOfferSent"> [TO_NAME] ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’é€ã‚Šã¾ã—ãŸã€‚ </notification> @@ -2567,10 +2738,10 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã </form> </notification> <notification name="FriendshipAccepted"> - [NAME]ã¯ã€ãƒ•レンド登録をå—ã‘入れã¾ã—ãŸã€‚ + <nolink>[NAME]</nolink> ã¯ã‚ãªãŸã‹ã‚‰ã®å‹äººç™»éŒ²ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’å—諾ã—ã¾ã—ãŸã€‚ </notification> <notification name="FriendshipDeclined"> - [NAME]ã¯ã€ãƒ•レンド登録をæ–りã¾ã—ãŸã€‚ + <nolink>[NAME]</nolink> ã¯ã‚ãªãŸã‹ã‚‰ã®å‹äººç™»éŒ²ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’æ‹’å¦ã—ã¾ã—ãŸã€‚ </notification> <notification name="FriendshipAcceptedByMe"> フレンドã®ç™»éŒ²ä¾é ¼ãŒæ‰¿èªã•れã¾ã—ãŸã€‚ @@ -2580,7 +2751,7 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã </notification> <notification name="OfferCallingCard"> [NAME] ãŒã‚³ãƒ¼ãƒªãƒ³ã‚°ã‚«ãƒ¼ãƒ‰ã‚’渡ãã†ã¨ã—ã¦ã„ã¾ã™ã€‚ -ã‚ãªãŸã®æŒã¡ç‰©ã«ãƒ–ックマークãŒè¿½åŠ ã•れã€ã“ã®ä½äººã«ç´ æ—©ã IM ã‚’é€ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ +ã‚ãªãŸã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«ãƒ–ックマークãŒè¿½åŠ ã•れã€ã“ã®ä½äººã«ç´ æ—©ã IM ã‚’é€ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ <form name="form"> <button name="Accept" text="å—ã‘入れる"/> <button name="Decline" text="辞退"/> @@ -2626,32 +2797,28 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã </form> </notification> <notification name="ScriptQuestionCaution"> - [NAME] ãŒæ‰€æœ‰ã™ã‚‹ã€Œ<nolink>[OBJECTNAME]</nolink>〠ã¨ã„ã†ã‚ªãƒ–ジェクトãŒã€æ¬¡ã®ã“ã¨ã‚’ã—よã†ã¨ã—ã¦ã„ã¾ã™ï¼š - -[QUESTIONS] -ã“ã®ã‚ªãƒ–ジェクトや制作者を信用ã§ããªã„å ´åˆã¯ã€ã“ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’æ‹’å¦ã—ã¦ãã ã•ã„。 - -リクエストをå—ã‘ã¾ã™ã‹ï¼Ÿ + è¦å‘Šï¼šã‚ªãƒ–ジェクト '<nolink>[OBJECTNAME]</nolink>' ã¯ã‚ãªãŸã®ãƒªãƒ³ãƒ‡ãƒ³ãƒ‰ãƒ«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¸ã®ãƒˆãƒ¼ã‚¿ãƒ«ã‚¢ã‚¯ã‚»ã‚¹ã‚’希望ã—ã¦ã„ã¾ã™ã€‚アクセスを許å¯ã™ã‚‹ã¨ã€ã“ã®ã‚ªãƒ–ジェクトã¯ã„ã¤ã§ã‚‚ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‹ã‚‰è³‡é‡‘を削除ã—ãŸã‚Šã€ä»Šå¾Œè¦å‘Šã‚’表示ã™ã‚‹ã“ã¨ãªã継続的ã«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’完全ã«ç©ºã«ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚ + +ã“ã®ã‚ˆã†ãªãƒªã‚¯ã‚¨ã‚¹ãƒˆãŒæ£å½“ã§ã‚ã‚‹ã“ã¨ã¯ç¨€ã§ã™ã€‚ã“ã®ã‚ªãƒ–ジェクトãŒã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã—ãŸã„ç†ç”±ã‚’完全ã«ç†è§£ã—ã¦ã„ã‚‹å ´åˆã‚’除ãã€ã‚¢ã‚¯ã‚»ã‚¹ã®è¨±å¯ã¯é¿ã‘ã¦ãã ã•ã„。 <form name="form"> - <button name="Grant" text="許å¯"/> + <button name="Grant" text="トータルアクセスを許å¯"/> <button name="Deny" text="æ‹’å¦"/> - <button name="Details" text="詳細..."/> </form> </notification> <notification name="ScriptDialog"> [NAME] ã®ã€Œ<nolink>[TITLE]</nolink>〠[MESSAGE] <form name="form"> - <button name="Mute" text="ブãƒãƒƒã‚¯"/> - <button name="Ignore" text="無視ã™ã‚‹"/> + <button name="Client_Side_Mute" text="ブãƒãƒƒã‚¯"/> + <button name="Client_Side_Ignore" text="無視"/> </form> </notification> <notification name="ScriptDialogGroup"> [GROUPNAME] ã®ã€Œ<nolink>[TITLE]</nolink>〠[MESSAGE] <form name="form"> - <button name="Mute" text="ブãƒãƒƒã‚¯"/> - <button name="Ignore" text="無視ã™ã‚‹"/> + <button name="Client_Side_Mute" text="ブãƒãƒƒã‚¯"/> + <button name="Client_Side_Ignore" text="無視"/> </form> </notification> <notification name="BuyLindenDollarSuccess"> @@ -2670,7 +2837,7 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ <notification name="FirstSandbox"> ã“ã“ã¯ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã‚¨ãƒªã‚¢ã§ã™ã€‚ä½äººãŒåˆ¶ä½œã‚’å¦ã¶ã“ã¨ãŒã§ãã¾ã™ã€‚ -ã“ã“ã§åˆ¶ä½œã•れãŸã‚‚ã®ã¯æ™‚é–“ãŒçµŒã¤ã¨å‰Šé™¤ã•れã¾ã™ã€‚制作ã—ãŸã‚¢ã‚¤ãƒ†ãƒ ã‚’å³ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€Œå–ã‚‹ã€ã‚’é¸ã³ã€æŒã¡ç‰©ã«å…¥ã‚Œã¦ãŠæŒã¡å¸°ã‚Šã™ã‚‹ã®ã‚’ãŠå¿˜ã‚Œãªã。 +ã“ã“ã§åˆ¶ä½œã•れãŸã‚‚ã®ã¯æ™‚é–“ãŒçµŒã¤ã¨å‰Šé™¤ã•れã¾ã™ã€‚制作ã—ãŸã‚¢ã‚¤ãƒ†ãƒ ã‚’å³ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€Œå–ã‚‹ã€ã‚’é¸ã³ã€ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«å…¥ã‚Œã¦ãŠæŒã¡å¸°ã‚Šã™ã‚‹ã®ã‚’ãŠå¿˜ã‚Œãªã。 </notification> <notification name="MaxListSelectMessage"> ã“ã®ãƒªã‚¹ãƒˆã‹ã‚‰ [MAX_SELECT] 個ã¾ã§ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’é¸æŠžã§ãã¾ã™ã€‚ @@ -2691,7 +2858,7 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ [NAME] ã¯ãŠé‡‘ã‚’å—ã‘å–りã€è‡ªå‹•çš„ã«ãƒ–ãƒãƒƒã‚¯ãŒè§£é™¤ã•れã¾ã—ãŸã€‚ </notification> <notification name="AutoUnmuteByInventory"> - [NAME] ã¯æŒã¡ç‰©ã‚’å—ã‘å–りã€è‡ªå‹•çš„ã«ãƒ–ãƒãƒƒã‚¯ãŒè§£é™¤ã•れã¾ã—ãŸã€‚ + [NAME] ã¯ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‚’å—ã‘å–りã€è‡ªå‹•çš„ã«ãƒ–ãƒãƒƒã‚¯ãŒè§£é™¤ã•れã¾ã—ãŸã€‚ </notification> <notification name="VoiceInviteGroup"> [NAME] 㯠[GROUP] ã®ãƒœã‚¤ã‚¹ãƒãƒ£ãƒƒãƒˆã‚³ãƒ¼ãƒ«ã«å‚åŠ ã—ã¾ã—ãŸã€‚ @@ -2846,6 +3013,18 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ [RESIDENTS] <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> + <notification name="ShareFolderConfirmation"> + フォルダã¯ä¸€åº¦ã« 1 ã¤ã—ã‹å…±æœ‰ã§ãã¾ã›ã‚“。 + +次ã®ã‚¢ã‚¤ãƒ†ãƒ を共有ã—ã¾ã™ã‹ï¼Ÿ + +<nolink>[ITEMS]</nolink> + +次ã®ä½äººã¨å…±æœ‰ï¼š + +[RESIDENTS] + <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="Ok"/> + </notification> <notification name="ItemsShared"> アイテムãŒå…±æœ‰ã•れã¾ã—ãŸã€‚ </notification> @@ -2924,6 +3103,10 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ ( 作æˆå¾Œ[EXISTENCE]秒経éŽï¼‰ '[BODYREGION]'ã®[RESOLUTION]ã®ãƒ™ãƒ¼ã‚¯ãƒ‰ãƒ†ã‚¯ã‚¹ãƒãƒ£ã¯[TIME]秒後ã«ãƒãƒ¼ã‚«ãƒ«ã«æ›´æ–°ã•れã¾ã—ãŸã€‚ </notification> + <notification name="LivePreviewUnavailable"> + コピーä¸å¯ãŠã‚ˆã³/ã¾ãŸã¯è»¢é€ä¸å¯ã®ãŸã‚ã€ã“ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’表示ã§ãã¾ã›ã‚“。 + <usetemplate ignoretext="コピーä¸å¯ãŠã‚ˆã³/ã¾ãŸã¯è»¢é€ä¸å¯ãƒ†ã‚¯ã‚¹ãƒãƒ£ã§ãƒ©ã‚¤ãƒ–プレビューモードを使用ã§ããªã„ã“ã¨ã‚’è¦å‘Šã™ã‚‹" name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> ã“ã®ã‚³ãƒ¼ãƒ«ã‹ã‚‰æŠœã‘ã¾ã™ã‹ï¼Ÿ <usetemplate ignoretext="コールã‹ã‚‰æŠœã‘ã‚‹å‰ã®ç¢ºèª" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> @@ -2972,7 +3155,7 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ カメラã®è¦–点を変更ã™ã‚‹ã«ã¯ã€æ°´å¹³ãƒ»åž‚直コントãƒãƒ¼ãƒ«ã‚’使ã„ã¾ã™ã€‚Escape を押ã™ã‹ã€ã¾ãŸã¯æ©è¡Œã™ã‚‹ã¨ã€è¦–点ãŒãƒªã‚»ãƒƒãƒˆã•れã¾ã™ã€‚ </notification> <notification label="インベントリ" name="HintInventory"> - æŒã¡ç‰©ã«ã¯ã‚ãªãŸã®ã‚¢ã‚¤ãƒ†ãƒ ãŒã™ã¹ã¦å«ã¾ã‚Œã¾ã™ã€‚æ–°ã—ãè¿½åŠ ã•れãŸã‚¢ã‚¤ãƒ†ãƒ ã¯ã€Œæœ€æ–°ã€ã‚¿ãƒ–ã«ä¸€è¦§è¡¨ç¤ºã•れã¦ã„ã¾ã™ã€‚ + インベントリã«ã¯ã‚ãªãŸã®ã‚¢ã‚¤ãƒ†ãƒ ãŒã™ã¹ã¦å«ã¾ã‚Œã¾ã™ã€‚æ–°ã—ãè¿½åŠ ã•れãŸã‚¢ã‚¤ãƒ†ãƒ ã¯ã€Œæœ€æ–°ã€ã‚¿ãƒ–ã«ä¸€è¦§è¡¨ç¤ºã•れã¦ã„ã¾ã™ã€‚ </notification> <notification label="ã‚ãªãŸã®ãƒªãƒ³ãƒ‡ãƒ³ãƒ‰ãƒ«" name="HintLindenDollar"> ã“れãŒã‚ãªãŸã® L$ 残高ã§ã™ã€‚リンデンドルを購入ã™ã‚‹ã«ã¯ã€ŒL$ ã®è³¼å…¥ã€ã‚’クリックã—ã¾ã™ã€‚ @@ -3080,7 +3263,7 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ <usetemplate name="okcancelbuttons" notext="終了ã—ãªã„" yestext="終了"/> </notification> <notification label="" name="NoInventory"> - æŒã¡ç‰©ã®è¡¨ç¤ºã¯ã‚¢ãƒ‰ãƒãƒ³ã‚¹ãƒ¢ãƒ¼ãƒ‰ã§ã®ã¿åˆ©ç”¨ã§ãã¾ã™ã€‚ãƒã‚°ã‚¢ã‚¦ãƒˆã—ã¦ãƒ¢ãƒ¼ãƒ‰ã‚’変更ã—ã¾ã™ã‹ï¼Ÿ + インベントリã®è¡¨ç¤ºã¯ã‚¢ãƒ‰ãƒãƒ³ã‚¹ãƒ¢ãƒ¼ãƒ‰ã§ã®ã¿åˆ©ç”¨ã§ãã¾ã™ã€‚ãƒã‚°ã‚¢ã‚¦ãƒˆã—ã¦ãƒ¢ãƒ¼ãƒ‰ã‚’変更ã—ã¾ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="終了ã—ãªã„" yestext="終了"/> </notification> <notification label="" name="NoAppearance"> @@ -3095,6 +3278,62 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ ã“ã®æ“作ã«ã‚ˆã‚Šã€å…¨ã¦ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼é …ç›®ã¨ãƒœã‚¿ãƒ³ãŒéžè¡¨ç¤ºã«ãªã‚Šã¾ã™ã€‚å†ã³è¡¨ç¤ºã™ã‚‹ã«ã¯ [SHORTCUT] ã‚’ã‚‚ã†ä¸€åº¦ã‚¯ãƒªãƒƒã‚¯ã—ã¦ãã ã•ã„。 <usetemplate ignoretext="UI ã‚’éžè¡¨ç¤ºã«ã™ã‚‹å‰ã«ç¢ºèª" name="okcancelignore" notext="å–り消ã—" yestext="OK"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + é¸æŠžã•れãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ãƒ•ァントムフラグãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã¾ã™ã€‚ + +ç¶šã‘ã¾ã™ã‹ï¼Ÿ + <usetemplate ignoretext="é¸æŠžã•れãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã®ãƒ•ァントムフラグãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã¾ã™ã€‚" name="okcancelignore" notext="å–り消ã—" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + 一部ã®é¸æŠžã•れãŸãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•れã¦ã„ã‚‹ãŸã‚ã€'[REQUESTED_TYPE]' ã«è¨å®šã§ãã¾ã›ã‚“。ã“れらã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ä»£ã‚り㫠'[RESTRICTED_TYPE]' ã«è¨å®šã•れã¾ã™ã€‚ + +ç¶šã‘ã¾ã™ã‹ï¼Ÿ + <usetemplate ignoretext="一部ã®é¸æŠžã•れãŸãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•れã¦ã„ã‚‹ãŸã‚è¨å®šã§ãã¾ã›ã‚“。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + é¸æŠžã•れãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€å½¢çжãŒå‡¸çжã§ãªã„ãŸã‚ã€'[REQUESTED_TYPE]' ã«è¨å®šã§ãã¾ã›ã‚“。 + +ç¶šã‘ã¾ã™ã‹ï¼Ÿ + <usetemplate ignoretext="é¸æŠžã•れãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€å½¢çжãŒå‡¸çжã§ãªã„ãŸã‚è¨å®šã§ãã¾ã›ã‚“。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + é¸æŠžã•れãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ãƒ•ァントムフラグãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã¾ã™ã€‚ + +一部ã®é¸æŠžã•れãŸãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•れã¦ã„ã‚‹ãŸã‚ã€'[REQUESTED_TYPE]' ã«è¨å®šã§ãã¾ã›ã‚“。ã“れらã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ä»£ã‚り㫠'[RESTRICTED_TYPE]' ã«è¨å®šã•れã¾ã™ã€‚ + +ç¶šã‘ã¾ã™ã‹ï¼Ÿ + <usetemplate ignoretext="é¸æŠžã•れãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã®ãƒ•ァントムフラグãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã€ä»–ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•れã¦ã„ã‚‹ãŸã‚è¨å®šã§ãã¾ã›ã‚“。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + é¸æŠžã•れãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ãƒ•ァントムフラグãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã¾ã™ã€‚ + +é¸æŠžã•れãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€å½¢çжãŒå‡¸çжã§ãªã„ãŸã‚ã€'[REQUESTED_TYPE]' ã«è¨å®šã§ãã¾ã›ã‚“。 + +ç¶šã‘ã¾ã™ã‹ï¼Ÿ + <usetemplate ignoretext="é¸æŠžã•れãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã®ãƒ•ァントムフラグãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã€ä»–ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯å½¢çжãŒå‡¸çжã§ãªã„ãŸã‚è¨å®šã§ãã¾ã›ã‚“。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + 一部ã®é¸æŠžã•れãŸãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•れã¦ã„ã‚‹ãŸã‚ã€'[REQUESTED_TYPE]' ã«è¨å®šã§ãã¾ã›ã‚“。ã“れらã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ä»£ã‚り㫠'[RESTRICTED_TYPE]' ã«è¨å®šã•れã¾ã™ã€‚ + +é¸æŠžã•れãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€å½¢çжãŒå‡¸çжã§ãªã„ãŸã‚ã€'[REQUESTED_TYPE]' ã«è¨å®šã§ãã¾ã›ã‚“。ã“れらã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã®ç”¨é€”タイプã¯å¤‰ã‚りã¾ã›ã‚“。 + +ç¶šã‘ã¾ã™ã‹ï¼Ÿ + <usetemplate ignoretext="一部ã®é¸æŠžã•れãŸãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•れã¦ãŠã‚Šã€ã¾ãŸå½¢çжãŒå‡¸çжã§ãªã„ãŸã‚è¨å®šã§ãã¾ã›ã‚“。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + é¸æŠžã•れãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ãƒ•ァントムフラグãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã¾ã™ã€‚ + +一部ã®é¸æŠžã•れãŸãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•れã¦ã„ã‚‹ãŸã‚ã€'[REQUESTED_TYPE]' ã«è¨å®šã§ãã¾ã›ã‚“。ã“れらã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ä»£ã‚り㫠'[RESTRICTED_TYPE]' ã«è¨å®šã•れã¾ã™ã€‚ + +é¸æŠžã•れãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€å½¢çжãŒå‡¸çжã§ãªã„ãŸã‚ã€'[REQUESTED_TYPE]' ã«è¨å®šã§ãã¾ã›ã‚“。ã“れらã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã®ç”¨é€”タイプã¯å¤‰ã‚りã¾ã›ã‚“。 + +ç¶šã‘ã¾ã™ã‹ï¼Ÿ + <usetemplate ignoretext="é¸æŠžã•れãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã®ãƒ•ァントムフラグãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã€ä»–ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•れã€ã¾ãŸå½¢çжãŒå‡¸çжã§ãªã„ãŸã‚è¨å®šã§ãã¾ã›ã‚“。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + é¸æŠžã•れãŸã‚ªãƒ–ジェクトã¯ãƒŠãƒ“メッシュã«å½±éŸ¿ã‚’与ãˆã¾ã™ã€‚オブジェクトをフレã‚シブルパスã«å¤‰æ›´ã™ã‚‹ã¨ã€ãƒŠãƒ“メッシュã‹ã‚‰å‰Šé™¤ã•れã¾ã™ã€‚ + <usetemplate ignoretext="é¸æŠžã•れãŸã‚ªãƒ–ジェクトã¯ãƒŠãƒ“メッシュã«å½±éŸ¿ã‚’与ãˆã¾ã™ã€‚オブジェクトをフレã‚シブルパスã«å¤‰æ›´ã™ã‚‹ã¨ã€ãƒŠãƒ“メッシュã‹ã‚‰å‰Šé™¤ã•れã¾ã™ã€‚" name="okcancelignore" notext="å–り消ã—" yestext="OK"/> + </notification> <global name="UnsupportedGLRequirements"> [APP_NAME] ã«å¿…è¦ãªãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãŒãªã„よã†ã§ã™ã€‚ [APP_NAME] ã«ã¯ãƒžãƒ«ãƒãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’サãƒãƒ¼ãƒˆã™ã‚‹ OpenGL グラフィックカードãŒå¿…è¦ã§ã™ã€‚ ãŠä½¿ã„ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ã‚«ãƒ¼ãƒ‰ã®æœ€æ–°ãƒ‰ãƒ©ã‚¤ãƒãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã‚‹ã‹ã©ã†ã‹ã€ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã®ã‚µãƒ¼ãƒ“スパックã¨ãƒ‘ッãƒãŒå…¥ã£ã¦ã„ã‚‹ã‹ã‚’ã”確èªãã ã•ã„。 @@ -3119,4 +3358,24 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ <global name="You died and have been teleported to your home location"> æ»ã‚“ã§ã—ã¾ã£ãŸã®ã§ã€ãƒ›ãƒ¼ãƒ ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã•れã¾ã—ãŸã€‚ </global> + <notification name="LocalBitmapsUpdateFileNotFound"> + [FNAME] ã¯ã€è¦‹ã¤ã‹ã‚‰ãªã‹ã£ãŸãŸã‚ã€æ›´æ–°ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ +ã“ã®ãƒ•ァイルã«å¯¾ã™ã‚‹ä»Šå¾Œã®æ›´æ–°ã‚’無効ã«ã—ã¾ã™ã€‚ + </notification> + <notification name="LocalBitmapsUpdateFailedFinal"> + [FNAME] ã‚’é–‹ãã¾ãŸã¯ãƒ‡ã‚³ãƒ¼ãƒ‰ã™ã‚‹è©¦è¡Œã«å¤±æ•—ã—ã¾ã—ãŸï¼ˆè©¦è¡Œå›žæ•° [NRETRIES] 回)。ãã®ãŸã‚ã€ã“ã®ãƒ•ァイルã¯å£Šã‚Œã¦ã„ã‚‹ã‚‚ã®ã¨ã—ã¦å‡¦ç†ã•れã¾ã—ãŸã€‚ +ã“ã®ãƒ•ァイルã«å¯¾ã™ã‚‹ä»Šå¾Œã®æ›´æ–°ã‚’無効ã«ã—ã¾ã™ã€‚ + </notification> + <notification name="LocalBitmapsVerifyFail"> + é–‹ãã“ã¨ãŒã§ããªã„ã€ã¾ãŸã¯ãƒ‡ã‚³ãƒ¼ãƒ‰ã§ããªã„無効ã¾ãŸã¯èªã¿å–りä¸èƒ½ãªç”»åƒãƒ•ァイル [FNAME] ã‚’è¿½åŠ ã—よã†ã¨ã—ã¾ã—ãŸã€‚ +ã“ã®è©¦è¡Œã¯ã‚ャンセルã•れã¾ã—ãŸã€‚ + </notification> + <notification name="PathfindingReturnMultipleItems"> + [NUM_ITEMS] 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’è¿”å´ä¸ã§ã™ã€‚ç¶šã‘ã¾ã™ã‹ï¼Ÿ + <usetemplate ignoretext="複数ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’è¿”ã—ã¾ã™ã‹ï¼Ÿ" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + [NUM_ITEMS] 個ã®ã‚¢ã‚¤ãƒ†ãƒ を削除ä¸ã§ã™ã€‚ç¶šã‘ã¾ã™ã‹ï¼Ÿ + <usetemplate ignoretext="複数ã®ã‚¢ã‚¤ãƒ†ãƒ を削除ã—ã¾ã™ã‹ï¼Ÿ" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/ja/panel_bottomtray.xml b/indra/newview/skins/default/xui/ja/panel_bottomtray.xml deleted file mode 100644 index 3529abbf36..0000000000 --- a/indra/newview/skins/default/xui/ja/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="マイクã®ã‚ªãƒ³ãƒ»ã‚ªãƒ•"/> - <string name="VoiceControlBtnToolTip" value="ボイスコントãƒãƒ¼ãƒ«ãƒ‘ãƒãƒ«ã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="話ã™" label_selected="話ã™" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="ジェスãƒãƒ£ãƒ¼" name="Gesture" tool_tip="ジェスãƒãƒ£ãƒ¼ã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="移動" name="movement_btn" tool_tip="移動コントãƒãƒ¼ãƒ«ã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="視界" name="camera_btn" tool_tip="カメラコントãƒãƒ¼ãƒ«ã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button label="" name="snapshots" tool_tip="スナップショットを撮りã¾ã™"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="制作" name="build_btn" tool_tip="制作ツールã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="検索" name="search_btn" tool_tip="検索ã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="地図" name="world_map_btn" tool_tip="世界地図ã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="ミニマップ" name="mini_map_btn" tool_tip="ミニマップã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="会話"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="通知"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> 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_group_control_panel.xml b/indra/newview/skins/default/xui/ja/panel_group_control_panel.xml index f7f575206a..49749732c9 100644 --- a/indra/newview/skins/default/xui/ja/panel_group_control_panel.xml +++ b/indra/newview/skins/default/xui/ja/panel_group_control_panel.xml @@ -1,8 +1,8 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_im_control_panel"> <layout_stack name="vertical_stack"> <layout_panel name="group_info_btn_panel"> - <button label="ã‚°ãƒ«ãƒ¼ãƒ—æƒ…å ±" name="group_info_btn"/> + <button label="グループプãƒãƒ•ィール" name="group_info_btn"/> </layout_panel> <layout_panel name="call_btn_panel"> <button label="グループコール" name="call_btn"/> diff --git a/indra/newview/skins/default/xui/ja/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/ja/panel_group_info_sidetray.xml index 85406702bc..7aa1aec6d0 100644 --- a/indra/newview/skins/default/xui/ja/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/ja/panel_group_info_sidetray.xml @@ -1,5 +1,5 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="ã‚°ãƒ«ãƒ¼ãƒ—æƒ…å ±" name="GroupInfo"> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="グループインベントリ" name="GroupInfo"> <panel.string name="default_needs_apply_text"> ä¿å˜ã—ã¦ã„ãªã„変更ãŒã‚りã¾ã™ </panel.string> diff --git a/indra/newview/skins/default/xui/ja/panel_group_invite.xml b/indra/newview/skins/default/xui/ja/panel_group_invite.xml index a21b340fdd..cc9ebc405b 100644 --- a/indra/newview/skins/default/xui/ja/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/ja/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> é¸æŠžã—ãŸä½äººã®ãªã‹ã«ã€æ—¢ã«ã‚°ãƒ«ãƒ¼ãƒ—ã«æ‰€å±žã—ã¦ã„る人ãŒã„ã‚‹ãŸã‚ã€æ‹›å¾…ã‚’é€ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ </panel.string> + <panel.string name="invite_selection_too_large"> + グループã¸ã®æ‹›å¾…ãŒé€ä¿¡ã•れã¦ã„ã¾ã›ã‚“: é¸æŠžã•れãŸä½äººãŒå¤šã™ãŽã¾ã™ã€‚グループã¸ã®æ‹›å¾…ã¯1回ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚ãŸã‚Š100人ã«åˆ¶é™ã•れã¦ã„ã¾ã™ã€‚ + </panel.string> <text bottom_delta="-96" font="SansSerifSmall" height="72" name="help_text"> グループã«ã¯ä¸€åº¦ã«è¤‡æ•°ã®ä½äººã‚’招待ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ 「リストã‹ã‚‰ä½äººã‚’é¸æŠžã€ã‚’クリックã—ã¦ãã ã•ã„。 </text> diff --git a/indra/newview/skins/default/xui/ja/panel_group_notices.xml b/indra/newview/skins/default/xui/ja/panel_group_notices.xml index 96e0382975..ddad6c1f9b 100644 --- a/indra/newview/skins/default/xui/ja/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/ja/panel_group_notices.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="通知" name="notices_tab"> <panel.string name="help_text"> 通知ã§ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’é€ã‚‹ã“ã¨ãŒã§ãã€é€šçŸ¥ã«ã‚¢ã‚¤ãƒ†ãƒ を添付ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ @@ -39,10 +39,10 @@ <text name="string"> ã“ã“ã«ã‚¢ã‚¤ãƒ†ãƒ をドラッグ&ドãƒãƒƒãƒ—ã—ã¦æ·»ä»˜ã—ã¦ãã ã•ã„: </text> - <button label="æŒã¡ç‰©" name="open_inventory" tool_tip="æŒã¡ç‰©ã‚’é–‹ãã¾ã™"/> + <button label="インベントリ" name="open_inventory" tool_tip="インベントリを開ãã¾ã™"/> <button label="å–り外ã™" label_selected="添付物を削除" name="remove_attachment" tool_tip="ã‚ãªãŸã®é€šçŸ¥ã‹ã‚‰æ·»ä»˜ã•れãŸã‚¢ã‚¤ãƒ†ãƒ を削除ã—ã¾ã™"/> <button label="é€ä¿¡" label_selected="é€ä¿¡" name="send_notice"/> - <group_drop_target name="drop_target" tool_tip="æŒã¡ç‰©ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’ã“ã®ãƒœãƒƒã‚¯ã‚¹ã«ãƒ‰ãƒ©ãƒƒã‚°ã—ã¦ã€é€šçŸ¥ã¨ä¸€ç·’ã«é€ã‚Šã¾ã™ã€‚ 添付ã™ã‚‹ã«ã¯ã€ãã®ã‚¢ã‚¤ãƒ†ãƒ ã®ã‚³ãƒ”ーã¨å†è²©ãƒ»ãƒ—ãƒ¬ã‚¼ãƒ³ãƒˆã®æ¨©é™ãŒã‚ãªãŸã«ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚"/> + <group_drop_target name="drop_target" tool_tip="インベントリã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’ã“ã®ãƒœãƒƒã‚¯ã‚¹ã«ãƒ‰ãƒ©ãƒƒã‚°ã—ã¦ã€é€šçŸ¥ã¨ä¸€ç·’ã«é€ã‚Šã¾ã™ã€‚ 添付ã™ã‚‹ã«ã¯ã€ãã®ã‚¢ã‚¤ãƒ†ãƒ ã®ã‚³ãƒ”ーã¨å†è²©ãƒ»ãƒ—ãƒ¬ã‚¼ãƒ³ãƒˆã®æ¨©é™ãŒã‚ãªãŸã«ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚"/> </panel> <panel label="éŽåŽ»ã®é€šçŸ¥ã‚’表示" name="panel_view_past_notice"> <text name="lbl"> diff --git a/indra/newview/skins/default/xui/ja/panel_landmarks.xml b/indra/newview/skins/default/xui/ja/panel_landmarks.xml index e3b716c35b..24d6ff23ae 100644 --- a/indra/newview/skins/default/xui/ja/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/ja/panel_landmarks.xml @@ -1,9 +1,9 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Landmarks"> <accordion name="landmarks_accordion"> <accordion_tab name="tab_favorites" title="ãŠæ°—ã«å…¥ã‚Šãƒãƒ¼"/> <accordion_tab name="tab_landmarks" title="マイ ランドマーク"/> - <accordion_tab name="tab_inventory" title="æŒã¡ç‰©"/> + <accordion_tab name="tab_inventory" title="インベントリ"/> <accordion_tab name="tab_library" title="ライブラリ"/> </accordion> <panel name="bottom_panel"> diff --git a/indra/newview/skins/default/xui/ja/panel_login.xml b/indra/newview/skins/default/xui/ja/panel_login.xml index ac1fe455c7..396d9e65b1 100644 --- a/indra/newview/skins/default/xui/ja/panel_login.xml +++ b/indra/newview/skins/default/xui/ja/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://jp.secondlife.com/registration/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php?lang=ja </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + ãƒã‚°ã‚¤ãƒ³ + </text> <text name="username_text"> ユーザーãƒãƒ¼ãƒ : </text> @@ -15,15 +15,8 @@ <text name="password_text"> パスワード: </text> - <check_box label="パスワードを記憶" name="remember_check"/> - <button label="ãƒã‚°ã‚¤ãƒ³" left_pad="30" name="connect_btn" width="60"/> - <text name="mode_selection_text"> - モード: - </text> - <combo_box name="mode_combo" tool_tip="ãƒ¢ãƒ¼ãƒ‰ã‚’é¸æŠžã—ã¾ã™ã€‚ベーシックモードã§ã¯æŽ¢ç´¢ã‚„ãƒãƒ£ãƒƒãƒˆã‚’ã™ã°ã‚„ãç°¡å˜ã«å®Ÿè¡Œã§ãã€ã‚¢ãƒ‰ãƒãƒ³ã‚¹ãƒ¢ãƒ¼ãƒ‰ã§ã¯ã€ã‚ˆã‚Šå¤šãã®æ©Ÿèƒ½ãŒåˆ©ç”¨ã§ãã¾ã™ã€‚"> - <combo_box.item label="ベーシック" name="Basic"/> - <combo_box.item label="アドãƒãƒ³ã‚¹" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> 開始地点: </text> @@ -33,16 +26,21 @@ <combo_box.item label="<地域åを入力>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - ãŠç”³ã—込㿠+ <layout_panel name="links_login_panel"> + <text name="login_help"> + ãƒã‚°ã‚¤ãƒ³ã®æ–¹æ³• </text> <text name="forgot_password_text"> ユーザーåã¾ãŸã¯ãƒ‘スワードをãŠå¿˜ã‚Œã§ã™ã‹ï¼Ÿ </text> - <text name="login_help"> - ãƒã‚°ã‚¤ãƒ³ã®æ–¹æ³• + <button label="ãƒã‚°ã‚¤ãƒ³" left_pad="30" name="connect_btn" width="60"/> + <check_box label="パスワードを記憶" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + アカウントを作æˆã—ã¦ãã ã•ã„ </text> + <button label="今ã™ãé–‹å§‹" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_main_inventory.xml b/indra/newview/skins/default/xui/ja/panel_main_inventory.xml index ff968696b7..f908262f4f 100644 --- a/indra/newview/skins/default/xui/ja/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/ja/panel_main_inventory.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="ã‚‚ã®" name="main inventory panel"> <panel.string name="ItemcountFetching"> [ITEM_COUNT] 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’å–å¾—ä¸ã§ã™... [FILTER] @@ -9,9 +9,9 @@ <text name="ItemcountText"> アイテム: </text> - <filter_editor label="æŒã¡ç‰©ã‚’フィルター" name="inventory search editor"/> + <filter_editor label="インベントリをフィルター" name="inventory search editor"/> <tab_container name="inventory filter tabs"> - <inventory_panel label="æŒã¡ç‰©" name="All Items"/> + <inventory_panel label="インベントリ" name="All Items"/> <recent_inventory_panel label="最新" name="Recent Items"/> </tab_container> <layout_stack name="bottom_panel"> diff --git a/indra/newview/skins/default/xui/ja/panel_me.xml b/indra/newview/skins/default/xui/ja/panel_me.xml index 896bbff0ee..3df1ae8048 100644 --- a/indra/newview/skins/default/xui/ja/panel_me.xml +++ b/indra/newview/skins/default/xui/ja/panel_me.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="マイ プãƒãƒ•ィール" name="panel_me"> - <panel label="マイ ピック" name="panel_picks"/> + <panel label="マイ-ピック" name="panel_picks"/> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_my_profile.xml b/indra/newview/skins/default/xui/ja/panel_my_profile.xml deleted file mode 100644 index a0d99ba5a8..0000000000 --- a/indra/newview/skins/default/xui/ja/panel_my_profile.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="プãƒãƒ•ィール" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=ja - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/billing.php?lang=ja - </string> - <string name="my_account_link_url" value="http://secondlife.com/account"/> - <string name="no_partner_text" value="ãªã—"/> - <string name="no_group_text" value="ãªã—"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="scroll_content_panel"> - <panel name="second_life_image_panel"> - <text name="display_name_descr_text"> - ユーザーå - </text> - <text name="name_descr_text"> - 表示å - </text> - <button label="プãƒãƒ•ィール" name="see_profile_btn" tool_tip="ã“ã®ã‚¢ãƒã‚¿ãƒ¼ã®ãƒ—ãƒãƒ•ィールを表示"/> - </panel> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_nearby_chat.xml b/indra/newview/skins/default/xui/ja/panel_nearby_chat.xml index aca055bb43..4048b48d3a 100644 --- a/indra/newview/skins/default/xui/ja/panel_nearby_chat.xml +++ b/indra/newview/skins/default/xui/ja/panel_nearby_chat.xml @@ -1,4 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="nearby_chat"> - <check_box label="ãƒãƒ£ãƒƒãƒˆã‚’翻訳" name="translate_chat_checkbox"/> + <layout_stack name="stack"> + <layout_panel name="translate_chat_checkbox_lp"> + <check_box label="ãƒãƒ£ãƒƒãƒˆã‚’翻訳" name="translate_chat_checkbox"/> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml index 5998206f27..201fb0a376 100644 --- a/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="chat_bar"> +<panel name="nearby_chat"> <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/panel_notes.xml b/indra/newview/skins/default/xui/ja/panel_notes.xml deleted file mode 100644 index aa6d823c59..0000000000 --- a/indra/newview/skins/default/xui/ja/panel_notes.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="メモã¨ãƒ—ライãƒã‚·ãƒ¼" name="panel_notes"> - <layout_stack name="layout"> - <layout_panel name="notes_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <text name="status_message" value="個人的メモ:"/> - <text name="status_message2" value="ã“ã®äººã«è¨±å¯ï¼š"/> - <check_box label="オンライン状態ã®ç¢ºèª" name="status_check"/> - <check_box label="地図ã§å±…å ´æ‰€ã‚’ç¢ºèª" name="map_check"/> - <check_box label="ç§ã®ã‚ªãƒ–ジェクトã®ç·¨é›†ãƒ»å‰Šé™¤ãƒ»å–å¾—" name="objects_check"/> - </panel> - </scroll_container> - </layout_panel> - <layout_panel name="notes_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="フレンド登録" name="add_friend" tool_tip="フレンド登録を申ã—出ã¾ã™"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="インスタントメッセージを開ãã¾ã™"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="コール" name="call" tool_tip="ã“ã®ä½äººã«ã‚³ãƒ¼ãƒ«ã™ã‚‹"/> - </layout_panel> - <layout_panel name="show_on_map_btn_lp"> - <button label="地図" name="show_on_map_btn" tool_tip="ä½äººã‚’地図上ã§è¡¨ç¤ºã™ã‚‹"/> - </layout_panel> - <layout_panel name="teleport_btn_lp"> - <button label="テレãƒãƒ¼ãƒˆ" name="teleport" tool_tip="テレãƒãƒ¼ãƒˆã‚’é€ã‚Šã¾ã™"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml index 47f570ab86..1a14283113 100644 --- a/indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml +++ b/indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml @@ -1,2 +1,2 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<outbox_inventory_panel name="inventory_outbox" tool_tip="商å“ã‚’ã“ã“ã«ãƒ‰ãƒ©ãƒƒã‚°ã‚¢ãƒ³ãƒ‰ãƒ‰ãƒãƒƒãƒ—ã™ã‚‹ã¨ã€ã‚ãªãŸã®åº—é ã«ä¸¦ã³ã¾ã™"/> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<outbox_inventory_panel name="inventory_outbox" tool_tip="アイテムをã“ã“ã«ãƒ‰ãƒ©ãƒƒã‚°ã‚¢ãƒ³ãƒ‰ãƒ‰ãƒãƒƒãƒ—ã™ã‚‹ã¨ã€ã‚ãªãŸã®åº—é ã«ä¸¦ã³ã¾ã™"/> diff --git a/indra/newview/skins/default/xui/ja/panel_outfit_edit.xml b/indra/newview/skins/default/xui/ja/panel_outfit_edit.xml index 6897660214..e89ce0c479 100644 --- a/indra/newview/skins/default/xui/ja/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/ja/panel_outfit_edit.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <!-- Side tray Outfit Edit panel --> <panel label="アウトフットã®ç·¨é›†" name="outfit_edit"> <string name="No Outfit" value="アウトフィットãªã—"/> @@ -30,7 +30,7 @@ <button label="ã•らã«è¿½åŠ ..." name="show_add_wearables_btn" tool_tip="é–‹ãï¼é–‰ã˜ã‚‹"/> </layout_panel> <layout_panel name="filter_panel"> - <filter_editor label="æŒã¡ç‰©ã®ç€ç”¨ç‰©ã‚’フィルター" name="look_item_filter"/> + <filter_editor label="インベントリã®ç€ç”¨ç‰©ã‚’フィルター" name="look_item_filter"/> </layout_panel> </layout_stack> </layout_panel> diff --git a/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml index 2a0647653d..93df0ba2bd 100644 --- a/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="ã‚‚ã®" name="Outfits"> <panel.string name="wear_outfit_tooltip"> é¸æŠžã—ãŸã‚¢ã‚¦ãƒˆãƒ•ィットをç€ç”¨ã™ã‚‹ </panel.string> <panel.string name="wear_items_tooltip"> - é¸æŠžã—ãŸå•†å“ã‚’ç€ç”¨ + é¸æŠžã—ãŸã‚¢ã‚¤ãƒ†ãƒ ã‚’ç€ç”¨ </panel.string> <tab_container name="appearance_tabs"> <panel label="マイ アウトフィット" name="outfitslist_tab"/> diff --git a/indra/newview/skins/default/xui/ja/panel_people.xml b/indra/newview/skins/default/xui/ja/panel_people.xml index 1c90f7327e..88c31451b5 100644 --- a/indra/newview/skins/default/xui/ja/panel_people.xml +++ b/indra/newview/skins/default/xui/ja/panel_people.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <!-- Side tray panel --> <panel label="人" name="people_panel"> <string name="no_recent_people" value="最近交æµã—ãŸäººã¯ã„ã¾ã›ã‚“。 一緒ã«ä½•ã‹ã™ã‚‹ä»²é–“ã‚’ãŠæŽ¢ã—ã§ã™ã‹ï¼Ÿ [secondlife:///app/search/people 検索] ã‹ [secondlife:///app/worldmap 世界地図] ã‚’ãŠè©¦ã—ãã ã•ã„。"/> @@ -73,7 +73,7 @@ <button label="コール" name="call_btn" tool_tip="ã“ã®ä½äººã«ã‚³ãƒ¼ãƒ«ã™ã‚‹"/> </layout_panel> <layout_panel name="share_btn_lp"> - <button label="共有" name="share_btn" tool_tip="「æŒã¡ç‰©ã€ã®ã‚¢ã‚¤ãƒ†ãƒ を共有ã™ã‚‹"/> + <button label="共有" name="share_btn" tool_tip="インベントリã®ã‚¢ã‚¤ãƒ†ãƒ を共有ã™ã‚‹"/> </layout_panel> <layout_panel name="teleport_btn_lp"> <button label="テレãƒãƒ¼ãƒˆ" name="teleport_btn" tool_tip="テレãƒãƒ¼ãƒˆã‚’é€ã‚Šã¾ã™"/> @@ -81,7 +81,7 @@ </layout_stack> <layout_stack name="bottom_bar_ls1"> <layout_panel name="group_info_btn_lp"> - <button label="ã‚°ãƒ«ãƒ¼ãƒ—æƒ…å ±" name="group_info_btn" tool_tip="ã‚°ãƒ«ãƒ¼ãƒ—æƒ…å ±ã‚’è¡¨ç¤ºã—ã¾ã™"/> + <button label="グループプãƒãƒ•ィール" name="group_info_btn" tool_tip="グループプãƒãƒ•ィールを表示ã—ã¾ã™"/> </layout_panel> <layout_panel name="chat_btn_lp"> <button label="グループãƒãƒ£ãƒƒãƒˆ" name="chat_btn" tool_tip="ãƒãƒ£ãƒƒãƒˆã‚’é–‹å§‹ã—ã¾ã™"/> 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..b6e344ca48 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,7 @@ <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"/> + <button label="自動置æ›..." name="autoreplace_showgui"/> + <button label="スペルãƒã‚§ãƒƒã‚¯ä¸..." name="spellcheck_showgui"/> </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_profile.xml b/indra/newview/skins/default/xui/ja/panel_profile.xml deleted file mode 100644 index 1acad9f81a..0000000000 --- a/indra/newview/skins/default/xui/ja/panel_profile.xml +++ /dev/null @@ -1,74 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="プãƒãƒ•ィール" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=ja-JP - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=ja - </string> - <string name="my_account_link_url" value="http://secondlife.com/my/account/index.php?lang=ja-JP"/> - <string name="no_partner_text" value="ãªã—"/> - <string name="no_group_text" value="ãªã—"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <panel name="second_life_image_panel"> - <text name="title_sl_descr_text" value="[SECOND_LIFE]:"/> - </panel> - <panel name="first_life_image_panel"> - <text name="title_rw_descr_text" value="ç¾å®Ÿä¸–界:"/> - </panel> - <text name="title_member_text" value="ä½äººç™»éŒ²ï¼š"/> - <text name="title_acc_status_text" value="アカウントã®çŠ¶æ…‹ï¼š"/> - <text_editor name="acc_status_text"> - ä½äººã€‚ æ”¯æ‰•æƒ…å ±æœªç™»éŒ²ã€‚ - リンデン。 - </text_editor> - <text name="title_partner_text" value="パートナー:"/> - <panel name="partner_data_panel"> - <text initial_value="(å–å¾—ä¸ï¼‰" name="partner_text"/> - </panel> - <text name="title_groups_text" value="グループ:"/> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> - <layout_stack name="layout_verb_buttons"> - <layout_panel name="profile_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="フレンド登録" name="add_friend" tool_tip="フレンド登録を申ã—出ã¾ã™"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="インスタントメッセージを開ãã¾ã™"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="コール" name="call" tool_tip="ã“ã®ä½äººã«ã‚³ãƒ¼ãƒ«ã™ã‚‹"/> - </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="テレãƒãƒ¼ãƒˆ" name="teleport" tool_tip="テレãƒãƒ¼ãƒˆã‚’é€ã‚Šã¾ã™"/> - </layout_panel> - <layout_panel name="overflow_btn_lp"> - <menu_button label="â–¼" name="overflow_btn" tool_tip="ä½äººã«ãŠé‡‘を渡ã™ã‹æŒã¡ç‰©ã‚’共有ã—ã¾ã™"/> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="profile_me_buttons_panel"> - <button label="プãƒãƒ•ィールã®ç·¨é›†" name="edit_profile_btn" tool_tip="å€‹äººçš„ãªæƒ…å ±ã‚’ç·¨é›†ã—ã¾ã™"/> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_profile_view.xml b/indra/newview/skins/default/xui/ja/panel_profile_view.xml deleted file mode 100644 index 5cb6575773..0000000000 --- a/indra/newview/skins/default/xui/ja/panel_profile_view.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_target_profile"> - <string name="status_online"> - オンライン - </string> - <string name="status_offline"> - オフライン - </string> - <text name="display_name_label" value="表示å:"/> - <text name="solo_username_label" value="ユーザーå:"/> - <text name="status" value="オンライン"/> - <text name="user_name_small" value="Jack oh look at me this is a super duper long name"/> - <text name="user_name" value="Jack Linden"/> - <button name="copy_to_clipboard" tool_tip="クリップボードã«ã‚³ãƒ”ー"/> - <text name="user_label" value="ユーザーå:"/> - <text name="user_slid" value="jack.linden"/> - <tab_container name="tabs"> - <panel label="プãƒãƒ•ィール" name="panel_profile"/> - <panel label="ピック" name="panel_picks"/> - <panel label="メモã¨ãƒ—ライãƒã‚·ãƒ¼" name="panel_notes"/> - </tab_container> -</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_region_debug.xml b/indra/newview/skins/default/xui/ja/panel_region_debug.xml index f6865c12b1..169da27ce5 100644 --- a/indra/newview/skins/default/xui/ja/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/ja/panel_region_debug.xml @@ -36,5 +36,5 @@ <button label="?" name="top_scripts_help"/> <button label="地域å†èµ·å‹•" name="restart_btn" tool_tip="2分間ã®ã‚«ã‚¦ãƒ³ãƒˆãƒ€ã‚¦ãƒ³å¾Œã€åœ°åŸŸã‚’å†èµ·å‹•ã—ã¾ã™"/> <button label="?" name="restart_help"/> - <button label="å†èµ·å‹•ã‚’é…å»¶" name="cancel_restart_btn" tool_tip="地域ã®å†èµ·å‹•を1時間é…å»¶ã—ã¾ã™"/> + <button label="å†èµ·å‹•ã‚’ã‚ャンセル" name="cancel_restart_btn" tool_tip="リージョンã®å†èµ·å‹•ã‚’ã‚ャンセル"/> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_region_estate.xml b/indra/newview/skins/default/xui/ja/panel_region_estate.xml index 5b2ef36045..b5cc6b9765 100644 --- a/indra/newview/skins/default/xui/ja/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/ja/panel_region_estate.xml @@ -16,10 +16,10 @@ ï¼ˆä¸æ˜Žï¼‰ </text> <text name="Only Allow"> - 次ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ï¼š + 次ã®ä½äººã«ã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ï¼š </text> - <check_box label="æ”¯æ‰•æƒ…å ±ç™»éŒ²æ¸ˆ" name="limit_payment" tool_tip="未確èªã®ä½äººã®ç«‹å…¥ã‚’ç¦æ¢ã—ã¾ã™"/> - <check_box label="å¹´é½¢ç¢ºèªæ¸ˆ" name="limit_age_verified" tool_tip="年齢確èªã‚’済ã¾ã›ã¦ã„ãªã„ä½äººã®ç«‹å…¥ã‚’ç¦æ¢ã—ã¾ã™ã€‚ 詳ã—ã„æƒ…å ±ã¯ [SUPPORT_SITE] ã‚’ã”覧下ã•ã„。"/> + <check_box label="æ”¯æ‰•æƒ…æƒ…å ±ãŒç™»éŒ²ã•れã¦ã„ã‚‹" name="limit_payment" tool_tip="æ”¯æ‰•æƒ…å ±ãŒç™»éŒ²ã•れã¦ã„ãªã„ã¨ã€ã“ã®ä¸å‹•産ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。詳細ã«ã¤ã„ã¦ã¯ã€[SUPPORT_SITE] ã‚’ã”覧ãã ã•ã„。"/> + <check_box label="18 æ‰ä»¥ä¸Šã§ã™" name="limit_age_verified" tool_tip="ã“ã®ä¸å‹•産(エステート)ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ã€18 æ‰ä»¥ä¸Šã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。詳細ã«ã¤ã„ã¦ã¯ã€[SUPPORT_SITE] ã‚’ã”覧ãã ã•ã„。"/> <check_box label="ボイスãƒãƒ£ãƒƒãƒˆã‚’許å¯" name="voice_chat_check"/> <button label="?" name="voice_chat_help"/> <text name="abuse_email_text"> diff --git a/indra/newview/skins/default/xui/ja/panel_region_texture.xml b/indra/newview/skins/default/xui/ja/panel_region_texture.xml deleted file mode 100644 index 9e442ce091..0000000000 --- a/indra/newview/skins/default/xui/ja/panel_region_texture.xml +++ /dev/null @@ -1,58 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="地é¢ãƒ†ã‚¯ã‚¹ãƒãƒ£" name="Textures"> - <text name="region_text_lbl"> - 地域: - </text> - <text name="region_text"> - 未知 - </text> - <text name="detail_texture_text"> - 地形ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ (512x512ã€24ビット .tgaファイルãŒå¿…è¦ã§ã™ï¼‰ - </text> - <text name="height_text_lbl"> - 1(低) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4(高) - </text> - <text name="height_text_lbl5"> - 地形テクスãƒãƒ£ã®éš†èµ·ç¯„囲 - </text> - <text name="height_text_lbl6"> - 北西 - </text> - <text name="height_text_lbl7"> - åŒ—æ± - </text> - <text name="height_text_lbl8"> - å—西 - </text> - <text name="height_text_lbl9"> - å—æ± - </text> - <spinner label="低" name="height_start_spin_0"/> - <spinner label="低" name="height_start_spin_1"/> - <spinner label="低" name="height_start_spin_2"/> - <spinner label="低" name="height_start_spin_3"/> - <spinner label="高" name="height_range_spin_0"/> - <spinner label="高" name="height_range_spin_1"/> - <spinner label="高" name="height_range_spin_2"/> - <spinner label="高" name="height_range_spin_3"/> - <text name="height_text_lbl10"> - 数値ã¯ä¸Šã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ãŒèª¿å’Œã™ã‚‹ç¯„囲を示ã—ã¾ã™ã€‚ - </text> - <text name="height_text_lbl11"> - 計測å˜ä½ã¯ãƒ¡ãƒ¼ãƒˆãƒ«ã§ã€ã€Œä½Žã€ã®å€¤ã¯ã€1番ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®é«˜ã•ã® -「最大値ã€ã§ã™ã€‚「高ã€ã®å€¤ã¯ã€4番ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®é«˜ã•ã®ã€Œæœ€ä½Žå€¤ã€ã§ã™ã€‚ - </text> - <text name="height_text_lbl12"> - ãã—ã¦ã€Œé«˜ã€ã®å€¤ã¯ãƒ†ã‚¯ã‚¹ãƒãƒ£#4ã®é«˜ã•ã®ä¸‹é™ã¨ãªã‚Šã¾ã™ã€‚ - </text> - <button label="é©ç”¨" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_script_ed.xml b/indra/newview/skins/default/xui/ja/panel_script_ed.xml index 9fdd16d567..14d55002a3 100644 --- a/indra/newview/skins/default/xui/ja/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/ja/panel_script_ed.xml @@ -22,6 +22,8 @@ <menu label="ファイル" name="File"> <menu_item_call label="ä¿å˜" name="Save"/> <menu_item_call label="å¤‰æ›´ã‚’å…ƒã«æˆ»ã™" name="Revert All Changes"/> + <menu_item_call label="ファイルã‹ã‚‰ãƒãƒ¼ãƒ‰..." name="LoadFromFile"/> + <menu_item_call label="ファイルã«ä¿å˜..." name="SaveToFile"/> </menu> <menu label="編集" name="Edit"> <menu_item_call label="å…ƒã«æˆ»ã™" name="Undo"/> diff --git a/indra/newview/skins/default/xui/ja/panel_script_question_toast.xml b/indra/newview/skins/default/xui/ja/panel_script_question_toast.xml new file mode 100644 index 0000000000..a2d0237da0 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_script_question_toast.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel label="script_question_panel" name="panel_script_question_toast"> + <panel label="buttons_panel" name="buttons_panel"/> +</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_side_tray.xml b/indra/newview/skins/default/xui/ja/panel_side_tray.xml deleted file mode 100644 index 3fd14ece06..0000000000 --- a/indra/newview/skins/default/xui/ja/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="サイドãƒãƒ¼ã‚’表示・éžè¡¨ç¤º" name="sidebar_openclose" tab_title="サイドãƒãƒ¼ã‚’é–‹ã・閉ã˜ã‚‹"/> - <sidetray_tab description="ホーム。" name="sidebar_home" tab_title="ホーム"> - <panel label="ホーム" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="ã‚ãªãŸã®å…¬é–‹ãƒ—ãƒãƒ•ィールã¨ãƒ”ックを編集ã—ã¦ãã ã•ã„。" name="sidebar_me" tab_title="マイ プãƒãƒ•ィール"> - <panel_container name="panel_container"> - <panel label="ミー" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="フレンドã€é€£çµ¡å…ˆã€è¿‘ãã®äººã‚’探ã—ã¦ãã ã•ã„。" name="sidebar_people" tab_title="人"> - <panel_container name="panel_container"> - <panel label="ã‚°ãƒ«ãƒ¼ãƒ—æƒ…å ±" name="panel_group_info_sidetray"/> - <panel label="ブãƒãƒƒã‚¯ã•れãŸä½äººã¨ã‚ªãƒ–ジェクト" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="行ããŸã„å ´æ‰€ã€è¡Œã£ãŸã“ã¨ã®ã‚ã‚‹å ´æ‰€ã‚’æŽ¢ã—ã¦ãã ã•ã„。" label="å ´æ‰€" name="sidebar_places" tab_title="å ´æ‰€"> - <panel label="å ´æ‰€" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="ã‚ãªãŸã®æŒã¡ç‰©ã‚’眺ã‚ã¦ãã ã•ã„。" name="sidebar_inventory" tab_title="æŒã¡ç‰©"> - <panel label="æŒã¡ç‰©ã‚’編集" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="ã‚ãªãŸã®å®¹å§¿ã‚„ç¾åœ¨ã®è¦‹ãŸç›®ã‚’変更ã—ã¦ãã ã•ã„。" name="sidebar_appearance" tab_title="容姿"> - <panel label="容姿ã®ç·¨é›†" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> 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..e496e6602b --- /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..c3b1cd91e7 --- /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..f09643d562 100644 --- a/indra/newview/skins/default/xui/ja/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/ja/panel_status_bar.xml @@ -15,10 +15,10 @@ <panel.string name="buycurrencylabel"> L$ [AMT] </panel.string> - <panel name="balance_bg"> + <panel left="-370" name="balance_bg" width="160"> <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/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/ja/panel_volume_pulldown.xml new file mode 100644 index 0000000000..967dedf061 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater"> + <slider label="マスター" name="System Volume"/> + <slider label="ボタン" name="UI Volume"/> + <slider label="環境音" name="Wind Volume"/> + <slider label="サウンド" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="ジェスãƒãƒ£ãƒ¼ã®éŸ³ã‚’有効ã«ã™ã‚‹"/> + <slider label="音楽" name="Music Volume"/> + <check_box name="enable_music" tool_tip="ストリーミング音楽を有効ã«ã™ã‚‹"/> + <slider label="メディア" name="Media Volume"/> + <check_box name="enable_media" tool_tip="ストリーミングメディアを有効ã«ã™ã‚‹"/> + <slider label="ボイス" name="Voice Volume"/> + <check_box name="enable_voice_check" tool_tip="ボイスãƒãƒ£ãƒƒãƒˆã‚’有効ã«ã™ã‚‹"/> +</panel> diff --git a/indra/newview/skins/default/xui/ja/role_actions.xml b/indra/newview/skins/default/xui/ja/role_actions.xml index c53ad838f7..896ed556ae 100644 --- a/indra/newview/skins/default/xui/ja/role_actions.xml +++ b/indra/newview/skins/default/xui/ja/role_actions.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <role_actions> <action_set description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—メンãƒãƒ¼ã‚’è¿½åŠ ã€æŽ’é™¤ã—ã€æ‹›å¾…状ãªã—ã«æ–°ãƒ¡ãƒ³ãƒãƒ¼ã®å‚åŠ ã‚’èªã‚る権é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" name="Membership"> <action description="ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«äººã‚’招待" longdescription="「役割ã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã®ã€Œãƒ¡ãƒ³ãƒãƒ¼ã€ã‚¿ãƒ–内ã«ã‚る「招待ã€ãƒœã‚¿ãƒ³ã‚’押ã—ã¦ã€ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«ãƒ¡ãƒ³ãƒãƒ¼ã‚’招待ã—ã¾ã™ã€‚" name="member invite" value="1"/> @@ -51,7 +51,7 @@ <action description="グループ所有オブジェクトã®è¿”å´" longdescription="グループ所有ã®åŒºç”»ä¸Šã®ã‚ªãƒ–ジェクトã®ã†ã¡ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®ã‚ªãƒ–ジェクトを返å´ã™ã‚‹ã«ã¯ã€ã€ŒåœŸåœ°æƒ…å ±ã€ï¼žã€Œã‚ªãƒ–ジェクトã€ã‚¿ãƒ–を使ã„ã¾ã™ã€‚" name="land return group owned" value="48"/> <action description="グループã«è¨å®šã•れã¦ã„るオブジェクトを返å´" longdescription="グループ所有ã®åŒºç”»ä¸Šã®ã‚ªãƒ–ジェクトã®ã†ã¡ã€ã‚°ãƒ«ãƒ¼ãƒ—ã«è¨å®šã•れã¦ã„るオブジェクトを返å´ã™ã‚‹ã«ã¯ã€ã€ŒåœŸåœ°æƒ…å ±ã€ï¼žã€Œã‚ªãƒ–ジェクトã€ã‚¿ãƒ–を使ã„ã¾ã™ã€‚" name="land return group set" value="33"/> <action description="éžã‚°ãƒ«ãƒ¼ãƒ—オブジェクトã®è¿”å´" longdescription="グループ所有ã®åŒºç”»ä¸Šã®ã‚ªãƒ–ジェクトã®ã†ã¡ã€ã‚°ãƒ«ãƒ¼ãƒ—以外ã®ã‚ªãƒ–ジェクトを返å´ã™ã‚‹ã«ã¯ã€ã€ŒåœŸåœ°æƒ…å ±ã€ï¼žã€Œã‚ªãƒ–ジェクトã€ã‚¿ãƒ–を使ã„ã¾ã™ã€‚" name="land return non group" value="34"/> - <action description="ãƒªãƒ³ãƒ‡ãƒ³è£½ã®æ¤ç‰©ã‚’使用ã—ã¦æ™¯è¦³ä½œæˆ" longdescription="ãƒªãƒ³ãƒ‡ãƒ³è£½ã®æ¨¹æœ¨ã€æ¤ç‰©ã€è‰ã‚’æ¤ãˆã‚‹ã€æ™¯è¦³ã¥ãりã®èƒ½åŠ›ã§ã™ã€‚ ã“ã‚Œã‚‰ã®æ¤ç‰©ã¯ã‚ãªãŸã®æŒã¡ç‰©å†…ã®ã€Œãƒ©ã‚¤ãƒ–ラリ〠> 「オブジェクトã€ãƒ•ォルダã«ã‚りã¾ã™ã€‚「制作ã€ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã§ä½œæˆã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚" name="land gardening" value="35"/> + <action description="ãƒªãƒ³ãƒ‡ãƒ³è£½ã®æ¤ç‰©ã‚’使用ã—ã¦æ™¯è¦³ä½œæˆ" longdescription="ãƒªãƒ³ãƒ‡ãƒ³è£½ã®æ¨¹æœ¨ã€æ¤ç‰©ã€è‰ã‚’æ¤ãˆã‚‹ã€æ™¯è¦³ã¥ãりã®èƒ½åŠ›ã§ã™ã€‚ ã“ã‚Œã‚‰ã®æ¤ç‰©ã¯ã‚ãªãŸã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªå†…ã®ã€Œãƒ©ã‚¤ãƒ–ラリ〠> 「オブジェクトã€ãƒ•ォルダã«ã‚りã¾ã™ã€‚「制作ã€ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã§ä½œæˆã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚" name="land gardening" value="35"/> </action_set> <action_set description="ã“れらã®ã€Œèƒ½åŠ›ã€ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã‚’è²æ¸¡ã€ä¿®æ£ã€è²©å£²ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚ 変更ã¯ã€Œåˆ¶ä½œãƒ„ール〠> 「一般ã€ã‚¿ãƒ–ã§è¡Œã„ã¾ã™ã€‚ オブジェクトをå³ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€Œç·¨é›†ã€ã‚’é–‹ãã¨è¨å®šå†…容を確èªã§ãã¾ã™ã€‚" name="Object Management"> <action description="グループã«ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã‚’è²æ¸¡" longdescription="「制作ツール〠> 「一般ã€ã‚¿ãƒ–ã§ã€ã‚ªãƒ–ジェクトをグループã«è²æ¸¡ã—ã¾ã™ã€‚" name="object deed" value="36"/> diff --git a/indra/newview/skins/default/xui/ja/sidepanel_inventory.xml b/indra/newview/skins/default/xui/ja/sidepanel_inventory.xml index fc0293307b..51d6d48f90 100644 --- a/indra/newview/skins/default/xui/ja/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/ja/sidepanel_inventory.xml @@ -2,47 +2,24 @@ <panel label="ã‚‚ã®" name="objects panel"> <panel label="" name="sidepanel__inventory_panel"> <layout_stack name="inventory_layout_stack"> - <layout_panel name="inbox_outbox_layout_panel"> - <layout_stack name="inbox_outbox_layout_stack"> - <layout_panel name="inbox_layout_panel"> - <panel label="" name="marketplace_inbox"> - <string name="InboxLabelWithArg"> - å—ã‘å–ã£ãŸå•†å“([NUM]) - </string> - <string name="InboxLabelNoArg"> - å—ã‘å–ã£ãŸå•†å“ - </string> - <button label="å—ã‘å–ã£ãŸå•†å“" name="inbox_btn"/> - <text name="inbox_fresh_new_count"> - [NUM] å€‹ã®æ–°å•†å“ - </text> - <panel tool_tip="Drag and drop items to your inventory to manage and use them"> - <text name="inbox_inventory_placeholder"> - マーケットプレイスã‹ã‚‰è³¼å…¥ã—ãŸå•†å“ã¯ã“ã“ã«é…é”ã•れã¾ã™ã€‚ - </text> - </panel> - </panel> - </layout_panel> - <layout_panel name="outbox_layout_panel"> - <panel label="" name="marketplace_outbox"> - <string name="OutboxLabelWithArg"> - マーãƒãƒ£ãƒ³ãƒˆã®ã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ ([NUM]) - </string> - <string name="OutboxLabelNoArg"> - マーãƒãƒ£ãƒ³ãƒˆã®ã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ - </string> - <button label="マーãƒãƒ£ãƒ³ãƒˆã®ã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹" name="outbox_btn"/> - <button label="" name="outbox_sync_btn" tool_tip="自分ã®ãƒžãƒ¼ã‚±ãƒƒãƒˆãƒ—レイス店é ã«ç§»å‹•"/> - <panel> - <panel name="outbox_inventory_placeholder_panel"> - <text name="outbox_inventory_placeholder_title"> - ãƒãƒ¼ãƒ‡ã‚£ãƒ³ã‚°... - </text> - </panel> - </panel> - </panel> - </layout_panel> - </layout_stack> + <layout_panel name="inbox_layout_panel"> + <panel label="" name="marketplace_inbox"> + <string name="InboxLabelWithArg"> + å—ã‘å–ã£ãŸã‚¢ã‚¤ãƒ†ãƒ ([NUM]) + </string> + <string name="InboxLabelNoArg"> + å—ã‘å–ã£ãŸã‚¢ã‚¤ãƒ†ãƒ + </string> + <button label="å—ã‘å–ã£ãŸã‚¢ã‚¤ãƒ†ãƒ " name="inbox_btn"/> + <text name="inbox_fresh_new_count"> + [NUM] å€‹ã®æ–°ã‚¢ã‚¤ãƒ†ãƒ + </text> + <panel name="inbox_inventory_placeholder_panel" tool_tip="アイテムを使用ã™ã‚‹ã«ã¯ã€ãã®ã‚¢ã‚¤ãƒ†ãƒ をインベントリã«ãƒ‰ãƒ©ãƒƒã‚°ã‚¢ãƒ³ãƒ‰ãƒ‰ãƒãƒƒãƒ—"> + <text name="inbox_inventory_placeholder"> + マーケットプレイスã‹ã‚‰è³¼å…¥ã—ãŸå•†å“ã¯ã“ã“ã«é…é”ã•れã¾ã™ã€‚ + </text> + </panel> + </panel> </layout_panel> </layout_stack> <panel name="button_panel"> @@ -51,7 +28,7 @@ <button label="プãƒãƒ•ィール" name="info_btn" tool_tip="オブジェクトã®ãƒ—ãƒãƒ•ィールを表示ã™ã‚‹"/> </layout_panel> <layout_panel name="share_btn_lp"> - <button label="共有" name="share_btn" tool_tip="「æŒã¡ç‰©ã€ã®ã‚¢ã‚¤ãƒ†ãƒ を共有ã™ã‚‹"/> + <button label="共有" name="share_btn" tool_tip="インベントリã®ã‚¢ã‚¤ãƒ†ãƒ を共有ã™ã‚‹"/> </layout_panel> <layout_panel name="shop_btn_lp"> <button label="店" name="shop_btn" tool_tip="マーケットプレイスã®ã‚µã‚¤ãƒˆã‚’é–‹ã"/> diff --git a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml index d820994b59..e70d91d258 100644 --- a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> ï¼ˆä¸æ˜Žï¼‰ </panel.string> + <panel.string name="unknown_multiple"> + (䏿˜Ž/複数) + </panel.string> <panel.string name="public"> (公開) </panel.string> @@ -16,13 +19,13 @@ [year,datetime,local] [mth,datetime,local] [day,datetime,local] [wkday,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] </panel.string> <panel.string name="origin_inventory"> - (æŒã¡ç‰©ï¼‰ + (インベントリ) </panel.string> <panel.string name="origin_inworld"> (インワールド) </panel.string> <text name="title" value="アイテムã®ãƒ—ãƒãƒ•ィール"/> - <text name="origin" value="(æŒã¡ç‰©ï¼‰"/> + <text name="origin" value="(インベントリ)"/> <scroll_container name="item_profile_scroll"> <panel label="" name="item_profile"> <text name="LabelItemNameTitle"> diff --git a/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml b/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml index eb2bfa993b..c61c73657f 100644 --- a/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> ã“れらã®ã‚ªãƒ–ジェクトを修æ£ã§ãã¾ã›ã‚“ </panel.string> + <panel.string name="text modify info 5"> + 地域(リージョン)ã®å¢ƒç•Œã‚’è¶Šãˆã¦ã“ã®ã‚ªãƒ–ジェクトを修æ£ã§ãã¾ã›ã‚“ + </panel.string> + <panel.string name="text modify info 6"> + 地域(リージョン)ã®å¢ƒç•Œã‚’è¶Šãˆã¦ã“れらã®ã‚ªãƒ–ジェクトを修æ£ã§ãã¾ã›ã‚“ + </panel.string> <panel.string name="text modify warning"> ã“ã®ã‚ªãƒ–ジェクトã«ã¯ã€ãƒ‘ーツãŒãƒªãƒ³ã‚¯ã•れã¦ã„ã¾ã™ </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="ä¾¡æ ¼ï¼š L$" name="Edit Cost"/> <check_box label="検索ã«è¡¨ç¤º" name="search_check" tool_tip="ã“ã®ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã‚’æ¤œç´¢çµæžœã«è¡¨ç¤ºã—ã¾ã™"/> + <text name="pathfinding_attributes_label"> + パスファインディング属性: + </text> <text name="B:"> B. </text> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index f611b96502..50697e5500 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -137,7 +137,7 @@ 終了 </string> <string name="create_account_url"> - http://join.secondlife.com/index.php?lang=ja-JP + http://join.secondlife.com/index.php?lang=ja-JP&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> ãŠä½¿ã„ã®å¤ã„ビューワã§ã¯ Second Life ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。以下ã®ãƒšãƒ¼ã‚¸ã‹ã‚‰æ–°ã—ã„ビューワをダウンãƒãƒ¼ãƒ‰ã—ã¦ãã ã•ã„: @@ -181,8 +181,8 @@ http://secondlife.com/viewer-access-faq </string> <string name="LoginFailedPremiumOnly"> æ—¢ã«ãƒã‚°ã‚¤ãƒ³ã—ã¦ã„ã‚‹ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«æœ€ä¸Šã®ã‚¤ãƒ³ãƒ¯ãƒ¼ãƒ«ãƒ‰ä½“験をæä¾›ã™ã‚‹ãŸã‚ã€Second Life ã¸ã®ãƒã‚°ã‚¤ãƒ³ã¯ä¸€æ™‚çš„ã«åˆ¶é™ã•れã¦ã„ã¾ã™ã€‚ - -申ã—訳ã”ã–ã„ã¾ã›ã‚“ãŒã€æœ‰æ–™ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’優先ã™ã‚‹ãŸã‚ã«ã€ç¾æ™‚点ã®ã¨ã“ã‚無料アカウントã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ã¯ Second Life ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’ã”é æ…®ã„ãŸã ã„ã¦ã„ã¾ã™ã€‚ + +申ã—訳ã”ã–ã„ã¾ã›ã‚“ãŒã€æœ‰æ–™ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’優先ã™ã‚‹ãŸã‚ã€ç¾åœ¨ã®ã¨ã“ã‚無料アカウントã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ã¯ Second Life ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’ã”é æ…®ã„ãŸã ã„ã¦ã„ã¾ã™ã€‚ </string> <string name="LoginFailedComputerProhibited"> ã“ã®ãƒ‘ソコンã‹ã‚‰ã¯ Second Life ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。 @@ -339,17 +339,35 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 アイテム㯠1 ã¤ã ã‘ã“ã“ã«ãƒ‰ãƒ©ãƒƒã‚°ã§ãã¾ã™ </string> <string name="TooltipPrice" value="L$[AMOUNT]:"/> + <string name="TooltipOutboxDragToWorld"> + マーãƒãƒ£ãƒ³ãƒˆãƒœãƒƒã‚¯ã‚¹å†…ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’ Rez ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ + </string> <string name="TooltipOutboxNoTransfer"> - ã“れらオブジェクト㮠1 ã¤ã¾ãŸã¯è¤‡æ•°ã¯ã€åˆ¥ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«å£²ã‚Šæ¸¡ã—ãŸã‚Šè²æ¸¡ã§ããªã„ã‚‚ã®ã§ã™ã€‚ + ã“れらオブジェクト㮠1 ã¤ã¾ãŸã¯è¤‡æ•°ã¯å£²ã‚Šæ¸¡ã—ãŸã‚Šè²æ¸¡ã—ãŸã‚Šã§ããªã„ã‚‚ã®ã§ã™ã€‚ + </string> + <string name="TooltipOutboxNotInInventory"> + マーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ã§ã¯ã€ã”自分ã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‹ã‚‰ã®ã‚¢ã‚¤ãƒ†ãƒ ã—ã‹å—ã‘入れるã“ã¨ãŒã§ãã¾ã›ã‚“ </string> <string name="TooltipOutboxWorn"> - ã‚ãªãŸã¯ã“れらオブジェクト㮠1 ã¤ã¾ãŸã¯è¤‡æ•°ã‚’装ç€ã—ã¦ã„ã¾ã™ã€‚ã‚¢ãƒã‚¿ãƒ¼ã‹ã‚‰ãれらをå–り外ã—ã€å†ã³ç§»å‹•ã—ã¦ã¿ã¦ãã ã•ã„。 + ç€ç”¨ã—ã¦ã„るアイテムをマーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ã«å…¥ã‚Œã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ + </string> + <string name="TooltipOutboxCallingCard"> + コーリングカードをマーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ã«å…¥ã‚Œã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ </string> <string name="TooltipOutboxFolderLevels"> - ã“ã®ãƒ•ォルダã«ã‚るサブフォルダã®éšŽå±¤ãŒå¤šã™ãŽã¾ã™ã€‚サブフォルダã¯4階層以内(ルートフォルダã®ä¸‹ã«Aã€ãã®ä¸‹ã«Bã€ãã®ä¸‹ã«Cã¨ã„ã†é¢¨ã«ï¼‰ã«ã¾ã¨ã‚ç›´ã—ã¦ãã ã•ã„。 + ãƒã‚¹ãƒˆå…¥ã‚Šãƒ•ã‚©ãƒ«ãƒ€ã®æ·±ã•㌠3 ã‚’è¶…ãˆã¦ã„ã¾ã™ + </string> + <string name="TooltipOutboxTooManyFolders"> + 最上ä½ãƒ•ォルダ内ã®ã‚µãƒ–フォルダ数㌠20 ã‚’è¶…ãˆã¦ã„ã¾ã™ </string> <string name="TooltipOutboxTooManyObjects"> - ã“ã®ãƒ•ォルダã«ã¯ 200 個以上ã®ã‚ªãƒ–ジェクトãŒå«ã¾ã‚Œã¾ã™ã€‚商å“ã®ã„ã¤ã‹ã‚’ボックスã«å…¥ã‚Œã€ã‚ªãƒ–ジェクト数を減らã—ã¦ãã ã•ã„。 + 最上ä½ãƒ•ォルダ内ã®ã‚¢ã‚¤ãƒ†ãƒ 数㌠200 ã‚’è¶…ãˆã¦ã„ã¾ã™ + </string> + <string name="TooltipDragOntoOwnChild"> + フォルダをãã®åフォルダã«ç§»å‹•ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ + </string> + <string name="TooltipDragOntoSelf"> + フォルダをãã®ãƒ•ォルダ自身ã«ç§»å‹•ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ </string> <string name="TooltipHttpUrl"> クリックã—ã¦ã“ã® Web ページを見ã¾ã™ @@ -817,6 +835,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="anim_yes_head"> é ·ã </string> + <string name="multiple_textures"> + 複数 + </string> <string name="texture_loading"> ãƒãƒ¼ãƒ‡ã‚£ãƒ³ã‚°... </string> @@ -865,6 +886,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="ScriptQuestionCautionChatDenied"> [REGIONNAME] ã® [REGIONPOS] ã¨ã„ã†å ´æ‰€ã«ã‚ã‚‹ã€ã€Œ [OWNERNAME] ã€ãŒæ‰€æœ‰ã™ã‚‹ã€Œ [OBJECTNAME] ã€ã¨ã„ã†ã‚ªãƒ–ジェクトã¯ã€æ¬¡ã®æ¨©é™ã‚’æ‹’å¦ã—ã¾ã—ãŸï¼š [PERMISSIONS] </string> + <string name="AdditionalPermissionsRequestHeader"> + ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ã™ã‚‹ã¨ã€ã“ã®ã‚ªãƒ–ジェクトã«ã¯æ¬¡ã®æ“作も許å¯ã•れã¾ã™ï¼š + </string> <string name="ScriptTakeMoney"> リンデンドル(L$)を支払ㆠ</string> @@ -898,6 +922,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="ControlYourCamera"> カメラã®ã‚³ãƒ³ãƒˆãƒãƒ¼ãƒ« </string> + <string name="TeleportYourAgent"> + ã‚ãªãŸã‚’テレãƒãƒ¼ãƒˆ + </string> <string name="NotConnected"> 接続ã•れã¦ã„ã¾ã›ã‚“ </string> @@ -976,6 +1003,12 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="choose_the_directory"> å‚ç…§ </string> + <string name="script_files"> + スクリプト + </string> + <string name="dictionary_files"> + 辞書 + </string> <string name="AvatarSetNotAway"> 一時退å¸ä¸è§£é™¤ </string> @@ -1211,70 +1244,63 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 ã“ã“ã«ãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã‚’ドラッグã—ã¦ãŠæ°—ã«å…¥ã‚Šã«è¿½åŠ ã—ã¾ã™ã€‚ </string> <string name="InventoryNoTexture"> - 「æŒã¡ç‰©ã€å†…ã«ã“ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®ã‚³ãƒ”ーãŒã‚りã¾ã›ã‚“ + インベントリ内ã«ã“ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®ã‚³ãƒ”ーãŒã‚りã¾ã›ã‚“ </string> <string name="InventoryInboxNoItems"> - マーケットプレイスã§è³¼å…¥ã—ãŸå•†å“ã¯ã“ã“ã«é…é”ã•れã¾ã™ã€‚ + マーケットプレイスã§è³¼å…¥ã—ãŸå•†å“ã¯ã“ã“ã«è¡¨ç¤ºã•れã¾ã™ã€‚ãã®å¾Œã€ã‚¢ã‚¤ãƒ†ãƒ をインベントリã«ãƒ‰ãƒ©ãƒƒã‚°ã™ã‚Œã°ã€ãれらã®ã‚¢ã‚¤ãƒ†ãƒ を使用ã§ãã¾ã™ã€‚ </string> <string name="MarketplaceURL"> - http://marketplace.[DOMAIN_NAME] + https://marketplace.[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 + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4 </string> - <string name="InventoryOutboxCreationErrorTitle"> - マーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ãŒæ£ã—ãè¨å®šã•れã¦ã„ã¾ã›ã‚“ + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard </string> - <string name="InventoryOutboxCreationErrorTooltip"> - マーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ã®è¨å®šã‚¨ãƒ©ãƒ¼ + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports </string> - <string name="InventoryOutboxCreationError"> - å•題を解決ã™ã‚‹ã«ã¯ã‚«ã‚¹ã‚¿ãƒžãƒ¼ã‚µãƒ¼ãƒ“スã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more </string> <string name="InventoryOutboxNotMerchantTitle"> - マーケットプレイスã¯çš†ã®å£²ã‚Šå ´ã§ã™ - </string> - <string name="InventoryOutboxNotMerchantTooltip"> - ã‚ãªãŸã‚‚マーãƒãƒ£ãƒ³ãƒˆã«ï¼ + マーケットプレイスã§ã¯èª°ã§ã‚‚アイテムを売るã“ã¨ãŒã§ãã¾ã™ã€‚ </string> + <string name="InventoryOutboxNotMerchantTooltip"/> <string name="InventoryOutboxNotMerchant"> - [[MARKETPLACE_URL] Second Life マーケットプレイス] ã§ã¯ã€SL ä½äººãŒåˆ¶ä½œã—ãŸå•†å“ 100 万点以上ãŒè²©å£²ã•れã¦ã„ã¾ã™ã€‚ã‚ãªãŸã‚‚ã”自分ã®è‡ªä¿¡ä½œã‚„ã€ã‚ãªãŸãŒè³¼å…¥ã—ãŸã‚¢ã‚¤ãƒ†ãƒ を商å“ã¨ã—ã¦å£²ã£ã¦ã¿ã¾ã›ã‚“ã‹ã€‚ãã®æ‰‹é †ã¯ç°¡å˜ã§ã€ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—ã¯ç„¡æ–™ã§ã™ã€‚[[LEARN_MORE_URL] ã“ã¡ã‚‰ã§è©³ç´°ã‚’確ã‹ã‚]ã€ãƒžãƒ¼ã‚±ãƒƒãƒˆãƒ—レイスã«[[CREATE_STORE_URL] ストアを作æˆ] ã—ã¾ã—ょã†ã€‚ + マーãƒãƒ£ãƒ³ãƒˆã«ãªã‚ŠãŸã„æ–¹ã¯ã€[[MARKETPLACE_CREATE_STORE_URL] マーケットプレイスストアを作æˆ]ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ </string> <string name="InventoryOutboxNoItemsTitle"> - マーケットプレイスã¸ã®æ–°ã—ã„å‡ºè·æ–¹æ³• - </string> - <string name="InventoryOutboxNoItemsTooltip"> - 商å“ã‚’ã“ã“ã«ãƒ‰ãƒ©ãƒƒã‚°ã‚¢ãƒ³ãƒ‰ãƒ‰ãƒãƒƒãƒ—ã™ã‚‹ã ã‘ã§ã€ãƒžãƒ¼ã‚±ãƒƒãƒˆãƒ—レイスã®å£²ã‚Šç‰©ã¨ãªã‚Šã¾ã™ + アウトボックスã¯ç©ºã§ã™ã€‚ </string> + <string name="InventoryOutboxNoItemsTooltip"/> <string name="InventoryOutboxNoItems"> - 販売ã™ã‚‹å•†å“ã¾ãŸã¯ãƒ•ォルダをã“ã®ã‚¨ãƒªã‚¢ã«ãƒ‰ãƒ©ãƒƒã‚°ã—ã¾ã™ã€‚コピーä¸å¯ã®ã‚¢ã‚¤ãƒ†ãƒ ã§ãªã„é™ã‚Šã€ãƒ‰ãƒ©ãƒƒã‚°ã—ãŸå•†å“ã®ã‚³ãƒ”ーãŒè¡¨ç¤ºã•れるã ã‘ã§ã€ã‚ãªãŸã®æŒã¡ç‰©ã‹ã‚‰å•†å“ãŒå®Ÿéš›ã«ç§»å‹•ã™ã‚‹ã‚ã‘ã§ã¯ã‚りã¾ã›ã‚“。マーケットプレイスã«å•†å“ã‚’é€ã‚‹æº–å‚™ãŒæ•´ã£ãŸã‚‰ã€ã€Œã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰ã€ãƒœã‚¿ãƒ³ã‚’クリックã—ã¾ã™ã€‚商å“ã¯ãƒžãƒ¼ã‚±ãƒƒãƒˆãƒ—レイスインベントリã«ç§»å‹•ã—ãŸæ™‚点ã§ã“ã®ãƒ•ォルダã‹ã‚‰å‰Šé™¤ã•れã¾ã™ã€‚ + [[MARKETPLACE_DASHBOARD_URL] マーケットプレイス]ã«è²©å£²ã™ã‚‹ã‚¢ã‚¤ãƒ†ãƒ を一覧ã™ã‚‹ã«ã¯ã€ãƒ•ォルダをã“ã®ã‚¨ãƒªã‚¢ã«ãƒ‰ãƒ©ãƒƒã‚°ã—ã€ã€Œãƒžãƒ¼ã‚±ãƒƒãƒˆãƒ—レイスã«é€ä¿¡ã€ã‚’クリックã—ã¾ã™ã€‚ </string> <string name="Marketplace Error None"> エラーãªã— </string> <string name="Marketplace Error Not Merchant"> - エラー:マーケットプレイスã«å•†å“ã‚’é€ã‚‹å‰ã«ã€ã‚ãªãŸè‡ªèº«ã‚’マーãƒãƒ£ãƒ³ãƒˆç™»éŒ²ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ï¼ˆç™»éŒ²ã¯ç„¡æ–™ã§ã™ï¼‰ã€‚ + エラー:マーケットプレイスã«ã‚¢ã‚¤ãƒ†ãƒ ã‚’é€ã‚‹å‰ã«ã€ã‚ãªãŸè‡ªèº«ã‚’マーãƒãƒ£ãƒ³ãƒˆç™»éŒ²ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ï¼ˆç™»éŒ²ã¯ç„¡æ–™ã§ã™ï¼‰ã€‚ </string> <string name="Marketplace Error Empty Folder"> エラー:ã“ã®ãƒ•ォルダã¯ç©ºã§ã™ã€‚ </string> <string name="Marketplace Error Unassociated Products"> - エラー:ã‚ãªãŸã®ãƒžãƒ¼ãƒãƒ£ãƒ³ãƒˆã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«ã¯ã€å•†å“ã¨ç„¡é–¢ä¿‚ã®ã‚¢ã‚¤ãƒ†ãƒ ãŒå¤šã™ãŽã‚‹ãŸã‚ã€ã“ã®ã‚¢ã‚¤ãƒ†ãƒ をアップãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚¨ãƒ©ãƒ¼ã‚’解消ã™ã‚‹ã«ã¯ã€ãƒžãƒ¼ã‚±ãƒƒãƒˆãƒ—レイスã®ã‚¦ã‚§ãƒ–サイトã«ãƒã‚°ã‚¤ãƒ³ã—ã€å•†å“ã«é–¢ä¿‚ã®ãªã„アイテム数を減らã—ã¦ãã ã•ã„。 + エラー:ã‚ãªãŸã®ãƒžãƒ¼ãƒãƒ£ãƒ³ãƒˆã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«ã¯ã€å•†å“ã«é–¢é€£ä»˜ã‘られã¦ã„ãªã„アイテムãŒå¤šã™ãŽã‚‹ãŸã‚ã€ã“ã®ã‚¢ã‚¤ãƒ†ãƒ をアップãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚¨ãƒ©ãƒ¼ã‚’解消ã™ã‚‹ã«ã¯ã€ãƒžãƒ¼ã‚±ãƒƒãƒˆãƒ—レイス㮠Web サイトã«ãƒã‚°ã‚¤ãƒ³ã—ã€é–¢é€£ä»˜ã‘られã¦ã„ãªã„ã‚¢ã‚¤ãƒ†ãƒ ã®æ•°ã‚’減らã—ã¦ãã ã•ã„。 </string> <string name="Marketplace Error Object Limit"> - エラー:ã“ã®å•†å“ã«å«ã¾ã‚Œã‚‹ã‚ªãƒ–ジェクトãŒå¤šã™ãŽã¾ã™ã€‚オブジェクトをã„ãã¤ã‹ãƒœãƒƒã‚¯ã‚¹ã«ã¾ã¨ã‚ã€ã‚ªãƒ–ジェクト数を200ä»¥ä¸‹ã«æ¸›ã‚‰ã—ã¦ãã ã•ã„。 + エラー:ã“ã®ã‚¢ã‚¤ãƒ†ãƒ ã«å«ã¾ã‚Œã‚‹ã‚ªãƒ–ジェクトãŒå¤šã™ãŽã¾ã™ã€‚オブジェクトをã„ãã¤ã‹ãƒœãƒƒã‚¯ã‚¹ã«ã¾ã¨ã‚ã€ã‚ªãƒ–ジェクト数を200ä»¥ä¸‹ã«æ¸›ã‚‰ã—ã¦ãã ã•ã„。 </string> <string name="Marketplace Error Folder Depth"> - エラー:ã“ã®å•†å“ã¯ãƒã‚¹ãƒˆå…¥ã‚Šãƒ•ォルダã®éšŽå±¤ãŒå¤šã™ãŽã¾ã™ã€‚ãƒã‚¹ãƒˆå…¥ã‚Šãƒ•ォルダを 3 階層以内ã«ã¾ã¨ã‚ç›´ã—ã¦ãã ã•ã„。 + エラー:ã“ã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ãƒã‚¹ãƒˆå…¥ã‚Šãƒ•ォルダã®éšŽå±¤ãŒå¤šã™ãŽã¾ã™ã€‚ãƒã‚¹ãƒˆå…¥ã‚Šãƒ•ォルダを 3 階層以内ã«ã¾ã¨ã‚ç›´ã—ã¦ãã ã•ã„。 </string> <string name="Marketplace Error Unsellable Item"> - エラー:ã“ã®é …目をマーケットプレイスã§è²©å£²ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 + エラー:ã“ã®ã‚¢ã‚¤ãƒ†ãƒ をマーケットプレイスã§è²©å£²ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 </string> <string name="Marketplace Error Internal Import"> - エラー:ã“ã®å•†å“ã«é–¢ã—ã¦å•題ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã—ã°ã‚‰ãã—ã¦ã‹ã‚‰ãŠè©¦ã—ãã ã•ã„。 + エラー:ã“ã®ã‚¢ã‚¤ãƒ†ãƒ ã«é–¢ã—ã¦å•題ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã—ã°ã‚‰ãã—ã¦ã‹ã‚‰ãŠè©¦ã—ãã ã•ã„。 </string> <string name="Open landmarks"> ランドマークを開ã @@ -1323,7 +1349,7 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="No Filters" value="ã„ã„㈠"/> <string name="Since Logoff" value=" - ãƒã‚°ã‚ªãƒ•以æ¥"/> <string name="InvFolder My Inventory"> - æŒã¡ç‰© + インベントリ </string> <string name="InvFolder Library"> ライブラリ @@ -1356,7 +1382,7 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 æ–°è¦ãƒ•ォルダ </string> <string name="InvFolder Inventory"> - æŒã¡ç‰© + インベントリ </string> <string name="InvFolder Uncompressed Images"> 圧縮ã•れã¦ã„ãªã„ç”»åƒ @@ -1388,6 +1414,12 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="InvFolder favorite"> ãŠæ°—ã«å…¥ã‚Š </string> + <string name="InvFolder Favorites"> + ãŠæ°—ã«å…¥ã‚Š + </string> + <string name="InvFolder favorites"> + ãŠæ°—ã«å…¥ã‚Š + </string> <string name="InvFolder Current Outfit"> ç€ç”¨ä¸ã®ã‚¢ã‚¦ãƒˆãƒ•ィット </string> @@ -1403,6 +1435,12 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="InvFolder Meshes"> メッシュ </string> + <string name="InvFolder Received Items"> + å—ã‘å–ã£ãŸå•†å“ + </string> + <string name="InvFolder Merchant Outbox"> + マーãƒãƒ£ãƒ³ãƒˆã®ã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ + </string> <string name="InvFolder Friends"> フレンド </string> @@ -1412,6 +1450,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="no_attachments"> ç€ç”¨ã—ã¦ã„るアタッãƒãƒ¡ãƒ³ãƒˆã¯ã‚りã¾ã›ã‚“ </string> + <string name="Attachments remain"> + アタッãƒãƒ¡ãƒ³ãƒˆï¼ˆæ®‹ã‚Šã®ã‚¹ãƒãƒƒãƒˆæ•°ï¼š[COUNT]) + </string> <string name="Buy"> 買ㆠ</string> @@ -1538,6 +1579,12 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="Right Pec"> å³èƒ¸ç‹ </string> + <string name="Neck"> + 首 + </string> + <string name="Avatar Center"> + ã‚¢ãƒã‚¿ãƒ¼ã®ä¸å¤® + </string> <string name="Invalid Attachment"> 装ç€å…ˆãŒæ£ã—ãã‚りã¾ã›ã‚“ </string> @@ -3832,6 +3879,12 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã ã <string name="LocationCtrlSeeAVsTooltip"> ã“ã®åŒºç”»å¤–ã«ã‚¢ãƒã‚¿ãƒ¼ã‚’見ãˆã‚‹ã‚ˆã†ã«ã—ã¦ã€ãƒãƒ£ãƒƒãƒˆã‚‚è¨±å¯ </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + 地域(リージョン)ãŒå†æ§‹ç¯‰ã•れるã¾ã§ã€ç§»å‹•ã™ã‚‹ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã¯æ£ã—ã動作ã—ãªã„å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚ + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã§ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ‘ã‚¹ãƒ•ã‚¡ã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ãŒæœ‰åйã«ãªã£ã¦ã„ã¾ã›ã‚“。 + </string> <string name="UpdaterWindowTitle"> [APP_NAME] アップデート </string> @@ -3898,6 +3951,9 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã ã <string name="Saved_message"> (ä¿å˜æ—¥æ™‚:[LONG_TIMESTAMP]) </string> + <string name="IM_unblock_only_groups_friends"> + ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã™ã‚‹ã«ã¯ã€ã€Œç’°å¢ƒè¨å®šã€ã®ã€Œãƒ—ライãƒã‚·ãƒ¼ã€ã§ã€Œãƒ•レンドã¨ã‚°ãƒ«ãƒ¼ãƒ—以外ã‹ã‚‰ã¯ã‚³ãƒ¼ãƒ«ã¨ IM ã‚’å—ä¿¡ã—ãªã„ã€ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã‚’オフã«ã—ã¾ã™ã€‚ + </string> <string name="answered_call"> 相手ãŒã‚³ãƒ¼ãƒ«ã‚’å—ã‘ã¾ã—㟠</string> @@ -3929,10 +3985,10 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã ã [AGENT_NAME] ã¨ã‚³ãƒ³ãƒ•ァレンスã™ã‚‹ </string> <string name="inventory_item_offered-im"> - æŒã¡ç‰©ã‚¢ã‚¤ãƒ†ãƒ ã‚’é€ã‚Šã¾ã—㟠+ インベントリアイテムをé€ã‚Šã¾ã—㟠</string> <string name="share_alert"> - æŒã¡ç‰©ã‹ã‚‰ã“ã“ã«ã‚¢ã‚¤ãƒ†ãƒ をドラッグã—ã¾ã™ + インベントリã‹ã‚‰ã“ã“ã«ã‚¢ã‚¤ãƒ†ãƒ をドラッグã—ã¾ã™ </string> <string name="no_session_message"> (IM セッションãŒå˜åœ¨ã—ã¾ã›ã‚“) @@ -4030,6 +4086,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> @@ -4083,7 +4151,7 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã ã </string> <string name="uploading_abuse_report"> アップãƒãƒ¼ãƒ‰ä¸... - + 嫌ãŒã‚‰ã›ã®å ±å‘Š </string> <string name="New Shape"> @@ -4349,10 +4417,10 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã ã </string> <string name="words_separator" value=","/> <string name="server_is_down"> - 大変申ã—訳ã”ã–ã„ã¾ã›ã‚“ãŒã€äºˆæœŸã›ã¬å•題ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ + 大変申ã—訳ã”ã–ã„ã¾ã›ã‚“ãŒã€äºˆæœŸã—ãªã„å•題ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ - status.secondlifegrid.netã§ã€ã‚µãƒ¼ãƒ“スã«é–¢ã™ã‚‹æ—¢çŸ¥ã®å•題ã«ã¤ã„ã¦ãŠèª¿ã¹ãã ã•ã„。 - å•題ãŒå¼•ãç¶šã発生ã™ã‚‹å ´åˆã¯ã€ãŠä½¿ã„ã®ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚„ファイアウォールã®è¨å®šã‚’確èªã—ã¦ãã ã•ã„。 + サービスã«é–¢ã™ã‚‹æ—¢çŸ¥ã®å•題ã«ã¤ã„ã¦ã¯ã€status.secondlifegrid.net ã‚’ã”覧ãã ã•ã„。 +å•題ãŒå¼•ãç¶šã発生ã™ã‚‹å ´åˆã¯ã€ãŠä½¿ã„ã®ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚„ファイアウォールã®è¨å®šã‚’調ã¹ã¦ãã ã•ã„。 </string> <string name="dateTimeWeekdaysNames"> 日曜日:月曜日:ç«æ›œæ—¥:水曜日:木曜日:金曜日:土曜日 @@ -4440,6 +4508,12 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã ã <string name="ExternalEditorFailedToRun"> 外部エディターを実行ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ </string> + <string name="TranslationFailed"> + 翻訳ã§ãã¾ã›ã‚“ã§ã—ãŸï¼š[REASON] + </string> + <string name="TranslationResponseParseError"> + 翻訳ã®å¿œç”ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ + </string> <string name="Esc"> Esc </string> @@ -4798,7 +4872,7 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã ã ãƒã‚¦ãƒ„ー </string> <string name="Command_Inventory_Label"> - æŒã¡ç‰© + インベントリ </string> <string name="Command_Map_Label"> 地図 @@ -4810,7 +4884,10 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã ã ミニマップ </string> <string name="Command_Move_Label"> - 移動 + æ©è¡Œ / 走行 / 飛行 + </string> + <string name="Command_Outbox_Label"> + マーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹ </string> <string name="Command_People_Label"> 人 @@ -4837,10 +4914,10 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã ã 話㙠</string> <string name="Command_View_Label"> - 視界 + カメラコントãƒãƒ¼ãƒ« </string> <string name="Command_Voice_Label"> - è¿‘ãã®ãƒœã‚¤ã‚¹ + ボイスè¨å®š </string> <string name="Command_AboutLand_Tooltip"> 訪å•å…ˆã«é–¢ã™ã‚‹æƒ…å ± @@ -4870,7 +4947,7 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã ã 一般的タスクã®å®Ÿè¡Œæ–¹æ³• </string> <string name="Command_Inventory_Tooltip"> - æŒã¡ç‰©ã‚’表示・使用 + インベントリを表示・使用 </string> <string name="Command_Map_Tooltip"> 世界地図 @@ -4884,6 +4961,9 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã ã <string name="Command_Move_Tooltip"> ã‚¢ãƒã‚¿ãƒ¼ã®ç§»å‹• </string> + <string name="Command_Outbox_Tooltip"> + 販売用ã«ã‚¢ã‚¤ãƒ†ãƒ をマーケットプレイスã«è»¢é€ + </string> <string name="Command_People_Tooltip"> フレンドã€ã‚°ãƒ«ãƒ¼ãƒ—ã€è¿‘ãã®äºº </string> @@ -4912,7 +4992,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 +5027,40 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã ã <string name="Normal"> 普通 </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + ãªã— + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + ナビメッシュã«å½±éŸ¿ã‚’与ãˆã‚‹ + </string> + <string name="Pathfinding_Object_Attr_Character"> + ã‚ャラクター + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (複数) + </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> + <string name="TeleportMaturityExceeded"> + ä½äººã¯ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã‚’訪å•ã§ãã¾ã›ã‚“。 + </string> + <string name="UserDictionary"> + [User] + </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..7868c25807 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"> 残念ãªãŒã‚‰ã€ãã®ãƒ†ãƒ¬ãƒãƒ¼ãƒˆç›®çš„地ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒã‚りã¾ã›ã‚“。 @@ -45,7 +45,10 @@ テレãƒãƒ¼ãƒˆã®ç›®çš„地を見ã¤ã‘られã¾ã›ã‚“。目的地ãŒä¸€æ™‚çš„ã«åˆ©ç”¨ã§ããªã„状態ã‹ã€ã¾ãŸã¯ã™ã§ã«æ¶ˆæ»…ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚数分後ã«ã‚„り直ã—ã¦ãã ã•ã„。 </message> <message name="no_inventory_host"> - æŒã¡ç‰©ã‚·ã‚¹ãƒ†ãƒ ã¯ç¾åœ¨åˆ©ç”¨ã§ãã¾ã›ã‚“。 + インベントリシステムã¯ç¾åœ¨åˆ©ç”¨ã§ãã¾ã›ã‚“。 + </message> + <message name="MustGetAgeRegion"> + ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«å…¥ã‚‹ã«ã¯ 18 æ‰ä»¥ä¸Šã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ </message> </message_set> <message_set name="progress"> @@ -82,5 +85,8 @@ <message name="requesting"> テレãƒãƒ¼ãƒˆã‚’リクエスト... </message> + <message name="pending"> + テレãƒãƒ¼ãƒˆã‚’ä¿ç•™ä¸... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/pl/floater_camera.xml b/indra/newview/skins/default/xui/pl/floater_camera.xml index 5b9dd47616..60f3cd0fff 100644 --- a/indra/newview/skins/default/xui/pl/floater_camera.xml +++ b/indra/newview/skins/default/xui/pl/floater_camera.xml @@ -9,15 +9,6 @@ <floater.string name="move_tooltip"> Poruszaj kamerÄ… w dół/górÄ™ oraz w prawo/lewo </floater.string> - <floater.string name="camera_modes_title"> - Ustawienia - </floater.string> - <floater.string name="pan_mode_title"> - W prawo lub w lewo - </floater.string> - <floater.string name="presets_mode_title"> - Ustaw widok - </floater.string> <floater.string name="free_mode_title"> Zobacz obiekt </floater.string> diff --git a/indra/newview/skins/default/xui/pl/menu_im_well_button.xml b/indra/newview/skins/default/xui/pl/menu_im_well_button.xml deleted file mode 100644 index 207bc2211b..0000000000 --- a/indra/newview/skins/default/xui/pl/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<context_menu name="IM Well Button Context Menu"> - <menu_item_call label="Zamknij wszystkie" name="Close All"/> -</context_menu> diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml index fe4662c5a2..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"/> @@ -119,6 +116,7 @@ <menu_item_call label="dźwiÄ™k (L$[COST])..." name="Upload Sound"/> <menu_item_call label="animacjÄ™ (L$[COST])..." name="Upload Animation"/> <menu_item_call label="zbiór plików (L$[COST] za jeden plik)..." name="Bulk Upload"/> + <menu_item_call label="Ustaw domyÅ›lne pozwolenia Å‚adowania" name="perm prefs"/> </menu> <menu_item_call label="Cofnij" name="Undo"/> <menu_item_call label="Ponów" name="Redo"/> @@ -152,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"/> @@ -179,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"/> @@ -191,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"/> @@ -266,9 +254,8 @@ <menu_item_call label="Upuść pakiet pamiÄ™ci" name="Drop a Packet"/> </menu> <menu_item_call label="Zderzenia, popchniÄ™cia & uderzenia" name="Bumps, Pushes &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> @@ -290,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"/> @@ -315,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 7d3225ea31..f255b1b8ea 100644 --- a/indra/newview/skins/default/xui/pl/notifications.xml +++ b/indra/newview/skins/default/xui/pl/notifications.xml @@ -946,7 +946,7 @@ Zaproponować znajomość [NAME]? </form> </notification> <notification name="RemoveFromFriends"> - Czy chcesz usunąć [NAME] z listy znajomych? + Czy chcesz usunąć <nolink>[NAME]</nolink> z listy znajomych? <usetemplate name="okcancelbuttons" notext="Anuluj" yestext="OK"/> </notification> <notification name="RemoveMultipleFromFriends"> @@ -1106,7 +1106,6 @@ Możesz normalnie używać [SECOND_LIFE], inni użytkownicy bÄ™dÄ… CiÄ™ widzieli Instalacja [APP_NAME] zakoÅ„czona. Jeżeli używasz [SECOND_LIFE] po raz pierwszy to musisz stworzyć konto żeby móc siÄ™ zalogować. -Czy chcesz przejść na stronÄ™ [http://join.secondlife.com secondlife.com] żeby stworzyć nowe konto? <usetemplate name="okcancelbuttons" notext="Kontynuuj" yestext="Nowe konto..."/> </notification> <notification name="LoginPacketNeverReceived"> @@ -1385,7 +1384,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 <nolink>[GROUP]</nolink>. Chcesz opuÅ›cić grupÄ™? <usetemplate name="okcancelbuttons" notext="Anuluj" yestext="OK"/> </notification> @@ -2078,10 +2077,10 @@ Zamieść go na stronie internetowej żeby umożliwić innym Å‚atwy dostÄ™p do t Temat: [SUBJECT], Treść: [MESSAGE] </notification> <notification name="FriendOnline"> - [NAME] jest w Second Life + <nolink>[NAME]</nolink> jest w Second Life </notification> <notification name="FriendOffline"> - [NAME] opuszcza Second Life + <nolink>[NAME]</nolink> opuszcza Second Life </notification> <notification name="AddSelfFriend"> Nie możesz dodać siebie do listy znajomych. @@ -2458,10 +2457,10 @@ Spróbuj ponowanie za kilka minut. </form> </notification> <notification name="FriendshipAccepted"> - Twoja propozycja znajomoÅ›ci zostaÅ‚a przyjÄ™ta przez [NAME]. + Twoja propozycja znajomoÅ›ci zostaÅ‚a przyjÄ™ta przez <nolink>[NAME]</nolink>. </notification> <notification name="FriendshipDeclined"> - Twoja propozycja znajomoÅ›ci zostaÅ‚a odrzucona przez [NAME]. + Twoja propozycja znajomoÅ›ci zostaÅ‚a odrzucona przez <nolink>[NAME]</nolink>. </notification> <notification name="FriendshipAcceptedByMe"> Propozycja znajomoÅ›ci zostaÅ‚a zaakceptowana. diff --git a/indra/newview/skins/default/xui/pl/panel_login.xml b/indra/newview/skins/default/xui/pl/panel_login.xml index dc8e7399af..c87a3d3bd4 100644 --- a/indra/newview/skins/default/xui/pl/panel_login.xml +++ b/indra/newview/skins/default/xui/pl/panel_login.xml @@ -5,6 +5,9 @@ </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + POÅÄ„CZ + </text> <text name="username_text"> Użytkownik: </text> @@ -12,15 +15,8 @@ <text name="password_text"> HasÅ‚o: </text> - <check_box label="ZapamiÄ™taj hasÅ‚o" name="remember_check"/> - <button label="Połącz" name="connect_btn"/> - <text name="mode_selection_text"> - Tryb życia: - </text> - <combo_box name="mode_combo" tool_tip="Wybierz tryb życia. Wybierz tryb turystyczny dla Å‚atwego zwiedzania i czatowania. Wybierz tryb zaawansowany aby mieć dostÄ™p do wiÄ™kszej iloÅ›ci opcji."> - <combo_box.item label="Turystyczny" name="Basic"/> - <combo_box.item label="Zaawansowany" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Rozpocznij w: </text> @@ -30,16 +26,23 @@ <combo_box.item label="<Wpisz Region>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Utwórz nowe konto + <layout_panel name="links_login_panel"> + <text name="login_help"> + Potrzebujesz pomocy z logowaniem siÄ™? </text> <text name="forgot_password_text"> ZapomniaÅ‚eÅ› swojej nazwy użytkownika lub hasÅ‚a? </text> - <text name="login_help"> - Potrzebujesz pomocy z logowaniem siÄ™? + <button label="Połącz" name="connect_btn"/> + <check_box label="ZapamiÄ™taj hasÅ‚o" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + CREATE YǾUR ACCǾUNT </text> + <button name="create_new_account_btn" + label="Utwórz nowe konto" + width="120"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/pl/panel_my_profile.xml b/indra/newview/skins/default/xui/pl/panel_my_profile.xml deleted file mode 100644 index cdc833241d..0000000000 --- a/indra/newview/skins/default/xui/pl/panel_my_profile.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Profil" name="panel_profile"> - <string name="no_partner_text" value="Å»adne"/> - <string name="no_group_text" value="Å»adne"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="scroll_content_panel"> - <panel name="second_life_image_panel"> - <text name="display_name_descr_text"> - Nazwa użytkownika - </text> - <text name="name_descr_text"> - WyÅ›wietlana nazwa - </text> - <button label="Profil" name="see_profile_btn" tool_tip="Zobacz profil tego awatara"/> - </panel> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml index 63cf96b571..4ed3ff669b 100644 --- a/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="chat_bar"> +<panel name="nearby_chat"> <string name="min_width"> 192 </string> diff --git a/indra/newview/skins/default/xui/pl/panel_notes.xml b/indra/newview/skins/default/xui/pl/panel_notes.xml deleted file mode 100644 index 571171d64c..0000000000 --- a/indra/newview/skins/default/xui/pl/panel_notes.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Notatki & Prywatność" name="panel_notes"> - <layout_stack name="layout"> - <layout_panel name="notes_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <text name="status_message" value="Notatki:"/> - <text name="status_message2" value="Pozwól tej osobie na:"/> - <check_box label="Widzenie mojego statusu" name="status_check"/> - <check_box label="Lokalizowanie mnie na mapie" name="map_check"/> - <check_box label="Edytowanie, kasowanie lub zabieranie moich obiektów" name="objects_check"/> - </panel> - </scroll_container> - </layout_panel> - <layout_panel name="notes_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Dodaj do Znajomych" name="add_friend" tool_tip="Zaoferuj znajomość Rezydentowi"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="Otwórz wiadomoÅ›ci IM"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="DzwoÅ„" name="call" tool_tip="ZadzwoÅ„ do Rezydenta"/> - </layout_panel> - <layout_panel name="show_on_map_btn_lp"> - <button label="Mapa" name="show_on_map_btn" tool_tip="Pokaż Rezydenta na mapie"/> - </layout_panel> - <layout_panel name="teleport_btn_lp"> - <button label="Teleportuj" name="teleport" tool_tip="Teleportuj"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/pl/panel_profile.xml b/indra/newview/skins/default/xui/pl/panel_profile.xml deleted file mode 100644 index 77dd951bc4..0000000000 --- a/indra/newview/skins/default/xui/pl/panel_profile.xml +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Profil" name="panel_profile"> - <string name="no_partner_text" value="Brak"/> - <string name="no_group_text" value="Å»adne"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <panel name="second_life_image_panel"> - <text name="title_sl_descr_text" value="[SECOND_LIFE]:"/> - </panel> - <panel name="first_life_image_panel"> - <text name="title_rw_descr_text" value="Å»ycie#1:"/> - </panel> - <text name="title_member_text" value="Urodziny:"/> - <text name="title_acc_status_text" value="Konto:"/> - <text name="title_partner_text" value="Partner:"/> - <panel name="partner_data_panel"> - <text initial_value="(przetwarzanie)" name="partner_text"/> - </panel> - <text name="title_groups_text" value="Grupy:"/> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> - <layout_stack name="layout_verb_buttons"> - <layout_panel name="profile_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Poznaj" name="add_friend" tool_tip="Zaproponuj znajomość Rezydentowi"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="Otwórz wiadomoÅ›ci IM"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="DzwoÅ„" name="call" tool_tip="ZadzwoÅ„ do tego Rezydenta"/> - </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="Teleportuj" name="teleport" tool_tip="Teleportuj"/> - </layout_panel> - <layout_panel name="overflow_btn_lp"> - <menu_button label="â–¼" name="overflow_btn" tool_tip="ZapÅ‚ać lub udostÄ™pnij obiekt Rezydentowi"/> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="profile_me_buttons_panel"> - <button label="Edytuj profil" name="edit_profile_btn" tool_tip="Edytuj informacje o sobie"/> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/pl/panel_profile_view.xml b/indra/newview/skins/default/xui/pl/panel_profile_view.xml deleted file mode 100644 index 1fd6bc1d10..0000000000 --- a/indra/newview/skins/default/xui/pl/panel_profile_view.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_target_profile"> - <string name="status_online"> - Obecnie w SL - </string> - <string name="status_offline"> - Nieaktywny - </string> - <text name="display_name_label" value="WyÅ›wietlana nazwa:"/> - <text name="solo_username_label" value="Nazwa użytkownika:"/> - <text name="status" value="Obecnie w SL"/> - <text name="user_name_small" value="Jack oh look at me this is a super duper long name"/> - <button name="copy_to_clipboard" tool_tip="Kopiuj do schowka"/> - <text name="user_label" value="Nazwa użytkownika:"/> - <tab_container name="tabs"> - <panel label="PROFIL" name="panel_profile"/> - <panel label="ULUBIONE" name="panel_picks"/> - <panel label="NOTATKI & PRYWATNOŚĆ" name="panel_notes"/> - </tab_container> -</panel> diff --git a/indra/newview/skins/default/xui/pl/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/pl/panel_volume_pulldown.xml new file mode 100644 index 0000000000..1611900700 --- /dev/null +++ b/indra/newview/skins/default/xui/pl/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel name="volumepulldown_floater"> + <slider label="Główny" name="System Volume"/> + <slider label="Przyciski" name="UI Volume"/> + <slider label="Okolica" name="Wind Volume"/> + <slider label="Efekty" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="Włącz dźwiÄ™ki gestów"/> + <slider label="Muzyka" name="Music Volume"/> + <check_box tool_tip="Włącz muzykÄ™ strumieniowÄ…" name="enable_music"/> + <slider label="Media" name="Media Volume"/> + <check_box tool_tip="Włącz media strumieniowe" name="enable_media"/> + <slider label="GÅ‚os" name="Voice Volume"/> + <check_box tool_tip="Włącz rozmowy gÅ‚osowe" name="enable_voice_check"/> +</panel> diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index 6a8309cca5..f6dec8536b 100644 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml @@ -423,6 +423,9 @@ <string name="symbolic folder link"> link folderu </string> + <string name="AvatarEditingAppearance"> + (Edycja WyglÄ…d) + </string> <string name="AvatarAway"> Åšpi </string> diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml index c374264c4a..299f88b22a 100644 --- a/indra/newview/skins/default/xui/pt/floater_about.xml +++ b/indra/newview/skins/default/xui/pt/floater_about.xml @@ -65,13 +65,34 @@ 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-2009 3Dconnexion + APR Copyright (C) 2011 The Apache Software Foundation + Collada DOM Copyright 2006 Sony Computer Entertainment Inc. + cURL Copyright (C) 1996-2010, 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, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. + 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) 2002, Xiphophorus + OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. + PCRE Copyright (c) 1997-2012 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-2012 Jean-loup Gailly and Mark Adler. -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..f48280840c 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 > 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: + Avatares em outros lotes podem ver e conversar 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> @@ -461,12 +460,12 @@ MÃdia: <text name="Limit access to this parcel to:"> Acesso a este lote </text> - <check_box label="Acesso para público categoria [MATURITY]" name="public_access"/> + <check_box label="Permitir acesso público (Desmarcar esse item cria limites)" name="public_access"/> <text name="Only Allow"> - Restringir acesso a contas confirmardas por: + Permitir acesso apenas para residentes que: </text> - <check_box label="Dados de pagamento fornecidos [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Banir residentes sem identificação."/> - <check_box label="Idade comprovada: [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Banir residentes que não comprovaram a idade. Consulte o [SUPPORT_SITE] para saber mais."/> + <check_box label="Possuam Dados de pagamento fornecidos [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Os residentes devem ter seus dados de pagamento cadastrados para acessar este lote. Consulte o [SUPPORT_SITE] para saber mais."/> + <check_box label="Tem 18 anos ou mais [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Os residentes devem ter 18 anos ou mais para acessar este lote. Consulte o [SUPPORT_SITE] para obter mais informações."/> <check_box label="Permitir acesso do grupo: [GROUP]" name="GroupCheck" tool_tip="Definir grupo na aba Geral."/> <check_box label="Vender passes para:" name="PassCheck" tool_tip="Permite acesso temporário a este terreno"/> <combo_box name="pass_combo"> diff --git a/indra/newview/skins/default/xui/pt/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/pt/floater_animation_anim_preview.xml new file mode 100644 index 0000000000..05326d8594 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_animation_anim_preview.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Anim Preview" title="ANIMATION.ANIM"> + <text name="name_label"> + Nome: + </text> + <text name="description_label"> + Descrição: + </text> + <button label="Envio (L$[AMOUNT])" name="ok_btn"/> + <button label="Cancelar" label_selected="Cancelar" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_animation_preview.xml b/indra/newview/skins/default/xui/pt/floater_animation_bvh_preview.xml index 3ec81612a1..5cae581045 100644 --- a/indra/newview/skins/default/xui/pt/floater_animation_preview.xml +++ b/indra/newview/skins/default/xui/pt/floater_animation_bvh_preview.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview" title=""> +<floater name="Animation Preview"> <floater.string name="failed_to_initialize"> - Não foi possÃvel iniciar o movimento + Falha ao iniciar animação </floater.string> <floater.string name="anim_too_long"> - O arquivo de animação tem [LENGTH] segundos de duração. + O arquivo de animação possui [LENGTH] segundos de duração. -A duração máxima de animação permitida é de [MAX_LENGTH] segundos. +A duração máxima da animação é de [MAX_LENGTH] segundos. </floater.string> <floater.string name="failed_file_read"> Não foi possÃvel ler o arquivo de animação. @@ -14,10 +14,10 @@ A duração máxima de animação permitida é de [MAX_LENGTH] segundos. [STATUS] </floater.string> <floater.string name="E_ST_OK"> - OK + Ok </floater.string> <floater.string name="E_ST_EOF"> - Fim de arquivo prematuro + Fim de arquivo prematuro. </floater.string> <floater.string name="E_ST_NO_CONSTRAINT"> ImpossÃvel ler definição constraint. @@ -115,14 +115,14 @@ A duração máxima de animação permitida é de [MAX_LENGTH] segundos. <text name="description_label"> Descrição: </text> - <spinner label="Prioridade" label_width="72" name="priority" tool_tip="Controla quais animações podem ser interrompidas por esta animação" width="110"/> + <spinner label="Prioridade" name="priority" tool_tip="Controla quais animações podem ser interrompidas por esta animação"/> <check_box label="Loop" name="loop_check" tool_tip="Executa esta animação sem parar"/> - <spinner label="Dentro(%)" label_width="56" left="65" name="loop_in_point" tool_tip="Define o ponto em que a animação em loop reinicia" width="116"/> - <spinner label="Fora(%)" label_width="40" left="185" name="loop_out_point" tool_tip="Define o ponto em que a animação em loop acaba"/> + <spinner label="Dentro(%)" name="loop_in_point" tool_tip="Define o ponto em que a animação em loop reinicia"/> + <spinner label="Fora(%)" name="loop_out_point" tool_tip="Define o ponto em que a animação em loop acaba"/> <text name="hand_label"> - Pose de Mão + Pose das mãos </text> - <combo_box left_delta="100" name="hand_pose_combo" tool_tip="Controla os gestos das mãos durante a animação" width="184"> + <combo_box name="hand_pose_combo" tool_tip="Controla os gestos das mãos durante a animação"> <combo_box.item label="Abrir" name="Spread"/> <combo_box.item label="Relaxado" name="Relaxed"/> <combo_box.item label="Apontar ambas" name="PointBoth"/> @@ -140,7 +140,7 @@ A duração máxima de animação permitida é de [MAX_LENGTH] segundos. <text name="emote_label"> Expressão </text> - <combo_box left_delta="100" name="emote_combo" tool_tip="Controla as expressões faciais durante a animação" width="184"> + <combo_box name="emote_combo" tool_tip="Controla as expressões faciais durante a animação"> <item label="(nenhum)" name="[None]" value=""/> <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> <item label="Com medo" name="Afraid" value="Com medo"/> @@ -162,26 +162,25 @@ A duração máxima de animação permitida é de [MAX_LENGTH] segundos. <item label="Piscar" name="Wink" value="Piscar"/> <item label="Preocupado" name="Worry" value="Preocupado"/> </combo_box> - <text name="preview_label" width="250"> - Prever enquanto + <text name="preview_label"> + Visualizar enquanto </text> - <combo_box left_delta="100" name="preview_base_anim" tool_tip="Use isto para testar o comportamento de sua animação enquanto seu avatar executa ações comuns." width="130"> + <combo_box name="preview_base_anim" tool_tip="Use para testar o comportamento de sua animação enquanto seu avatar executa ações comuns."> <item label="Em pé" name="Standing" value="Em pé"/> - <item label="Andando" name="Walking" value="Andando"/> + <item label="Andar" name="Walking" value="Andar"/> <item label="Sentado" name="Sitting" value="Sentado"/> - <item label="Voando" name="Flying" value="Voando"/> + <item label="Voar" name="Flying" value="Voar"/> </combo_box> - <spinner label="Facilitar a entrada (sec)" label_width="125" name="ease_in_time" tool_tip="Tempo (em segundos) da transição inicial da animação" width="192"/> - <spinner bottom_delta="-20" label="Facilitar a saÃda (sec)" label_width="125" left="10" name="ease_out_time" tool_tip="Tempo (em segundos) da transição de saÃda da animação" width="192"/> - <button bottom_delta="-32" name="play_btn" tool_tip="Executar animação"/> + <spinner label="Aproximação (seg)" name="ease_in_time" tool_tip="Tempo (em segundos) da transição inicial da animação"/> + <spinner label="Afastamento (seg)" name="ease_out_time" tool_tip="Tempo (em segundos) da transição de saÃda da animação"/> + <button name="play_btn" tool_tip="Executar animação"/> <button name="pause_btn" tool_tip="Pausar a animação"/> - <button label="" name="stop_btn" tool_tip="Interrompe a execução da animação."/> + <button name="stop_btn" tool_tip="Interromper a execução da animação"/> <text name="bad_animation_text"> - Incapaz de ler o arquivo de animação. + Não foi possÃvel ler o arquivo de animação. -Nós recomendamos exportar arquivos BVH do -Poser 4. +Recomendamos que os arquivos BVH sejam exportados do Poser 4. </text> - <button label="Carregar (L$[AMOUNT])" name="ok_btn"/> + <button label="Envio (L$[AMOUNT])" name="ok_btn"/> <button label="Cancelar" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_autoreplace.xml b/indra/newview/skins/default/xui/pt/floater_autoreplace.xml new file mode 100644 index 0000000000..ca813a8540 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="Configurações da substituição automática"> + <check_box label="Habilitar substituição automática" name="autoreplace_enable" tool_tip="Ao inserir texto de bate-papo, substitua quaisquer palavras-chave inseridas pela substituição correspondente"/> + <button label="Importar lista..." name="autoreplace_import_list" tool_tip="Carrega uma lista exportada anteriormente de um arquivo."/> + <button label="Exportar lista..." name="autoreplace_export_list" tool_tip="Salva um arquivo da lista selecionada para compartilhá-la."/> + <button label="Nova lista..." name="autoreplace_new_list" tool_tip="Cria uma nova lista."/> + <button label="Excluir lista" name="autoreplace_delete_list" tool_tip="Exclui a lista selecionada."/> + <button name="autoreplace_list_up" tool_tip="Aumenta a prioridade desta lista."/> + <button name="autoreplace_list_down" tool_tip="Diminui a prioridade desta lista."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Palavra-chave" name="keyword"/> + <scroll_list.columns label="Substituição" name="replacement"/> + </scroll_list> + <button label="Adicionar..." name="autoreplace_add_entry"/> + <button label="Remover" name="autoreplace_delete_entry"/> + <button label="Salvar entrada" name="autoreplace_save_entry" tool_tip="Salva esta entrada."/> + <button label="Salvar alterações" name="autoreplace_save_changes" tool_tip="Salvar todas as alterações."/> + <button label="Cancelar" name="autoreplace_cancel" tool_tip="Descarta todas as alterações."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </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 0e4fc1b455..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> @@ -9,15 +9,6 @@ <floater.string name="move_tooltip"> Mover a Câmera para Cima e para Baixo, para a Esquerda e para a Direita </floater.string> - <floater.string name="camera_modes_title"> - Modos de câmera - </floater.string> - <floater.string name="pan_mode_title"> - Pan zoom orbital - </floater.string> - <floater.string name="presets_mode_title"> - Ângulos predefinidos - </floater.string> <floater.string name="free_mode_title"> Visualizar objeto </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..2eb2c94940 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> +<floater name="nearby_chat" title="BATE-PAPO LOCAL"> + <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..1204fb93e2 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"> @@ -25,6 +25,10 @@ Habilitar VBO: </text> <check_box initial_value="true" label="Habilitar Objetos com Armazenamento de Vértices" name="vbo" tool_tip="Habilitando-o em máquinas novas, ele oferece um ganho de performance. Contudo, as máquinas antigas tem freqüentemente implementações pobres de VBOs e você pode ter travamentos quando esta opção é habilitada."/> + <text name="tc label"> + Habilitar S3TC: + </text> + <check_box initial_value="true" label="Habilitar compressão de texturas (requer reinÃcio)" name="texture compression" tool_tip="Comprime as texturas na memória de vÃdeo, permitindo o carregamento de texturas de maior resolução em detrimento da qualidade da cor."/> <slider label="Memória de texturas (MB):" name="GraphicsCardTextureMemory" tool_tip="Quanto da memória deve ser alocado para texturas. O padrão é definido pela memória da placa de vÃdeo. Reduzir este valor pode melhorar o desempenho, mas as texturas podem fica fora de foco."/> <spinner label="Relação de Distância de Nevoeiro:" name="fog"/> <button label="OK" label_selected="OK" name="OK"/> diff --git a/indra/newview/skins/default/xui/pt/floater_inventory.xml b/indra/newview/skins/default/xui/pt/floater_inventory.xml deleted file mode 100644 index ae3312eab0..0000000000 --- a/indra/newview/skins/default/xui/pt/floater_inventory.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="MEU INVENTÃRIO"> - <floater.string name="Title"> - MEU INVENTÃRIO - </floater.string> - <floater.string name="TitleFetching"> - MEU INVENTÃRIO (Pegando [ITEM_COUNT] items...) [FILTER] - </floater.string> - <floater.string name="TitleCompleted"> - MEU INVENTÃRIO ([ITEM_COUNT] items) [FILTER] - </floater.string> - <floater.string name="Fetched"> - Obtido - </floater.string> - <panel label="Painel do inventário" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml new file mode 100644 index 0000000000..bb6113671b --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_merchant_outbox" title="CAIXA DE SAÃDA DO LOJISTA"> + <string name="OutboxFolderCount1"> + 1 pasta + </string> + <string name="OutboxFolderCountN"> + [NUM] pasta(s) + </string> + <string name="OutboxImporting"> + Enviando pastas... + </string> + <string name="OutboxInitializing"> + Iniciando... + </string> + <panel label=""> + <panel> + <panel name="outbox_inventory_placeholder_panel"> + <text name="outbox_inventory_placeholder_title"> + Carregando... + </text> + </panel> + </panel> + <panel> + <button label="Enviar para Mercado" name="outbox_import_btn" tool_tip="Enviar para a Frente da loja do meu Mercado"/> + </panel> + </panel> +</floater> 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..8194278b16 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> @@ -89,19 +92,54 @@ <text initial_value="Triângulos" name="triangles" value="Triângulos"/> <text initial_value="Vértices" name="vertices" value="Vértices"/> <text initial_value="Alto" name="high_label" value="Alto"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Carregar do arquivo"/> + <item name="Generate" value="Gerar"/> + </combo_box> <button label="Procurar..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="Limite de triângulos"/> + <item name="Error Threshold" value="Limite de erro"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Médio" name="medium_label" value="Médio"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Carregar do arquivo"/> + <item name="Generate" value="Gerar"/> + <item name="Use LoD above" value="Usar LoD acima"/> + </combo_box> <button label="Procurar..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="Limite de triângulos"/> + <item name="Error Threshold" value="Limite de erro"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Baixo" name="low_label" value="Baixo"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Carregar do arquivo"/> + <item name="Generate" value="Gerar"/> + <item name="Use LoD above" value="Usar LoD acima"/> + </combo_box> <button label="Procurar..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="Limite de triângulos"/> + <item name="Error Threshold" value="Limite de erro"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="Mais baixo" name="lowest_label" value="Mais baixo"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Carregar do arquivo"/> + <item name="Generate" value="Gerar"/> + <item name="Use LoD above" value="Usar LoD acima"/> + </combo_box> <button label="Procurar..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="Limite de triângulos"/> + <item name="Error Threshold" value="Limite de erro"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Gerar normais" name="gen_normals"/> diff --git a/indra/newview/skins/default/xui/pt/floater_model_wizard.xml b/indra/newview/skins/default/xui/pt/floater_model_wizard.xml deleted file mode 100644 index d9195adbf9..0000000000 --- a/indra/newview/skins/default/xui/pt/floater_model_wizard.xml +++ /dev/null @@ -1,205 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Model Wizard" title="CARREGAR ASSISTENTE DE MODELAGEM"> - <button label="5. Carregar" name="upload_btn"/> - <button label="4. Revisar" name="review_btn"/> - <button label="3. FÃsica" name="physics_btn"/> - <button label="2. Otimizar" name="optimize_btn"/> - <button label="1. Selecionra arquivo" name="choose_file_btn"/> - <panel name="choose_file_panel"> - <panel name="header_panel"> - <text name="header_text"> - Escolher arquivo de modelo - </text> - </panel> - <panel name="content"> - <text name="advanced_users_text"> - Usuários avançados: se você estiver familiarizado com ferramentas de criação de conteúdo 3D, use o Advanced Uploader. - </text> - <button label="Trocar para avançado" name="switch_to_advanced"/> - <text name="Cache location"> - Escolha o arquivo de modelo para upload - </text> - <button label="Procurar..." label_selected="Procurar..." name="browse"/> - <text name="dimensions"> - X Y Z - </text> - <text name="warning_label"> - AVISO: - </text> - <text name="warning_text"> - Não será possÃvel concluir a etapa final do upload desse modelo para os servidores do Second Life. [secondlife:///app/floater/learn_more Saiba como] configurar sua conta para uploads de modelos mesh. - </text> - </panel> - </panel> - <panel name="optimize_panel"> - <panel name="header_panel"> - <text name="header_text"> - Otimizar modelo - </text> - </panel> - <text name="description"> - O modelo foi ajustado para desempenho. Faça novos ajustes, se desejar. - </text> - <panel name="content"> - <text name="high_detail_text"> - Gerar nÃvel de detalhes: Alto - </text> - <text name="medium_detail_text"> - Gerar nÃvel de detalhes: Médio - </text> - <text name="low_detail_text"> - Gerar nÃvel de detalhes: Baixo - </text> - <text name="lowest_detail_text"> - Gerar nÃvel de detalhes: mais baixo - </text> - </panel> - <panel name="content2"> - <button label="Recalcular geometria" name="recalculate_geometry_btn"/> - <text name="lod_label"> - Visualização da geometria - </text> - <combo_box name="preview_lod_combo" tool_tip="LOD para exibir na renderização de visualização"> - <combo_item name="high"> - Máximo de detalhes - </combo_item> - <combo_item name="medium"> - Detalhes médios - </combo_item> - <combo_item name="low"> - Poucos detalhes - </combo_item> - <combo_item name="lowest"> - MÃnimo de detalhes - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="physics_panel"> - <panel name="header_panel"> - <text name="header_text"> - Ajustar fÃsico - </text> - </panel> - <text name="description"> - Criaremos uma forma para o corpo externo do modelo. Ajuste o nÃvel de detalhes como necessário para a finalidade desejada de seu modelo. - </text> - <panel name="content"> - <button label="Recalcular fÃsico" name="recalculate_physics_btn"/> - <button label="Recalculando..." name="recalculating_physics_btn"/> - <text name="lod_label"> - Visualização do fÃsico - </text> - <combo_box name="preview_lod_combo2" tool_tip="LOD para exibir na renderização de visualização"> - <combo_item name="high"> - Máximo de detalhes - </combo_item> - <combo_item name="medium"> - Detalhes médios - </combo_item> - <combo_item name="low"> - Poucos detalhes - </combo_item> - <combo_item name="lowest"> - MÃnimo de detalhes - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="review_panel"> - <panel name="header_panel"> - <text name="header_text"> - Revisar - </text> - </panel> - <panel name="content"> - <text name="review_prim_equiv"> - Impacto no lote/região: [EQUIV] equivalentes de prim - </text> - <text name="review_fee"> - Uma tarifa de upload de L$ [FEE] será debitada da sua conta. - </text> - <text name="review_confirmation"> - Ao clicar no botão de upload, você confirma que detém os direitos apropriados sobre o material contido no modelo. - </text> - </panel> - </panel> - <panel name="upload_panel"> - <panel name="header_panel"> - <text name="header_text"> - Upload concluÃdo - </text> - </panel> - <text name="model_uploaded_text"> - Seu modelo foi carregado. - </text> - <text name="inventory_text"> - DisponÃvel na pasta Objetos do seu inventário. - </text> - <text name="charged_fee"> - L$ [FEE] foram debitados da sua conta. - </text> - </panel> - <button label="<< Voltar" name="back"/> - <button label="Próximo >>" name="next"/> - <button label="Calcular pesos e tarifa >>" name="calculate"/> - <button label="Calculando..." name="calculating"/> - <button label="Carregar" name="upload" tool_tip="Carregar no simulador"/> - <button label="Cancelar" name="cancel"/> - <button label="Fechar" name="close"/> - <spinner name="import_scale" value="1.0"/> - <string name="status_idle"> - Inativo - </string> - <string name="status_parse_error"> - Dae parsing - erro, detalhes no log. - </string> - <string name="status_reading_file"> - Carregando... - </string> - <string name="status_generating_meshes"> - Gerando meshes... - </string> - <string name="status_vertex_number_overflow"> - Erro: Número de Vertex acima de 65534. Abortado. - </string> - <string name="bad_element"> - Erro: elemento inválido - </string> - <string name="high"> - Alto - </string> - <string name="medium"> - Médio - </string> - <string name="low"> - Baixo - </string> - <string name="lowest"> - Mais baixo - </string> - <string name="mesh_status_good"> - Entregar! - </string> - <string name="mesh_status_na"> - N/D - </string> - <string name="mesh_status_none"> - Nenhum - </string> - <string name="mesh_status_submesh_mismatch"> - Cada nÃvel de detalhamento têm um número de faces para textura. - </string> - <string name="mesh_status_mesh_mismatch"> - Cada nÃvel de detalhamento têm um número de faces para textura. - </string> - <string name="mesh_status_too_many_vertices"> - O nÃvel de detalhamento possui vértices demais. - </string> - <string name="mesh_status_missing_lod"> - Falta o nÃvel de detalhamento necessário. - </string> - <string name="layer_all"> - Tudo - </string> -</floater> 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_nearby_chat.xml b/indra/newview/skins/default/xui/pt/floater_nearby_chat.xml deleted file mode 100644 index 653861f7d8..0000000000 --- a/indra/newview/skins/default/xui/pt/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="Bate-papo local"> - <check_box label="Traduzir bate-papo" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/pt/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..05784115e7 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="Personagens do pathfinding"> + <floater.string name="messaging_get_inprogress"> + Procurando por personagens do pathfinding... + </floater.string> + <floater.string name="messaging_get_error"> + Erro detectado ao procurar por personagens do pathfinding. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Nenhum personagem do pathfinding. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] personagens selecionados de [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + Esta região não está habilitada para pathfinding. + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Carregando] + </floater.string> + <floater.string name="character_owner_unknown"> + [Desconhecido] + </floater.string> + <floater.string name="character_owner_group"> + [grupo] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nome" name="name"/> + <scroll_list.columns label="Descrição" name="description"/> + <scroll_list.columns label="Proprietário" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="Altitude" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + Personagens: + </text> + <button label="Atualizar lista" name="refresh_objects_list"/> + <button label="Selecionar tudo" name="select_all_objects"/> + <button label="Selecionar nenhum" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + Ações nos personagens selecionados: + </text> + <check_box label="Exibir baliza" name="show_beacon"/> + <check_box label="Exibir cápsula da fÃsica" name="show_physics_capsule"/> + <button label="Pegar" name="take_objects"/> + <button label="Pegar uma cópia" name="take_copy_objects"/> + <button label="Teletransportar-me até ele" name="teleport_me_to_object" tool_tip="Habilitado apenas quando um personagem é selecionado."/> + <button label="Devolver" name="return_objects"/> + <button label="Excluir" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/pt/floater_pathfinding_console.xml new file mode 100644 index 0000000000..182f2513e0 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="Visualização/teste do pathfinding"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + ImpossÃvel encontrar a implementação de biblioteca de pathing. + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + Esta região não está habilitada para pathfinding. + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + Aguardando a conclusão do carregamento da região. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Verificando o status do navmesh. + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Baixando o navmesh. + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + O navmesh foi alterado no servidor. Baixando o navmesh mais recente. + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + O navmesh mais recente foi baixado. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + ImpossÃvel baixar o navmesh com êxito. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + O navmesh tem alterações pendentes. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + O navmesh está compilando. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + Algumas regiões navmesh têm alterações pendentes. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + Algumas regiões navmesh estão compilando. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + Algumas regiões navmesh têm alterações pendentes e outras estão compilando. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + O navmesh está atualizado. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + ImpossÃvel encontrar a implementação de biblioteca de pathing. + </floater.string> + <floater.string name="pathing_region_not_enabled"> + Esta região não está habilitada para pathfinding. + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Escolha os pontos inicial e final. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Escolha o ponto inicial. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Escolha o ponto final. + </floater.string> + <floater.string name="pathing_path_valid"> + O caminho é exibido em laranja. + </floater.string> + <floater.string name="pathing_path_invalid"> + ImpossÃvel encontrar um caminho entre os pontos escolhidos. + </floater.string> + <floater.string name="pathing_error"> + Ocorreu um erro durante a geração do caminho. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Visualizar" name="view_panel"> + <text name="show_label"> + Exibir: + </text> + <check_box label="Mundo" name="show_world"/> + <check_box label="Apenas móveis" name="show_world_movables_only"/> + <check_box label="Navmesh" name="show_navmesh"/> + <text name="show_walkability_label"> + Exibir mapa de possibilidade de caminhar: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="Não exibir" name="show_heatmap_mode_none"/> + <combo_box.item label="Tipo de personagem A" name="show_heatmap_mode_a"/> + <combo_box.item label="Tipo de personagem B" name="show_heatmap_mode_b"/> + <combo_box.item label="Tipo de personagem C" name="show_heatmap_mode_c"/> + <combo_box.item label="Tipo de personagem D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Caminháveis" name="show_walkables"/> + <check_box label="Volumes materiais" name="show_material_volumes"/> + <check_box label="Obstáculos estáticos" name="show_static_obstacles"/> + <check_box label="Volumes de exclusão" name="show_exclusion_volumes"/> + <check_box label="Plano aquático" name="show_water_plane"/> + <check_box label="Com visão de raio X" name="show_xray"/> + </panel> + <panel label="Testar caminho" name="test_panel"> + <text name="ctrl_click_label"> + Aperte a tecla Ctrl e clique com o mouse para selecionar o ponto inicial. + </text> + <text name="shift_click_label"> + Aperte a tecla Shift e clique com o mouse para selecionar o ponto final. + </text> + <text name="character_width_label"> + Largura do personagem + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + Tipo de personagem + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Nenhum" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Limpar caminho" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/pt/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..e0c60679dd --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Linksets do pathfinding"> + <floater.string name="messaging_get_inprogress"> + Procurando por linksets do pathfinding... + </floater.string> + <floater.string name="messaging_get_error"> + Erro detectado ao procurar por linksets do pathfinding. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Modificando os linksets do pathfinding selecionados... + </floater.string> + <floater.string name="messaging_set_error"> + Erro detectado ao modificar os linksets do pathfinding selecionados. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Nenhum linkset do pathfinding. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] linksets selecionados de [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + Esta região não está habilitada para pathfinding. + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terreno] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Carregando] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Desconhecido] + </floater.string> + <floater.string name="linkset_owner_group"> + [grupo] + </floater.string> + <floater.string name="linkset_is_scripted"> + Sim + </floater.string> + <floater.string name="linkset_is_not_scripted"> + Não + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + Desconhecido + </floater.string> + <floater.string name="linkset_use_walkable"> + Caminhável + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Obstáculo estático + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Obstáculo móvel + </floater.string> + <floater.string name="linkset_use_material_volume"> + Volume material + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + Volume de exclusão + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Fantasma móvel + </floater.string> + <floater.string name="linkset_is_terrain"> + [inalterável] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [restrito] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [côncavo] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [restrito,côncavo] + </floater.string> + <floater.string name="linkset_choose_use"> + Escolher uso do linkset... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="Filtrar por uso do linkset..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Caminhável" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Obstáculo estático" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Obstáculo móvel" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Volume material" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="Volume de exclusão" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Fantasma móvel" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Aplicar" name="apply_filters"/> + <button label="Limpar" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nome (prim raiz)" name="name"/> + <scroll_list.columns label="Descrição (prim raiz)" name="description"/> + <scroll_list.columns label="Proprietário" name="owner"/> + <scroll_list.columns label="Com script" name="scripted"/> + <scroll_list.columns label="Impacto" name="land_impact"/> + <scroll_list.columns label="Distância" name="dist_from_you"/> + <scroll_list.columns label="Uso do linkset" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + Linksets: + </text> + <button label="Atualizar lista" name="refresh_objects_list"/> + <button label="Selecionar tudo" name="select_all_objects"/> + <button label="Selecionar nenhum" name="select_none_objects"/> + </panel> + <panel> + <check_box label="Exibir baliza" name="show_beacon"/> + <button label="Pegar" name="take_objects"/> + <button label="Pegar uma cópia" name="take_copy_objects"/> + <button label="Teletransportar-me até ele" name="teleport_me_to_object"/> + <button label="Devolver" name="return_objects"/> + <button label="Excluir" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + Possibilidade de caminhar: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="Possibilidade de caminhar para os personagens do tipo A. Por exemplo: o tipo do personagem é humano."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="Possibilidade de caminhar para os personagens do tipo B. Por exemplo: o tipo do personagem é criatura."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="Possibilidade de caminhar para os personagens do tipo C. Por exemplo: o tipo do personagem é robô."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="Possibilidade de caminhar para os personagens do tipo D. Por exemplo: o tipo do personagem é outro."/> + <button label="Aplicar alterações" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Humano) + </text> + <text name="suggested_use_b_label"> + (Criatura) + </text> + <text name="suggested_use_c_label"> + (Robô) + </text> + <text name="suggested_use_d_label"> + (Outro) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_postcard.xml b/indra/newview/skins/default/xui/pt/floater_postcard.xml deleted file mode 100644 index 9740fbcb4d..0000000000 --- a/indra/newview/skins/default/xui/pt/floater_postcard.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="ENVIAR FOTO VIA EMAIL"> - <text name="to_label" width="135"> - Para (email): - </text> - <line_editor left="143" name="to_form" width="127"/> - <text name="from_label"> - De (email): - </text> - <line_editor left="143" name="from_form" width="127"/> - <text name="name_label"> - Seu nome: - </text> - <line_editor left="143" name="name_form" width="127"/> - <text name="subject_label"> - Assunto: - </text> - <line_editor left="143" name="subject_form" width="127"/> - <line_editor label="Digite o assunto aqui" name="subject_form"/> - <text name="msg_label"> - Mensagem: - </text> - <text_editor name="msg_form"> - Digite sua mensagem aqui. - </text_editor> - <text name="fine_print"> - Se seu indicado entrar no [SECOND_LIFE], você receberá um bônus pela indicação. - </text> - <button label="Cancelar" name="cancel_btn"/> - <button label="Enviar" name="send_btn"/> - <string name="default_subject"> - Postal do [SECOND_LIFE]. - </string> - <string name="default_message"> - Dá uma olhada nisto! - </string> - <string name="upload_message"> - Enviando... - </string> -</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_preview_animation.xml b/indra/newview/skins/default/xui/pt/floater_preview_animation.xml index b650b7945c..19474d8099 100644 --- a/indra/newview/skins/default/xui/pt/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/pt/floater_preview_animation.xml @@ -6,6 +6,6 @@ <text name="desc txt"> Descrição: </text> - <button label="Tocar inworld" label_selected="Parar" name="Anim play btn" tool_tip="Tocar essa animação de forma que outros possam ver" width="131"/> - <button label="Executar localmente" label_selected="Parar" left="162" name="Anim audition btn" tool_tip="Tocar essa animação de forma que apenas você possa ver" width="120"/> + <button label="Tocar inworld" label_selected="Parar" name="Inworld" tool_tip="Executar essa animação de forma que outros possam ver"/> + <button label="Tocar localmente" label_selected="Parar" name="Locally" tool_tip="Executar animação de forma que apenas você possa ver"/> </floater> 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_spellcheck.xml b/indra/newview/skins/default/xui/pt/floater_spellcheck.xml new file mode 100644 index 0000000000..02bb154d26 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="Configurações do verificador ortográfico"> + <check_box label="Habilitar verificador ortográfico" name="spellcheck_enable"/> + <text name="spellcheck_main"> + Dicionário principal: + </text> + <text label="Logs:" name="spellcheck_additional"> + Dicionários adicionais: + </text> + <text name="spellcheck_available"> + DisponÃvel + </text> + <text name="spellcheck_active"> + Ativo + </text> + <button label="Remover" name="spellcheck_remove_btn"/> + <button label="Importar..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/pt/floater_spellcheck_import.xml new file mode 100644 index 0000000000..f4e95bddec --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Importar dicionário"> + <button label="Procurar" label_selected="Procurar" name="dictionary_path_browse"/> + <button label="Importar" name="ok_btn"/> + <button label="Cancelar" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_stats.xml b/indra/newview/skins/default/xui/pt/floater_stats.xml index f0a053ebe3..be53624145 100644 --- a/indra/newview/skins/default/xui/pt/floater_stats.xml +++ b/indra/newview/skins/default/xui/pt/floater_stats.xml @@ -14,8 +14,11 @@ <stat_bar label="KTris desenhados por segundo" name="ktrissec"/> <stat_bar label="Total Objects" name="objs"/> <stat_bar label="New Objects" name="newobjs"/> + <stat_bar label="Taxa de acertos do cache do objeto" name="object_cache_hits"/> </stat_view> <stat_view label="Texture" name="texture"> + <stat_bar label="Taxa de acertos do cache" name="texture_cache_hits"/> + <stat_bar label="Latência de leitura do cache" name="texture_cache_read_latency"/> <stat_bar label="Count" name="numimagesstat"/> <stat_bar label="Raw Count" name="numrawimagesstat"/> <stat_bar label="GL Mem" name="gltexmemstat"/> @@ -44,6 +47,12 @@ <stat_bar label="Low LOD Objects" name="physicslodtasks"/> <stat_bar label="Memory Allocated" name="physicsmemoryallocated"/> </stat_view> + <stat_bar label="Scripts executados" name="simpctscriptsrun"/> + <stat_view label="Pathfinding" name="simpathfinding"> + <stat_bar label="Tempo de etapa de AI" name="simsimaistepmsec"/> + <stat_bar label="Etapas de silhueta ignoradas" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Personagens atualizados" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_view label="Time (ms)" name="simperf"> <stat_bar label="Total Frame Time" name="simframemsec"/> <stat_bar label="Net Time" name="simnetmsec"/> diff --git a/indra/newview/skins/default/xui/pt/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/pt/floater_test_layout_stacks.xml new file mode 100644 index 0000000000..b479d5f6d6 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_test_layout_stacks.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="LAYOUTSTACK TESTS"/> diff --git a/indra/newview/skins/default/xui/pt/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/pt/floater_test_text_vertical_aligment.xml new file mode 100644 index 0000000000..dd282bf1fc --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_test_text_vertical_aligment.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="JANELA DE TESTE"/> diff --git a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml index 144bc0340e..a75cf34a94 100644 --- a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml @@ -1,23 +1,35 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="texture picker" title="DESTAQUE: TEXTURA"> - <string name="choose_picture"> + <floater.string name="choose_picture"> Clique para escolher uma imagem - </string> + </floater.string> + <floater.string name="pick title"> + Pegar: + </floater.string> <text name="Multiple"> Multiplas texturas </text> + <radio_group name="mode_selection"> + <radio_item label="Inventário" name="inventory" value="0"/> + <radio_item label="Local" name="local" value="1"/> + </radio_group> <text name="unknown"> Tamanho: [DIMENSÕES] </text> <button label="Padrão" label_selected="Padrão" name="Default"/> - <button label="Nenhum" label_selected="Nenhum" name="None"/> <button label="Branco" label_selected="Branco" name="Blank"/> - <check_box label="Exibir pastas" name="show_folders_check"/> - <search_editor label="Filtrar texturas" name="inventory search editor"/> - <check_box label="Applicar agora" name="apply_immediate_check"/> - <button label="Cancelar" label_selected="Cancelar" name="Cancel"/> + <button label="Nenhum" label_selected="Nenhum" name="None"/> + <check_box initial_value="true" label="Visualização em tempo real" name="apply_immediate_check"/> + <text name="preview_disabled" value="Visualização desativada"/> + <filter_editor label="Filtrar texturas" name="inventory search editor"/> + <check_box initial_value="false" label="Exibir pastas" name="show_folders_check"/> + <button label="Adicionar" label_selected="Adicionar" name="l_add_btn"/> + <button label="Remover" label_selected="Remover" name="l_rem_btn"/> + <button label="Enviar" label_selected="Enviar" name="l_upl_btn"/> + <scroll_list name="l_name_list"> + <column label="Nome" name="unit_name"/> + <column label="ID" name="unit_id_HIDDEN"/> + </scroll_list> <button label="OK" label_selected="OK" name="Select"/> - <string name="pick title"> - Pegar: - </string> + <button label="Cancelar" label_selected="Cancelar" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/pt/floater_texture_fetch_debugger.xml new file mode 100644 index 0000000000..0e897aea09 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_texture_fetch_debugger.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="TexFetchDebugger" title="Depurador de obtenção de textura"> + <text name="total_num_fetched_label"> + 1, Número total de texturas obtidas: [NUM] + </text> + <text name="total_num_fetching_requests_label"> + 2, Número total de solicitações de obtenção: [NUM] + </text> + <text name="total_num_cache_hits_label"> + 3, Número total de acertos de cache: [NUM] + </text> + <text name="total_num_visible_tex_label"> + 4, Número total de texturas visÃveis: [NUM] + </text> + <text name="total_num_visible_tex_fetch_req_label"> + 5, Número total de solicitações de obtenção de texturas visÃveis: [NUM] + </text> + <text name="total_fetched_data_label"> + 6, Número total de dados obtidos: [SIZE1]KB, Dados decodificados: [SIZE2]KB, [PIXEL]MPixels + </text> + <text name="total_fetched_vis_data_label"> + 7, Número total de dados visÃveis: [SIZE1]KB, Dados decodificados: [SIZE2]KB + </text> + <text name="total_fetched_rendered_data_label"> + 8, Número total de dados renderizados: [SIZE1]KB, Dados decodificados: [SIZE2]KB, [PIXEL]MPixels + </text> + <text name="total_time_cache_read_label"> + 9, Tempo total de leituras de cache: [TIME] segundos + </text> + <text name="total_time_cache_write_label"> + 10, Tempo total de gravações em cache: [TIME] segundos + </text> + <text name="total_time_decode_label"> + 11, Tempo total das decodificações: [TIME] segundos + </text> + <text name="total_time_gl_label"> + 12, Tempo total de criação de texturas gl: [TIME] segundos + </text> + <text name="total_time_http_label"> + 13, Tempo total de obtenção de HTTP: [TIME] segundos + </text> + <text name="total_time_fetch_label"> + 14, Tempo total de obtenção completa: [TIME] segundos + </text> + <text name="total_time_refetch_vis_cache_label"> + 15, Obtendo novamente visÃveis do cache, Tempo: [TIME] segundos, Obtidos: [SIZE]KB, [PIXEL]MPixels + </text> + <text name="total_time_refetch_all_cache_label"> + 16, Obtendo novamente todas as texturas do cache, Tempo: [TIME] segundos, Obtidos: [SIZE]KB, [PIXEL]MPixels + </text> + <text name="total_time_refetch_vis_http_label"> + 17, Obtendo novamente visÃveis do HTTP, Tempo: [TIME] segundos, Obtidos: [SIZE]KB, [PIXEL]MPixels + </text> + <text name="total_time_refetch_all_http_label"> + 18, Obtendo novamente todas as texturas do HTTP, Tempo: [TIME] segundos, Obtidos: [SIZE]KB, [PIXEL]MPixels + </text> + <spinner label="19, Proporção de texel/pixel:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, Origem da textura: + </text> + <radio_group name="texture_source"> + <radio_item label="Cache + HTTP" name="0"/> + <radio_item label="Apenas HTTP" name="1"/> + </radio_group> + <button label="Iniciar" name="start_btn"/> + <button label="Redefinir" name="clear_btn"/> + <button label="Fechar" name="close_btn"/> + <button label="Leitura do cache" name="cacheread_btn"/> + <button label="Gravação em cache" name="cachewrite_btn"/> + <button label="HTTP" name="http_btn"/> + <button label="Decodificar" name="decode_btn"/> + <button label="Textura GL" name="gl_btn"/> + <button label="Obter novamente cache visÃvel" name="refetchviscache_btn"/> + <button label="Obter todo o cache novamente" name="refetchallcache_btn"/> + <button label="Obter novamente HTTP visÃvel" name="refetchvishttp_btn"/> + <button label="Obter todo o HTTP novamente" name="refetchallhttp_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_tools.xml b/indra/newview/skins/default/xui/pt/floater_tools.xml index f35f31f5f7..8c245c582e 100644 --- a/indra/newview/skins/default/xui/pt/floater_tools.xml +++ b/indra/newview/skins/default/xui/pt/floater_tools.xml @@ -1,5 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="toolbox floater" short_title="BUILD TOOLS" title=""> + <floater.string name="grid_screen_text"> + Tela + </floater.string> + <floater.string name="grid_local_text"> + Local + </floater.string> + <floater.string name="grid_world_text"> + Mundo + </floater.string> + <floater.string name="grid_reference_text"> + Referência + </floater.string> + <floater.string name="grid_attachment_text"> + Anexo + </floater.string> <floater.string name="status_rotate"> Arrastar as faixas coloridas para girar o objeto </floater.string> @@ -63,7 +78,12 @@ </text> <check_box initial_value="true" label="Esticar texturas" name="checkbox stretch textures"/> <check_box initial_value="true" label="Ajustar" name="checkbox snap to grid"/> - <button label="Opções..." label_selected="Opções..." name="Options..." tool_tip="Mais opções de grade"/> + <combo_box name="combobox grid mode" tool_tip="Selecione o tipo de régua da grade onde o objeto será colocado"> + <combo_box.item label="Mundo" name="World"/> + <combo_box.item label="Local" name="Local"/> + <combo_box.item label="Referência" name="Reference"/> + </combo_box> + <button label="" label_selected="Opções..." name="Options..." tool_tip="Mais opções de grade"/> <button label="" label_selected="" name="ToolCube" tool_tip="Cubo"/> <button label="" label_selected="" name="ToolPrism" tool_tip="Prisma"/> <button label="" label_selected="" name="ToolPyramid" tool_tip="Pirâmide"/> @@ -128,6 +148,12 @@ <panel.string name="text modify info 4"> Você não pode modificar estes objetos </panel.string> + <panel.string name="text modify info 5"> + Não é possÃvel modificar este objeto através de uma demarcação da região + </panel.string> + <panel.string name="text modify info 6"> + Não é possÃvel modificar estes objetos através de uma demarcação da região + </panel.string> <panel.string name="text modify warning"> Selecione o objeto inteiro para configurar as autorizações </panel.string> @@ -177,12 +203,12 @@ <combo_box.item label="Zoom" name="Zoom"/> </combo_box> <check_box label="À venda" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Cópia" name="Copy"/> <combo_box.item label="Conteúdo" name="Contents"/> <combo_box.item label="Original" name="Original"/> </combo_box> - <spinner label="Preço: L$" name="Edit Cost"/> <check_box label="Mostrar na busca" name="search_check" tool_tip="Permitir que as pessoas vejam este objeto nos resultados de busca"/> <panel name="perms_build"> <text name="perm_modify"> @@ -218,6 +244,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Atributos do pathfinding: + </text> + </panel> </panel> <panel label="Objeto" name="Object"> <check_box label="Travado" name="checkbox locked" tool_tip="Previne que o objeto seja movido ou apagado. Muito útil para evitar edições não intencionais durante a construção."/> diff --git a/indra/newview/skins/default/xui/pt/floater_top_objects.xml b/indra/newview/skins/default/xui/pt/floater_top_objects.xml index c3d5820616..ef682714c6 100644 --- a/indra/newview/skins/default/xui/pt/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/pt/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> Tempo </floater.string> - <floater.string name="scripts_mono_time_label"> - Hora Mono - </floater.string> <floater.string name="top_colliders_title"> Principais Colidentes </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="Nome" name="name"/> <scroll_list.columns label="Proprietário" name="owner"/> <scroll_list.columns label="Local" name="location"/> + <scroll_list.columns label="Lote" name="parcel"/> <scroll_list.columns label="Tempo" name="time"/> - <scroll_list.columns label="Hora Mono" name="mono_time"/> <scroll_list.columns label="URLs" name="URLs"/> + <scroll_list.columns label="Memória (KB)" name="memory"/> </scroll_list> <text name="id_text"> ID do Objeto: @@ -51,6 +49,10 @@ </text> <line_editor font="SansSerifSmall" left="140" name="owner_name_editor" width="280"/> <button label="Filtro" name="filter_owner_btn"/> + <text name="parcel_name_text"> + Lote: + </text> + <button label="Filtrar" name="filter_parcel_btn"/> <button label="Atualizar" name="refresh_btn"/> <button label="Retornar Selecionado" name="return_selected_btn" width="170"/> <button label="Retornar Tudo" left="190" name="return_all_btn"/> 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/floater_voice_effect.xml b/indra/newview/skins/default/xui/pt/floater_voice_effect.xml index 4f01600d9f..b29ca3d699 100644 --- a/indra/newview/skins/default/xui/pt/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/pt/floater_voice_effect.xml @@ -42,13 +42,16 @@ <string name="effect_Demon"> Demônio </string> + <string name="effect_Female Elf"> + Elfa + </string> <string name="effect_Flirty"> Paquerador </string> <string name="effect_Foxy"> Sensual </string> - <string name="effect_Halloween_2010_Bonus"> + <string name="effect_Halloween 2010 Bonus"> Bônus_Halloween_2010 </string> <string name="effect_Helium"> @@ -57,9 +60,18 @@ <string name="effect_Husky"> Rouco </string> + <string name="effect_Husky Whisper"> + Sussurro rouco + </string> <string name="effect_Intercom"> Interfone </string> + <string name="effect_Julia"> + Julia + </string> + <string name="effect_Lo Lilt"> + Cantarolado baixo + </string> <string name="effect_Macho"> Macho </string> @@ -69,6 +81,9 @@ <string name="effect_Mini"> Mini </string> + <string name="effect_Model"> + Modelo + </string> <string name="effect_Nano"> Nano </string> @@ -90,6 +105,9 @@ <string name="effect_Roxanne"> Roxanne </string> + <string name="effect_Rumble"> + Ronco + </string> <string name="effect_Sabrina"> Sabrina </string> @@ -102,6 +120,9 @@ <string name="effect_Shorty"> Baixinho </string> + <string name="effect_Smaller"> + Menor + </string> <string name="effect_Sneaky"> Sorrateiro </string> diff --git a/indra/newview/skins/default/xui/pt/floater_window_size.xml b/indra/newview/skins/default/xui/pt/floater_window_size.xml index 6a8ccbd002..7deb799bd7 100644 --- a/indra/newview/skins/default/xui/pt/floater_window_size.xml +++ b/indra/newview/skins/default/xui/pt/floater_window_size.xml @@ -7,10 +7,17 @@ Definir tamanho da janela: </text> <combo_box name="window_size_combo" tool_tip="largura x altura"> - <combo_box.item label="1000 x 700 (padrão)" name="item0"/> - <combo_box.item label="1024 x 768" name="item1"/> - <combo_box.item label="1280 x 720 (720p)" name="item2"/> - <combo_box.item label="1920 x 1080 (1080p)" name="item3"/> + <combo_box.item label="1000 x 700 (padrão)" name="item1"/> + <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/> + <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/> + <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/> + <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/> + <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/> + <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/> + <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/> + <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/> + <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/> + <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/> </combo_box> <button label="Definir" name="set_btn"/> <button label="Cancelar" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/pt/inspect_avatar.xml b/indra/newview/skins/default/xui/pt/inspect_avatar.xml index a199c58c15..19244d9b27 100644 --- a/indra/newview/skins/default/xui/pt/inspect_avatar.xml +++ b/indra/newview/skins/default/xui/pt/inspect_avatar.xml @@ -5,10 +5,10 @@ --> <floater name="inspect_avatar"> <string name="Subtitle"> - [IDADE] + [AGE] </string> <string name="Details"> - [PERFIL_SL] + [SL_PROFILE] </string> <text name="user_details"> This is my second life description and I really think it is great. But for some reason my description is super extra long because I like to talk a whole lot diff --git a/indra/newview/skins/default/xui/pt/menu_bottomtray.xml b/indra/newview/skins/default/xui/pt/menu_bottomtray.xml deleted file mode 100644 index 4598b8ab25..0000000000 --- a/indra/newview/skins/default/xui/pt/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="Botão Falar" name="EnableVoiceChat"/> - <menu_item_check label="Botão de gestos" name="ShowGestureButton"/> - <menu_item_check label="Botão de movimento" name="ShowMoveButton"/> - <menu_item_check label="Botão de ver" name="ShowCameraButton"/> - <menu_item_check label="Botão de fotos" name="ShowSnapshotButton"/> - <menu_item_check label="Botão Construir" name="ShowBuildButton"/> - <menu_item_check label="Botão Buscar" name="ShowSearchButton"/> - <menu_item_check label="Botão Mapa" name="ShowWorldMapButton"/> - <menu_item_check label="Botão do Mini mapa" name="ShowMiniMapButton"/> - <menu_item_call label="Cortar" name="NearbyChatBar_Cut"/> - <menu_item_call label="Copiar" name="NearbyChatBar_Copy"/> - <menu_item_call label="Colar" name="NearbyChatBar_Paste"/> - <menu_item_call label="Excluir" name="NearbyChatBar_Delete"/> - <menu_item_call label="Selecionar tudo" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/pt/menu_im_well_button.xml b/indra/newview/skins/default/xui/pt/menu_im_well_button.xml deleted file mode 100644 index 2d37cefd6f..0000000000 --- a/indra/newview/skins/default/xui/pt/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<context_menu name="IM Well Button Context Menu"> - <menu_item_call label="Fechar tudo" name="Close All"/> -</context_menu> diff --git a/indra/newview/skins/default/xui/pt/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/pt/menu_inspect_object_gear.xml index 184db26538..7e271904e9 100644 --- a/indra/newview/skins/default/xui/pt/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/pt/menu_inspect_object_gear.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<menu name="Gear Menu"> +<toggleable_menu name="Gear Menu"> <menu_item_call label="Tocar" name="touch"/> <menu_item_call label="Sentar" name="sit"/> <menu_item_call label="Pagar" name="pay"/> @@ -12,7 +12,8 @@ <menu_item_call label="Adicionar" name="add"/> <menu_item_call label="Denunciar" name="report"/> <menu_item_call label="Bloquear" name="block"/> + <menu_item_call label="Desbloquear" name="unblock"/> <menu_item_call label="Mais zoom" name="zoom_in"/> <menu_item_call label="Tirar" name="remove"/> <menu_item_call label="Mais informações" name="more_info"/> -</menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/pt/menu_inventory.xml b/indra/newview/skins/default/xui/pt/menu_inventory.xml index ba3879b5a1..a3a648eb34 100644 --- a/indra/newview/skins/default/xui/pt/menu_inventory.xml +++ b/indra/newview/skins/default/xui/pt/menu_inventory.xml @@ -59,6 +59,7 @@ <menu_item_call label="Propriedades" name="Properties"/> <menu_item_call label="Renomear" name="Rename"/> <menu_item_call label="Copiar item UUID" name="Copy Asset UUID"/> + <menu_item_call label="Cortar" name="Cut"/> <menu_item_call label="Copiar" name="Copy"/> <menu_item_call label="Colar" name="Paste"/> <menu_item_call label="Colar como link" name="Paste As Link"/> @@ -67,6 +68,7 @@ <menu_item_call label="Excluir pasta do sistema" name="Delete System Folder"/> <menu_item_call label="Pasta conversa em conferência" name="Conference Chat Folder"/> <menu_item_call label="Executar som" name="Sound Play"/> + <menu_item_call label="Copiar SLurl" name="url_copy"/> <menu_item_call label="Sobre o marco" name="About Landmark"/> <menu_item_call label="Executar animação" name="Animation Play"/> <menu_item_call label="Executar áudio" name="Animation Audition"/> @@ -84,6 +86,6 @@ <menu_item_call label="Adicionar" name="Wearable Add"/> <menu_item_call label="Tirar" name="Take Off"/> <menu_item_call label="Copiar para Caixa de saÃda do lojista" name="Merchant Copy"/> - <menu_item_call label="Mover para Caixa de saÃda do lojista" name="Merchant Move"/> + <menu_item_call label="Enviar para Mercado" name="Marketplace Send"/> <menu_item_call label="--Sem opções--" name="--no options--"/> </menu> diff --git a/indra/newview/skins/default/xui/pt/menu_login.xml b/indra/newview/skins/default/xui/pt/menu_login.xml index 94195f1b8c..be94ad49db 100644 --- a/indra/newview/skins/default/xui/pt/menu_login.xml +++ b/indra/newview/skins/default/xui/pt/menu_login.xml @@ -16,8 +16,8 @@ <menu_item_call label="Definir tamanho da janela:" name="Set Window Size..."/> <menu_item_call label="Mostrar TOS" name="TOS"/> <menu_item_call label="Mostrar mensagem crÃtica" name="Critical"/> - <menu_item_call label="Teste de mÃdia do navegador" name="Web Browser Test"/> <menu_item_call label="Test de Bugs de Conteúdo Web" name="Web Content Floater Debug Test"/> + <menu label="Configurar nÃvel de registro em log" name="Set Logging Level"/> <menu_item_check label="Exibir seletor da grade" name="Show Grid Picker"/> <menu_item_call label="Exibir painel de notificações" name="Show Notifications Console"/> </menu> diff --git a/indra/newview/skins/default/xui/pt/menu_mode_change.xml b/indra/newview/skins/default/xui/pt/menu_mode_change.xml deleted file mode 100644 index 314d3e409b..0000000000 --- a/indra/newview/skins/default/xui/pt/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="Básico" name="BasicMode"/> - <menu_item_check label="Avançado" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/pt/menu_object.xml b/indra/newview/skins/default/xui/pt/menu_object.xml index f4919e0c1f..28dd9febe2 100644 --- a/indra/newview/skins/default/xui/pt/menu_object.xml +++ b/indra/newview/skins/default/xui/pt/menu_object.xml @@ -5,6 +5,8 @@ </menu_item_call> <menu_item_call label="Editar" name="Edit..."/> <menu_item_call label="Construir" name="Build"/> + <menu_item_call label="Exibir em linksets" name="show_in_linksets"/> + <menu_item_call label="Exibir em personagens" name="show_in_characters"/> <menu_item_call label="Abrir" name="Open"/> <menu_item_call label="Sentar aqui" name="Object Sit"/> <menu_item_call label="Ficar de pé" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/pt/menu_text_editor.xml b/indra/newview/skins/default/xui/pt/menu_text_editor.xml index 31c284c6ed..a26b50e1c2 100644 --- a/indra/newview/skins/default/xui/pt/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/pt/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(desconhecido)" name="Suggestion 1"/> + <menu_item_call label="(desconhecido)" name="Suggestion 2"/> + <menu_item_call label="(desconhecido)" name="Suggestion 3"/> + <menu_item_call label="(desconhecido)" name="Suggestion 4"/> + <menu_item_call label="(desconhecido)" name="Suggestion 5"/> + <menu_item_call label="Adicionar ao dicionário" name="Add to Dictionary"/> + <menu_item_call label="Adicionar para ignorar" name="Add to Ignore"/> <menu_item_call label="Cortar" name="Cut"/> <menu_item_call label="Copiar" name="Copy"/> <menu_item_call label="Colar" name="Paste"/> 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 9b5711d402..ca378c1b58 100644 --- a/indra/newview/skins/default/xui/pt/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml @@ -1,55 +1,62 @@ <?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"/> <menu_item_check label="Correr sempre" name="Always Run"/> <menu_item_call label="Parar minha animação" name="Stop Animating My Avatar"/> + <menu_item_call label="Andar/correr/voar..." name="Walk / run / fly"/> </menu> <menu label="Status" name="Status"> <menu_item_call label="Ausente" name="Set Away"/> <menu_item_call label="Ocupado" name="Set Busy"/> </menu> - <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="Comprar L$..." name="Buy and Sell L$"/> + <menu_item_call label="Caixa de saÃda do lojista..." name="MerchantOutbox"/> + <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_check label="Exibir anexos de HUD" name="Show HUD Attachments"/> <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_item_call label="Lista de bloqueados" name="Block List"/> </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 +65,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 label="Sol" name="Sun"> <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="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> @@ -96,7 +102,7 @@ </menu> <menu_item_call label="Link" name="Link"/> <menu_item_call label="Desconectar links" name="Unlink"/> - <menu_item_check label="Edit Linked Parts" name="Edit Linked Parts"/> + <menu_item_check label="Editar partes linkadas" name="Edit Linked Parts"/> <menu label="Selecionar partes conectadas" name="Select Linked Parts"> <menu_item_call label="Selecionar próxima parte" name="Select Next Part"/> <menu_item_call label="Selecionar parte anterior" name="Select Previous Part"/> @@ -110,16 +116,21 @@ <menu_item_call label="Pegar" name="Menu Object Take"/> <menu_item_call label="Pegar uma cópia" name="Take Copy"/> <menu_item_call label="Salvar no meu inventário" name="Save Object Back to My Inventory"/> - <menu_item_call label="Save Back to Object Contents" name="Save Object Back to Object Contents"/> + <menu_item_call label="Salvar objeto de volta aos conteúdos do objeto" name="Save Object Back to Object Contents"/> <menu_item_call label="Devolver objeto" name="Return Object back to Owner"/> </menu> <menu label="Scripts" name="Scripts"> - <menu_item_call label="Recompilar scripts (LSL)" name="Mono"/> + <menu_item_call label="Recompilar scripts (Mono)" name="Mono"/> <menu_item_call label="Recompilar scripts (LSL)" name="LSL"/> <menu_item_call label="Resetar scripts" name="Reset Scripts"/> <menu_item_call label="Scripts em modo execução" name="Set Scripts to Running"/> <menu_item_call label="Scripts em modo não execução" name="Set Scripts to Not Running"/> </menu> + <menu label="Pathfinding" name="Pathfinding"> + <menu_item_call label="Linksets..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="Personagens..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="Visualização/teste..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Opções" name="Options"> <menu_item_check label="Mostrar permissões avançadas" name="DebugPermissions"/> <menu_item_check label="Só selecionar meus objetos" name="Select Only My Objects"/> @@ -140,11 +151,13 @@ <menu_item_call label="Animação (L$[COST])..." name="Upload Animation"/> <menu_item_call label="Modelar..." name="Upload Model"/> <menu_item_call label="Volume (L$[COST] por arquivo)..." name="Bulk Upload"/> + <menu_item_call label="Autorizações de upload padrão" name="perm prefs"/> </menu> <menu_item_call label="Desfazer" name="Undo"/> <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"/> @@ -157,7 +170,7 @@ <menu_item_check label="Limitar distância da seleção" name="Limit Select Distance"/> <menu_item_check label="Disable Camera Constraints" name="Disable Camera Distance"/> <menu_item_check label="Foto de alta resolução" name="HighResSnapshot"/> - <menu_item_check label="Compactar fotos para HD" name="QuietSnapshotsToDisk"/> + <menu_item_check label="Fotos sem barulho para HD" name="QuietSnapshotsToDisk"/> <menu label="Ferramentas de desempenho" name="Performance Tools"> <menu_item_call label="Medidor de lag" name="Lag Meter"/> <menu_item_check label="Barra de estatÃsticas" name="Statistics Bar"/> @@ -165,29 +178,28 @@ </menu> <menu label="Realces e visibilidade" name="Highlighting and Visibility"> <menu_item_check label="Efeito baliza piscando" name="Cheesy Beacon"/> - <menu_item_check label="Hide Particles" name="Hide Particles"/> + <menu_item_check label="Esconder partÃculas" name="Hide Particles"/> <menu_item_check label="Ocultar seleções" name="Hide Selected"/> <menu_item_check label="Realçar transparentes" name="Highlight Transparent"/> - <menu_item_check label="Mostrar anexos HUD" name="Show HUD Attachments"/> <menu_item_check label="Mostrar retÃculo na vista subjetiva" name="ShowCrosshairs"/> </menu> <menu label="Tipos de renderização" name="Rendering Types"> - <menu_item_check label="Simples" name="Simple"/> - <menu_item_check label="Alpha" name="Alpha"/> - <menu_item_check label="Ãrvore" name="Tree"/> - <menu_item_check label="Avatares" name="Character"/> - <menu_item_check label="Patch de superfÃcie" name="Surface Patch"/> - <menu_item_check label="Céu" name="Sky"/> - <menu_item_check label="Ãgua" name="Water"/> - <menu_item_check label="Chão" name="Ground"/> - <menu_item_check label="Volume" name="Volume"/> - <menu_item_check label="Grama" name="Grass"/> - <menu_item_check label="Nuvens" name="Clouds"/> - <menu_item_check label="Particles" name="Particles"/> - <menu_item_check label="Elevação" name="Bump"/> + <menu_item_check label="Simples" name="Rendering Type Simple"/> + <menu_item_check label="Alpha" name="Rendering Type Alpha"/> + <menu_item_check label="Ãrvore" name="Rendering Type Tree"/> + <menu_item_check label="Avatares" name="Rendering Type Character"/> + <menu_item_check label="Patch de superfÃcie" name="Rendering Type Surface Patch"/> + <menu_item_check label="Céu" name="Rendering Type Sky"/> + <menu_item_check label="Ãgua" name="Rendering Type Water"/> + <menu_item_check label="Chão" name="Rendering Type Ground"/> + <menu_item_check label="Volume" name="Rendering Type Volume"/> + <menu_item_check label="Grama" name="Rendering Type Grass"/> + <menu_item_check label="Nuvens" name="Rendering Type Clouds"/> + <menu_item_check label="PartÃculas" name="Rendering Type Particles"/> + <menu_item_check label="Elevação" name="Rendering Type Bump"/> </menu> <menu label="Recursos de renderização" name="Rendering Features"> - <menu_item_check label="Interface" name="UI"/> + <menu_item_check label="Interface" name="ToggleUI"/> <menu_item_check label="Selecionado" name="Selected"/> <menu_item_check label="Realçado" name="Highlighted"/> <menu_item_check label="Texturas dinâmicas" name="Dynamic Textures"/> @@ -198,11 +210,8 @@ <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"/> @@ -211,13 +220,6 @@ <menu_item_check label="Flycam Joystick" name="Joystick Flycam"/> <menu_item_call label="Visão padrão" name="Reset View"/> <menu_item_call label="Olhar para quem fala por último" name="Look at Last Chatter"/> - <menu label="Selecionar ferramenta de construção" name="Select Tool"> - <menu_item_call label="Ferramenta enfoque" name="Focus"/> - <menu_item_call label="Ferramenta de movimentação" name="Move"/> - <menu_item_call label="Ferramenta de edição" name="Edit"/> - <menu_item_call label="Ferramenta criar" name="Create"/> - <menu_item_call label="Ferramenta de terrenos" name="Land"/> - </menu> <menu_item_call label="Mais zoom" name="Zoom In"/> <menu_item_call label="Zoom padrão" name="Zoom Default"/> <menu_item_call label="Menos zoom" name="Zoom Out"/> @@ -230,11 +232,10 @@ <menu_item_check label="Painel de textura" name="Texture Console"/> <menu_item_check label="Console de depuração" name="Debug Console"/> <menu_item_call label="Painel de avisos" name="Notifications"/> - <menu_item_check label="Painel de tamanho de textura" name="Texture Size"/> - <menu_item_check label="Painel de texturas" name="Texture Category"/> <menu_item_check label="Tempos" name="Fast Timers"/> <menu_item_check label="Memória" name="Memory"/> <menu_item_check label="EstatÃsticas da cena" name="Scene Statistics"/> + <menu_item_call label="Painel de depuração de obtenção de textura" name="Texture Fetch Debug Console"/> <menu_item_call label="Region Info to Debug Console" name="Region Info to Debug Console"/> <menu_item_check label="Câmera:" name="Camera"/> <menu_item_check label="Vento" name="Wind"/> @@ -271,8 +272,16 @@ <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="Bytes do anexo" name="attachment bytes"/> <menu_item_check label="Esculpir" name="Sculpt"/> + <menu label="Densidade da textura" name="Texture Density"> + <menu_item_check label="Nenhuma" name="None"/> + <menu_item_check label="Atual" name="Current"/> + <menu_item_check label="Desejada" name="Desired"/> + <menu_item_check label="Completa" name="Full"/> + </menu> </menu> <menu label="Rendering" name="Rendering"> <menu_item_check label="Axes" name="Axes"/> @@ -280,7 +289,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"/> @@ -295,11 +303,10 @@ <menu_item_call label="Drop a Packet" name="Drop a Packet"/> </menu> <menu_item_call label="Empurrões, trombadas e tapas" name="Bumps, Pushes &amp; Hits"/> - <menu label="Mundo" name="World"> - <menu_item_check label="Impor sobre sol regional" name="Sim Sun Override"/> - <menu_item_check label="Efeito baliza piscando" name="Cheesy Beacon"/> - <menu_item_check label="Fixed Weather" name="Fixed Weather"/> - <menu_item_call label="Dump Region Object Cache" name="Dump Region Object Cache"/> + <menu label="Mundo" name="DevelopWorld"> + <menu_item_check label="Impor sobre sol de simulação" name="Sim Sun Override"/> + <menu_item_check label="Clima fixo" name="Fixed Weather"/> + <menu_item_call label="Descartar cache do objeto de região" name="Dump Region Object Cache"/> </menu> <menu label="Interface" name="UI"> <menu_item_call label="Teste de mÃdia do navegador" name="Web Browser Test"/> @@ -319,11 +326,11 @@ </menu> <menu label="Avatar" name="Character"> <menu label="Grab Baked Texture" name="Grab Baked Texture"> - <menu_item_call label="Ãris" name="Iris"/> - <menu_item_call label="Cabeça" name="Head"/> - <menu_item_call label="Cintura acima" name="Upper Body"/> - <menu_item_call label="Cintura para baixo" name="Lower Body"/> - <menu_item_call label="Saia" name="Skirt"/> + <menu_item_call label="Ãris" name="Grab Iris"/> + <menu_item_call label="Cabeça" name="Grab Head"/> + <menu_item_call label="Cintura acima" name="Grab Upper Body"/> + <menu_item_call label="Cintura para baixo" name="Grab Lower Body"/> + <menu_item_call label="Saia" name="Grab Skirt"/> </menu> <menu label="Testes de personagem" name="Character Tests"> <menu_item_call label="Toggle Character Geometry" name="Toggle Character Geometry"/> @@ -339,18 +346,27 @@ </menu> <menu_item_check label="Texturas HTTP" name="HTTP Textures"/> <menu_item_check label="Inventário HTTP" name="HTTP Inventory"/> + <menu_item_call label="Habilitar Visual Leak Detector" name="Enable Visual Leak Detector"/> <menu_item_check label="Console Window on next Run" name="Console Window"/> + <menu label="Configurar nÃvel de registro em log" name="Set Logging Level"> + <menu_item_check label="Depurar" name="Debug"/> + <menu_item_check label="Info" name="Info"/> + <menu_item_check label="Aviso" name="Warning"/> + <menu_item_check label="Error" name="Error"/> + <menu_item_check label="Nenhum" name="None"/> + </menu> <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_check label="Mostrar menu admin" name="View Admin Options"/> </menu> <menu label="Admin" name="Admin"> - <menu label="Object"> - <menu_item_call label="Pegar uma cópia" name="Take Copy"/> - <menu_item_call label="Force Owner To Me" name="Force Owner To Me"/> - <menu_item_call label="Force Owner Permissive" name="Force Owner Permissive"/> + <menu label="Objeto" name="AdminObject"> + <menu_item_call label="Pegar uma cópia" name="Admin Take Copy"/> + <menu_item_call label="Forçar propriedade para mim" name="Force Owner To Me"/> + <menu_item_call label="Forçar permissão de proprietário" name="Force Owner Permissive"/> <menu_item_call label="Excluir" name="Delete"/> <menu_item_call label="Bloquear" name="Lock"/> + <menu_item_call label="Obter IDs dos bens" name="Get Assets IDs"/> </menu> <menu label="Lote" name="Parcel"> <menu_item_call label="Force Owner To Me" name="Owner To Me"/> @@ -367,5 +383,16 @@ <menu label="Take Off Clothing" name="Take Off Clothing"> <menu_item_call label="FÃsico" name="Physics"/> </menu> + <menu label="Ajuda" name="DeprecatedHelp"> + <menu_item_call label="Blog oficial da Linden" name="Official Linden Blog"/> + <menu_item_call label="Portal de scripts" name="Scripting Portal"/> + <menu label="Relatar bugs" name="Bug Reporting"> + <menu_item_call label="Monitor de problemas" name="Public Issue Tracker"/> + <menu_item_call label="Ajuda do monitor de problemas" name="Publc Issue Tracker Help"/> + <menu_item_call label="Relatório de bugs 101" name="Bug Reporing 101"/> + <menu_item_call label="Problemas de segurança" name="Security Issues"/> + <menu_item_call label="Página Wiki" name="QA Wiki"/> + </menu> + </menu> </menu> </menu_bar> diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index 4bd9f86e0f..ff7382bf80 100644 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -85,17 +91,38 @@ Verifique se a conexão à internet está funcionando. <usetemplate canceltext="Cancelar" name="yesnocancelbuttons" notext="Não salvar" yestext="Salvar"/> </notification> <notification name="ConfirmNoCopyToOutbox"> - Você não tem permissão para copiar este item para a Caixa de saÃda do lojista. Tem certeza de que deseja mover o itens a seguir? - [ITEM_NAME] - <usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/> + Você não possui permissão para copiar um ou mais destes itens para a Caixa de saÃda do lojista. Você pode movê-los ou abandoná-los. + <usetemplate name="okcancelbuttons" notext="Não mover item(ns)" yestext="Mover item(ns)"/> + </notification> + <notification name="OutboxFolderCreated"> + Uma nova pasta foi criada para cada item transferido para o nÃvel superior de sua Caixa de saÃda do lojista. + <usetemplate ignoretext="Uma nova pasta foi criada na Caixa de saÃda do lojista" name="okignore" yestext="OK"/> </notification> - <notification name="OutboxUploadComplete"> - Envio para Mercado concluÃdo. - <usetemplate name="okbutton" yestext="Viva!"/> + <notification name="OutboxImportComplete"> + Êxito + +Todas as pastas foram enviadas para o Mercado com êxito. + <usetemplate ignoretext="Todas as pastas enviadas para o Mercado" name="okignore" yestext="OK"/> </notification> - <notification name="OutboxUploadHadErrors"> - Envio para Mercado concluÃdo com erros! Corrija os problemas em sua caixa de saÃda e tente novamente. Obrigado. - <usetemplate name="okbutton" yestext="Tudo bem!"/> + <notification name="OutboxImportHadErrors"> + Algumas pastas não foram transferidas + +Erro ao enviar algumas pastas para o Mercado. Estas pastas ainda estão na sua Caixa de saÃda do lojista. + +Consulte o [[MARKETPLACE_IMPORTS_URL] log de erros] para mais informações. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="OutboxImportFailed"> + Falha de transferência + +Nenhuma pasta enviada para o Mercado devido a um erro do sistema ou da rede. Tente novamente mais tarde. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="OutboxInitFailed"> + Falha na inicialização do Mercado + +Falha na inicialização do mercado devido a um erro do sistema ou da rede. Tente novamente mais tarde. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CompileQueueSaveText"> Houve um problema com o carregamento do texto para um script devido à seguinte razão: [REASON]. Por favor, tente novamente mais tarde. @@ -336,13 +363,19 @@ Digite o nome de usuário de seu avatar. É preciso ter uma conta para entrar no [SECOND_LIFE]. Deseja criar uma conta agora? <url name="url"> - https://join.secondlife.com/index.php?lang=pt-BR + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Tentar novamente" yestext="Abrir conta"/> </notification> <notification name="InvalidCredentialFormat"> Digite o nome de usuário ou o nome e sobrenome do seu avatar no campo Nome de usuário, depois entre em sua conta novamente. </notification> + <notification name="InvalidGrid"> + '[GRID]' não é um identificador de grade válido. + </notification> + <notification name="InvalidLocationSLURL"> + Seu ponto de partida não especificou uma grade válida. + </notification> <notification name="DeleteClassified"> Apagar classificado'[NAME]'? Não há reembolso por taxas já pagas. @@ -445,8 +478,8 @@ O objeto pode estar fora de alcance ou ter sido deletado. Houve um problema em salvar uma compilação de script devido a seguinte razão: [REASON]. Por favor, tente salvar novamente o script mais tarde. </notification> <notification name="StartRegionEmpty"> - Oops, você ainda não definiu sua região de partida. -Digite o nome da região na caixa 'Ponto de partida' ou selecione 'Última localização' ou 'Meu inÃcio' como ponto de partida. + Sua região de partida não está definida. +Digite o nome da região na caixa 'Ponto de partida' ou selecione 'Meu último local' ou 'Minha casa' como ponto de partida. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CouldNotStartStopScript"> @@ -468,6 +501,15 @@ Consultar [_URL] para mais informações? </url> <usetemplate ignoretext="O hardware do meu computador não é suportado" name="okcancelignore" notext="Não" yestext="Sim"/> </notification> + <notification name="IntelOldDriver"> + Provavelmente, há um driver mais recente para o seu chip gráfico. A atualização dos drivers gráficos pode melhorar significativamente o desempenho. + + Visitar [_URL] para verificar se há atualizações do driver? + <url name="url"> + http://www.intel.com/p/pt_BR/support/detect/graphics + </url> + <usetemplate ignoretext="Meu driver gráfico está desatualizado" name="okcancelignore" notext="Não" yestext="Sim"/> + </notification> <notification name="UnknownGPU"> A placa de vÃdeo do seu sistema não é reconhecida pelo [APP_NAME]. Isto acontece quando novos hardwares que ainda não foram testados no [APP_NAME]. Talvez isso não cause problemas, mas pode ser preciso checar as configurações de vÃdeo. @@ -564,6 +606,9 @@ Você pode unir um máximo de [MAX] objetos. Por favor, certifique-se de que nenhum deles está travado e que você é dono de todos eles. </notification> + <notification name="CannotLinkPermanent"> + Os objetos não podem ser vinculados através de demarcações de região. + </notification> <notification name="CannotLinkDifferentOwners"> Impossibilitado de unir porque nem todos os objetos são do mesmo dono. @@ -643,7 +688,7 @@ Esperada [VALIDS] Incapaz de criar arquivo de saÃda: [FILE] </notification> <notification name="DoNotSupportBulkAnimationUpload"> - O [APP_NAME] ainda não faz o upload de vários arquivos de animação de uma vez. + O [APP_NAME] ainda não faz o upload de vários arquivos de animação no formato BVH de uma vez. </notification> <notification name="CannotUploadReason"> Incapaz de carregar [FILE] devido ao seguinte motivo: [REASON] @@ -942,6 +987,41 @@ Oferecer amizade para [NAME]? <button name="Cancel" text="Cancelar"/> </form> </notification> + <notification label="Adicionar lista de substituição automática" name="AddAutoReplaceList"> + Nome para a nova lista: + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="Renomear lista de substituição automática" name="RenameAutoReplaceList"> + O nome '[DUPNAME]' já está em uso + Insira um novo nome exclusivo: + <form name="form"> + <button name="ReplaceList" text="Substituir lista atual"/> + <button name="SetName" text="Usar novo nome"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + A palavra-chave deve ser uma palavra única e a substituição não pode estar vazia. + </notification> + <notification name="InvalidAutoReplaceList"> + A lista de substituição é inválida. + </notification> + <notification name="SpellingDictImportRequired"> + Você deve especificar um arquivo, um nome e um idioma. + </notification> + <notification name="SpellingDictIsSecondary"> + O dicionário [DIC_NAME] não aparenta ter um arquivo "aff"; isso significa que ele é um dicionário "secundário". +Ele pode ser usado como dicionário adicional mas não como dicionário Principal. + +Consulte https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + ImpossÃvel copiar + [FROM_NAME] + para + [TO_NAME] + </notification> <notification label="Salvar este look" name="SaveOutfitAs"> Veja o meu novo visual: <form name="form"> @@ -973,7 +1053,7 @@ Oferecer amizade para [NAME]? </form> </notification> <notification name="RemoveFromFriends"> - Remover [NAME] da sua lista de amigos? + Deseja remover <nolink>[NAME]</nolink> da sua lista de amigos? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Remover"/> </notification> <notification name="RemoveMultipleFromFriends"> @@ -1099,8 +1179,13 @@ Doar este terreno de [AREA] m² para o grupo '[GROUP_NAME]'? <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 '[LAST_GPU]' +para '[THIS_GPU]' + </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] @@ -1111,7 +1196,7 @@ Doar este terreno de [AREA] m² para o grupo '[GROUP_NAME]'? Você chegou a uma região próxima. </notification> <notification name="AvatarMovedLast"> - Esse destino não está disponÃvel no momento. + O destino solicitado não está disponÃvel no momento. Você chegou a uma região próxima. </notification> <notification name="AvatarMovedHome"> @@ -1127,11 +1212,10 @@ Enquando isso, use o [SECOND_LIFE] normalmente. Seu visual será exibido correta </form> </notification> <notification name="FirstRun"> - A instalação do [APP_NAME] está pronta. + A instalação do [APP_NAME] está pronta. -Se você ainda não conhece o [SECOND_LIFE], basta criar uma conta para começar. -Voltar para [http://join.secondlife.com secondlife.com] para criar sua conta? - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Nova conta.."/> +Se você ainda não conhece o [SECOND_LIFE], basta criar uma conta para começar. + <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Criar conta"/> </notification> <notification name="LoginPacketNeverReceived"> Estamos detectando um problema de conexão. Pode haver um problema com a sua conexão à internet ou com o [SECOND_LIFE_GRID]. @@ -1419,8 +1503,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]. -Sair do grupo? + Você é atualmente um membro do grupo <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Sair"/> </notification> <notification name="ConfirmKick"> @@ -1648,83 +1731,128 @@ Isto mudará milhares de regiões e fará o spaceserver soluçar. <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Mudar"/> </notification> <notification name="RegionEntryAccessBlocked"> - Você não é permitido na Região devido à sua Classificação de maturidade. Isto pode ser o resultado da falta de informação de validação de sua idade. - -Por favor, verifique se você está com o último Visualizador instalado e vá ao Banco de Conhecimento para detalhes em como acessar áreas com esta classificação de maturidade. + A região que você está tentando visitar tem conteúdo que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu > Preferências > Geral. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - Você não é permitido nesta região devido à sua Classificação de maturidade. - -Ir para o Banco de Conhecimento para maiores informações sobre Classificações de maturidade? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], acessÃvel apenas para adultos. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/pt + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Não posso entrar nessa região devido à classificação do conteúdo" name="okcancelignore" notext="Fechar" yestext="Ir para o Banco de Conhecimento"/> + <usetemplate ignoretext="Passagem de região: A região que você está tentando visitar tem conteúdo acessÃvel apenas para adultos." name="okcancelignore" notext="Fechar" yestext="Ir para a Base de Conhecimento"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - Você não é permitido nesta região devido à sua Classificação de maturidade. + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], acessÃvel apenas para adultos. </notification> <notification name="RegionEntryAccessBlocked_Change"> - Você não pode entrar nessa região devido à sua seleção de maturidade. - -Para entrar na região desejada, mude o nÃvel de maturidade. Você então poderá fazer buscas e acessar conteúdo [REGIONMATURITY]. Para desfazer qualquer mudança, vá para Eu > Preferências > Geral. + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências ou você pode cancelar. Após a alteração de suas preferências, você pode tentar acessar a região novamente. <form name="form"> - <button name="OK" text="Mudar preferência"/> - <button default="true" name="Cancel" text="Fechar"/> - <ignore name="ignore" text="Minha preferência de maturidade impede que eu vá a uma região"/> + <button name="OK" text="Mudar preferências"/> + <button default="true" name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Passagem de região: A região que você está tentando visitar tem conteúdo excluÃdo por suas preferências."/> + </form> + </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + Estamos tendo dificuldades técnicas com seu teletransporte, pois suas preferências estão dessincronizadas com o servidor. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + A região que você está tentando visitar tem conteúdo que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu > Preferências > Geral. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], acessÃvel apenas para adultos. + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="Teletransportar: A região que você está tentando visitar tem conteúdo acessÃvel apenas para adultos." name="okcancelignore" notext="Fechar" yestext="Ir para a Base de Conhecimento"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], acessÃvel apenas para adultos. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências e continuar o teletransporte, ou você pode cancelar este teletransporte. + <form name="form"> + <button name="OK" text="Alterar e continuar"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Teletransportar (reinicializável): A região que você está tentando visitar tem conteúdo excluÃdo por suas preferências."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências ou você pode cancelar o teletransporte. Após a alteração de suas preferências, você pode tentar se teletransportar novamente. + <form name="form"> + <button name="OK" text="Mudar preferências"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Teletransportar (não reinicializável): A região que você está tentando visitar tem conteúdo excluÃdo por suas preferências."/> </form> </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + Estamos tendo dificuldades técnicas com seu teletransporte, pois suas preferências estão dessincronizadas com o servidor. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - Sua opção de nÃvel de maturidade é [RATING]. + Você não receberá mais notificações de que está prestes a visitar uma região com conteúdo [RATING]. Posteriormente você poderá alterar suas preferências de conteúdo acessando Eu > Preferências > Geral da barra do menu. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + ImpossÃvel alterar suas preferências para visualizar conteúdo [PREFERRED_MATURITY] no momento. Suas preferências foram redefinidas para visualizar conteúdo [ACTUAL_MATURITY]. Você pode tentar alterar suas preferências novamente acessando Eu > Preferências > Geral na barra do menu. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - Você não pode reclamar esta terra devido à sua Classificação de maturidade. Isto pode ser o resultado de falta de informação na validação de sua idade. - -Por favor, verifique se você tem o último Visualizador instalado e vá para o Banco de Conhecimento para detalhes sobre o acesso de áreas com esta Classificação de maturidade. + O terreno que você está tentando reivindicar possui uma classificação de maturidade que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu > Preferências > Geral. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - Você não pode reclamar esta terra devido à sua Classificação de maturidade. - -Ir para a o Banco de Conhecimento para maiores informações sobre Classificações de maturidade? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + Apenas adultos podem reivindicar este terreno. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/pt + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Não reivindicar essa região devido à classificação do conteúdo" name="okcancelignore" notext="Fechar" yestext="Ir para o Banco de Conhecimento"/> + <usetemplate ignoretext="Apenas adultos podem reivindicar este terreno." name="okcancelignore" notext="Fechar" yestext="Ir para a Base de Conhecimento"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - Você não pode reclamar esta terra devido à sua Classificação de maturidade. + O terreno que você está tentando reivindicar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + O terreno que você está tentando reivindicar tem conteúdo [REGIONMATURITY], que é acessÃvel apenas para adultos. </notification> <notification name="LandClaimAccessBlocked_Change"> - Você não pode reivindicar essa região devido à sua preferência de maturidade - -Clique em 'Mudar preferência' para aumentar o nÃvel de maturidade e entrar nessa região. De agora em diante você pode buscar e acessar conteúdo [REGIONMATURITY] . Para modificar esta configuração, vá à Eu > Preferências > Geral. - <usetemplate ignoretext="Minha preferência de conteúdo impede que eu reivindique terrenos" name="okcancelignore" notext="Fechar" yestext="Mudar Preferência"/> + O terreno que você está tentando reivindicar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências e, então, você poderá tentar reivindicar a região novamente. + <form name="form"> + <button name="OK" text="Mudar preferências"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="O terreno que você está tentando reivindicar tem conteúdo excluÃdo por suas preferências."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - Você não pode comprar esta terra devido à sua Classificação de maturidade. Isto pode ser o resultado de falta de informação na validação de sua idade. - -Por favor, verifique se você tem o último Visualizador instalado e vá para o Banco de Conhecimento para detalhes sobre o acesso de áreas com esta Classificação de maturidade. + O terreno que você está tentando comprar possui uma classificação de maturidade que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu > Preferências > Geral. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - Você não pode comprar esta terra devido à sua Classificação de maturidade. - -Ir para o Banco de Conhecimento para maiores informações sobre Classificações de Maturidade? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Apenas adultos podem comprar este terreno. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/pt + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Não posso comprar essa região devido à classificação do conteúdo" name="okcancelignore" notext="Fechar" yestext="Ir para o Banco de Conhecimento"/> + <usetemplate ignoretext="Apenas adultos podem comprar este terreno." name="okcancelignore" notext="Fechar" yestext="Ir para a Base de Conhecimento"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - Você não pode comprar esta terra devido à sua Classificação de maturidade. + O terreno que você está tentando comprar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], que é acessÃvel apenas para adultos. </notification> <notification name="LandBuyAccessBlocked_Change"> - Você não pode comprar esse terreno devido à sua preferência de maturidade - -Clique em 'Mudar preferência' para aumentar o nÃvel de maturidade e entrar nessa região. De agora em diante você pode buscar e acessar conteúdo [REGIONMATURITY] . Para modificar esta configuração, vá à Eu > Preferências > Geral. - <usetemplate ignoretext="Minha preferência de conteúdo não me deixa comprar terrenos" name="okcancelignore" notext="Fechar" yestext="Mudar Preferência"/> + O terreno que você está tentando comprar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências e, então, você poderá tentar comprar a região novamente. + <form name="form"> + <button name="OK" text="Mudar preferências"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="O terreno que você está tentando comprar tem conteúdo excluÃdo por suas preferências."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Muitos prims foram selecionados. Selecione [MAX_PRIM_COUNT] ou menos prims, e tente de novo @@ -1779,10 +1907,9 @@ Publicar este classificado agora por L$ [AMOUNT]? </form> </notification> <notification label="Modificar a maturidade da Região" name="RegionMaturityChange"> - O conteúdo desta região foi reclassificado. -Talvez leve algum tempo para a mudança ser refletida no mapa. - -Para ir a regiões de conteúdo Adulto, é preciso ter uma conta verificada, seja comprovando a idade ou com dados de pagamento. + A classificação de maturidade desta região foi alterada. +Talvez leve algum tempo para que esta mudança seja refletida no mapa. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="Discordância de Versão de Voz" name="VoiceVersionMismatch"> Esta versão do [APP_NAME] não é compatÃvel com o recurso 'Bate-papo de voz' desta região. Para o bate-papo de voz funcionar, atualize o [APP_NAME]. @@ -1900,7 +2027,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"/> @@ -2066,14 +2199,11 @@ Inclua um link para facilitar o acesso para visitantes. Teste o link na barra de <usetemplate ignoretext="Vestir as roupas que eu criar enquanto edito minha aparência" name="okcancelignore" notext="Não" yestext="Sim"/> </notification> <notification name="NotAgeVerified"> - Você deve ter no mÃnimo 18 anos para acessar conteúdo e áreas adultas no Second Life. Visite nossa página de verificação de idade para confirmar que você tem mais de 18 anos. -Isso abrirá o seu navegador. - -[_URL] - <url name="url" option="0"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="Ainda não comprovei minha idade" name="okcancelignore" notext="Cancelar" yestext="Ir para verificação de idade"/> + O local que você está tentando visitar é restrito a residentes com 18 anos ou mais. + <usetemplate ignoretext="Não tenho idade suficiente para visitar áreas com restrição de idade." name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + Localização restrita para 18 anos de idade ou mais. </notification> <notification name="Cannot enter parcel: no payment info on file"> Ãrea restrita a residentes que já cadastraram seus dados de pagamento Deseja ir ao site do [SECOND_LIFE] para cuidar disso? @@ -2109,10 +2239,10 @@ Isso abrirá o seu navegador. Assunto: [SUBJECT], Mensagem: [MESSAGE] </notification> <notification name="FriendOnline"> - [NAME] está online + <nolink>[NAME]</nolink> está online </notification> <notification name="FriendOffline"> - [NAME] está offline + <nolink>[NAME]</nolink> está offline </notification> <notification name="AddSelfFriend"> Você é o máximo! Mesmo assim, não dá para adicionar a si mesmo(a) como amigo(a). @@ -2225,14 +2355,16 @@ Selecione só um objeto. Seu cartão de visita foi negado. </notification> <notification name="TeleportToLandmark"> - Para se teletransportar para lugares como '[NAME]', abra o painel 'Lugares' à direita da tela e selecione a guia Marcos. -Basta clicar em qualquer marco e depois clicar em 'Teletransportar' 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 'Teletransportar'.) + Para se teletransportar para locais como '[NAME]', clique no botão "Lugares", + e selecione a guia Marcos na janela que é exibida. Clique em qualquer + marco para selecioná-lo e em seguida em 'Teletransportar' 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 'Teletransportar'.) </notification> <notification name="TeleportToPerson"> - Para entrar em contato com residentes como ''[NAME]', abra o painel 'Pessoas' à direita da tela. -Selecione o residente da lista e clique em 'MI' 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 'MI'.) + Para entrar em contato com residentes como '[NAME]', clique no botão "Pessoas", selecione um residente na janela que é exibida e clique em 'MI' 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 'MI'.) </notification> <notification name="CantSelectLandFromMultipleRegions"> ImpossÃvel selecionar terra nas fronteiras do servidor. Tente selecionar um pedaço menor de terra. @@ -2252,6 +2384,9 @@ Selecione o residente da lista e clique em 'MI' na parte de baixo do p <notification name="PaymentSent"> [MESSAGE] </notification> + <notification name="PaymentFailure"> + [MESSAGE] + </notification> <notification name="EventNotification"> Notificação de evento: @@ -2326,6 +2461,23 @@ Logo, não é possÃvel voar aqui. <notification name="NoBuild"> Esta área desativou a opção de construir. Não é possÃvel construir ou fazer rez de objetos nesta área. </notification> + <notification name="PathfindingDirty"> + A região possui alterações de pathfinding pendentes. Se você possui direitos de construção, poderá recarregar a região clicando no botão “Recarregar regiãoâ€. + </notification> + <notification name="DynamicPathfindingDisabled"> + O pathfinding dinâmico não está habilitado nesta região. Os objetos com script usando chamadas LSL de pathfinding podem não operar como o esperado na região. + </notification> + <notification name="PathfindingRebakeNavmesh"> + A alteração de determinados objetos nesta região pode resultar no comportamento incorreto de outros objeto em movimento. Para fazer com que os objetos em movimento se comportem corretamente, clique no botão “Recarregar regiãoâ€. Escolha “Ajuda†para obter mais informações. + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Ajuda" ignoretext="A alteração de determinados objetos nesta região pode resultar no comportamento incorreto de outros objeto em movimento." name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Erro. Pode haver um erro de rede ou do servidor, ou você pode não ter direitos de construção. Às vezes, fazer login e logout novamente resolve este problema. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> Este terreno oculta os avatares e bate-papo de outro terreno. Não é possÃvel ver residentes fora do terreno e vice-versa. O bate-papo por texto no canal 0 também está bloqueado. </notification> @@ -2344,9 +2496,7 @@ Os únicos scripts que funcionam são os do proprietário do terreno. Você só pode reivindicar terrenos públicos na região onde você está. </notification> <notification name="RegionTPAccessBlocked"> - Você não é permitido na Região devido à sua Classificação de maturidade. Você precisa validar sua idade e/ou instalar o último Visualizador. - -Por favor, vá ao Banco de Conhecimento para detalhes sobre o acesso de áreas com esta Classificação de maturidade. + A região que você está tentando visitar tem conteúdo que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu > Preferências > Geral. </notification> <notification name="URBannedFromRegion"> Você está banido da região. @@ -2357,8 +2507,11 @@ Por favor, vá ao Banco de Conhecimento para detalhes sobre o acesso de áreas c <notification name="ImproperPaymentStatus"> Você não tem o status de pagamento adequado para entrar nesta região. </notification> + <notification name="MustGetAgeRegion"> + Você deve ter 18 anos ou mais para acessar esta região. + </notification> <notification name="MustGetAgeParcel"> - Você precisa ter a idade verificada para entrar neste lote. + Você deve ter 18 anos ou mais para acessar este lote. </notification> <notification name="NoDestRegion"> Nenhuma região de destino encontrada. @@ -2460,12 +2613,33 @@ Por favor, tente novamente em alguns instantes. <notification name="TeleportOffered"> [NAME_SLURL] quer teletransportar você para a região deles: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="Teletransporte"/> <button name="Cancel" text="Cancelar"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] quer teletransportar você para a região deles: + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +A região tem conteúdo [REGION_CONTENT_MATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGION_CONTENT_MATURITY]. Podemos alterar suas preferências e continuar o teletransporte, ou você pode cancelar este teletransporte. + <form name="form"> + <button name="Teleport" text="Alterar e continuar"/> + <button name="Cancel" text="Cancelar"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] quer teletransportar você para a região deles: + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +No entanto, esta região tem conteúdo acessÃvel apenas para adultos. + </notification> <notification name="TeleportOfferSent"> Oferta de teletransporte enviada para [TO_NAME] </notification> @@ -2501,10 +2675,10 @@ Cada um pode ver o status do outro (definição padrão). </form> </notification> <notification name="FriendshipAccepted"> - [NAME] aceitou seu convite de amizade. + <nolink>[NAME]</nolink> aceitou sua oferta de amizade. </notification> <notification name="FriendshipDeclined"> - [NAME] recusou seu convite de amizade + <nolink>[NAME]</nolink> rejeitou sua oferta de amizade. </notification> <notification name="FriendshipAcceptedByMe"> Oferta de amizada aceita. @@ -2560,32 +2734,28 @@ OK? </form> </notification> <notification name="ScriptQuestionCaution"> - Um objeto chamado '<nolink>[OBJECTNAME]</nolink>'', de '[NAME]', gostaria de: - -[QUESTIONS] -Se você não confia nos objetos deste autor, recuse-o. - -Deseja aceitar? + Aviso: O objeto '<nolink>[OBJECTNAME]</nolink>' deseja obter acesso total à sua conta de dólares Linden. Se você conceder acesso, ele poderá remover fundos de sua conta a qualquer momento ou esvaziar sua conta completamente, continuamente e sem avisos adicionais. + +Esse tipo de pedido raramente é legÃtimo. Não conceda acesso se você não entender completamente por que ele deseja acessar sua conta. <form name="form"> - <button name="Grant" text="Autorizar"/> + <button name="Grant" text="Permitir acesso total"/> <button name="Deny" text="Negar"/> - <button name="Details" text="Detalhes..."/> </form> </notification> <notification name="ScriptDialog"> '<nolink>[TITLE]</nolink>' de [NAME] [MESSAGE] <form name="form"> - <button name="Mute" text="Bloquear"/> - <button name="Ignore" text="Ignorar"/> + <button name="Client_Side_Mute" text="Bloquear"/> + <button name="Client_Side_Ignore" text="Ignorar"/> </form> </notification> <notification name="ScriptDialogGroup"> <nolink>[TITLE]</nolink>' de [GROUPNAME]' [MESSAGE] <form name="form"> - <button name="Mute" text="Bloquear"/> - <button name="Ignore" text="Ignorar"/> + <button name="Client_Side_Mute" text="Bloquear"/> + <button name="Client_Side_Ignore" text="Ignorar"/> </form> </notification> <notification name="BuyLindenDollarSuccess"> @@ -2783,6 +2953,12 @@ Com os seguintes residentes: [RESIDENTS] <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> + <notification name="ShareFolderConfirmation"> + Apenas uma pasta pode ser compartilhada por vez. + +Tem certeza de que quer compartilhar os itens abaixo? + <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> + </notification> <notification name="ItemsShared"> Itens compartilhados. </notification> @@ -2861,6 +3037,10 @@ Você carregou uma textura com [RESOLUTION] para o(a) '[BODYREGION]' e ( [EXISTENCE] segundos de vida ) Você carregou uma textura com [RESOLUTION] para o(a) '[BODYREGION]' em [TIME] segundos. </notification> + <notification name="LivePreviewUnavailable"> + Não podemos exibir uma visualização desta textura, pois ela é cópia proibida e/ou transferência proibida. + <usetemplate ignoretext="Avise-me quando o modo Visualização em Tempo Real estiver indisponÃvel para texturas de cópia proibida e/ou transferência proibida" name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> Tem certeza de que quer sair desta ligação? <usetemplate ignoretext="Confirmar antes de deixar ligação" name="okcancelignore" notext="Não" yestext="Sim"/> @@ -3030,6 +3210,62 @@ Se o botão Falar for ocultado, o recurso de voz será desabilitado. Essa ação irá ocultar todos os itens de menu e botões. Para trazê-los de volta, clique em [SHORTCUT] novamente. <usetemplate ignoretext="Confirmar antes de ocultar interface" name="okcancelignore" notext="Cancelar" yestext="OK"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + Alguns linksets selecionados terão suas sinalizações fantasmas alternadas. + +Deseja continuar? + <usetemplate ignoretext="Algumas sinalizações fantasmas dos linksets selecionados serão alternadas." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Algumas sinalizações fantasmas dos linksets selecionados não podem ser definidas como '[REQUESTED_TYPE]' devido à s restrições de permissão no linkset. Ao invés disso, estes linksets serão definidos como '[RESTRICTED_TYPE]'. + +Deseja continuar? + <usetemplate ignoretext="Alguns linksets selecionados não podem ser definidos devido à s restrições de permissão no linkset." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Alguns linksets selecionados não podem ser definidos como '[REQUESTED_TYPE]', pois a forma não é convexa. + +Deseja continuar? + <usetemplate ignoretext="Alguns linksets selecionados não podem ser definidos, pois a forma não é convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + Alguns linksets selecionados terão suas sinalizações fantasmas alternadas. + +Algumas sinalizações fantasmas dos linksets selecionados não podem ser definidas como '[REQUESTED_TYPE]' devido à s restrições de permissão no linkset. Ao invés disso, estes linksets serão definidos como '[RESTRICTED_TYPE]'. + +Deseja continuar? + <usetemplate ignoretext="Algumas sinalizações fantasmas dos linksets selecionados serão alternadas e outras não poderão ser definidas devido à s restrições de permissão no linkset." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + Alguns linksets selecionados terão suas sinalizações fantasmas alternadas. + +Alguns linksets selecionados não podem ser definidos como '[REQUESTED_TYPE]', pois a forma não é convexa. + +Deseja continuar? + <usetemplate ignoretext="Algumas sinalizações fantasmas dos linksets selecionados serão alternadas e outros não podem ser definidas, pois a forma não é convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Algumas sinalizações fantasmas dos linksets selecionados não podem ser definidas como '[REQUESTED_TYPE]' devido à s restrições de permissão no linkset. Ao invés disso, estes linksets serão definidos como '[RESTRICTED_TYPE]'. + +Alguns linksets selecionados não podem ser definidos como '[REQUESTED_TYPE]', pois a forma não é convexa. Estes tipos de uso de linksets não mudarão. + +Deseja continuar? + <usetemplate ignoretext="Alguns linksets selecionados não podem ser definidos devido à s restrições de permissão no linkset e porque a forma não é convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + Alguns linksets selecionados terão suas sinalizações fantasmas alternadas. + +Algumas sinalizações fantasmas dos linksets selecionados não podem ser definidas como '[REQUESTED_TYPE]' devido à s restrições de permissão no linkset. Ao invés disso, estes linksets serão definidos como '[RESTRICTED_TYPE]'. + +Alguns linksets selecionados não podem ser definidos como '[REQUESTED_TYPE]', pois a forma não é convexa. Estes tipos de uso de linksets não mudarão. + +Deseja continuar? + <usetemplate ignoretext="Algumas sinalizações fantasmas dos linksets selecionados serão alternadas e outras não poderão ser definidas, pois a forma não é convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + O objeto selecionado afeta o navmesh. Alterá-lo para um Caminho FlexÃvel irá removê-lo do navmesh. + <usetemplate ignoretext="O objeto selecionado afeta o navmesh. Alterá-lo para um Caminho FlexÃvel irá removê-lo do navmesh." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> <global name="UnsupportedGLRequirements"> Aparentemente a sua máquina não atende os requisitos de hardware do [APP_NAME]. [APP_NAME] requer placas de vÃdeo OpenGL com suporte a multitexturas. Se sua place de vÃdeo tiver este perfil, atualize o driver da placa de vÃdeo, assim como patches e service packs do sistema operacional. @@ -3054,4 +3290,24 @@ Outra opção é procurar por lugares com a tag 'Infohub' no mapa. <global name="You died and have been teleported to your home location"> Você morreu e foi reenviado ao seu inÃcio. </global> + <notification name="LocalBitmapsUpdateFileNotFound"> + Não foi possÃvel atualizar [FNAME], pois o arquivo não pôde ser encontrado. +Desabilitando atualizações futuras deste arquivo. + </notification> + <notification name="LocalBitmapsUpdateFailedFinal"> + [FNAME] não pode ser aberto ou decodificado em [NRETRIES] tentativas, e agora é considerado corrompido. +Desabilitando atualizações futuras deste arquivo. + </notification> + <notification name="LocalBitmapsVerifyFail"> + Tentativa de adição de um formato de imagem inválido ou ilegÃvel [FNAME] que não pode ser aberto ou decodificado. +Tentativa cancelada. + </notification> + <notification name="PathfindingReturnMultipleItems"> + Você está devolvendo [NUM_ITEMS] itens. Tem certeza de que deseja continuar? + <usetemplate ignoretext="Tem certeza de que deseja devolver múltiplos itens?" name="okcancelignore" notext="Não" yestext="Sim"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + Você está excluindo [NUM_ITEMS] itens. Tem certeza de que deseja continuar? + <usetemplate ignoretext="Tem certeza de que deseja excluir múltiplos itens?" name="okcancelignore" notext="Não" yestext="Sim"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/pt/panel_bottomtray.xml b/indra/newview/skins/default/xui/pt/panel_bottomtray.xml deleted file mode 100644 index cb517f643c..0000000000 --- a/indra/newview/skins/default/xui/pt/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Liga e desliga o microfone"/> - <string name="VoiceControlBtnToolTip" value="Mostra/oculta os controles de voz"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Falar" label_selected="Falar" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="Gesto" name="Gesture" tool_tip="Mostra/oculta os gestos"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Movimentar" name="movement_btn" tool_tip="Mostra/oculta os controles de movimento"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Exibir" name="camera_btn" tool_tip="Mostra/oculta os controles da câmera"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button label="" name="snapshots" tool_tip="Tirar foto"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="Construir" name="build_btn" tool_tip="Mostra/oculta ferramentas de Construção"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="Busca" name="search_btn" tool_tip="Mostra/oculta os gestos"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Mapa" name="world_map_btn" tool_tip="Mostra/oculta o Mapa Múndi"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Mini Mapa" name="mini_map_btn" tool_tip="Mostra/oculta o Mini Mapa"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Conversas"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="Notificações"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> 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_group_invite.xml b/indra/newview/skins/default/xui/pt/panel_group_invite.xml index c7def0ed96..de057481de 100644 --- a/indra/newview/skins/default/xui/pt/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/pt/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> Alguns dos residentes selecionados já estão no grupo, portanto não receberam convite. </panel.string> + <panel.string name="invite_selection_too_large"> + Os convites para o grupo não foram enviados: muitos residentes selecionados. Os convites para o grupo são limitados a 100 por solicitação. + </panel.string> <text name="help_text" width="214"> Selecione um ou mais residentes para convidar. Clique em 'Abrir seletor de residentes' para começar. </text> diff --git a/indra/newview/skins/default/xui/pt/panel_login.xml b/indra/newview/skins/default/xui/pt/panel_login.xml index f4af6a7108..d7e9fa76ea 100644 --- a/indra/newview/skins/default/xui/pt/panel_login.xml +++ b/indra/newview/skins/default/xui/pt/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php?lang=pt </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + LOGIN + </text> <text name="username_text"> Nome de usuário: </text> @@ -15,33 +15,32 @@ <text name="password_text"> Senha: </text> - <check_box label="Lembrar senha" name="remember_check"/> - <button label="conectar" name="connect_btn"/> - <text name="mode_selection_text"> - Modo: - </text> - <combo_box name="mode_combo" tool_tip="Selecione o modo. O modo Básico é mais rápido e ideal para explorar e conversar. Use o modo Avançado para acessar mais recursos."> - <combo_box.item label="Básico" name="Basic"/> - <combo_box.item label="Avançado" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Começar em: </text> <combo_box name="start_location_combo"> <combo_box.item label="Última posição" name="MyLastLocation"/> - <combo_box.item label="Meu inÃcio" name="MyHome"/> + <combo_box.item label="Minha casa" name="MyHome"/> + <combo_box.item label="<Digite o nome da região>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Cadastre-se + <layout_panel name="links_login_panel"> + <text name="login_help"> + Precisa de ajuda com o login? </text> <text name="forgot_password_text"> Esqueceu seu nome ou senha? </text> - <text name="login_help"> - Precisa de ajuda ao conectar? + <button label="Login" name="connect_btn"/> + <check_box label="Lembrar senha" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + CRIE SUA CONTA </text> + <button label="Comece agora" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_my_profile.xml b/indra/newview/skins/default/xui/pt/panel_my_profile.xml deleted file mode 100644 index aa15a2445d..0000000000 --- a/indra/newview/skins/default/xui/pt/panel_my_profile.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Perfil" name="panel_profile"> - <string name="no_partner_text" value="Nenhum"/> - <string name="no_group_text" value="Nenhum"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="scroll_content_panel"> - <panel name="second_life_image_panel"> - <text name="display_name_descr_text"> - Nome de usuário - </text> - <text name="name_descr_text"> - Nome de tela - </text> - <button label="Perfil" name="see_profile_btn" tool_tip="Ver o perfil deste avatar"/> - </panel> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_nearby_chat.xml b/indra/newview/skins/default/xui/pt/panel_nearby_chat.xml index 15470dc94a..6828d41dee 100644 --- a/indra/newview/skins/default/xui/pt/panel_nearby_chat.xml +++ b/indra/newview/skins/default/xui/pt/panel_nearby_chat.xml @@ -1,4 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="nearby_chat"> - <check_box label="Traduzir bate-papo" name="translate_chat_checkbox"/> + <layout_stack name="stack"> + <layout_panel name="translate_chat_checkbox_lp"> + <check_box label="Traduzir bate-papo" name="translate_chat_checkbox"/> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml index 9b993488be..5628a87109 100644 --- a/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="chat_bar"> +<panel name="nearby_chat"> <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/panel_notes.xml b/indra/newview/skins/default/xui/pt/panel_notes.xml deleted file mode 100644 index c15e838b34..0000000000 --- a/indra/newview/skins/default/xui/pt/panel_notes.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Anotações e Privacidade" name="panel_notes"> - <layout_stack name="layout"> - <layout_panel name="notes_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <text name="status_message" value="Minhas anotações privadas:"/> - <text name="status_message2" value="Deixar esta pessoa:"/> - <check_box label="Ver meu status" name="status_check"/> - <check_box label="Ver minha localização no mapa" name="map_check"/> - <check_box label="Pegar, editar ou excluir objetos meus" name="objects_check"/> - </panel> - </scroll_container> - </layout_panel> - <layout_panel name="notes_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Adicionar amigo" name="add_friend" tool_tip="Oferecer amizade ao residente"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="MI" name="im" tool_tip="Abrir sessão de mensagem instantânea"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Ligar" name="call" tool_tip="Ligar para este residente"/> - </layout_panel> - <layout_panel name="show_on_map_btn_lp"> - <button label="Mapa" name="show_on_map_btn" tool_tip="Exibir o residente no mapa"/> - </layout_panel> - <layout_panel name="teleport_btn_lp"> - <button label="Teletransportar" name="teleport" tool_tip="Oferecer teletransporte"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> 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..350d53b81c 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,7 @@ <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="Tradução..." name="ok_btn"/> + <button label="Substituição automática..." name="autoreplace_showgui"/> + <button label="Verificando a ortografia..." name="spellcheck_showgui"/> </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_profile.xml b/indra/newview/skins/default/xui/pt/panel_profile.xml deleted file mode 100644 index 075ef55dee..0000000000 --- a/indra/newview/skins/default/xui/pt/panel_profile.xml +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Perfil" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=pt-BR - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=pt - </string> - <string name="my_account_link_url" value="http://secondlife.com/my/account/index.php?lang=pt-BR"/> - <string name="no_partner_text" value="Ninguém"/> - <string name="no_group_text" value="Nenhum"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <panel name="second_life_image_panel"> - <text name="title_sl_descr_text" value="[SECOND_LIFE]:"/> - </panel> - <panel name="first_life_image_panel"> - <text name="title_rw_descr_text" value="Mundo real:"/> - </panel> - <text name="title_member_text" value="Residente desde:"/> - <text name="title_acc_status_text" value="Conta:"/> - <text name="title_partner_text" value="Parceiro(a):"/> - <panel name="partner_data_panel"> - <text initial_value="(pesquisando)" name="partner_text"/> - </panel> - <text name="title_groups_text" value="Grupos:"/> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> - <layout_stack name="layout_verb_buttons"> - <layout_panel name="profile_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Adicionar amigo" name="add_friend" tool_tip="Oferecer amizade ao residente"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="MI" name="im" tool_tip="Abrir sessão de mensagem instantânea"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Ligar" name="call" tool_tip="Ligar para este residente"/> - </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="Teletransportar" name="teleport" tool_tip="Oferecer teletransporte"/> - </layout_panel> - <layout_panel name="overflow_btn_lp"> - <menu_button label="â–¼" name="overflow_btn" tool_tip="Pagar ou compartilhar inventário com o residente"/> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="profile_me_buttons_panel"> - <button label="Editar perfil" name="edit_profile_btn" tool_tip="Editar dados pessoais"/> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_profile_view.xml b/indra/newview/skins/default/xui/pt/panel_profile_view.xml deleted file mode 100644 index d81ee08e6c..0000000000 --- a/indra/newview/skins/default/xui/pt/panel_profile_view.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_target_profile"> - <string name="status_online"> - Conectado - </string> - <string name="status_offline"> - Desconectado - </string> - <text name="display_name_label" value="Nome de tela:"/> - <text name="solo_username_label" value="Nome de usuário:"/> - <text name="status" value="Conectado"/> - <text name="user_name_small" value="Jack oh look at me this is a super duper long name"/> - <button name="copy_to_clipboard" tool_tip="Copiar para área de transferência"/> - <text name="user_label" value="Nome de usuário:"/> - <tab_container name="tabs"> - <panel label="PERFIL" name="panel_profile"/> - <panel label="DESTAQUES" name="panel_picks"/> - <panel label="ANOTAÇÕES E PRIVACIDADE" name="panel_notes"/> - </tab_container> -</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_region_debug.xml b/indra/newview/skins/default/xui/pt/panel_region_debug.xml index f2cc9f644d..be15d40d74 100644 --- a/indra/newview/skins/default/xui/pt/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/pt/panel_region_debug.xml @@ -36,5 +36,5 @@ <button label="?" left="297" name="top_scripts_help"/> <button label="Reiniciar a região" name="restart_btn" tool_tip="Após 2 minutos de contagem regressiva, reiniciar a região"/> <button label="?" name="restart_help"/> - <button label="Adiar reinÃcio" name="cancel_restart_btn" tool_tip="Adiar o reinÃcio da região por uma hora"/> + <button label="Cancelar reinÃcio" name="cancel_restart_btn" tool_tip="Cancelar reinÃcio da região"/> </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_region_estate.xml b/indra/newview/skins/default/xui/pt/panel_region_estate.xml index e5d394865c..b1453c9c32 100644 --- a/indra/newview/skins/default/xui/pt/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/pt/panel_region_estate.xml @@ -23,10 +23,10 @@ <check_box label="Permitir acesso público" name="externally_visible_check"/> <button label="?" name="externally_visible_help"/> <text name="Only Allow"> - Restringir acesso a contas confirmardas por: + Permitir acesso apenas para residentes que: </text> - <check_box label="Dados de pagamento fornecidos" name="limit_payment" tool_tip="Banir residentes sem identificação."/> - <check_box label="Verificação de idade" name="limit_age_verified" tool_tip="Banir residentes que não comprovaram a idade. Consulte o [SUPPORT_SITE] para saber mais."/> + <check_box label="Dados de pagamento constam no registro." name="limit_payment" tool_tip="Propriedade de acesso restrito a residentes que já cadastraram seus dados de pagamento Consulte o [SUPPORT_SITE] para saber mais."/> + <check_box label="Tem 18 anos ou mais" name="limit_age_verified" tool_tip="Os residentes devem ter 18 anos ou mais para acessar esta propriedade. Consulte o [SUPPORT_SITE] para obter mais informações."/> <check_box label="Permitir conversa de voz" name="voice_chat_check"/> <button label="?" name="voice_chat_help"/> <check_box label="Permitir Tele-transporte direto" name="allow_direct_teleport"/> diff --git a/indra/newview/skins/default/xui/pt/panel_region_texture.xml b/indra/newview/skins/default/xui/pt/panel_region_texture.xml deleted file mode 100644 index 35928ccc67..0000000000 --- a/indra/newview/skins/default/xui/pt/panel_region_texture.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Texturas de Chão" name="Textures"> - <text name="region_text_lbl"> - Região: - </text> - <text name="region_text"> - desconhecido - </text> - <text name="detail_texture_text" width="380"> - Texturas de Terreno (requer 512x512, arquivos 24 bit .tga ) - </text> - <text name="height_text_lbl"> - 1 (baixo) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (alto) - </text> - <text name="height_text_lbl5"> - Escalas de Elevação de Terreno - </text> - <text name="height_text_lbl6"> - Noroeste - </text> - <text name="height_text_lbl7"> - Nordeste - </text> - <text name="height_text_lbl8"> - Sudoeste - </text> - <text name="height_text_lbl9"> - Sudeste - </text> - <spinner label="Baixo" name="height_start_spin_0"/> - <spinner label="Baixo" name="height_start_spin_1"/> - <spinner label="Baixo" name="height_start_spin_2"/> - <spinner label="Baixo" name="height_start_spin_3"/> - <spinner label="Alto" name="height_range_spin_0"/> - <spinner label="Alto" name="height_range_spin_1"/> - <spinner label="Alto" name="height_range_spin_2"/> - <spinner label="Alto" name="height_range_spin_3"/> - <text name="height_text_lbl10"> - Os valores representam o intervalo de mistura das texturas acima. - </text> - <text name="height_text_lbl11"> - Em metros, o valor BAIXO é a altura MÃXIMA da Textura 1, e HIGH é a altura MÃNIMA da Textura 4. - </text> - <text name="height_text_lbl12"> - e o valor Alto é a altura MÃnima da Textura #4. - </text> - <button label="Aplicar" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_script_ed.xml b/indra/newview/skins/default/xui/pt/panel_script_ed.xml index a1acb18cb4..de02aafe2f 100644 --- a/indra/newview/skins/default/xui/pt/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/pt/panel_script_ed.xml @@ -22,6 +22,8 @@ <menu label="Arquivo" name="File"> <menu_item_call label="Salvar" name="Save"/> <menu_item_call label="Reverter todas as alterações" name="Revert All Changes"/> + <menu_item_call label="Carregar do arquivo..." name="LoadFromFile"/> + <menu_item_call label="Salvar para o arquivo..." name="SaveToFile"/> </menu> <menu label="Editar" name="Edit"> <menu_item_call label="desfazer" name="Undo"/> diff --git a/indra/newview/skins/default/xui/pt/panel_script_question_toast.xml b/indra/newview/skins/default/xui/pt/panel_script_question_toast.xml new file mode 100644 index 0000000000..a2d0237da0 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_script_question_toast.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel label="script_question_panel" name="panel_script_question_toast"> + <panel label="buttons_panel" name="buttons_panel"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_side_tray.xml b/indra/newview/skins/default/xui/pt/panel_side_tray.xml deleted file mode 100644 index 1a424fb7f1..0000000000 --- a/indra/newview/skins/default/xui/pt/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Exibir ou não barra lateral" name="sidebar_openclose" tab_title="Exibir ou não barra lateral"/> - <sidetray_tab description="InÃcio" name="sidebar_home" tab_title="InÃcio"> - <panel label="InÃcio" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Edite seu perfil público e destaques." name="sidebar_me" tab_title="Meu perfil"> - <panel_container name="panel_container"> - <panel label="Eu" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Encontre seus amigos, contatos e pessoas nas proximidades." name="sidebar_people" tab_title="Pessoas"> - <panel_container name="panel_container"> - <panel label="Perfil do grupo" name="panel_group_info_sidetray"/> - <panel label="Residentes& Objetos bloqueados" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Encontre lugares para ir e lugares que você ja visitou." label="Lugares" name="sidebar_places" tab_title="Lugares"> - <panel label="Lugares" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="Abra seu inventário." name="sidebar_inventory" tab_title="Meu inventário"> - <panel label="Editar inventário" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Muda sua aparência e seu visual atual." name="sidebar_appearance" tab_title="Minha aparência"> - <panel label="Editar aparência" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> 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..cb9a6eb757 100644 --- a/indra/newview/skins/default/xui/pt/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/pt/panel_status_bar.xml @@ -15,10 +15,10 @@ <panel.string name="buycurrencylabel"> L$ [AMT] </panel.string> - <panel name="balance_bg"> + <panel left="-410" name="balance_bg" width="200"> <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/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/pt/panel_volume_pulldown.xml new file mode 100644 index 0000000000..1dfd2a69ca --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater"> + <slider label="Master" name="System Volume"/> + <slider label="Botões" name="UI Volume"/> + <slider label="Ambiente" name="Wind Volume"/> + <slider label="Sons" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="Ativar sons dos gestos"/> + <slider label="Música" name="Music Volume"/> + <check_box name="enable_music" tool_tip="Ativar streaming de música"/> + <slider label="MÃdia" name="Media Volume"/> + <check_box name="enable_media" tool_tip="Ativar mÃdia em stream"/> + <slider label="Voz" name="Voice Volume"/> + <check_box name="enable_voice_check" tool_tip="Ativar bate-papo de voz"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml b/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml index 77c552a852..7908ea5f3a 100644 --- a/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml @@ -2,47 +2,24 @@ <panel label="Coisas" name="objects panel"> <panel label="" name="sidepanel__inventory_panel"> <layout_stack name="inventory_layout_stack"> - <layout_panel name="inbox_outbox_layout_panel"> - <layout_stack name="inbox_outbox_layout_stack"> - <layout_panel name="inbox_layout_panel"> - <panel label="" name="marketplace_inbox"> - <string name="InboxLabelWithArg"> - Itens recebidos ([NUM]) - </string> - <string name="InboxLabelNoArg"> - Itens recebidos - </string> - <button label="Itens recebidos" name="inbox_btn"/> - <text name="inbox_fresh_new_count"> - [NUM] novo(s) - </text> - <panel tool_tip="Drag and drop items to your inventory to manage and use them"> - <text name="inbox_inventory_placeholder"> - Compras do marketplace serão entregues aqui. - </text> - </panel> - </panel> - </layout_panel> - <layout_panel name="outbox_layout_panel"> - <panel label="" name="marketplace_outbox"> - <string name="OutboxLabelWithArg"> - Caixa de saÃda do lojista ([NUM]) - </string> - <string name="OutboxLabelNoArg"> - Caixa de saÃda do lojista - </string> - <button label="Caixa de saÃda do lojista" name="outbox_btn"/> - <button label="" name="outbox_sync_btn" tool_tip="Enviar para a frente do meu mercado"/> - <panel> - <panel name="outbox_inventory_placeholder_panel"> - <text name="outbox_inventory_placeholder_title"> - Carregando... - </text> - </panel> - </panel> - </panel> - </layout_panel> - </layout_stack> + <layout_panel name="inbox_layout_panel"> + <panel label="" name="marketplace_inbox"> + <string name="InboxLabelWithArg"> + Itens recebidos ([NUM]) + </string> + <string name="InboxLabelNoArg"> + Itens recebidos + </string> + <button label="Itens recebidos" name="inbox_btn"/> + <text name="inbox_fresh_new_count"> + [NUM] novo(s) + </text> + <panel name="inbox_inventory_placeholder_panel" tool_tip="Arraste e solte itens para o seu inventário para usá-los"> + <text name="inbox_inventory_placeholder"> + As compras do marketplace serão entregues aqui. + </text> + </panel> + </panel> </layout_panel> </layout_stack> <panel name="button_panel"> diff --git a/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml b/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml index e6370ea830..d3cb087108 100644 --- a/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (desconhecido) </panel.string> + <panel.string name="unknown_multiple"> + (desconhecido / múltiplo) + </panel.string> <panel.string name="public"> (público) </panel.string> diff --git a/indra/newview/skins/default/xui/pt/sidepanel_task_info.xml b/indra/newview/skins/default/xui/pt/sidepanel_task_info.xml index 8092e6c145..3cfe0fe4f4 100644 --- a/indra/newview/skins/default/xui/pt/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/pt/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> Você não pode modificar estes objetos </panel.string> + <panel.string name="text modify info 5"> + Não é possÃvel modificar este objeto através de uma demarcação da região + </panel.string> + <panel.string name="text modify info 6"> + Não é possÃvel modificar estes objetos através de uma demarcação da região + </panel.string> <panel.string name="text modify warning"> O objeto contém links ligando suas partes </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Preço: L$" name="Edit Cost"/> <check_box label="Mostrar nos resultados de busca" name="search_check" tool_tip="Incluir o objeto nos resultados de busca"/> + <text name="pathfinding_attributes_label"> + Atributos do pathfinding: + </text> <text name="B:"> B: </text> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index cc61ad76d7..bc72b86020 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -128,7 +128,7 @@ Sair </string> <string name="create_account_url"> - http://join.secondlife.com/index.php?lang=pt-BR + http://join.secondlife.com/index.php?lang=pt-BR&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> O visualizador utilizado já não é compatÃvel com o Second Life. Visite a página abaixo para baixar uma versão atual: http://secondlife.com/download @@ -157,9 +157,9 @@ Para saber mais, visite as perguntas frequentes abaixo: http://secondlife.com/vi O Second Life está fechado para manutenção no momento. Somente funcionários podem acessá-lo. Consulte www.secondlife.com/status para as últimas atualizações. </string> <string name="LoginFailedPremiumOnly"> - O acesso ao Second Life está sendo restrito por alguns instantes para que todos tenham a melhor experiência possÃvel. - -Titulares de contas gratuitas não poderão acessar o Second Life para acomodar os assinantes do Second Life. + Logons do Second Life estão temporariamente restritos para garantir a melhor experiência possÃvel para os usuários no mundo virtual. + +Pessoas com contas gratuitas não poderão acessar o Second Life no momento para dar espaço para aquelas que pagaram pelo Second Life. </string> <string name="LoginFailedComputerProhibited"> O Second Life não pode ser acessado deste computador. Se você acredita que houve algum equÃvoco, contate support@secondlife.com. @@ -291,17 +291,35 @@ Titulares de contas gratuitas não poderão acessar o Second Life para acomodar Apenas um item único pode ser arrastado para este local </string> <string name="TooltipPrice" value="L$[AMOUNT]"/> + <string name="TooltipOutboxDragToWorld"> + Não é possÃvel fazer rez do itens em sua caixa de saÃda do lojista + </string> <string name="TooltipOutboxNoTransfer"> - Um ou mais objetos não podem ser vendidos ou transferidos para outros usuário. + Um ou mais destes objetos não podem ser vendidos ou transferidos. + </string> + <string name="TooltipOutboxNotInInventory"> + Sua caixa de saÃda do lojista aceita apenas itens direto do seu inventário </string> <string name="TooltipOutboxWorn"> - Você está usando um ou mais desses objetos. Remova-os de seu avatar e tente movê-los novamente. + Você não pode colocar os itens que está vestindo na sua caixa de saÃda do lojista + </string> + <string name="TooltipOutboxCallingCard"> + Não é possÃvel colocar cartões de visita em sua caixa de saÃda do lojista </string> <string name="TooltipOutboxFolderLevels"> - Esta pasta tem muitos nÃveis de subpastas. Reorganize as pastas internas em até 4 nÃveis no máximo (Pasta raiz contém A que contém B que contém C). + A profundidade das pastas aninhadas excede 3 + </string> + <string name="TooltipOutboxTooManyFolders"> + A contagem de subpastas na pasta de nÃvel superior excede 20 </string> <string name="TooltipOutboxTooManyObjects"> - Esta pasta contém mais de 200 objetos. Embale alguns dos itens para reduzir a contagem de objetos. + A contagem de itens na pasta de nÃvel superior excede 200 + </string> + <string name="TooltipDragOntoOwnChild"> + Não é possÃvel mover uma pasta para seu filho + </string> + <string name="TooltipDragOntoSelf"> + Não é possÃvel mover uma pasta para dentro dela mesma </string> <string name="TooltipHttpUrl"> Clique para ver a página web @@ -547,6 +565,9 @@ Titulares de contas gratuitas não poderão acessar o Second Life para acomodar <string name="mesh"> mesh </string> + <string name="AvatarEditingAppearance"> + (Edição Aparência) + </string> <string name="AvatarAway"> Distante </string> @@ -763,6 +784,9 @@ Titulares de contas gratuitas não poderão acessar o Second Life para acomodar <string name="anim_yes_head"> Sim </string> + <string name="multiple_textures"> + Múltiplo + </string> <string name="texture_loading"> Carregando... </string> @@ -811,6 +835,9 @@ Titulares de contas gratuitas não poderão acessar o Second Life para acomodar <string name="ScriptQuestionCautionChatDenied"> '[OBJECTNAME]', um objeto de '[OWNERNAME]', localizado em [REGIONNAME] a [REGIONPOS], teve permissão negada para: [PERMISSIONS]. </string> + <string name="AdditionalPermissionsRequestHeader"> + Se você permitir acesso à sua conta, o objeto também poderá: + </string> <string name="ScriptTakeMoney"> Tomar linden dólares (L$) de você </string> @@ -844,6 +871,9 @@ Titulares de contas gratuitas não poderão acessar o Second Life para acomodar <string name="ControlYourCamera"> Controle sua camera </string> + <string name="TeleportYourAgent"> + Teletransportá-lo + </string> <string name="SIM_ACCESS_PG"> Público geral </string> @@ -919,6 +949,12 @@ Titulares de contas gratuitas não poderão acessar o Second Life para acomodar <string name="choose_the_directory"> Selecionar pasta </string> + <string name="script_files"> + Scripts + </string> + <string name="dictionary_files"> + Dicionários + </string> <string name="AvatarSetNotAway"> deixar como ausente </string> @@ -1157,43 +1193,36 @@ 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. + Suas compras do Marketplace aparecerão aqui. Depois, você poderá arrastá-las para seu inventário para usá-las. </string> <string name="MarketplaceURL"> - http://marketplace.[DOMAIN_NAME] + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ </string> <string name="MarketplaceURL_CreateStore"> - http://marketplace.[DOMAIN_NAME]/create_store + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4 </string> - <string name="MarketplaceURL_LearnMore"> - http://marketplace.[DOMAIN_NAME]/learn_more + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard </string> - <string name="InventoryOutboxCreationErrorTitle"> - Sua Caixa de saÃda do lojista não está configurada corretamente + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports </string> - <string name="InventoryOutboxCreationErrorTooltip"> - Erro de configuração na Caixa de saÃda do lojista - </string> - <string name="InventoryOutboxCreationError"> - Entre em contato com o Atendimento para corrigir o problema. + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more </string> <string name="InventoryOutboxNotMerchantTitle"> - Qualquer um pode vender itens no Mercado - </string> - <string name="InventoryOutboxNotMerchantTooltip"> - Torne-se um lojista! + Qualquer um pode vender itens no Mercado. </string> + <string name="InventoryOutboxNotMerchantTooltip"/> <string name="InventoryOutboxNotMerchant"> - [[MARKETPLACE_URL] O Mercado do Second Life] oferece mais de um milhão de produtos virtuais para venda, todos criados pelos residentes. Você também pode vender os itens que você cria, além de alguns itens que comprou. É fácil e a configuração é gratuita. [[LEARN_MORE_URL] Saiba mais] ou [[CREATE_STORE_URL] crie uma loja] no Mercado para começar. + Se você deseja se tornar um lojista, precisará [[MARKETPLACE_CREATE_STORE_URL] criar uma loja no Mercado]. </string> <string name="InventoryOutboxNoItemsTitle"> - Uma nova maneira de vender os itens no Mercado - </string> - <string name="InventoryOutboxNoItemsTooltip"> - Arraste e solte os itens aqui para prepará-los para venda no Mercado + Sua caixa de saÃda está vazia </string> + <string name="InventoryOutboxNoItemsTooltip"/> <string name="InventoryOutboxNoItems"> - Arraste os itens ou pastas que deseja vender para esta área. Será exibida uma cópia deles, deixando seu inventário inalterado, a menos que você arraste um item que não permita cópia. Quando estiver pronto para enviar os itens para o Mercado, clique no botão Enviar. Quando os itens tiverem sido movidos para seu Inventário de mercado, eles desaparecerão desta pasta. + Arraste as pastas para estas áreas e então clique em "Enviar para Mercado" para listar os itens para venda no [[MARKETPLACE_DASHBOARD_URL] Mercado]. </string> <string name="Marketplace Error None"> Sem erros @@ -1205,7 +1234,7 @@ Titulares de contas gratuitas não poderão acessar o Second Life para acomodar Erro: esta pasta está vazia. </string> <string name="Marketplace Error Unassociated Products"> - Erro: ocorreu uma falha ao enviar este item, pois sua conta de lojista tem muitos itens não associados a produtos. Para corrigir esse erro, faça o login no site do mercado e reduza a contagem de itens não associados. + Erro: ocorreu uma falha ao enviar este item, pois sua conta de lojista tem muitos itens não associados a produtos. Para corrigir esse erro, faça o login no site do mercado e reduza a contagem de itens não associados. </string> <string name="Marketplace Error Object Limit"> Erro: este item contém muitos objetos. Corrija esse erro unindo os objetos em caixa para reduzir a contagem total a menos de 200. @@ -1325,6 +1354,12 @@ Titulares de contas gratuitas não poderão acessar o Second Life para acomodar <string name="InvFolder favorite"> Meus favoritos </string> + <string name="InvFolder Favorites"> + Meus favoritos + </string> + <string name="InvFolder favorites"> + Meus favoritos + </string> <string name="InvFolder Current Outfit"> Look atual </string> @@ -1340,6 +1375,12 @@ Titulares de contas gratuitas não poderão acessar o Second Life para acomodar <string name="InvFolder Meshes"> Meshes: </string> + <string name="InvFolder Received Items"> + Itens recebidos + </string> + <string name="InvFolder Merchant Outbox"> + Caixa de saÃda do lojista + </string> <string name="InvFolder Friends"> Amigos </string> @@ -1349,6 +1390,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> @@ -1475,6 +1519,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> @@ -3705,6 +3755,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="LocationCtrlSeeAVsTooltip"> Avatar visÃveis e bate-papo permitido fora deste terreno </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Os objetos que se movem podem não se comportar corretamente nesta região até que ela seja recarregada. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + O pathfinding dinâmico não está habilitado nesta região. + </string> <string name="UpdaterWindowTitle"> [APP_NAME] Atualização </string> @@ -3771,6 +3827,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Saved_message"> (Salvo em [LONG_TIMESTAMP]) </string> + <string name="IM_unblock_only_groups_friends"> + Para visualizar esta mensagem, você deve desmarcar "Apenas amigos e grupos podem me ligar ou enviar MIs" em Preferências/Privacidade. + </string> <string name="answered_call"> Ligação atendida </string> @@ -3883,16 +3942,28 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. [NAME] lhe pagou L$ [AMOUNT] </string> <string name="you_paid_ldollars"> - You pagou L$[AMOUNT] por [REASON] a [NAME]. + Você pagou L$[AMOUNT] por [REASON] a [NAME]. </string> <string name="you_paid_ldollars_no_info"> Você acaba de pagar L$[AMOUNT]. </string> <string name="you_paid_ldollars_no_reason"> - You pagou L$[AMOUNT] a [NAME]. + Você pagou L$[AMOUNT] a [NAME]. </string> <string name="you_paid_ldollars_no_name"> - You pagou L$[AMOUNT] por [REASON]. + 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] @@ -3947,7 +4018,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. </string> <string name="uploading_abuse_report"> Carregando... - + Denunciar abuso </string> <string name="New Shape"> @@ -4213,10 +4284,10 @@ Denunciar abuso </string> <string name="words_separator" value=","/> <string name="server_is_down"> - Aconteceu algo inesperado, apesar de termos tentador impedir isso. + Aconteceu algo inesperado, apesar de termos tentado impedir isso. - Cheque secondlifegrid.net para saber se foi detectado um problema com o serviço. - Se o problema persisitr, cheque a configuração da sua rede e firewall. + Cheque secondlifegrid.net para saber se foi detectado um problema com o serviço. + Se o problema persistir, cheque a configuração da sua rede e firewall. </string> <string name="dateTimeWeekdaysNames"> Domingo:Segunda:Terça:Quarta:Quinta:Sexta:Sábado @@ -4304,6 +4375,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> @@ -4674,7 +4751,10 @@ Tente colocar o caminho do editor entre aspas. Mini Mapa </string> <string name="Command_Move_Label"> - Mover + Andar/correr/voar + </string> + <string name="Command_Outbox_Label"> + Caixa de saÃda do lojista </string> <string name="Command_People_Label"> Pessoas @@ -4701,10 +4781,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 @@ -4748,6 +4828,9 @@ Tente colocar o caminho do editor entre aspas. <string name="Command_Move_Tooltip"> Movendo seu avatar </string> + <string name="Command_Outbox_Tooltip"> + Transferir itens para o seu mercado para venda + </string> <string name="Command_People_Tooltip"> Amigos, grupos e pessoas próximas </string> @@ -4776,7 +4859,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% @@ -4802,4 +4894,40 @@ Tente colocar o caminho do editor entre aspas. <string name="Normal"> Normal </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Nenhum + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Afeta o navmesh + </string> + <string name="Pathfinding_Object_Attr_Character"> + Personagem + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Múltiplo) + </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> + <string name="TeleportMaturityExceeded"> + O residente não pode visitar a região. + </string> + <string name="UserDictionary"> + [Usuário] + </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..40fb4caebf 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 'Ilha Welcome Pública' para repetir o tutorial. </message> <message name="noaccess_tport"> Desculpe, você não tem acesso ao destino deste teletransporte. @@ -43,6 +43,9 @@ Vá para a Ilha de Welcome Pública para repetir este tutorial. <message name="no_inventory_host"> O sistema de inventário está indisponÃvel no momento. </message> + <message name="MustGetAgeRegion"> + Você deve ter 18 anos ou mais para acessar esta região. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -78,5 +81,8 @@ Vá para a Ilha de Welcome Pública para repetir este tutorial. <message name="requesting"> Solicitando teletransporte... </message> + <message name="pending"> + Teletransporte pendente... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/ru/floater_about.xml b/indra/newview/skins/default/xui/ru/floater_about.xml index deb6be319c..bb6266ac9a 100644 --- a/indra/newview/skins/default/xui/ru/floater_about.xml +++ b/indra/newview/skins/default/xui/ru/floater_about.xml @@ -62,33 +62,34 @@ </panel> <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) + 3Dconnexion SDK (C) 1992-2009 3Dconnexion + APR (C) 2011 The Apache Software Foundation + Collada DOM (C) 2006 Sony Computer Entertainment Inc. + cURL (C) 1996-2010, 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, 2006 David Turner, Robert Wilhelm и Werner Lemberg. + 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) 2002, Xiphophorus + OpenSSL (C) 1998-2008 The OpenSSL Project. + PCRE (c) 1997-2012, КембриджÑкий универÑитет + 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-2012 Jean-loup Gailly и Mark Adler. -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..12691df684 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="Ð—ÐµÐ¼Ð»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть в ÑобÑтвенноÑти, иметь заданное Ñодержимое и не быть выÑтавленной на аукцион,"/> @@ -306,14 +306,13 @@ <panel.string name="push_restrict_region_text"> Ðе толкать (наÑтройки региона) </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 +328,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 +368,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> @@ -447,20 +443,15 @@ <panel.string name="access_estate_defined"> (Определено на землевладении) </panel.string> - <panel.string name="allow_public_access"> - Разрешить общий доÑтуп ([MATURITY]) (СнÑтие приведет к Ñозданию линий запрета) - </panel.string> <panel.string name="estate_override"> ЧаÑть Ñтих параметров уÑтановлена на уровне Ð·ÐµÐ¼Ð»ÐµÐ²Ð»Ð°Ð´ÐµÐ½Ð¸Ñ </panel.string> - <text name="Limit access to this parcel to:"> - ДоÑтуп на Ñтот учаÑток - </text> + <check_box label="Разрешить публичный доÑтуп (ÑнÑтие флажка приведет к Ñозданию линий запрета)" name="public_access"/> <text name="Only Allow"> - Разрешить доÑтуп только жителÑм, у которых: + Разрешить доÑтуп только таким жителÑм: </text> - <check_box label="ЗапиÑана Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± оплате [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Банить нераÑпознанных жителей."/> - <check_box label="Проверка возраÑта [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Банить жителей, не прошедших проверку возраÑта. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/> + <check_box label="ЗарегиÑтрирована Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± оплате [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Ð”Ð»Ñ Ð´Ð¾Ñтупа к Ñтому учаÑтку у Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть зарегиÑтрирована Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± оплате. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/> + <check_box label="18 лет и Ñтарше [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="ДоÑтуп к Ñтому учаÑтку имеют только жители 18 лет и Ñтарше. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/> <check_box label="Разрешить доÑтуп группе: [GROUP]" name="GroupCheck" tool_tip="Группа уÑтанавливаетÑÑ Ð½Ð° оÑновной вкладке."/> <check_box label="Продать доÑтуп:" name="PassCheck" tool_tip="Разрешить временный доÑтуп к учаÑтку."/> <combo_box name="pass_combo"> diff --git a/indra/newview/skins/default/xui/ru/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/ru/floater_animation_anim_preview.xml new file mode 100644 index 0000000000..711afc2717 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_animation_anim_preview.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Anim Preview" title="ANIMATION.ANIM"> + <text name="name_label"> + Ðазвание: + </text> + <text name="description_label"> + ОпиÑание: + </text> + <button label="Передать (L$[AMOUNT])" name="ok_btn"/> + <button label="Отмена" label_selected="Отмена" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_animation_preview.xml b/indra/newview/skins/default/xui/ru/floater_animation_bvh_preview.xml index b7075fbf97..8ad9d8657a 100644 --- a/indra/newview/skins/default/xui/ru/floater_animation_preview.xml +++ b/indra/newview/skins/default/xui/ru/floater_animation_bvh_preview.xml @@ -5,10 +5,12 @@ </floater.string> <floater.string name="anim_too_long"> Длина файла анимации: [LENGTH] Ñ. + МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° анимации: [MAX_LENGTH] Ñ. </floater.string> <floater.string name="failed_file_read"> Ðевозможно прочитать файл анимации. + [STATUS] </floater.string> <floater.string name="E_ST_OK"> @@ -124,7 +126,7 @@ <combo_box.item label="Разведены" name="Spread"/> <combo_box.item label="РаÑÑлаблены" name="Relaxed"/> <combo_box.item label="Указывают" name="PointBoth"/> - <combo_box.item label="Сжаты в кулаки" name="Fist"/> + <combo_box.item label="Сжаты в кулак" name="Fist"/> <combo_box.item label="Левые раÑÑлаблены" name="RelaxedLeft"/> <combo_box.item label="Левые указывают" name="PointLeft"/> <combo_box.item label="Левые в кулак" name="FistLeft"/> @@ -176,6 +178,7 @@ <button name="stop_btn" tool_tip="ОÑтановить проигрывание анимации"/> <text name="bad_animation_text"> Ðевозможно прочитать файл анимации. + РекомендуетÑÑ Ð¸Ñпользовать BVH-файлы, ÑкÑпортированные из Poser 4. </text> <button label="Передать (L$[AMOUNT])" name="ok_btn"/> diff --git a/indra/newview/skins/default/xui/ru/floater_autoreplace.xml b/indra/newview/skins/default/xui/ru/floater_autoreplace.xml new file mode 100644 index 0000000000..6827931e5d --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="ÐаÑтройки автозамены"> + <check_box label="Включить автозамену" name="autoreplace_enable" tool_tip="Ð’ чате по мере ввода текÑта ключевые Ñлова будут заменÑтьÑÑ ÑоответÑтвующими заменителÑми"/> + <button label="Импорт ÑпиÑка..." name="autoreplace_import_list" tool_tip="Загрузить ранее ÑкÑпортированный ÑпиÑок из файла."/> + <button label="ÐкÑпорт ÑпиÑка..." name="autoreplace_export_list" tool_tip="Сохранить выбранный ÑпиÑок в файл Ð´Ð»Ñ Ð¿Ð¾Ñледующего раÑпроÑтранениÑ."/> + <button label="Ðовый ÑпиÑок..." name="autoreplace_new_list" tool_tip="Создать новый ÑпиÑок."/> + <button label="Удалить ÑпиÑок" name="autoreplace_delete_list" tool_tip="Удалить выбранный ÑпиÑок."/> + <button name="autoreplace_list_up" tool_tip="ПовыÑить приоритет ÑпиÑка."/> + <button name="autoreplace_list_down" tool_tip="Понизить приоритет ÑпиÑка."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Ключевое Ñлово" name="keyword"/> + <scroll_list.columns label="Замена" name="replacement"/> + </scroll_list> + <button label="Добавить..." name="autoreplace_add_entry"/> + <button label="Удалить" name="autoreplace_delete_entry"/> + <button label="Сохранить запиÑÑŒ" name="autoreplace_save_entry" tool_tip="Сохранить Ñту запиÑÑŒ."/> + <button label="Сохранить изменениÑ" name="autoreplace_save_changes" tool_tip="Сохранить вÑе изменениÑ."/> + <button label="Отмена" name="autoreplace_cancel" tool_tip="Отменить вÑе изменениÑ."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </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 7a1f530668..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> @@ -9,15 +9,6 @@ <floater.string name="move_tooltip"> ПеремеÑтить камеру вверх, вниз, влево или вправо </floater.string> - <floater.string name="camera_modes_title"> - Режимы камеры - </floater.string> - <floater.string name="pan_mode_title"> - Вращение, приближение, Ñдвиг - </floater.string> - <floater.string name="presets_mode_title"> - Стандартные наÑтройки - </floater.string> <floater.string name="free_mode_title"> Смотреть на объект </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..f6b2fc81e1 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> +<floater name="nearby_chat" title="ЛОКÐЛЬÐЫЙ ЧÐТ"> + <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_env_settings.xml b/indra/newview/skins/default/xui/ru/floater_env_settings.xml deleted file mode 100644 index a3e77d61de..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_env_settings.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Environment Editor Floater" title="РЕДÐКТОРСРЕДЫ"> - <floater.string name="timeStr"> - [hour,datetime,utc]:[min,datetime,utc] - </floater.string> - <text name="EnvTimeText"> - Ð’Ñ€ÐµÐ¼Ñ Ñуток - </text> - <text name="EnvTimeText2"> - 12:00 - </text> - <text name="EnvCloudText"> - ОблачноÑть - </text> - <text name="EnvWaterColorText"> - Цвет воды - </text> - <color_swatch name="EnvWaterColor" tool_tip="Щелкните Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° цвета"/> - <text name="EnvWaterFogText"> - Водный туман - </text> - <button label="ИÑпользовать Ð²Ñ€ÐµÐ¼Ñ Ð² землевладении" name="EnvUseEstateTimeButton"/> - <button label="Улучшенное небо" name="EnvAdvancedSkyButton"/> - <button label="Ð£Ð»ÑƒÑ‡ÑˆÐµÐ½Ð½Ð°Ñ Ð²Ð¾Ð´Ð°" name="EnvAdvancedWaterButton"/> -</floater> 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..43f8c36473 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"> @@ -25,6 +25,10 @@ Включить VBO: </text> <check_box initial_value="иÑтина" label="Включить объекты вершинных буферов OpenGL" name="vbo" tool_tip="Включение Ñтого параметра на Ñовременном оборудовании даÑÑ‚ увеличение производительноÑти. Однако на Ñтаром оборудовании Ñто может привеÑти к Ñбою приложениÑ."/> + <text name="tc label"> + Включить S3TC: + </text> + <check_box initial_value="true" label="Разрешить Ñжатие текÑтур (требует перезагрузки)" name="texture compression" tool_tip="Сжатие текÑтур в видеопамÑти, что позволÑет загружать текÑтуры большего размера за Ñчет некоторого Ð¿Ð°Ð´ÐµÐ½Ð¸Ñ ÐºÐ°Ñ‡ÐµÑтва цвета."/> <slider label="ПамÑть Ð´Ð»Ñ Ñ‚ÐµÐºÑтур (Мб):" name="GraphicsCardTextureMemory" tool_tip="КоличеÑтво памÑти, отводимое Ð´Ð»Ñ Ñ‚ÐµÐºÑтур. По умолчанию равно памÑти видеокарты. Уменьшение поможет увеличить производительноÑть, но текÑтуры могут Ñтать размытыми."/> <spinner label="ДиÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ñ‚ÑƒÐ¼Ð°Ð½Ð°:" name="fog"/> <button label="OK" label_selected="OK" name="OK"/> diff --git a/indra/newview/skins/default/xui/ru/floater_inventory.xml b/indra/newview/skins/default/xui/ru/floater_inventory.xml deleted file mode 100644 index 35cbcf177d..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_inventory.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="МОЙ ИÐВЕÐТÐРЬ"> - <panel label="Панель инвентарÑ" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml new file mode 100644 index 0000000000..332fa3b82f --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_merchant_outbox" title="ТОРГОВЫЕ ИСХОДЯЩИЕ"> + <string name="OutboxFolderCount1"> + 1 папка + </string> + <string name="OutboxFolderCountN"> + [NUM] папки + </string> + <string name="OutboxImporting"> + Отправка папок.... + </string> + <string name="OutboxInitializing"> + ИнициализациÑ... + </string> + <panel label=""> + <panel> + <panel name="outbox_inventory_placeholder_panel"> + <text name="outbox_inventory_placeholder_title"> + Загрузка... + </text> + </panel> + </panel> + <panel> + <button label="Отправить в торговый центр" name="outbox_import_btn" tool_tip="Ð’Ñ‹Ñтавить на витрину моего магазина"/> + </panel> + </panel> +</floater> 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..0c6d41b4ef 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> @@ -89,19 +92,54 @@ <text initial_value="Треугольники" name="triangles" value="Треугольники"/> <text initial_value="Вершины" name="vertices" value="Вершины"/> <text initial_value="Ð’Ñ‹Ñокий" name="high_label" value="Ð’Ñ‹Ñокий"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Загрузка из файла"/> + <item name="Generate" value="Создать"/> + </combo_box> <button label="Обзор..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="Предельное чиÑло треугольников"/> + <item name="Error Threshold" value="Порог ошибки"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Средний" name="medium_label" value="Средний"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Загрузка из файла"/> + <item name="Generate" value="Создать"/> + <item name="Use LoD above" value="ИÑпользовать УД выше"/> + </combo_box> <button label="Обзор..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="Предельное чиÑло треугольников"/> + <item name="Error Threshold" value="Порог ошибки"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Ðизкий" name="low_label" value="Ðизкий"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Загрузка из файла"/> + <item name="Generate" value="Создать"/> + <item name="Use LoD above" value="ИÑпользовать УД выше"/> + </combo_box> <button label="Обзор..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="Предельное чиÑло треугольников"/> + <item name="Error Threshold" value="Порог ошибки"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="Самый низкий" name="lowest_label" value="Самый низкий"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Загрузка из файла"/> + <item name="Generate" value="Создать"/> + <item name="Use LoD above" value="ИÑпользовать УД выше"/> + </combo_box> <button label="Обзор..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="Предельное чиÑло треугольников"/> + <item name="Error Threshold" value="Порог ошибки"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Генерировать нормали" name="gen_normals"/> @@ -137,7 +175,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 deleted file mode 100644 index ef2fe8e5a5..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_model_wizard.xml +++ /dev/null @@ -1,205 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Model Wizard" title="ПЕРЕДÐТЬ МÐСТЕРМОДЕЛИРОВÐÐИЯ"> - <button label="5. Передать" name="upload_btn"/> - <button label="4. ПроÑмотр" name="review_btn"/> - <button label="3. Физика" name="physics_btn"/> - <button label="2. Оптимизировать" name="optimize_btn"/> - <button label="1. Выбрать файл" name="choose_file_btn"/> - <panel name="choose_file_panel"> - <panel name="header_panel"> - <text name="header_text"> - Выберите файл модели - </text> - </panel> - <panel name="content"> - <text name="advanced_users_text"> - ПользователÑм в раÑширенном режиме: еÑли вы умеете Ñоздавать трехмерные графичеÑкие объекты, то, возможно, захотите воÑпользоватьÑÑ ÑредÑтвом Advanced Uploader, которое предоÑтавлÑет раÑширенные возможноÑти передачи объектов. - </text> - <button label="Перейти в раÑширенный режим" name="switch_to_advanced"/> - <text name="Cache location"> - Выберите файл модели Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð¸ - </text> - <button label="Обзор..." label_selected="Обзор..." name="browse"/> - <text name="dimensions"> - X Y Z - </text> - <text name="warning_label"> - Ð’ÐИМÐÐИЕ! - </text> - <text name="warning_text"> - Ð’Ñ‹ не Ñможете завершить передачу Ñтой модели на Ñерверы Second Life. [secondlife:///app/floater/learn_more Узнайте, как] наÑтроить в вашем аккаунте передачу Ñеточных моделей. - </text> - </panel> - </panel> - <panel name="optimize_panel"> - <panel name="header_panel"> - <text name="header_text"> - Оптимизировать модель - </text> - </panel> - <text name="description"> - Мы оптимизировали модель Ð´Ð»Ñ Ð¿Ð¾Ð²Ñ‹ÑˆÐµÐ½Ð¸Ñ Ð±Ñ‹ÑтродейÑтвиÑ. По желанию можно выполнить дополнительную наÑтройку. - </text> - <panel name="content"> - <text name="high_detail_text"> - Создать уровень детализации: выÑокий - </text> - <text name="medium_detail_text"> - Создать уровень детализации: Ñредний - </text> - <text name="low_detail_text"> - Создать уровень детализации: низкий - </text> - <text name="lowest_detail_text"> - Создать уровень детализации: Ñамый низкий - </text> - </panel> - <panel name="content2"> - <button label="ПереÑчитать геометрию" name="recalculate_geometry_btn"/> - <text name="lod_label"> - ПроÑмотр геометрии - </text> - <combo_box name="preview_lod_combo" tool_tip="Ð”ÐµÑ‚Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸ предварительном проÑмотре"> - <combo_item name="high"> - Детально - </combo_item> - <combo_item name="medium"> - СреднÑÑ Ð´ÐµÑ‚Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ - </combo_item> - <combo_item name="low"> - Мало деталей - </combo_item> - <combo_item name="lowest"> - Минимум деталей - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="physics_panel"> - <panel name="header_panel"> - <text name="header_text"> - ÐаÑтроить физику - </text> - </panel> - <text name="description"> - Мы Ñоздадим форму Ð´Ð»Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ каркаÑа модели. ÐаÑтройте уровень детализации формы в ÑоответÑтвии Ñ Ñ†ÐµÐ»Ñми, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… предназначена модель. - </text> - <panel name="content"> - <button label="ПереÑчитать физику" name="recalculate_physics_btn"/> - <button label="ПереÑчет..." name="recalculating_physics_btn"/> - <text name="lod_label"> - ПроÑмотр физики - </text> - <combo_box name="preview_lod_combo2" tool_tip="Уровень детализации при предварительном проÑмотре"> - <combo_item name="high"> - Детально - </combo_item> - <combo_item name="medium"> - СреднÑÑ Ð´ÐµÑ‚Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ - </combo_item> - <combo_item name="low"> - Мало деталей - </combo_item> - <combo_item name="lowest"> - Минимум деталей - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="review_panel"> - <panel name="header_panel"> - <text name="header_text"> - ПроÑмотр - </text> - </panel> - <panel name="content"> - <text name="review_prim_equiv"> - ВоздейÑтвие на учаÑток/регион: Ñквивалент в примитивах: [EQUIV] - </text> - <text name="review_fee"> - За передачу Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ñчета будет ÑнÑта плата в размере L$[FEE]. - </text> - <text name="review_confirmation"> - Ðажав кнопку «Передать», вы подтверждаете, что у Ð²Ð°Ñ ÐµÑть надлежащие права на вÑе ÑоÑтавлÑющие модели. - </text> - </panel> - </panel> - <panel name="upload_panel"> - <panel name="header_panel"> - <text name="header_text"> - Передача завершена - </text> - </panel> - <text name="model_uploaded_text"> - Ваша модель передана. - </text> - <text name="inventory_text"> - ÐаходитÑÑ Ð² папке «Объекты» вашего инвентарÑ. - </text> - <text name="charged_fee"> - С вашего Ñчета ÑнÑто: L$[FEE]. - </text> - </panel> - <button label="<< Ðазад" name="back"/> - <button label="Далее >>" name="next"/> - <button label="РаÑÑчитать Ð²ÐµÑ Ð¸ плату >>" name="calculate"/> - <button label="РаÑчет..." name="calculating"/> - <button label="Передать" name="upload" tool_tip="Передать в ÑимулÑтор"/> - <button label="Отмена" name="cancel"/> - <button label="Закрыть" name="close"/> - <spinner name="import_scale" value="1.0"/> - <string name="status_idle"> - Ðеактивно - </string> - <string name="status_parse_error"> - Проблема при анализе файла DAE – Ñм. подробноÑти в журнале. - </string> - <string name="status_reading_file"> - Загрузка... - </string> - <string name="status_generating_meshes"> - СоздаютÑÑ Ð¼ÐµÑˆÐ¸... - </string> - <string name="status_vertex_number_overflow"> - Ошибка. ЧиÑло вершин превышает 65534. Прервано. - </string> - <string name="bad_element"> - Ошибка: недопуÑтимый Ñлемент - </string> - <string name="high"> - выÑокий - </string> - <string name="medium"> - Ñредний - </string> - <string name="low"> - низкий - </string> - <string name="lowest"> - Ñамый низкий - </string> - <string name="mesh_status_good"> - ДоÑтавлено! - </string> - <string name="mesh_status_na"> - Ð/Д - </string> - <string name="mesh_status_none"> - Ðет - </string> - <string name="mesh_status_submesh_mismatch"> - ОтличаетÑÑ Ñ‡Ð¸Ñло текÑтурируемых граней на уровнÑÑ… детализации. - </string> - <string name="mesh_status_mesh_mismatch"> - ОтличаетÑÑ Ñ‡Ð¸Ñло ÑкземплÑров меша на уровнÑÑ… детализации. - </string> - <string name="mesh_status_too_many_vertices"> - Слишком много вершин на уровне детализации. - </string> - <string name="mesh_status_missing_lod"> - ОтÑутÑтвует необходимый уровень детализации. - </string> - <string name="layer_all"> - Ð’Ñе - </string> -</floater> 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_nearby_chat.xml b/indra/newview/skins/default/xui/ru/floater_nearby_chat.xml deleted file mode 100644 index 184c753e40..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="ЛОКÐЛЬÐЫЙ ЧÐТ"> - <check_box label="Перевод чата" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/ru/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..ce7ffc3d20 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="ПерÑонажи Ñ Ð¿Ð¾Ð¸Ñком пути"> + <floater.string name="messaging_get_inprogress"> + ÐžÐ¿Ñ€Ð¾Ñ Ð¿ÐµÑ€Ñонажей Ñ Ð¿Ð¾Ð¸Ñком пути... + </floater.string> + <floater.string name="messaging_get_error"> + Ошибка при опроÑе перÑонажей Ñ Ð¿Ð¾Ð¸Ñком пути. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Ðет перÑонажей Ñ Ð¿Ð¾Ð¸Ñком пути. + </floater.string> + <floater.string name="messaging_complete_available"> + Выбрано перÑонажей: [NUM_SELECTED] из [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + Ð’ Ñтом регионе не разрешен поиÑк пути. + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] Ð¼ÐºÑ + </floater.string> + <floater.string name="character_owner_loading"> + [Загрузка] + </floater.string> + <floater.string name="character_owner_unknown"> + [ÐеизвеÑтно] + </floater.string> + <floater.string name="character_owner_group"> + [группа] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="ИмÑ" name="name"/> + <scroll_list.columns label="ОпиÑание" name="description"/> + <scroll_list.columns label="Владелец" name="owner"/> + <scroll_list.columns label="ЦП" name="cpu_time"/> + <scroll_list.columns label="Ð’Ñ‹Ñота" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + ПерÑонажи: + </text> + <button label="Обновить ÑпиÑок" name="refresh_objects_list"/> + <button label="Выбрать вÑе" name="select_all_objects"/> + <button label="Отменить выбор" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + ДейÑÑ‚Ð²Ð¸Ñ Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ð¼Ð¸ перÑонажами: + </text> + <check_box label="Показать метку" name="show_beacon"/> + <check_box label="Показать физичеÑкую капÑулу" name="show_physics_capsule"/> + <button label="ВзÑть" name="take_objects"/> + <button label="Сделать копию" name="take_copy_objects"/> + <button label="Телепортировать Ð¼ÐµÐ½Ñ Ñ‚ÑƒÐ´Ð°" name="teleport_me_to_object" tool_tip="Разрешено, только еÑли выбран один перÑонаж."/> + <button label="Возврат" name="return_objects"/> + <button label="Удалить" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/ru/floater_pathfinding_console.xml new file mode 100644 index 0000000000..fa72df04fd --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="ПроÑмотр/теÑтирование поиÑка пути"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + Ðе удалоÑÑŒ найти реализацию библиотеки поиÑка пути + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + Ð’ Ñтом регионе не разрешен поиÑк пути. + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + Ожидание Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ региона. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Проверка ÑоÑтоÑÐ½Ð¸Ñ Ð½Ð°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¾Ð¹ Ñетки. + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Загрузка навигационной Ñетки. + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + Ðа Ñервере изменилаÑÑŒ Ð½Ð°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ Ñетка. Загрузка новой навигационной Ñетки. + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + Загружена поÑледнÑÑ Ð½Ð°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ Ñетка. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + Ðе удалоÑÑŒ загрузить навигационную Ñетку. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + Ð’ навигационной Ñетке еÑть незавершенные изменениÑ. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + Идет поÑтроение навигационной Ñетки. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + Ð’ некоторых регионах навигационной Ñетки еÑть незавершенные изменениÑ. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + Идет поÑтроение регионов навигационной Ñетки. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + Ð’ некоторых регионах навигационной Ñетки еÑть незавершенные изменениÑ, идет поÑтроение других регионов. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + ÐÐ°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ Ñетка уже обновлена. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + Ðе удалоÑÑŒ найти реализацию библиотеки поиÑка пути + </floater.string> + <floater.string name="pathing_region_not_enabled"> + Ð’ Ñтом регионе не разрешен поиÑк пути. + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Выберите начальную и конечную точки. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Выберите начальную точку. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Выберите конечную точку. + </floater.string> + <floater.string name="pathing_path_valid"> + Путь показан оранжевым цветом. + </floater.string> + <floater.string name="pathing_path_invalid"> + Ðе удалоÑÑŒ найти путь между выбранными точками. + </floater.string> + <floater.string name="pathing_error"> + Ошибка при Ñоздании пути. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Вид" name="view_panel"> + <text name="show_label"> + Показать: + </text> + <check_box label="Мир" name="show_world"/> + <check_box label="Только перемещаемые предметы" name="show_world_movables_only"/> + <check_box label="ÐÐ°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ Ñетка" name="show_navmesh"/> + <text name="show_walkability_label"> + Показать карту проходимоÑти: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="Ðе показывать" name="show_heatmap_mode_none"/> + <combo_box.item label="Тип перÑонажа A" name="show_heatmap_mode_a"/> + <combo_box.item label="Тип перÑонажа B" name="show_heatmap_mode_b"/> + <combo_box.item label="Тип перÑонажа C" name="show_heatmap_mode_c"/> + <combo_box.item label="Тип перÑонажа D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Проходимые меÑта" name="show_walkables"/> + <check_box label="Материальные объемы" name="show_material_volumes"/> + <check_box label="Статичные препÑÑ‚ÑтвиÑ" name="show_static_obstacles"/> + <check_box label="ИÑключающие объемы" name="show_exclusion_volumes"/> + <check_box label="Водное зеркало" name="show_water_plane"/> + <check_box label="РентгеновÑкое зрение" name="show_xray"/> + </panel> + <panel label="Проверить путь" name="test_panel"> + <text name="ctrl_click_label"> + Ctrl-щелчок Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° начальной точки. + </text> + <text name="shift_click_label"> + Shift-щелчок Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° конечной точки. + </text> + <text name="character_width_label"> + Ширина перÑонажа + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + м + </text> + <text name="character_type_label"> + Тип перÑонажа + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Ðет" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Удалить путь" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/ru/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..db100fa415 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Ðаборы ÑвÑзей Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пути"> + <floater.string name="messaging_get_inprogress"> + Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð°Ð±Ð¾Ñ€Ð¾Ð² ÑвÑзей Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пути... + </floater.string> + <floater.string name="messaging_get_error"> + Ошибка при запроÑе наборов ÑвÑзей Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пути. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Изменение выбранных наборов ÑвÑзей Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пути... + </floater.string> + <floater.string name="messaging_set_error"> + Ошибка при изменении выбранных наборов ÑвÑзей Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пути. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Ðет наборов ÑвÑзей Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пути. + </floater.string> + <floater.string name="messaging_complete_available"> + Выбрано наборов ÑвÑзей: [NUM_SELECTED] из [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + Ð’ Ñтом регионе не разрешен поиÑк пути. + </floater.string> + <floater.string name="linkset_terrain_name"> + [Ландшафт] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Загрузка] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [ÐеизвеÑтно] + </floater.string> + <floater.string name="linkset_owner_group"> + [группа] + </floater.string> + <floater.string name="linkset_is_scripted"> + Да + </floater.string> + <floater.string name="linkset_is_not_scripted"> + Ðет + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + ÐеизвеÑтно + </floater.string> + <floater.string name="linkset_use_walkable"> + Проходимое меÑто + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Статичное препÑÑ‚Ñтвие + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Перемещаемое препÑÑ‚Ñтвие + </floater.string> + <floater.string name="linkset_use_material_volume"> + Материальный объем + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + ИÑключающий объем + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Перемещаемый фантом + </floater.string> + <floater.string name="linkset_is_terrain"> + [неизменÑемый] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [ограниченный] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [вогнутый] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [ограниченный,вогнутый] + </floater.string> + <floater.string name="linkset_choose_use"> + Выберите Ñтепень иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ð°Ð±Ð¾Ñ€Ð¾Ð² ÑвÑзей... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="Фильтр по Ñтепени иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ð°Ð±Ð¾Ñ€Ð¾Ð² ÑвÑзей..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Проходимое меÑто" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Статичное препÑÑ‚Ñтвие" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Перемещаемое препÑÑ‚Ñтвие" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Материальный объем" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="ИÑключающий объем" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Перемещаемый фантом" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Применить" name="apply_filters"/> + <button label="ЧиÑто" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Ð˜Ð¼Ñ (корневой примитив)" name="name"/> + <scroll_list.columns label="ОпиÑание (корневой примитив)" name="description"/> + <scroll_list.columns label="Владелец" name="owner"/> + <scroll_list.columns label="Скриптовые" name="scripted"/> + <scroll_list.columns label="ВоздейÑтвие" name="land_impact"/> + <scroll_list.columns label="РаÑÑтоÑние" name="dist_from_you"/> + <scroll_list.columns label="ИÑпользование набора ÑвÑзей" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + Ðаборы ÑвÑзей: + </text> + <button label="Обновить ÑпиÑок" name="refresh_objects_list"/> + <button label="Выбрать вÑе" name="select_all_objects"/> + <button label="Отменить выбор" name="select_none_objects"/> + </panel> + <panel> + <check_box label="Показать метку" name="show_beacon"/> + <button label="ВзÑть" name="take_objects"/> + <button label="Сделать копию" name="take_copy_objects"/> + <button label="Телепортировать Ð¼ÐµÐ½Ñ Ñ‚ÑƒÐ´Ð°" name="teleport_me_to_object"/> + <button label="Возврат" name="return_objects"/> + <button label="Удалить" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + ПроходимоÑть: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="ПроходимоÑть Ð´Ð»Ñ Ð¿ÐµÑ€Ñонажей типа A. Пример перÑонажа – гуманоид."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="ПроходимоÑть Ð´Ð»Ñ Ð¿ÐµÑ€Ñонажей типа B. Пример перÑонажа – ÑущеÑтво."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="ПроходимоÑть Ð´Ð»Ñ Ð¿ÐµÑ€Ñонажей типа C. Пример перÑонажа – механизм."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="ПроходимоÑть Ð´Ð»Ñ Ð¿ÐµÑ€Ñонажей типа D. Пример перÑонажа – иное."/> + <button label="Применить изменениÑ" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Гуманоид) + </text> + <text name="suggested_use_b_label"> + (СущеÑтво) + </text> + <text name="suggested_use_c_label"> + (Механизм) + </text> + <text name="suggested_use_d_label"> + (Иное) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_postcard.xml b/indra/newview/skins/default/xui/ru/floater_postcard.xml deleted file mode 100644 index 889d219511..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_postcard.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="ПОСЛÐТЬ СÐИМОК ПО EMAIL"> - <floater.string name="default_subject"> - Открытка из [SECOND_LIFE]. - </floater.string> - <floater.string name="default_message"> - Побывай здеÑÑŒ! - </floater.string> - <floater.string name="upload_message"> - Отправка... - </floater.string> - <text name="to_label"> - Email получателÑ: - </text> - <text name="from_label"> - Ваш Email: - </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"/> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_preview_animation.xml b/indra/newview/skins/default/xui/ru/floater_preview_animation.xml index a1fabedb85..22c6bc5901 100644 --- a/indra/newview/skins/default/xui/ru/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/ru/floater_preview_animation.xml @@ -6,6 +6,6 @@ <text name="desc txt"> ОпиÑание: </text> - <button label="Проиграть Ð´Ð»Ñ Ð²Ñех" label_selected="Стоп" name="Anim play btn" tool_tip="Проигрывание Ñтой анимации могут видеть другие учаÑтники"/> - <button label="Проиграть Ð´Ð»Ñ ÑебÑ" label_selected="Стоп" name="Anim audition btn" tool_tip="Проигрывание Ñтой анимации можете видеть только вы"/> + <button label="Проиграть Ð´Ð»Ñ Ð²Ñех" label_selected="Стоп" name="Inworld" tool_tip="Проигрывание Ñтой анимации могут видеть другие учаÑтники"/> + <button label="Проиграть Ð´Ð»Ñ ÑебÑ" label_selected="Стоп" name="Locally" tool_tip="Проигрывание Ñтой анимации можете видеть только вы"/> </floater> 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_spellcheck.xml b/indra/newview/skins/default/xui/ru/floater_spellcheck.xml new file mode 100644 index 0000000000..691b4a89c3 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="ÐаÑтройки проверки правопиÑаниÑ"> + <check_box label="Включить проверку правопиÑаниÑ" name="spellcheck_enable"/> + <text name="spellcheck_main"> + ОÑновной Ñловарь: + </text> + <text label="Журналы:" name="spellcheck_additional"> + Дополнительные Ñловари: + </text> + <text name="spellcheck_available"> + ДоÑтупно + </text> + <text name="spellcheck_active"> + Ðктивно + </text> + <button label="Удалить" name="spellcheck_remove_btn"/> + <button label="Импорт..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/ru/floater_spellcheck_import.xml new file mode 100644 index 0000000000..a01866db73 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Импорт ÑловарÑ"> + <button label="Обзор" label_selected="Обзор" name="dictionary_path_browse"/> + <button label="Импорт" name="ok_btn"/> + <button label="Отмена" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_stats.xml b/indra/newview/skins/default/xui/ru/floater_stats.xml index b1f60c8029..46426495dc 100644 --- a/indra/newview/skins/default/xui/ru/floater_stats.xml +++ b/indra/newview/skins/default/xui/ru/floater_stats.xml @@ -14,8 +14,11 @@ <stat_bar label="Треугольников в Ñекунду" name="ktrissec"/> <stat_bar label="Ð’Ñего объектов" name="objs"/> <stat_bar label="Ðовых объектов" name="newobjs"/> + <stat_bar label="ЧаÑтота попаданий в кÑш объектов" name="object_cache_hits"/> </stat_view> <stat_view label="ТекÑтура" name="texture"> + <stat_bar label="ЧаÑтота попаданий в кÑш" name="texture_cache_hits"/> + <stat_bar label="Задержка Ñ‡Ñ‚ÐµÐ½Ð¸Ñ ÐºÑша" name="texture_cache_read_latency"/> <stat_bar label="КоличеÑтво" name="numimagesstat"/> <stat_bar label="Ðеобраб. изображений" name="numrawimagesstat"/> <stat_bar label="ПамÑть GL" name="gltexmemstat"/> @@ -50,7 +53,13 @@ <stat_bar label="Объекты" name="simobjects"/> <stat_bar label="Ðктивные объекты" name="simactiveobjects"/> <stat_bar label="Ðктивные Ñкрипты" name="simactivescripts"/> + <stat_bar label="Запущенные Ñкрипты" name="simpctscriptsrun"/> <stat_bar label="Ð¡Ð¾Ð±Ñ‹Ñ‚Ð¸Ñ Ñкрипта" name="simscripteps"/> + <stat_view label="ПоиÑк пути" name="simpathfinding"> + <stat_bar label="Ð’Ñ€ÐµÐ¼Ñ ÑˆÐ°Ð³Ð° ИИ" name="simsimaistepmsec"/> + <stat_bar label="Пропущенные ÑилуÑтные шаги" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Обновленные перÑонажи" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_bar label="ВходÑщие пакеты" name="siminpps"/> <stat_bar label="ИÑходÑщие пакеты" name="simoutpps"/> <stat_bar label="Отложенные загрузки" name="simpendingdownloads"/> diff --git a/indra/newview/skins/default/xui/ru/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/ru/floater_test_layout_stacks.xml new file mode 100644 index 0000000000..b479d5f6d6 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_test_layout_stacks.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="LAYOUTSTACK TESTS"/> diff --git a/indra/newview/skins/default/xui/ru/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/ru/floater_test_text_vertical_aligment.xml new file mode 100644 index 0000000000..d0bd86160e --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_test_text_vertical_aligment.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="ТЕСТИРОВÐТЬ ОКÐО"/> diff --git a/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml index d55daea836..db37089aeb 100644 --- a/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml @@ -9,15 +9,27 @@ <text name="Multiple"> ÐеÑколько текÑтур </text> + <radio_group name="mode_selection"> + <radio_item label="Инвентарь" name="inventory" value="0"/> + <radio_item label="Локально" name="local" value="1"/> + </radio_group> <text name="unknown"> Размер: [DIMENSIONS] </text> <button label="По умолчанию" label_selected="По умолчанию" name="Default"/> - <button label="Ðет" label_selected="Ðет" name="None"/> <button label="ОчиÑтить" label_selected="ОчиÑтить" name="Blank"/> - <check_box initial_value="иÑтина" label="Применить ÑейчаÑ" name="apply_immediate_check"/> + <button label="Ðет" label_selected="Ðет" name="None"/> + <check_box initial_value="иÑтина" label="ПроÑмотр вживую" name="apply_immediate_check"/> + <text name="preview_disabled" value="ПроÑмотр отключен"/> <filter_editor label="Фильтровать текÑтуры" name="inventory search editor"/> <check_box initial_value="ложь" label="Показывать папки" name="show_folders_check"/> + <button label="Добавить" label_selected="Добавить" name="l_add_btn"/> + <button label="Удалить" label_selected="Удалить" name="l_rem_btn"/> + <button label="Передать" label_selected="Передать" name="l_upl_btn"/> + <scroll_list name="l_name_list"> + <column label="ИмÑ" name="unit_name"/> + <column label="ID" name="unit_id_HIDDEN"/> + </scroll_list> <button label="ОК" label_selected="ОК" name="Select"/> <button label="Отмена" label_selected="Отмена" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/ru/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/ru/floater_texture_fetch_debugger.xml new file mode 100644 index 0000000000..628e6c5c87 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_texture_fetch_debugger.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="TexFetchDebugger" title="Отладчик Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Ñ‚ÐµÐºÑтур"> + <text name="total_num_fetched_label"> + 1, Общее количеÑтво извлеченных текÑтур: [NUM] + </text> + <text name="total_num_fetching_requests_label"> + 2, Общее количеÑтво запроÑов на извлечение: [NUM] + </text> + <text name="total_num_cache_hits_label"> + 3, Общее количеÑтво попаданий в кÑш: [NUM] + </text> + <text name="total_num_visible_tex_label"> + 4, Общее количеÑтво видимых текÑтур: [NUM] + </text> + <text name="total_num_visible_tex_fetch_req_label"> + 5, Общее количеÑтво запроÑов на извлечение видимых текÑтур: [NUM] + </text> + <text name="total_fetched_data_label"> + 6, Общий объем извлеченных данных: [SIZE1] КБ, декодированные данные: [SIZE2] КБ, [PIXEL] МпикÑелов + </text> + <text name="total_fetched_vis_data_label"> + 7, Общий объем видимых данных: [SIZE1] КБ, декодированные данные: [SIZE2] КБ + </text> + <text name="total_fetched_rendered_data_label"> + 8, Общий объем визуализированных данных: [SIZE1] КБ, декодированные данные: [SIZE2] КБ, [PIXEL] МпикÑелов + </text> + <text name="total_time_cache_read_label"> + 9, Общее Ð²Ñ€ÐµÐ¼Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð¸Ð· кÑша: [TIME] Ñ + </text> + <text name="total_time_cache_write_label"> + 10, Общее Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð¿Ð¸Ñи в кÑш: [TIME] Ñ + </text> + <text name="total_time_decode_label"> + 11, Общее Ð²Ñ€ÐµÐ¼Ñ Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ: [TIME] Ñ + </text> + <text name="total_time_gl_label"> + 12, Общее Ð²Ñ€ÐµÐ¼Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ‚ÐµÐºÑтур: [TIME] Ñ + </text> + <text name="total_time_http_label"> + 13, Общее Ð²Ñ€ÐµÐ¼Ñ HTTP-извлечениÑ: [TIME] Ñ + </text> + <text name="total_time_fetch_label"> + 14, Общее Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ð»Ð½Ð¾Ð³Ð¾ извлечениÑ: [TIME] Ñ + </text> + <text name="total_time_refetch_vis_cache_label"> + 15, Повторное извлечение из кÑша, времÑ: [TIME] Ñ, извлечено: [SIZE] КБ, [PIXEL] МпикÑелов + </text> + <text name="total_time_refetch_all_cache_label"> + 16, Повторное извлечение вÑех текÑтур из кÑша, времÑ: [TIME] Ñ, извлечено: [SIZE] КБ, [PIXEL] МпикÑелов + </text> + <text name="total_time_refetch_vis_http_label"> + 17, Повторное извлечение из HTTP, времÑ: [TIME] Ñ, извлечено: [SIZE] КБ, [PIXEL] МпикÑелов + </text> + <text name="total_time_refetch_all_http_label"> + 18, Повторное извлечение вÑех текÑтур из HTTP, времÑ: [TIME] Ñ, извлечено: [SIZE] КБ, [PIXEL] МпикÑелов + </text> + <spinner label="19, Отношение текÑелы/пикÑелы:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, ИÑтоÑник текÑтур: + </text> + <radio_group name="texture_source"> + <radio_item label="КÑш + HTTP" name="0"/> + <radio_item label="Только HTTP" name="1"/> + </radio_group> + <button label="ПуÑк" name="start_btn"/> + <button label="СброÑ" name="clear_btn"/> + <button label="Закрыть" name="close_btn"/> + <button label="Чтение кÑша" name="cacheread_btn"/> + <button label="ЗапиÑÑŒ в кÑш" name="cachewrite_btn"/> + <button label="HTTP" name="http_btn"/> + <button label="Декодировать" name="decode_btn"/> + <button label="ТекÑтура GL" name="gl_btn"/> + <button label="Повторно извлечь из кÑша" name="refetchviscache_btn"/> + <button label="Повторно извлечь вÑе из кÑша" name="refetchallcache_btn"/> + <button label="Повторно извлечь из HTTP" name="refetchvishttp_btn"/> + <button label="Повторно извлечь вÑе из HTTP" name="refetchallhttp_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_tools.xml b/indra/newview/skins/default/xui/ru/floater_tools.xml index eb9083f7fc..c312f73428 100644 --- a/indra/newview/skins/default/xui/ru/floater_tools.xml +++ b/indra/newview/skins/default/xui/ru/floater_tools.xml @@ -1,5 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="toolbox floater" short_title="ИÐСТРУМЕÐТЫ ДЛЯ СТРОИТЕЛЬСТВÐ"> + <floater.string name="grid_screen_text"> + Ðкран + </floater.string> + <floater.string name="grid_local_text"> + Ð›Ð¾ÐºÐ°Ð»ÑŒÐ½Ð°Ñ + </floater.string> + <floater.string name="grid_world_text"> + ÐœÐ¸Ñ€Ð¾Ð²Ð°Ñ + </floater.string> + <floater.string name="grid_reference_text"> + Точка отÑчета + </floater.string> + <floater.string name="grid_attachment_text"> + ПриÑоединение + </floater.string> <floater.string name="status_rotate"> ПеретÑгивайте цветные полоÑÑ‹ Ð´Ð»Ñ Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° </floater.string> @@ -63,7 +78,12 @@ </text> <check_box initial_value="иÑтина" label="РаÑÑ‚Ñгивать текÑтуры" name="checkbox stretch textures"/> <check_box initial_value="иÑтина" label="ПривÑзка" name="checkbox snap to grid"/> - <button label="Параметры..." name="Options..." tool_tip="Дополнительные параметры Ñетки"/> + <combo_box name="combobox grid mode" tool_tip="Выберите тип линейки Ñетки Ð´Ð»Ñ Ñ€Ð°Ð·Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°"> + <combo_box.item label="МироваÑ" name="World"/> + <combo_box.item label="ЛокальнаÑ" name="Local"/> + <combo_box.item label="Точка отÑчета" name="Reference"/> + </combo_box> + <button label="" name="Options..." tool_tip="Дополнительные параметры Ñетки"/> <button name="ToolCube" tool_tip="Куб"/> <button name="ToolPrism" tool_tip="Призма"/> <button name="ToolPyramid" tool_tip="Пирамида"/> @@ -130,6 +150,12 @@ <panel.string name="text modify info 4"> Ðти объекты Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ñть </panel.string> + <panel.string name="text modify info 5"> + Ðтот объект Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ñть через границу региона + </panel.string> + <panel.string name="text modify info 6"> + Ðти объекты Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ñть через границу региона + </panel.string> <panel.string name="text modify warning"> Чтобы задать права доÑтупа, нужно выделить объект целиком </panel.string> @@ -179,12 +205,12 @@ <combo_box.item label="Увеличение" name="Zoom"/> </combo_box> <check_box label="Ð”Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð°Ð¶Ð¸:" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Копировать" name="Copy"/> <combo_box.item label="Контент" name="Contents"/> <combo_box.item label="Оригинал" name="Original"/> </combo_box> - <spinner label="Цена: L$" name="Edit Cost"/> <check_box label="Показать в поиÑке" name="search_check" tool_tip="Показывать объект в результатах поиÑка"/> <panel name="perms_build"> <text name="perm_modify"> @@ -220,6 +246,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Ðтрибуты поиÑка пути: + </text> + </panel> </panel> <panel label="Объект" name="Object"> <check_box label="ФикÑированный" name="checkbox locked" tool_tip="Предотвращение Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°. Обычно Ñта Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð° во Ð²Ñ€ÐµÐ¼Ñ Ñтройки Ð´Ð»Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°Ð½Ð¸Ñ Ð½ÐµÐ¶ÐµÐ»Ð°Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ñ… изменений."/> diff --git a/indra/newview/skins/default/xui/ru/floater_top_objects.xml b/indra/newview/skins/default/xui/ru/floater_top_objects.xml index a6ffe5c030..c7ece5c9c9 100644 --- a/indra/newview/skins/default/xui/ru/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/ru/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> Ð’Ñ€ÐµÐ¼Ñ </floater.string> - <floater.string name="scripts_mono_time_label"> - Ð’Ñ€ÐµÐ¼Ñ Ð¼Ð¾Ð½Ð¾ - </floater.string> <floater.string name="top_colliders_title"> Лучшие ÑÑ‚Ð¾Ð»ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸Ñ </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="Ðазвание" name="name"/> <scroll_list.columns label="Владелец" name="owner"/> <scroll_list.columns label="МеÑто" name="location"/> + <scroll_list.columns label="УчаÑток" name="parcel"/> <scroll_list.columns label="ВремÑ" name="time"/> - <scroll_list.columns label="Ð’Ñ€ÐµÐ¼Ñ Ð¼Ð¾Ð½Ð¾" name="mono_time"/> <scroll_list.columns label="URL-адреÑа" name="URLs"/> + <scroll_list.columns label="ПамÑть (КБ)" name="memory"/> </scroll_list> <text name="id_text"> ID объекта: @@ -48,6 +46,10 @@ Владелец: </text> <button label="Фильтр" name="filter_owner_btn"/> + <text name="parcel_name_text"> + УчаÑток: + </text> + <button label="Фильтр" name="filter_parcel_btn"/> <button label="Вернуть выбранное" name="return_selected_btn"/> <button label="Вернуть вÑе" name="return_all_btn"/> <button label="Отключить выбранное" name="disable_selected_btn"/> 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/floater_voice_effect.xml b/indra/newview/skins/default/xui/ru/floater_voice_effect.xml index d4bf615fe4..1eb8a94d7a 100644 --- a/indra/newview/skins/default/xui/ru/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/ru/floater_voice_effect.xml @@ -42,13 +42,16 @@ <string name="effect_Demon"> Demon </string> + <string name="effect_Female Elf"> + Ð¤ÐµÑ + </string> <string name="effect_Flirty"> Flirty </string> <string name="effect_Foxy"> Foxy </string> - <string name="effect_Halloween_2010_Bonus"> + <string name="effect_Halloween 2010 Bonus"> БонуÑ_за_Ð¥Ñллоуин_2010 </string> <string name="effect_Helium"> @@ -57,9 +60,18 @@ <string name="effect_Husky"> Husky </string> + <string name="effect_Husky Whisper"> + Хриплый шепот + </string> <string name="effect_Intercom"> ВнутреннÑÑ ÑвÑзь </string> + <string name="effect_Julia"> + Julia + </string> + <string name="effect_Lo Lilt"> + Ðапев + </string> <string name="effect_Macho"> Macho </string> @@ -69,6 +81,9 @@ <string name="effect_Mini"> Mini </string> + <string name="effect_Model"> + Модель + </string> <string name="effect_Nano"> Nano </string> @@ -90,6 +105,9 @@ <string name="effect_Roxanne"> Roxanne </string> + <string name="effect_Rumble"> + Урчание + </string> <string name="effect_Sabrina"> Sabrina </string> @@ -102,6 +120,9 @@ <string name="effect_Shorty"> Shorty </string> + <string name="effect_Smaller"> + Меньше + </string> <string name="effect_Sneaky"> Sneaky </string> diff --git a/indra/newview/skins/default/xui/ru/floater_water.xml b/indra/newview/skins/default/xui/ru/floater_water.xml deleted file mode 100644 index 5030351f5b..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_water.xml +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Water Floater" title="Ð ÐСШИРЕÐÐЫЙ РЕДÐКТОРВОДЫ"> - <floater.string name="WLDefaultWaterNames"> - По умолчанию:глÑнец:пруд:туман:Second Plague:SNAKE!!!:Valdez - </floater.string> - <text name="KeyFramePresetsText"> - ÐаÑтройки воды: - </text> - <button label="Создать" label_selected="Создать" name="WaterNewPreset"/> - <button label="Сохранить" label_selected="Сохранить" name="WaterSavePreset"/> - <button label="Удалить" label_selected="Удалить" name="WaterDeletePreset"/> - <tab_container name="Water Tabs"> - <panel label="ÐÐСТРОЙКИ" name="Settings"> - <text name="BHText"> - Цвет водного тумана - </text> - <color_swatch name="WaterFogColor" tool_tip="Щелкните Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° цвета"/> - <text name="WaterFogDensText"> - ПлотноÑть тумана - </text> - <text name="WaterUnderWaterFogModText"> - Подводный туман - </text> - <text name="BDensText"> - Уровень Ð¾Ñ‚Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð²Ð¾Ð»Ð½ - </text> - <slider label="1" name="WaterNormalScaleX"/> - <slider label="2" name="WaterNormalScaleY"/> - <slider label="3" name="WaterNormalScaleZ"/> - <text name="HDText"> - МаÑштаб Ð¤Ñ€ÐµÐ½ÐµÐ»Ñ - </text> - <text name="FresnelOffsetText"> - Сдвиг Ð¤Ñ€ÐµÐ½ÐµÐ»Ñ - </text> - <text name="DensMultText"> - Преломление над водой - </text> - <text name="WaterScaleBelowText"> - Преломление под водой - </text> - <text name="MaxAltText"> - КоÑффициент Ñ€Ð°Ð·Ð¼Ñ‹Ñ‚Ð¸Ñ - </text> - </panel> - <panel label="ИЗОБРÐЖЕÐИЕ" name="Waves"> - <text name="BHText"> - Ðаправление больших волн - </text> - <text name="WaterWave1DirXText"> - X - </text> - <text name="WaterWave1DirYText"> - Y - </text> - <text name="BHText2"> - Ðаправление маленьких волн - </text> - <text name="WaterWave2DirXText"> - X - </text> - <text name="WaterWave2DirYText"> - Y - </text> - <text name="BHText3"> - Карта поверхноÑти - </text> - </panel> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_windlight_options.xml b/indra/newview/skins/default/xui/ru/floater_windlight_options.xml deleted file mode 100644 index bbb37aaaa0..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_windlight_options.xml +++ /dev/null @@ -1,167 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="WindLight floater" title="Ð ÐСШИРЕÐÐЫЙ РЕДÐКТОРÐЕБÐ"> - <floater.string name="WLDefaultSkyNames"> - A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor's Delight:Sheer Sensuality - </floater.string> - <text name="KeyFramePresetsText"> - ÐаÑтройки неба: - </text> - <button label="ÐоваÑ" label_selected="ÐоваÑ" name="WLNewPreset"/> - <button label="Сохранить" label_selected="Сохранить" name="WLSavePreset"/> - <button label="Удалить" label_selected="Удалить" name="WLDeletePreset"/> - <button label="Редактор Ñуточных циклов" label_selected="Редактор Ñуточных циклов" name="WLDayCycleMenuButton"/> - <tab_container name="WindLight Tabs"> - <panel label="ÐТМОСФЕРÐ" name="Atmosphere"> - <text name="BHText"> - Голубой горизонт - </text> - <text name="BHText2"> - R - </text> - <text name="BHText3"> - G - </text> - <text name="BHText4"> - B - </text> - <text name="BHText5"> - I - </text> - <text name="BDensText"> - Дымка на горизонте - </text> - <text name="BDensText2"> - ÐаÑыщенноÑть голубого - </text> - <text name="BHText6"> - R - </text> - <text name="BHText7"> - G - </text> - <text name="BHText8"> - B - </text> - <text name="BHText9"> - I - </text> - <text name="HDText"> - ПлотноÑть дымки - </text> - <text name="DensMultText"> - КоÑффициент плотноÑти - </text> - <text name="WLDistanceMultText"> - КоÑффициент раÑÑтоÑÐ½Ð¸Ñ - </text> - <text name="MaxAltText"> - МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð²Ñ‹Ñота - </text> - </panel> - <panel label="ОСВЕЩЕÐИЕ" name="Lighting"> - <text name="SLCText"> - Цвет Ñолнца/луны - </text> - <text name="BHText"> - R - </text> - <text name="BHText2"> - G - </text> - <text name="BHText3"> - B - </text> - <text name="BHText4"> - I - </text> - <text name="TODText"> - Положение Ñолнца/луны - </text> - <text name="WLAmbientText"> - РаÑÑеÑнное - </text> - <text name="BHText5"> - R - </text> - <text name="BHText6"> - G - </text> - <text name="BHText7"> - B - </text> - <text name="BHText8"> - I - </text> - <text name="WLEastAngleText"> - Смещение отноÑительно воÑтока - </text> - <text name="SunGlowText"> - СиÑние Ñолнца - </text> - <slider label="ФокуÑ" name="WLGlowB"/> - <slider label="Размер" name="WLGlowR"/> - <text name="SceneGammaText"> - Гамма-ÐºÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ñцены - </text> - <text name="WLStarText"> - ЯркоÑть звезд - </text> - </panel> - <panel label="ОБЛÐКÐ" name="Clouds"> - <text name="WLCloudColorText"> - Цвет - </text> - <text name="BHText"> - R - </text> - <text name="BHText2"> - G - </text> - <text name="BHText3"> - B - </text> - <text name="BHText4"> - I - </text> - <text name="WLCloudColorText2"> - Положение и плотноÑть - </text> - <text name="BHText5"> - X - </text> - <text name="BHText6"> - Y - </text> - <text name="BHText7"> - П - </text> - <text name="WLCloudCoverageText"> - ОблачноÑть - </text> - <text name="WLCloudScaleText"> - Размеры - </text> - <text name="WLCloudDetailText"> - Ð”ÐµÑ‚Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ (положение/плотноÑть) - </text> - <text name="BHText8"> - X - </text> - <text name="BHText9"> - Y - </text> - <text name="BHText10"> - П - </text> - <text name="WLCloudScrollXText"> - СкороÑть по X - </text> - <check_box label="Ðа меÑте" name="WLCloudLockX"/> - <text name="WLCloudScrollYText"> - СкороÑть по Y - </text> - <check_box label="Ðа меÑте" name="WLCloudLockY"/> - <check_box label="Создать клаÑÑичеÑкие облака" name="DrawClassicClouds"/> - </panel> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_window_size.xml b/indra/newview/skins/default/xui/ru/floater_window_size.xml index 24865a6ba5..fbff6a72b2 100644 --- a/indra/newview/skins/default/xui/ru/floater_window_size.xml +++ b/indra/newview/skins/default/xui/ru/floater_window_size.xml @@ -7,10 +7,17 @@ Задать размер окна: </text> <combo_box name="window_size_combo" tool_tip="ширина x выÑота"> - <combo_box.item label="1000 x 700 (по умолчанию)" name="item0"/> - <combo_box.item label="1024 x 768" name="item1"/> - <combo_box.item label="1280 x 720 (720p)" name="item2"/> - <combo_box.item label="1920 x 1080 (1080p)" name="item3"/> + <combo_box.item label="1000 x 700 (по умолчанию)" name="item1"/> + <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/> + <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/> + <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/> + <combo_box.item label="1280 x 1024 (5:4 WXGA)" name="item5"/> + <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/> + <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/> + <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/> + <combo_box.item label="1680 x 1050 (8:5 WSXGA)" name="item10"/> + <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/> + <combo_box.item label="1920 x 1200 (8:5 UXGA)" name="item12"/> </combo_box> <button label="Задать" name="set_btn"/> <button label="Отмена" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/ru/menu_bottomtray.xml b/indra/newview/skins/default/xui/ru/menu_bottomtray.xml deleted file mode 100644 index fa3558945b..0000000000 --- a/indra/newview/skins/default/xui/ru/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="Кнопка разговора" name="EnableVoiceChat"/> - <menu_item_check label="Кнопка жеÑтов" name="ShowGestureButton"/> - <menu_item_check label="Кнопка движениÑ" name="ShowMoveButton"/> - <menu_item_check label="Кнопка камеры" name="ShowCameraButton"/> - <menu_item_check label="Кнопка Ñнимка" name="ShowSnapshotButton"/> - <menu_item_check label="Кнопка ÑтроительÑтва" name="ShowBuildButton"/> - <menu_item_check label="Кнопка поиÑка" name="ShowSearchButton"/> - <menu_item_check label="Кнопка карты" name="ShowWorldMapButton"/> - <menu_item_check label="Кнопка миникарты" name="ShowMiniMapButton"/> - <menu_item_call label="Вырезать" name="NearbyChatBar_Cut"/> - <menu_item_call label="Копировать" name="NearbyChatBar_Copy"/> - <menu_item_call label="Ð’Ñтавить" name="NearbyChatBar_Paste"/> - <menu_item_call label="Удалить" name="NearbyChatBar_Delete"/> - <menu_item_call label="Выделить вÑе" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/ru/menu_im_well_button.xml b/indra/newview/skins/default/xui/ru/menu_im_well_button.xml deleted file mode 100644 index 5a5bde61b9..0000000000 --- a/indra/newview/skins/default/xui/ru/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<context_menu name="IM Well Button Context Menu"> - <menu_item_call label="Закрыть вÑе" name="Close All"/> -</context_menu> diff --git a/indra/newview/skins/default/xui/ru/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/ru/menu_inspect_object_gear.xml index a72b2bef23..30953e830b 100644 --- a/indra/newview/skins/default/xui/ru/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/ru/menu_inspect_object_gear.xml @@ -12,6 +12,7 @@ <menu_item_call label="Добавить" name="add"/> <menu_item_call label="ПожаловатьÑÑ" name="report"/> <menu_item_call label="Заблокировать" name="block"/> + <menu_item_call label="Разблокировать" name="unblock"/> <menu_item_call label="Приблизить" name="zoom_in"/> <menu_item_call label="Удалить" name="remove"/> <menu_item_call label="Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ" name="more_info"/> diff --git a/indra/newview/skins/default/xui/ru/menu_inventory.xml b/indra/newview/skins/default/xui/ru/menu_inventory.xml index 4eeb1e46c2..37ee19fc1d 100644 --- a/indra/newview/skins/default/xui/ru/menu_inventory.xml +++ b/indra/newview/skins/default/xui/ru/menu_inventory.xml @@ -59,6 +59,7 @@ <menu_item_call label="СвойÑтва" name="Properties"/> <menu_item_call label="Переименовать" name="Rename"/> <menu_item_call label="Копировать UUID актива" name="Copy Asset UUID"/> + <menu_item_call label="Вырезать" name="Cut"/> <menu_item_call label="Копировать" name="Copy"/> <menu_item_call label="Ð’Ñтавить" name="Paste"/> <menu_item_call label="Ð’Ñтавить как ÑÑылку" name="Paste As Link"/> @@ -67,6 +68,7 @@ <menu_item_call label="Удалить ÑиÑтемную папку" name="Delete System Folder"/> <menu_item_call label="Ðачать конференцию" name="Conference Chat Folder"/> <menu_item_call label="ВоÑпроизвеÑти" name="Sound Play"/> + <menu_item_call label="Копировать URL SL" name="url_copy"/> <menu_item_call label="О закладке" name="About Landmark"/> <menu_item_call label="Проиграть Ð´Ð»Ñ Ð²Ñех" name="Animation Play"/> <menu_item_call label="Проиграть Ð´Ð»Ñ ÑебÑ" name="Animation Audition"/> @@ -84,6 +86,6 @@ <menu_item_call label="Добавить" name="Wearable Add"/> <menu_item_call label="СнÑть" name="Take Off"/> <menu_item_call label="Копировать в «Торговые иÑходÑщие»" name="Merchant Copy"/> - <menu_item_call label="ПеремеÑтить в «Торговые иÑходÑщие»" name="Merchant Move"/> + <menu_item_call label="Отправить в торговый центр" name="Marketplace Send"/> <menu_item_call label="- нет дейÑтвий -" name="--no options--"/> </menu> diff --git a/indra/newview/skins/default/xui/ru/menu_login.xml b/indra/newview/skins/default/xui/ru/menu_login.xml index aa3570f176..93a5ffbb25 100644 --- a/indra/newview/skins/default/xui/ru/menu_login.xml +++ b/indra/newview/skins/default/xui/ru/menu_login.xml @@ -17,8 +17,8 @@ <menu_item_call label="Задать размер окна..." name="Set Window Size..."/> <menu_item_call label="Показать лицензионное Ñоглашение" name="TOS"/> <menu_item_call label="Показать Ñообщение об ошибке" name="Critical"/> - <menu_item_call label="Проверка медиабраузера" name="Web Browser Test"/> <menu_item_call label="ТеÑÑ‚ отладки плавающего окна Ñ Ð²ÐµÐ±-контентом" name="Web Content Floater Debug Test"/> + <menu label="Уровень журнала" name="Set Logging Level"/> <menu_item_check label="Выбор Ñетки" name="Show Grid Picker"/> <menu_item_call label="КонÑоль уведомлений" name="Show Notifications Console"/> </menu> diff --git a/indra/newview/skins/default/xui/ru/menu_mode_change.xml b/indra/newview/skins/default/xui/ru/menu_mode_change.xml deleted file mode 100644 index 25d6e9af27..0000000000 --- a/indra/newview/skins/default/xui/ru/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="ОÑновной" name="BasicMode"/> - <menu_item_check label="РаÑширенный" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/ru/menu_object.xml b/indra/newview/skins/default/xui/ru/menu_object.xml index d6abfd12a2..288df3beb9 100644 --- a/indra/newview/skins/default/xui/ru/menu_object.xml +++ b/indra/newview/skins/default/xui/ru/menu_object.xml @@ -3,6 +3,8 @@ <menu_item_call label="КоÑнутьÑÑ" name="Object Touch"/> <menu_item_call label="Изменить" name="Edit..."/> <menu_item_call label="СтроительÑтво" name="Build"/> + <menu_item_call label="Показывать в наборах ÑвÑзей" name="show_in_linksets"/> + <menu_item_call label="Показывать в перÑонажах" name="show_in_characters"/> <menu_item_call label="Открыто" name="Open"/> <menu_item_call label="СеÑть здеÑÑŒ" name="Object Sit"/> <menu_item_call label="Ð’Ñтать" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/ru/menu_text_editor.xml b/indra/newview/skins/default/xui/ru/menu_text_editor.xml index 113dd85318..0c928308a1 100644 --- a/indra/newview/skins/default/xui/ru/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/ru/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(неизвеÑтно)" name="Suggestion 1"/> + <menu_item_call label="(неизвеÑтно)" name="Suggestion 2"/> + <menu_item_call label="(неизвеÑтно)" name="Suggestion 3"/> + <menu_item_call label="(неизвеÑтно)" name="Suggestion 4"/> + <menu_item_call label="(неизвеÑтно)" name="Suggestion 5"/> + <menu_item_call label="Добавить в Ñловарь" name="Add to Dictionary"/> + <menu_item_call label="Добавить в ÑпиÑок игнорируемых" name="Add to Ignore"/> <menu_item_call label="Вырезать" name="Cut"/> <menu_item_call label="Копировать" name="Copy"/> <menu_item_call label="Ð’Ñтавить" name="Paste"/> 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..d9425937c3 100644 --- a/indra/newview/skins/default/xui/ru/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml @@ -1,53 +1,60 @@ <?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"/> <menu_item_check label="Ð’Ñегда бегать" name="Always Run"/> <menu_item_call label="ОÑтановить анимацию" name="Stop Animating My Avatar"/> + <menu_item_call label="Ходьба / бег / полет..." name="Walk / run / fly"/> </menu> <menu label="СтатуÑ" name="Status"> <menu_item_call label="Ðет на меÑте" name="Set Away"/> <menu_item_call label="Ðе беÑпокоить" name="Set Busy"/> </menu> - <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="Купить L$..." name="Buy and Sell L$"/> + <menu_item_call label="Торговые иÑходÑщие..." name="MerchantOutbox"/> + <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_check label="Показывать приÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ HUD" name="Show HUD Attachments"/> <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_item_call label="Черный ÑпиÑок" name="Block List"/> </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 +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 label="Солнце" name="Sun"> <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"/> @@ -118,6 +124,11 @@ <menu_item_call label="ЗапуÑтить Ñкрипты" name="Set Scripts to Running"/> <menu_item_call label="ОÑтановить Ñкрипты" name="Set Scripts to Not Running"/> </menu> + <menu label="ПоиÑк пути" name="Pathfinding"> + <menu_item_call label="Ðаборы ÑвÑзей..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="ПерÑонажи..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="ПроÑмотр/теÑтирование..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Параметры" name="Options"> <menu_item_check label="Показать раÑширенные разрешениÑ" name="DebugPermissions"/> <menu_item_check label="Выбирать только мои объекты" name="Select Only My Objects"/> @@ -144,6 +155,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"/> @@ -167,26 +179,25 @@ <menu_item_check label="Скрыть чаÑтицы" name="Hide Particles"/> <menu_item_check label="Скрыть выбранное" name="Hide Selected"/> <menu_item_check label="ПодÑветка прозрачного" name="Highlight Transparent"/> - <menu_item_check label="Показывать приÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ HUD" name="Show HUD Attachments"/> <menu_item_check label="Показывать прицел при обзоре мышью" name="ShowCrosshairs"/> </menu> <menu label="Типы визуализации" 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="Surface Patch"/> - <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="Функции визуализации" name="Rendering Features"> - <menu_item_check label="Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" name="UI"/> + <menu_item_check label="Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" name="ToggleUI"/> <menu_item_check label="Выбрано" name="Selected"/> <menu_item_check label="Выделено" name="Highlighted"/> <menu_item_check label="ДинамичеÑкие текÑтуры" name="Dynamic Textures"/> @@ -198,11 +209,8 @@ <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"/> @@ -211,13 +219,6 @@ <menu_item_check label="Обзор джойÑтиком" 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="Приблизить" name="Zoom In"/> <menu_item_call label="Стандартный маÑштаб" name="Zoom Default"/> <menu_item_call label="Отодвинуть" name="Zoom Out"/> @@ -230,11 +231,10 @@ <menu_item_check label="КонÑоль текÑтур" name="Texture Console"/> <menu_item_check label="КонÑоль отладки" name="Debug Console"/> <menu_item_call label="КонÑоль уведомлений" name="Notifications"/> - <menu_item_check label="КонÑоль размера текÑтуры" name="Texture Size"/> - <menu_item_check label="КонÑоль категории текÑтуры" name="Texture Category"/> <menu_item_check label="Оперативные таймеры" name="Fast Timers"/> <menu_item_check label="ПамÑть" name="Memory"/> <menu_item_check label="СтатиÑтика по Ñцене" name="Scene Statistics"/> + <menu_item_call label="КонÑоль отладки Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Ñ‚ÐµÐºÑтур" name="Texture Fetch Debug Console"/> <menu_item_call label="Данные о регионе на конÑоль отладки" name="Region Info to Debug Console"/> <menu_item_call label="Данны о группе на конÑоль отладки" name="Group Info to Debug Console"/> <menu_item_call label="Данные о ÑпоÑобноÑÑ‚ÑÑ… на конÑоль отладки" name="Capabilities Info to Debug Console"/> @@ -288,8 +288,16 @@ <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="attachment bytes"/> <menu_item_check label="Лепка" name="Sculpt"/> + <menu label="ПлотноÑть текÑтуры" name="Texture Density"> + <menu_item_check label="Ðет" name="None"/> + <menu_item_check label="ТекущаÑ" name="Current"/> + <menu_item_check label="ЖелаемаÑ" name="Desired"/> + <menu_item_check label="ПолнаÑ" name="Full"/> + </menu> </menu> <menu label="ВизуализациÑ" name="Rendering"> <menu_item_check label="ОÑи" name="Axes"/> @@ -300,7 +308,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)"/> @@ -308,7 +315,6 @@ <menu_item_check label="ТекÑтуры анимаций" name="Animation Textures"/> <menu_item_check label="Отключить текÑтуры" name="Disable Textures"/> <menu_item_check label="ТекÑтуры в полном разрешении" name="Rull Res Textures"/> - <menu_item_check label="Проверить текÑтуры" name="Audit Textures"/> <menu_item_check label="ÐÑ‚Ð»Ð°Ñ Ñ‚ÐµÐºÑтур (ÑкÑÐ¿ÐµÑ€Ð¸Ð¼ÐµÐ½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ)" name="Texture Atlas"/> <menu_item_check label="Ð’Ð¸Ð·ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸Ñоединенных иÑточников Ñвета" name="Render Attached Lights"/> <menu_item_check label="Ð’Ð¸Ð·ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸Ñоединенных чаÑтиц" name="Render Attached Particles"/> @@ -331,9 +337,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="Мигающий маÑк" name="Cheesy Beacon"/> <menu_item_check label="ÐÐµÐ¸Ð·Ð¼ÐµÐ½Ð½Ð°Ñ Ð¿Ð¾Ð³Ð¾Ð´Ð°" name="Fixed Weather"/> <menu_item_call label="Вывод кÑша региональных объектов" name="Dump Region Object Cache"/> </menu> @@ -365,18 +370,17 @@ </menu> <menu label="Ðватар" name="Character"> <menu label="Захват запеченных текÑтур" name="Grab Baked Texture"> - <menu_item_call label="Радужка" name="Iris"/> - <menu_item_call label="Голова" name="Head"/> - <menu_item_call label="ВерхнÑÑ Ñ‡Ð°Ñть тела" name="Upper Body"/> - <menu_item_call label="ÐижнÑÑ Ñ‡Ð°Ñть тела" name="Lower Body"/> - <menu_item_call label="Юбка" name="Skirt"/> + <menu_item_call label="Радужка" name="Grab Iris"/> + <menu_item_call label="Голова" name="Grab Head"/> + <menu_item_call label="ВерхнÑÑ Ñ‡Ð°Ñть тела" name="Grab Upper Body"/> + <menu_item_call label="ÐижнÑÑ Ñ‡Ð°Ñть тела" name="Grab Lower Body"/> + <menu_item_call label="Юбка" name="Grab Skirt"/> </menu> <menu label="Проверка перÑонажа" name="Character Tests"> <menu_item_call label="Внешний вид в XML" name="Appearance To XML"/> <menu_item_call label="Ðктивировать геометрию перÑонажа" name="Toggle Character Geometry"/> <menu_item_call label="Проверка мужчины" name="Test Male"/> <menu_item_call label="Проверка женщины" name="Test Female"/> - <menu_item_call label="Ðктивировать PG-контент" name="Toggle PG"/> <menu_item_check label="Разрешить выбор аватара" name="Allow Select Avatar"/> </menu> <menu_item_call label="Скинуть параметры" name="Force Params to Default"/> @@ -397,16 +401,24 @@ <menu_item_check label="ТекÑтуры HTTP" name="HTTP Textures"/> <menu_item_check label="Инвентарь HTTP" name="HTTP Inventory"/> <menu_item_call label="Сжатие изображений" name="Compress Images"/> + <menu_item_call label="Включить Visual Leak Detector" name="Enable Visual Leak Detector"/> <menu_item_check label="Вывод минидампа при отладке" name="Output Debug Minidump"/> <menu_item_check label="Окно конÑоли при Ñледующем запуÑке" name="Console Window"/> + <menu label="Уровень журнала" name="Set Logging Level"> + <menu_item_check label="Отладка" name="Debug"/> + <menu_item_check label="ИнформациÑ" name="Info"/> + <menu_item_check label="Предупреждение" name="Warning"/> + <menu_item_check label="Ошибка" name="Error"/> + <menu_item_check label="Ðет" name="None"/> + </menu> <menu_item_call label="Ð—Ð°Ð¿Ñ€Ð¾Ñ ÑтатуÑа админиÑтратора" name="Request Admin Options"/> <menu_item_call label="Выход из ÑтатуÑа админиÑтратора" name="Leave Admin Options"/> <menu_item_check label="Показать меню админиÑтратора" name="View Admin Options"/> </menu> <menu label="ÐдминиÑтратор" name="Admin"> - <menu label="Object"> - <menu_item_call label="ВзÑть копию" name="Take Copy"/> - <menu_item_call label="Ðазначить ÑÐµÐ±Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼" name="Force Owner To Me"/> + <menu label="Объект" name="AdminObject"> + <menu_item_call label="Сделать копию" name="Admin Take Copy"/> + <menu_item_call label="Ðазначить Ð¼ÐµÐ½Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼" name="Force Owner To Me"/> <menu_item_call label="Ðазначить полноправным владельцем" name="Force Owner Permissive"/> <menu_item_call label="Удалить" name="Delete"/> <menu_item_call label="Ðа меÑте" name="Lock"/> @@ -441,7 +453,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="Официальный блог Linden" name="Official Linden Blog"/> <menu_item_call label="Портал Ñкриптов" name="Scripting Portal"/> <menu label="Сообщение об ошибке" name="Bug Reporting"> diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml index d43d907164..85b7074253 100644 --- a/indra/newview/skins/default/xui/ru/notifications.xml +++ b/indra/newview/skins/default/xui/ru/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -86,17 +92,38 @@ <usetemplate canceltext="Отмена" name="yesnocancelbuttons" notext="Ðе ÑохранÑть" yestext="Сохранить"/> </notification> <notification name="ConfirmNoCopyToOutbox"> - У Ð²Ð°Ñ Ð½ÐµÑ‚ прав Ð´Ð»Ñ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñтого Ñлемента в иÑходÑщую папку магазина. Ð’Ñ‹ дейÑтвительно хотите перемеÑтить Ñледующий Ñлемент? - [ITEM_NAME] - <usetemplate name="okcancelbuttons" notext="Ðет" yestext="Да"/> + У Ð²Ð°Ñ Ð½ÐµÑ‚ прав на копирование Ñтих предметов в папку «Торговые иÑходÑщие». ПеремеÑтите их или оÑтавьте здеÑÑŒ. + <usetemplate name="okcancelbuttons" notext="Ðе перемещать предмет(Ñ‹)" yestext="ПеремеÑтить предмет(Ñ‹)"/> + </notification> + <notification name="OutboxFolderCreated"> + Ð”Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ предмета, перенеÑенного на верхний уровень папки «Торговые иÑходÑщие», Ñоздана Ð½Ð¾Ð²Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°. + <usetemplate ignoretext="Ð’ папке «Торговые иÑходÑщие» Ñоздана Ð½Ð¾Ð²Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°" name="okignore" yestext="OK"/> + </notification> + <notification name="OutboxImportComplete"> + УÑпешно + +Ð’Ñе папки уÑпешно отправлены в торговый центр. + <usetemplate ignoretext="Ð’Ñе папки отправлены в торговый центр" name="okignore" yestext="OK"/> + </notification> + <notification name="OutboxImportHadErrors"> + Ðекоторые папки не перенеÑены + +Ошибки при отправке некоторых папок в торговый центр. Ðти папки оÑталиÑÑŒ в вашей папке «Торговые иÑходÑщие». + +Подробнее Ñм. в [[MARKETPLACE_IMPORTS_URL] журнале ошибок]. + <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="OutboxUploadComplete"> - Передача магазина завершена. - <usetemplate name="okbutton" yestext="Ура!"/> + <notification name="OutboxImportFailed"> + Ошибка при передаче + +Папки не отправлены в торговый центр из-за ошибки ÑиÑтемы или Ñети. Повторите попытку позже. + <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="OutboxUploadHadErrors"> - Передача магазина выполнена Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°Ð¼Ð¸! УÑтраните проблемы в иÑходÑщей папке и повторите передачу. СпаÑибо! - <usetemplate name="okbutton" yestext="Бу-у-у!"/> + <notification name="OutboxInitFailed"> + Ошибка инициализации торгового центра + +Ðе удалоÑÑŒ инициализировать торговый центр из-за ошибки ÑиÑтемы или Ñети. Повторите попытку позже. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CompileQueueSaveText"> Ошибка при передаче текÑта Ñкрипта по Ñледующей причине: [REASON]. Повторите попытку позже. @@ -339,13 +366,19 @@ Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в [SECOND_LIFE] нужен аккаунт. Создать его? <url name="url"> - http://join.secondlife.com/ + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Повторить попытку" yestext="Создать новый аккаунт"/> </notification> <notification name="InvalidCredentialFormat"> Введите Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ Ð¸Ð¼Ñ Ð¸ фамилию вашего аватара в поле Â«Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ», затем Ñнова войдите в программу. </notification> + <notification name="InvalidGrid"> + «[GRID]» – недопуÑтимый идентификатор Ñетки. + </notification> + <notification name="InvalidLocationSLURL"> + Ð’ меÑте Ñтарта не указана Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ Ñетка. + </notification> <notification name="DeleteClassified"> Удалить рекламу «[NAME]»? Плата за нее не будет возвращена. @@ -451,8 +484,8 @@ Ошибка при Ñохранении Ñкомпилированного Ñкрипта по Ñледующей причине: [REASON]. Попробуйте Ñохранить Ñкрипт через некоторое времÑ. </notification> <notification name="StartRegionEmpty"> - Ðй-Ñй-Ñй, ваш Ñтартовый регион не определен. -Введите название региона в поле «МеÑто Ñтарта» или выберите в качеÑтве меÑта Ñтарта «Мое поÑледнее меÑтоположение» или «Мой дом». + Ваш Ñтартовый регион не определен. +Введите название региона в поле «МеÑто Ñтарта» или выберите в качеÑтве меÑта Ñтарта «Мое поÑледнее меÑто» или «Мой дом». <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CouldNotStartStopScript"> @@ -474,6 +507,15 @@ </url> <usetemplate ignoretext="Оборудование моего компьютера не поддерживаетÑÑ" name="okcancelignore" notext="Ðет" yestext="Да"/> </notification> + <notification name="IntelOldDriver"> + Возможно, Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ видеокарты имеетÑÑ Ð±Ð¾Ð»ÐµÐµ новый драйвер. Обновление драйвера может ÑущеÑтвенно повыÑить быÑтродейÑтвие. + + Проверить наличие Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð° по адреÑу [_URL]? + <url name="url"> + http://www.intel.com/p/ru_RU/support/detect/graphics + </url> + <usetemplate ignoretext="Мой графичеÑкий драйвер уÑтарел" name="okcancelignore" notext="Ðет" yestext="Да"/> + </notification> <notification name="UnknownGPU"> Ð’ вашей ÑиÑтеме уÑтановлена графичеÑÐºÐ°Ñ ÐºÐ°Ñ€Ñ‚Ð°, которую [APP_NAME] не может раÑпознать. Так чаÑто бывает, еÑли новое оборудование еще не было проверено на работу Ñ [APP_NAME]. Скорее вÑего, оно будет работать нормально, но, возможно, придетÑÑ Ð¾Ñ‚Ñ€ÐµÐ³ÑƒÐ»Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ параметры графики. @@ -570,6 +612,9 @@ УбедитеÑÑŒ, что вÑе объекты разблокированы и что вы владеете вÑеми ими. </notification> + <notification name="CannotLinkPermanent"> + Объекты Ð½ÐµÐ»ÑŒÐ·Ñ ÑвÑзывать через границу региона. + </notification> <notification name="CannotLinkDifferentOwners"> Ðевозможно объединить объекты: не у вÑех объектов один владелец. @@ -649,7 +694,7 @@ Ðевозможно Ñоздать выходной файл: [FILE] </notification> <notification name="DoNotSupportBulkAnimationUpload"> - [APP_NAME] пока не поддерживает маÑÑовую передачу файлов анимации. + [APP_NAME] пока не поддерживает маÑÑовую передачу файлов анимации формата BVH. </notification> <notification name="CannotUploadReason"> Ðевозможно передать [FILE] по Ñледующей причине: [REASON] @@ -948,6 +993,41 @@ <button name="Cancel" text="Отмена"/> </form> </notification> + <notification label="Добавить ÑпиÑок автозамены" name="AddAutoReplaceList"> + Ð˜Ð¼Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ ÑпиÑка: + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="Переименовать ÑпиÑок автозамены" name="RenameAutoReplaceList"> + Ð˜Ð¼Ñ Â«[DUPNAME]» уже занÑто. + Введите новое уникальное имÑ: + <form name="form"> + <button name="ReplaceList" text="Заменить текущий ÑпиÑок"/> + <button name="SetName" text="ИÑпользовать новое имÑ"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + Ключевое Ñлово должно быть одним Ñловом, а поле замены не может быть пуÑтым. + </notification> + <notification name="InvalidAutoReplaceList"> + ÐедопуÑтимый ÑпиÑок замены. + </notification> + <notification name="SpellingDictImportRequired"> + Следует указать файл, Ð¸Ð¼Ñ Ð¸ Ñзык. + </notification> + <notification name="SpellingDictIsSecondary"> + Словарь [DIC_NAME] не ÑвлÑетÑÑ aff-файлом, Ñ‚. е. Ñто «вÑпомогательный» Ñловарь. +Он может иÑпользоватьÑÑ ÐºÐ°Ðº дополнительный, но не как оÑновной Ñловарь. + +См. https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + Ðевозможно Ñкопировать + [FROM_NAME] + в + [TO_NAME] + </notification> <notification label="Сохранить коÑтюм" name="SaveOutfitAs"> Сохранить текущую одежду как новый коÑтюм: <form name="form"> @@ -979,7 +1059,7 @@ </form> </notification> <notification name="RemoveFromFriends"> - Удалить Ð¶Ð¸Ñ‚ÐµÐ»Ñ [NAME] из вашего ÑпиÑка друзей? + Удалить Ð¶Ð¸Ñ‚ÐµÐ»Ñ <nolink>[NAME]</nolink> из вашего ÑпиÑка друзей? <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> </notification> <notification name="RemoveMultipleFromFriends"> @@ -1110,8 +1190,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] @@ -1122,7 +1207,7 @@ Ð’Ñ‹ перемещены в ÑоÑедний регион. </notification> <notification name="AvatarMovedLast"> - Ваше поÑледнее меÑтоположение ÑÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ´Ð¾Ñтупно. + Требуемое вами меÑтоположение ÑÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ´Ð¾Ñтупно. Ð’Ñ‹ перемещены в ÑоÑедний регион. </notification> <notification name="AvatarMovedHome"> @@ -1141,7 +1226,6 @@ УÑтановка [APP_NAME] завершена. ЕÑли вы иÑпользуете [SECOND_LIFE] впервые, Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в программу вам потребуетÑÑ Ñоздать аккаунт. -ВернутьÑÑ Ð½Ð° [http://join.secondlife.com secondlife.com] Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð°ÐºÐºÐ°ÑƒÐ½Ñ‚Ð°? <usetemplate name="okcancelbuttons" notext="Продолжить" yestext="Создать аккаунт..."/> </notification> <notification name="LoginPacketNeverReceived"> @@ -1431,7 +1515,7 @@ http://secondlife.com/download. <usetemplate ignoretext="Подтверждать перед возвратом объектов владельцам" name="okcancelignore" notext="Отмена" yestext="OK"/> </notification> <notification name="GroupLeaveConfirmMember"> - Ð’Ñ‹ ÑвлÑетеÑÑŒ учаÑтником группы [GROUP]. + Ð’Ñ‹ ÑÐµÐ¹Ñ‡Ð°Ñ Ð²Ñ…Ð¾Ð´Ð¸Ñ‚Ðµ в группу <nolink>[GROUP]</nolink>. Хотите покинуть группу? <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> </notification> @@ -1659,83 +1743,128 @@ http://secondlife.com/download. <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> </notification> <notification name="RegionEntryAccessBlocked"> - Вам Ð½ÐµÐ»ÑŒÐ·Ñ Ð±Ñ‹Ñ‚ÑŒ в Ñтом регионе из-за вашего рейтинга зрелоÑти. Возможно, Ñто результат недоÑтатка информации, подтверждающей ваш возраÑÑ‚. - -УбедитеÑÑŒ, что у Ð²Ð°Ñ ÑƒÑтановлена поÑледнÑÑ Ð²ÐµÑ€ÑÐ¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð°, и прочитайте в Базе знаний о доÑтупе к облаÑÑ‚Ñм Ñ Ñтим рейтингом зрелоÑти. + Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором не ÑоответÑтвует вашим наÑтройкам. Попробуйте изменить наÑтройки в меню «Я > ÐаÑтройки > Общие». <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - Вам Ð½ÐµÐ»ÑŒÐ·Ñ Ð±Ñ‹Ñ‚ÑŒ в Ñтом регионе из-за вашего рейтинга зрелоÑти. - -Перейти в Базу знаний и ознакомитьÑÑ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð°Ð¼Ð¸ зрелоÑти? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY] и предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Я не могу войти в Ñтот регион из-за ограничений по рейтингу зрелоÑти" name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> + <usetemplate ignoretext="ПереÑечение региона: вы пытаетеÑÑŒ поÑетить регион, контент в котором предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых." name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - Вам Ð½ÐµÐ»ÑŒÐ·Ñ Ð±Ñ‹Ñ‚ÑŒ в Ñтом регионе из-за вашего рейтинга зрелоÑти. + Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY] и предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых. </notification> <notification name="RegionEntryAccessBlocked_Change"> - Вам Ð½ÐµÐ»ÑŒÐ·Ñ Ð±Ñ‹Ñ‚ÑŒ в Ñтом регионе из-за вашей наÑтройки рейтинга зрелоÑти. - -Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в желаемый регион измените наÑтройку рейтинга зрелоÑти. ПоÑле Ñтого вам будет разрешено иÑкать и проÑматривать контент [REGIONMATURITY]. Ð”Ð»Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ñ‹ изменений выберите команды «Я > ÐаÑтройки > Общие». + Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. Ð’Ñ‹ можете отказатьÑÑ Ð¾Ñ‚ поÑещениÑ, или ваши наÑтройки будут изменены. ПоÑле Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ð°Ñтроек вы можете попробовать войти в регион Ñнова. + <form name="form"> + <button name="OK" text="Изменить наÑтройки"/> + <button name="Cancel" text="Отмена"/> + <ignore name="ignore" text="ПереÑечение региона: вы пытаетеÑÑŒ поÑетить регион, контент в котором запрещен вашими наÑтройками."/> + </form> + </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + При телепортации возникли техничеÑкие проблемы, так как ваши наÑтройки не Ñинхронизированы Ñ Ñервером. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором не ÑоответÑтвует вашим наÑтройкам. Попробуйте изменить наÑтройки в меню «Я > ÐаÑтройки > Общие». + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY] и предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых. + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="ТелепортациÑ: вы пытаетеÑÑŒ поÑетить регион, контент в котором предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых." name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY] и предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. Ð’Ñ‹ можете отказатьÑÑ Ð¾Ñ‚ телепортации, или ваши наÑтройки будут изменены. <form name="form"> - <button name="OK" text="Изменить наÑтройку"/> - <button name="Cancel" text="Закрыть"/> - <ignore name="ignore" text="Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð¼Ð½Ð¾Ð¹ наÑтройка рейтинга запрещает мне вход в регион"/> + <button name="OK" text="Изменить и продолжить"/> + <button name="Cancel" text="Отмена"/> + <ignore name="ignore" text="Ð¢ÐµÐ»ÐµÐ¿Ð¾Ñ€Ñ‚Ð°Ñ†Ð¸Ñ (возобновлÑемаÑ): вы пытаетеÑÑŒ поÑетить регион, контент в котором запрещен вашими наÑтройками."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. Ð’Ñ‹ можете отказатьÑÑ Ð¾Ñ‚ телепортации, или ваши наÑтройки будут изменены. ПоÑле Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ð°Ñтроек вы можете попробовать телепортироватьÑÑ Ñнова. + <form name="form"> + <button name="OK" text="Изменить наÑтройки"/> + <button name="Cancel" text="Отмена"/> + <ignore name="ignore" text="Ð¢ÐµÐ»ÐµÐ¿Ð¾Ñ€Ñ‚Ð°Ñ†Ð¸Ñ (невозобновлÑемаÑ): вы пытаетеÑÑŒ поÑетить регион, контент в котором запрещен вашими наÑтройками."/> </form> </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + При телепортации возникли техничеÑкие проблемы, так как ваши наÑтройки не Ñинхронизированы Ñ Ñервером. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - Теперь ваша наÑтройка рейтинга зрелоÑти: [RATING]. + Ð’Ñ‹ больше не будете получать уведомлений о поÑещении региона Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ½Ñ‚Ð¾Ð¼ рейтинга [RATING]. ÐаÑтройки Ð´Ð»Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ½Ñ‚Ð° можно изменить на будущее Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ команд меню «Я > ÐаÑтройки > Общие». + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + Ðе удалоÑÑŒ изменить ваши наÑтройки так, чтобы вы могли видеть контент Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð¾Ð¼ [PREFERRED_MATURITY]. Ваши теперешние наÑтройки разрешают проÑматривать контент [ACTUAL_MATURITY]. Попробуйте изменить наÑтройки Ñнова Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ команд меню «Я > ÐаÑтройки > Общие». + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - Ð’Ñ‹ не можете претендовать на Ñту землю из-за вашего рейтинга зрелоÑти. Возможно, Ñто результат недоÑтатка информации, подтверждающей ваш возраÑÑ‚. - -УбедитеÑÑŒ, что у Ð²Ð°Ñ ÑƒÑтановлена поÑледнÑÑ Ð²ÐµÑ€ÑÐ¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð°, и прочитайте в Базе знаний о доÑтупе к облаÑÑ‚Ñм Ñ Ñтим рейтингом зрелоÑти. + Ð’Ñ‹ претендуете на землю, рейтинг зрелоÑти контента на которой не ÑоответÑтвует вашим наÑтройкам. Попробуйте изменить наÑтройки в меню «Я > ÐаÑтройки > Общие». <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - Ð’Ñ‹ не можете претендовать на Ñту землю из-за вашего рейтинга зрелоÑти. - -Перейти в Базу знаний и ознакомитьÑÑ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð°Ð¼Ð¸ зрелоÑти? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + Ðа Ñту землю могут претендовать только взроÑлые. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Я не могу претендовать на Ñту землю из-за ограничений по рейтингу зрелоÑти" name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> + <usetemplate ignoretext="Ðа Ñту землю могут претендовать только взроÑлые." name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - Ð’Ñ‹ не можете претендовать на Ñту землю из-за вашего рейтинга зрелоÑти. + Ð’Ñ‹ претендуете на землю, контент на которой имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + Ð’Ñ‹ претендуете на землю Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ½Ñ‚Ð¾Ð¼ [REGIONMATURITY], который предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых. </notification> <notification name="LandClaimAccessBlocked_Change"> - Ð’Ñ‹ не можете претендовать на Ñту землю из-за вашей наÑтройки рейтинга зрелоÑти. - -Ðажмите кнопку «Изменить наÑтройку», чтобы повыÑить Ñвой рейтинг зрелоÑти. ПоÑле Ñтого вам будет разрешено иÑкать и проÑматривать контент [REGIONMATURITY]. ЕÑли в будущем понадобитÑÑ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ñто изменение, выберите команды «Я > ÐаÑтройки > Общие». - <usetemplate ignoretext="Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð¼Ð½Ð¾Ð¹ наÑтройка рейтинга запрещает мне претендовать на землю" name="okcancelignore" notext="Закрыть" yestext="Изменить наÑтройку"/> + Ð’Ñ‹ претендуете на землю, контент на которой имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. Мы можем изменить ваши наÑтройки, поÑле чего вы Ñможете претендовать на землю Ñнова. + <form name="form"> + <button name="OK" text="Изменить наÑтройки"/> + <button name="Cancel" text="Отмена"/> + <ignore name="ignore" text="Ð’Ñ‹ претендуете на землю, контент на которой запрещен вашими наÑтройками."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - Ð’Ñ‹ не можете купить Ñту землю из-за вашего рейтинга зрелоÑти. Возможно, Ñто результат недоÑтатка информации, подтверждающей ваш возраÑÑ‚. - -УбедитеÑÑŒ, что у Ð²Ð°Ñ ÑƒÑтановлена поÑледнÑÑ Ð²ÐµÑ€ÑÐ¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð°, и прочитайте в Базе знаний о доÑтупе к облаÑÑ‚Ñм Ñ Ñтим рейтингом зрелоÑти. + Ð’Ñ‹ пытаетеÑÑŒ купить землю, рейтинг зрелоÑти контента на которой не ÑоответÑтвует вашим наÑтройкам. Попробуйте изменить наÑтройки в меню «Я > ÐаÑтройки > Общие». <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - Ð’Ñ‹ не можете купить Ñту землю из-за вашего рейтинга зрелоÑти. - -Перейти в Базу знаний и ознакомитьÑÑ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð°Ð¼Ð¸ зрелоÑти? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Ðту землю могут купить только взроÑлые. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Я не могу купить Ñту землю из-за ограничений по рейтингу зрелоÑти" name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> + <usetemplate ignoretext="Ðту землю могут купить только взроÑлые." name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - Ð’Ñ‹ не можете купить Ñту землю из-за вашего рейтинга зрелоÑти. + Ð’Ñ‹ пытаетеÑÑŒ купить землю, контент на которой имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + Ð’Ñ‹ пытаетеÑÑŒ купить землю Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ½Ñ‚Ð¾Ð¼ [REGIONMATURITY], который предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых. </notification> <notification name="LandBuyAccessBlocked_Change"> - Ð’Ñ‹ не можете купить Ñту землю из-за выбранного вами рейтинга зрелоÑти. - -Ðажмите кнопку «Изменить наÑтройку», чтобы повыÑить Ñвой рейтинг зрелоÑти. ПоÑле Ñтого вам будет разрешено иÑкать и проÑматривать контент [REGIONMATURITY]. ЕÑли в будущем понадобитÑÑ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ñто изменение, выберите команды «Я > ÐаÑтройки > Общие». - <usetemplate ignoretext="Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð¼Ð½Ð¾Ð¹ наÑтройка рейтинга запрещает мне покупать землю" name="okcancelignore" notext="Закрыть" yestext="Изменить наÑтройку"/> + Ð’Ñ‹ пытаетеÑÑŒ купить землю, контент на которой имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. Мы можем изменить ваши наÑтройки, поÑле чего вы Ñможете попробовать купить землю Ñнова. + <form name="form"> + <button name="OK" text="Изменить наÑтройки"/> + <button name="Cancel" text="Отмена"/> + <ignore name="ignore" text="Ð’Ñ‹ пытаетеÑÑŒ купить землю, контент на которой запрещен вашими наÑтройками."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Выбрано Ñлишком много примитивов. Выберите [MAX_PRIM_COUNT] или меньше примитивов и повторите попытку. @@ -1789,10 +1918,9 @@ http://secondlife.com/download. </form> </notification> <notification label="Изменен рейтинг зрелоÑти региона" name="RegionMaturityChange"> - Рейтинг зрелоÑти Ð´Ð»Ñ Ñтого региона будет обновлен. + Рейтинг зрелоÑти Ð´Ð»Ñ Ñтого региона был изменен. Отображение Ñтого Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ð° карте может занÑть некоторое времÑ. - -Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в регионы Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых у Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ быть подтвержденный аккаунт: либо Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸ÐµÐ¼ возраÑта, либо Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸ÐµÐ¼ оплаты. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="ÐеÑоответÑтвие верÑии голоÑа" name="VoiceVersionMismatch"> Ð”Ð°Ð½Ð½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ [APP_NAME] неÑовмеÑтима Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸ÐµÐ¹ голоÑового чата в Ñтом регионе. Ð”Ð»Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ð¹ работы голоÑового чата необходимо обновить [APP_NAME]. @@ -1910,7 +2038,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"/> @@ -2076,14 +2210,11 @@ http://secondlife.com/download. <usetemplate ignoretext="Ðадевать одежду, Ñоздаваемую при редактировании моей внешноÑти" name="okcancelignore" notext="Ðет" yestext="Да"/> </notification> <notification name="NotAgeVerified"> - ДоÑтуп к контенту и облаÑÑ‚Ñм Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых в Second Life разрешен только Ñ 18 лет. ПоÑетите нашу Ñтраницу проверки возраÑта и подтвердите, что вам уже иÑполнилоÑÑŒ 18. -Страница будет открыта в браузере. - -[_URL] - <url name="url"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="Мой возраÑÑ‚ не подтвержден" name="okcancelignore" notext="Отмена" yestext="Перейти к проверке возраÑта"/> + Ð’Ñ‹ пытаетеÑÑŒ поÑетить меÑто, доÑтуп в которое разрешен только жителÑм 18 лет и Ñтарше. + <usetemplate ignoretext="Мне еще рано поÑещать меÑта Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñми по возраÑту." name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + Ðто меÑто разрешено Ð´Ð»Ñ Ð¶Ð¸Ñ‚ÐµÐ»ÐµÐ¹ 18 лет и Ñтарше. </notification> <notification name="Cannot enter parcel: no payment info on file"> Ð”Ð»Ñ Ð¿Ð¾ÑÐµÑ‰ÐµÐ½Ð¸Ñ Ñтой облаÑти необходимо зарегиÑтрировать платеж. Перейти на веб-Ñайт [SECOND_LIFE] и ввеÑти Ñту информацию? @@ -2119,10 +2250,10 @@ http://secondlife.com/download. Раздел: [SUBJECT], Ñообщение: [MESSAGE] </notification> <notification name="FriendOnline"> - [NAME] в Ñети + <nolink>[NAME]</nolink> в Ñети </notification> <notification name="FriendOffline"> - [NAME] не в Ñети + <nolink>[NAME]</nolink> не в Ñети </notification> <notification name="AddSelfFriend"> Ð’Ñ‹ лучше вÑех, но Ð½ÐµÐ»ÑŒÐ·Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ в Ð´Ñ€ÑƒÐ·ÑŒÑ ÑÐµÐ±Ñ Ñамого. @@ -2236,14 +2367,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 +2397,9 @@ http://secondlife.com/download. <notification name="PaymentSent"> [MESSAGE] </notification> + <notification name="PaymentFailure"> + [MESSAGE] + </notification> <notification name="EventNotification"> Уведомление о Ñобытии: @@ -2340,6 +2476,23 @@ http://secondlife.com/download. <notification name="NoBuild"> Ð’ Ñтой облаÑти запрещено ÑтроительÑтво. ЗдеÑÑŒ вы не Ñможете Ñтроить или выкладывать объекты. </notification> + <notification name="PathfindingDirty"> + Ð’ регионе еÑть незавершенные Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð¸Ñка пути. ЕÑли у Ð²Ð°Ñ ÐµÑть права на ÑтроительÑтво, воÑÑтановите регион, нажав кнопку «ВоÑÑтановить регион». + </notification> + <notification name="DynamicPathfindingDisabled"> + Ð’ Ñтом регионе не разрешен динамичеÑкий поиÑк пути. Возможны Ð½Ð°Ñ€ÑƒÑˆÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñкриптовых объектов Ñ Ð¸Ñпользованием вызовов LSL поиÑка пути. + </notification> + <notification name="PathfindingRebakeNavmesh"> + Изменение некоторых объектов в регионе может привеÑти к неправильному поведению других подвижных объектов. Чтобы иÑправить их поведение, нажмите кнопку «ВоÑÑтановить регион». Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ â€“ по ÑÑылке «Справка». + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Справка" ignoretext="Изменение некоторых объектов в регионе может привеÑти к неправильному поведению других подвижных объектов." name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Произошла ошибка. Возможно, неполадка в Ñети или на Ñервере, или у Ð²Ð°Ñ Ð½ÐµÑ‚ прав на ÑтроительÑтво. Иногда Ð´Ð»Ñ ÑƒÑÑ‚Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñтой проблемы доÑтаточно выйти и Ñнова войти. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> Ðа Ñтом учаÑтке аватары и текÑтовый чат Ñкрыты от другого учаÑтка. Жителей за пределами Ñтого учаÑтка не будет видно, а они не будут видеть ваÑ. Обычный текÑтовый чат на канале 0 также блокируетÑÑ. </notification> @@ -2358,9 +2511,7 @@ http://secondlife.com/download. Ð’Ñ‹ можете претендовать на публичную землю только в регионе, в котором вы находитеÑÑŒ. </notification> <notification name="RegionTPAccessBlocked"> - Вам Ð½ÐµÐ»ÑŒÐ·Ñ Ð±Ñ‹Ñ‚ÑŒ в Ñтом регионе из-за вашего рейтинга зрелоÑти. Подтвердите Ñвой возраÑÑ‚ и/или уÑтановите поÑледнюю верÑию клиента. - -Прочитайте в Базе знаний о доÑтупе к облаÑÑ‚Ñм Ñ Ñтим рейтингом зрелоÑти. + Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором не ÑоответÑтвует вашим наÑтройкам. Попробуйте изменить наÑтройки в меню «Я > ÐаÑтройки > Общие». </notification> <notification name="URBannedFromRegion"> Ð’Ñ‹ забанены в регионе. @@ -2371,11 +2522,11 @@ http://secondlife.com/download. <notification name="ImproperPaymentStatus"> У Ð²Ð°Ñ Ð½ÐµÑ‚ необходимого ÑтатуÑа оплаты Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в Ñтот регион. </notification> - <notification name="MustGetAgeRgion"> - Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в Ñтот регион необходимо подтверждение возраÑта. + <notification name="MustGetAgeRegion"> + Входить в Ñтот регион могут только жители 18 лет и Ñтарше. </notification> <notification name="MustGetAgeParcel"> - Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° на Ñтот учаÑток необходимо подтверждение возраÑта. + Входить на Ñтот учаÑток могут только жители 18 лет и Ñтарше. </notification> <notification name="NoDestRegion"> Ðе найден регион назначениÑ. @@ -2477,12 +2628,33 @@ http://secondlife.com/download. <notification name="TeleportOffered"> [NAME_SLURL] предложил(а) телепортировать Ð²Ð°Ñ Ðº Ñебе: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +«[MESSAGE]» +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="ТелепортациÑ"/> <button name="Cancel" text="Отмена"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] предложил(а) телепортировать Ð²Ð°Ñ Ðº Ñебе: + +«[MESSAGE]» +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Ðтот регион Ñодержит контент Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð¾Ð¼ [REGION_CONTENT_MATURITY], но ваши наÑтройки не допуÑкают контента [REGION_CONTENT_MATURITY]. Ð’Ñ‹ можете отказатьÑÑ Ð¾Ñ‚ телепортации, или ваши наÑтройки будут изменены. + <form name="form"> + <button name="Teleport" text="Изменить и продолжить"/> + <button name="Cancel" text="Отмена"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] предложил(а) телепортировать Ð²Ð°Ñ Ðº Ñебе: + +«[MESSAGE]» +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Однако Ñтот регион Ñодержит контент, доÑтупный только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых. + </notification> <notification name="TeleportOfferSent"> Предложение телепортации отправлено [TO_NAME] </notification> @@ -2518,10 +2690,10 @@ http://secondlife.com/download. </form> </notification> <notification name="FriendshipAccepted"> - [NAME] принÑл(а) ваше предложение дружить. + <nolink>[NAME]</nolink> принÑл(а) ваше предложение дружить. </notification> <notification name="FriendshipDeclined"> - [NAME] отклонил(а) ваше предложение дружить. + <nolink>[NAME]</nolink> отклонил(а) ваше предложение дружить. </notification> <notification name="FriendshipAcceptedByMe"> Предложение дружить принÑто. @@ -2577,32 +2749,28 @@ http://secondlife.com/download. </form> </notification> <notification name="ScriptQuestionCaution"> - Объект «<nolink>[OBJECTNAME]</nolink>», владелец которого – «[NAME]», желает: - -[QUESTIONS] -ЕÑли вы не доверÑете Ñтому объекту или его Ñоздателю, отклоните запроÑ. - -ПринÑть Ñтот запроÑ? + Предупреждение. Объект «<nolink>[OBJECTNAME]</nolink>» требует полного доÑтупа к вашему аккаунту Ð´Ð»Ñ Linden-долларов. ЕÑли разрешить такой доÑтуп, объект Ñможет в любое Ð²Ñ€ÐµÐ¼Ñ Ñнимать ÑредÑтва Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ аккаунта или полноÑтью опуÑтошать его неоднократно и без предупреждениÑ. + +Такое требование чаще вÑего незаконно. Ðе разрешайте доÑтуп к Ñвоему аккаунту, еÑли только не полноÑтью оÑознаете, зачем он нужен Ñтому объекту. <form name="form"> - <button name="Grant" text="ПринÑть"/> + <button name="Grant" text="Разрешить полный доÑтуп"/> <button name="Deny" text="Отклонить"/> - <button name="Details" text="ПодробноÑти..."/> </form> </notification> <notification name="ScriptDialog"> [NAME] – «<nolink>[TITLE]</nolink>» [MESSAGE] <form name="form"> - <button name="Mute" text="Блокировать"/> - <button name="Ignore" text="Игнорировать"/> + <button name="Client_Side_Mute" text="Заблокировать"/> + <button name="Client_Side_Ignore" text="Игнорировать"/> </form> </notification> <notification name="ScriptDialogGroup"> [GROUPNAME] – «<nolink>[TITLE]</nolink>» [MESSAGE] <form name="form"> - <button name="Mute" text="Блокировать"/> - <button name="Ignore" text="Игнорировать"/> + <button name="Client_Side_Mute" text="Заблокировать"/> + <button name="Client_Side_Ignore" text="Игнорировать"/> </form> </notification> <notification name="BuyLindenDollarSuccess"> @@ -2798,6 +2966,18 @@ http://secondlife.com/download. Со Ñледующими жителÑми: [RESIDENTS] + <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> + </notification> + <notification name="ShareFolderConfirmation"> + Раздать можно только одну папку за раз. + +Ð’Ñ‹ дейÑтвительно хотите поделитьÑÑ Ð¿Ñ€ÐµÐ´Ð¼ÐµÑ‚Ð°Ð¼Ð¸: + +<nolink>[ITEMS]</nolink> + +Со Ñледующими жителÑми: + +[RESIDENTS] <usetemplate name="okcancelbuttons" notext="Отмена" yestext="ОК"/> </notification> <notification name="ItemsShared"> @@ -2878,6 +3058,10 @@ http://secondlife.com/download. ( [EXISTENCE] Ñек. жизни ) Ð’Ñ‹ локально обновили готовую текÑтуру [RESOLUTION] Ð´Ð»Ñ Â«[BODYREGION]» через [TIME] Ñек. </notification> + <notification name="LivePreviewUnavailable"> + ПроÑмотр Ñтой текÑтуры невозможен, так как запрещено ее копирование и/или переноÑ. + <usetemplate ignoretext="Предупреждать, еÑли режим проÑмотра вживую недоÑтупен Ð´Ð»Ñ Ñ‚ÐµÐºÑтур Ñ Ð·Ð°Ð¿Ñ€ÐµÑ‰ÐµÐ½Ð½Ñ‹Ð¼ копированием и/или переноÑом" name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> ДейÑтвительно покинуть Ñтот разговор? <usetemplate ignoretext="Подтверждать перед выходом из разговора" name="okcancelignore" notext="Ðет" yestext="Да"/> @@ -2888,7 +3072,7 @@ http://secondlife.com/download. позже, даже поÑле того, как вы покинули разговор. Заглушить вÑех? - <usetemplate ignoretext="Подтверждать перед заглушением вÑех учаÑтников группового разговора" name="okcancelignore" notext="Отмена" yestext="ОК"/> + <usetemplate ignoretext="Подтверждать перед заглушением вÑех учаÑтников группового разговора" name="okcancelignore" notext="Отмена" yestext="OK"/> </notification> <notification label="Чат" name="HintChat"> Чтобы приÑоединитьÑÑ Ðº чату, введите Ñлова в поле чата ниже. @@ -3049,6 +3233,62 @@ http://secondlife.com/download. Ðто дейÑтвие приведет к Ñкрытию вÑех меню и кнопок. Чтобы вернуть их, щелкните [SHORTCUT] Ñнова. <usetemplate ignoretext="Подтверждать перед Ñкрытием интерфейÑа" name="okcancelignore" notext="Отмена" yestext="OK"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + Признак фантомноÑти некоторых выбранных наборов ÑвÑзей будет изменен. + +Продолжить? + <usetemplate ignoretext="Признак фантомноÑти некоторых выбранных наборов ÑвÑзей будет изменен." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ тип «[REQUESTED_TYPE]» из-за ограничений Ñтих наборов. Ðти наборы ÑвÑзей будут иметь тип «[RESTRICTED_TYPE]». + +Продолжить? + <usetemplate ignoretext="ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ некоторые выбранные наборы ÑвÑзей из-за ограничений Ñтих наборов." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей невозможно задать тип «[REQUESTED_TYPE]», так как фигура не выпуклаÑ. + +Продолжить? + <usetemplate ignoretext="ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ некоторые выбранные наборы ÑвÑзей, так как фигура не выпуклаÑ." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + Признак фантомноÑти некоторых выбранных наборов ÑвÑзей будет изменен. + +Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ тип «[REQUESTED_TYPE]» из-за ограничений Ñтих наборов. Ðти наборы ÑвÑзей будут иметь тип «[RESTRICTED_TYPE]». + +Продолжить? + <usetemplate ignoretext="Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей будет изменен признак фантомноÑти, а другие наборы Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ из-за ограничений Ñтих наборов." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + Признак фантомноÑти некоторых выбранных наборов ÑвÑзей будет изменен. + +Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей невозможно задать тип «[REQUESTED_TYPE]», так как фигура не выпуклаÑ. + +Продолжить? + <usetemplate ignoretext="Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей будет изменен признак фантомноÑти, а другие наборы Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ, так как фигура не выпуклаÑ." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ тип «[REQUESTED_TYPE]» из-за ограничений Ñтих наборов. Ðти наборы ÑвÑзей будут иметь тип «[RESTRICTED_TYPE]». + +Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей невозможно задать тип «[REQUESTED_TYPE]», так как фигура не выпуклаÑ. Тип иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñтих наборов ÑвÑзей не изменитÑÑ. + +Продолжить? + <usetemplate ignoretext="ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ некоторые выбранные наборы ÑвÑзей из-за ограничений Ñтих наборов и потому, что фигура не выпуклаÑ." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + Признак фантомноÑти некоторых выбранных наборов ÑвÑзей будет изменен. + +Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ тип «[REQUESTED_TYPE]» из-за ограничений Ñтих наборов. Ðти наборы ÑвÑзей будут иметь тип «[RESTRICTED_TYPE]». + +Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей невозможно задать тип «[REQUESTED_TYPE]», так как фигура не выпуклаÑ. Тип иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñтих наборов ÑвÑзей не изменитÑÑ. + +Продолжить? + <usetemplate ignoretext="Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей будет изменен признак фантомноÑти, а другие наборы Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ из-за ограничений Ñтих наборов и потому, что фигура не выпуклаÑ." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + Выбранный объект влиÑет на навигационную Ñетку. ЕÑли заменить его на гибкий путь, он будет удален из навигационной Ñетки. + <usetemplate ignoretext="Выбранный объект влиÑет на навигационную Ñетку. ЕÑли заменить его на гибкий путь, он будет удален из навигационной Ñетки." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> <global name="UnsupportedGLRequirements"> По-видимому, ваше оборудование не удовлетворÑет требованиÑм [APP_NAME]. Ð”Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ [APP_NAME] необходима графичеÑÐºÐ°Ñ ÐºÐ°Ñ€Ñ‚Ð° OpenGL Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¾Ð¹ мультитекÑтур. ЕÑли у Ð²Ð°Ñ ÐµÑть Ñ‚Ð°ÐºÐ°Ñ ÐºÐ°Ñ€Ñ‚Ð°, убедитеÑÑŒ, что уÑтановлены новейшие верÑии драйверов Ð´Ð»Ñ Ð½ÐµÐµ и пакеты обновлений и иÑÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¾Ð¹ ÑиÑтемы. @@ -3073,4 +3313,24 @@ http://secondlife.com/download. <global name="You died and have been teleported to your home location"> Ð’Ñ‹ умерли и были телепортированы в ваше домашнее меÑтоположение. </global> + <notification name="LocalBitmapsUpdateFileNotFound"> + Ðе удалоÑÑŒ обновить [FNAME]: файл не найден. +ПоÑледующее обновление Ñтого файла запрещаетÑÑ. + </notification> + <notification name="LocalBitmapsUpdateFailedFinal"> + Ðе удалоÑÑŒ открыть или декодировать [FNAME] Ñ [NRETRIES] попыток. Ðтот файл ÑчитаетÑÑ Ð¿Ð¾Ð²Ñ€ÐµÐ¶Ð´ÐµÐ½Ð½Ñ‹Ð¼. +ПоÑледующее обновление Ñтого файла запрещаетÑÑ. + </notification> + <notification name="LocalBitmapsVerifyFail"> + Попытка добавить недопуÑтимый или нечитаемый файл Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ [FNAME], который не удалоÑÑŒ открыть или декодировать. +Попытка отменена. + </notification> + <notification name="PathfindingReturnMultipleItems"> + Возвращено [NUM_ITEMS] Ñлементов. Продолжить? + <usetemplate ignoretext="Возвратить неÑколько предметов?" name="okcancelignore" notext="Ðет" yestext="Да"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + Ð’Ñ‹ удалÑете неÑколько предметов ([NUM_ITEMS]). Продолжить? + <usetemplate ignoretext="Удалить неÑколько предметов?" name="okcancelignore" notext="Ðет" yestext="Да"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/ru/panel_bottomtray.xml b/indra/newview/skins/default/xui/ru/panel_bottomtray.xml deleted file mode 100644 index ebf6c4264b..0000000000 --- a/indra/newview/skins/default/xui/ru/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Включить/выключить микрофон"/> - <string name="VoiceControlBtnToolTip" value="Показать/Ñкрыть панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð³Ð¾Ð»Ð¾Ñом"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Говорить" label_selected="Говорить" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="ЖеÑты" name="Gesture" tool_tip="Показать/Ñкрыть жеÑты"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Перемещение" name="movement_btn" tool_tip="Показать/Ñкрыть панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð²Ð¸Ð¶ÐµÐ½Ð¸ÐµÐ¼"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Камера" name="camera_btn" tool_tip="Показать/Ñкрыть управление камерой"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button name="snapshots" tool_tip="Сделать Ñнимок"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="СтроительÑтво" name="build_btn" tool_tip="Показать/Ñкрыть инÑтрументы"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="ПоиÑк" name="search_btn" tool_tip="Показать/Ñкрыть поиÑк"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Карта" name="world_map_btn" tool_tip="Показать/Ñкрыть карту мира"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Миникарта" name="mini_map_btn" tool_tip="Показать/Ñкрыть миникарту"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Общение"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="УведомлениÑ"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> 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_group_invite.xml b/indra/newview/skins/default/xui/ru/panel_group_invite.xml index 3041046041..68dac5cd7e 100644 --- a/indra/newview/skins/default/xui/ru/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/ru/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> ÐеÑколько выбранных жителей уже ÑоÑтоÑÑ‚ в группе. Им Ð¿Ñ€Ð¸Ð³Ð»Ð°ÑˆÐµÐ½Ð¸Ñ Ð½Ðµ были отправлены. </panel.string> + <panel.string name="invite_selection_too_large"> + Групповые Ð¿Ñ€Ð¸Ð³Ð»Ð°ÑˆÐµÐ½Ð¸Ñ Ð½Ðµ отправлены: выбрано Ñлишком много жителей. Групповые Ð¿Ñ€Ð¸Ð³Ð»Ð°ÑˆÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ охватывать не более 100 пользователей за один запроÑ. + </panel.string> <text name="help_text"> Можно выбрать неÑколько жителей Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð³Ð»Ð°ÑˆÐµÐ½Ð¸Ñ Ð² группу. Чтобы начать, щелкните «Выбрать жителей». </text> diff --git a/indra/newview/skins/default/xui/ru/panel_login.xml b/indra/newview/skins/default/xui/ru/panel_login.xml index 7928191fa6..f0877731c6 100644 --- a/indra/newview/skins/default/xui/ru/panel_login.xml +++ b/indra/newview/skins/default/xui/ru/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + ВОЙТИ + </text> <text name="username_text"> Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: </text> @@ -15,15 +15,8 @@ <text name="password_text"> Пароль: </text> - <check_box label="Запомнить пароль" name="remember_check"/> - <button label="Войти" name="connect_btn"/> - <text name="mode_selection_text"> - Режим: - </text> - <combo_box name="mode_combo" tool_tip="Выберите режим. ОÑновной – Ð´Ð»Ñ Ð±Ñ‹Ñтрого и проÑтого Ð¾Ð·Ð½Ð°ÐºÐ¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ñ Ð¸Ð³Ñ€Ð¾Ð¹, а также общениÑ. РаÑширенный – Ð´Ð»Ñ Ð´Ð¾Ñтупа к более широким возможноÑÑ‚Ñм."> - <combo_box.item label="ОÑновной" name="Basic"/> - <combo_box.item label="РаÑширенный" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> МеÑто Ñтарта: </text> @@ -33,16 +26,21 @@ <combo_box.item label="<Введите название региона>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ + <layout_panel name="links_login_panel"> + <text name="login_help"> + Ðужна помощь при входе? </text> <text name="forgot_password_text"> Забыли Ð¸Ð¼Ñ Ð¸Ð»Ð¸ пароль? </text> - <text name="login_help"> - Ðужна помощь при входе? + <button label="Войти" name="connect_btn"/> + <check_box label="Запомнить пароль" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + СОЗДÐЙТЕ СВОЙ ÐККÐУÐТ </text> + <button label="Ðачать" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_my_profile.xml b/indra/newview/skins/default/xui/ru/panel_my_profile.xml deleted file mode 100644 index 9117bfec18..0000000000 --- a/indra/newview/skins/default/xui/ru/panel_my_profile.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Профиль" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=en - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=en - </string> - <string name="my_account_link_url" value="http://secondlife.com/account"/> - <string name="no_partner_text" value="Ðет"/> - <string name="no_group_text" value="Ðет"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="scroll_content_panel"> - <panel name="second_life_image_panel"> - <text name="display_name_descr_text"> - Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ - </text> - <text name="name_descr_text"> - Ðкранное Ð¸Ð¼Ñ - </text> - <button label="Профиль" name="see_profile_btn" tool_tip="ПоÑмотреть профиль Ñтого аватара"/> - </panel> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> -</panel> 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..a8fdfde1c4 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,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="nearby_chat"> - <check_box label="Перевод чата" name="translate_chat_checkbox"/> + <layout_stack name="stack"> + <layout_panel name="translate_chat_checkbox_lp"> + <check_box label="Переводить чат" name="translate_chat_checkbox"/> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml index 804ba7def7..395c643b0b 100644 --- a/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="chat_bar"> +<panel name="nearby_chat"> <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/panel_notes.xml b/indra/newview/skins/default/xui/ru/panel_notes.xml deleted file mode 100644 index aa74383349..0000000000 --- a/indra/newview/skins/default/xui/ru/panel_notes.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Заметки и приватноÑть" name="panel_notes"> - <layout_stack name="layout"> - <layout_panel name="notes_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <text name="status_message" value="Мои личные заметки:"/> - <text name="status_message2" value="Разрешить Ñтому жителю:"/> - <check_box label="Видеть мой ÑÑ‚Ð°Ñ‚ÑƒÑ Ð² Ñети" name="status_check"/> - <check_box label="Видеть Ð¼ÐµÐ½Ñ Ð½Ð° карте" name="map_check"/> - <check_box label="Редактировать, удалÑть или брать мои объекты" name="objects_check"/> - </panel> - </scroll_container> - </layout_panel> - <layout_panel name="notes_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Добавить в друзьÑ" name="add_friend" tool_tip="Предложить дружбу Ñтому жителю"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="Ðачать ÑÐµÐ°Ð½Ñ IM"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Звонок" name="call" tool_tip="Позвонить Ñтому жителю"/> - </layout_panel> - <layout_panel name="show_on_map_btn_lp"> - <button label="Карта" name="show_on_map_btn" tool_tip="Показать Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð½Ð° карте"/> - </layout_panel> - <layout_panel name="teleport_btn_lp"> - <button label="ТелепортациÑ" name="teleport" tool_tip="Предложить телепортацию"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</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..9283fc9e6e 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,7 @@ <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"/> + <button label="Ðвтозамена..." name="autoreplace_showgui"/> + <button label="Проверка правопиÑаниÑ..." name="spellcheck_showgui"/> </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_profile.xml b/indra/newview/skins/default/xui/ru/panel_profile.xml deleted file mode 100644 index fab57d678c..0000000000 --- a/indra/newview/skins/default/xui/ru/panel_profile.xml +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Профиль" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=en - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=en - </string> - <string name="my_account_link_url" value="http://secondlife.com/account"/> - <string name="no_partner_text" value="Ðет"/> - <string name="no_group_text" value="Ðет"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <panel name="second_life_image_panel"> - <text name="title_sl_descr_text" value="[SECOND_LIFE]:"/> - </panel> - <panel name="first_life_image_panel"> - <text name="title_rw_descr_text" value="Реальный мир:"/> - </panel> - <text name="title_member_text" value="Обитатель SL Ñ:"/> - <text name="title_acc_status_text" value="Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð°ÐºÐºÐ°ÑƒÐ½Ñ‚Ð°:"/> - <text name="title_partner_text" value="Партнер:"/> - <panel name="partner_data_panel"> - <text initial_value="(получение информации)" name="partner_text"/> - </panel> - <text name="title_groups_text" value="Группы:"/> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> - <layout_stack name="layout_verb_buttons"> - <layout_panel name="profile_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="Ð’ друзьÑ" name="add_friend" tool_tip="Предложить дружбу Ñтому жителю"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="Ðачать ÑÐµÐ°Ð½Ñ IM"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Звонок" name="call" tool_tip="Позвонить Ñтому жителю"/> - </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="ТелепортациÑ" name="teleport" tool_tip="Предложить телепортацию"/> - </layout_panel> - <layout_panel name="overflow_btn_lp"> - <menu_button label="â–¼" name="overflow_btn" tool_tip="Заплатить жителю или поделитьÑÑ Ñ Ð½Ð¸Ð¼ вещами"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_profile_view.xml b/indra/newview/skins/default/xui/ru/panel_profile_view.xml deleted file mode 100644 index c97c5afc01..0000000000 --- a/indra/newview/skins/default/xui/ru/panel_profile_view.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_target_profile"> - <string name="status_online"> - Онлайн - </string> - <string name="status_offline"> - Оффлайн - </string> - <text name="display_name_label" value="Ðкранное имÑ:"/> - <text name="solo_username_label" value="Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ:"/> - <text name="status" value="Онлайн"/> - <text name="user_name_small" value="ВзглÑни-ка, друг, какое длиннющее имÑ"/> - <button name="copy_to_clipboard" tool_tip="Копировать в буфер обмена"/> - <text name="user_label" value="Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ:"/> - <tab_container name="tabs"> - <panel label="ПРОФИЛЬ" name="panel_profile"/> - <panel label="ПОДБОРКÐ" name="panel_picks"/> - <panel label="ЗÐМЕТКИ И ДОСТУП" name="panel_notes"/> - </tab_container> -</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_region_debug.xml b/indra/newview/skins/default/xui/ru/panel_region_debug.xml index c21d2d7051..4be1e781fa 100644 --- a/indra/newview/skins/default/xui/ru/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/ru/panel_region_debug.xml @@ -30,5 +30,5 @@ <button label="Самые активные учаÑтники Ñтолкновений..." name="top_colliders_btn" tool_tip="СпиÑок объектов, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… ÑÑ‚Ð¾Ð»ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸Ñ Ð½Ð°Ð¸Ð±Ð¾Ð»ÐµÐµ вероÑтны"/> <button label="СпиÑок лучших Ñкриптов..." name="top_scripts_btn" tool_tip="Объекты, в которых Ñкрипты выполнÑÑŽÑ‚ÑÑ Ð´Ð¾Ð»ÑŒÑˆÐµ вÑего"/> <button label="Перезагрузить регион" name="restart_btn" tool_tip="ОтÑчитать 2 минуты и перезагрузить регион"/> - <button label="Отложить перезагрузку" name="cancel_restart_btn" tool_tip="Отложить перезагрузку региона на чаÑ"/> + <button label="Отменить перезапуÑк" name="cancel_restart_btn" tool_tip="Отменить перезапуÑк региона"/> </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_region_estate.xml b/indra/newview/skins/default/xui/ru/panel_region_estate.xml index 27ec10b323..bcfb974fcb 100644 --- a/indra/newview/skins/default/xui/ru/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/ru/panel_region_estate.xml @@ -20,10 +20,10 @@ <slider label="Фаза" name="sun_hour_slider"/> <check_box label="Разрешить общий доÑтуп" name="externally_visible_check"/> <text name="Only Allow"> - Разрешить доÑтуп только аккаунтам Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸ÐµÐ¼: + Разрешить доÑтуп только таким жителÑм: </text> - <check_box label="Информации об оплате в файле" name="limit_payment" tool_tip="Банить нераÑпознанных жителей"/> - <check_box label="Проверка возраÑта" name="limit_age_verified" tool_tip="Банить жителей, не прошедших проверку возраÑта. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/> + <check_box label="ЗарегиÑтрирована Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± оплате" name="limit_payment" tool_tip="Ð”Ð»Ñ Ð´Ð¾Ñтупа к Ñтому землевладению у Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть зарегиÑтрирована Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± оплате. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/> + <check_box label="18 лет и Ñтарше" name="limit_age_verified" tool_tip="ДоÑтуп к Ñтому землевладению имеют только жители 18 лет и Ñтарше. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/> <check_box label="Разрешить голоÑовое общение" name="voice_chat_check"/> <check_box label="Разрешить прÑмой телепорт" name="allow_direct_teleport"/> <button label="Применить" name="apply_btn"/> diff --git a/indra/newview/skins/default/xui/ru/panel_region_texture.xml b/indra/newview/skins/default/xui/ru/panel_region_texture.xml deleted file mode 100644 index c4b35a536d..0000000000 --- a/indra/newview/skins/default/xui/ru/panel_region_texture.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="ТекÑтуры земли" name="Textures"> - <text name="region_text_lbl"> - Регион: - </text> - <text name="region_text"> - неизвеÑтен - </text> - <text name="detail_texture_text"> - ТекÑтуры ландшафта (требованиÑ: 512x512, 24-битные TGA-файлы) - </text> - <text name="height_text_lbl"> - 1 (низ) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (верх) - </text> - <text name="height_text_lbl5"> - Диапазон выÑот текÑтур - </text> - <text name="height_text_lbl6"> - Северо-запад - </text> - <text name="height_text_lbl7"> - Северо-воÑток - </text> - <spinner label="Ðиз" name="height_start_spin_1"/> - <spinner label="Ðиз" name="height_start_spin_3"/> - <spinner label="Верх" name="height_range_spin_1"/> - <spinner label="Верх" name="height_range_spin_3"/> - <text name="height_text_lbl8"> - Юго-запад - </text> - <text name="height_text_lbl9"> - Юго-воÑток - </text> - <spinner label="Ðиз" name="height_start_spin_0"/> - <spinner label="Ðиз" name="height_start_spin_2"/> - <spinner label="Верх" name="height_range_spin_0"/> - <spinner label="Верх" name="height_range_spin_2"/> - <text name="height_text_lbl10"> - Ðти Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÑŽÑ‚ диапазон Ð¿ÐµÑ€ÐµÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ð²Ñ‹ÑˆÐµÑƒÐºÐ°Ð·Ð°Ð½Ð½Ñ‹Ñ… текÑтур. - </text> - <text name="height_text_lbl11"> - ИзмерÑетÑÑ Ð² метрах, значение «Ðиз» – Ñто МÐКСИМÐЛЬÐÐЯ выÑота текÑтуры â„–1, значение «Верх» – Ñто МИÐИМÐЛЬÐÐЯ выÑота текÑтуры â„–4. - </text> - <button label="Применить" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_script_ed.xml b/indra/newview/skins/default/xui/ru/panel_script_ed.xml index 1a9c512147..05ccaeb54b 100644 --- a/indra/newview/skins/default/xui/ru/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/ru/panel_script_ed.xml @@ -22,6 +22,8 @@ <menu label="Файл" name="File"> <menu_item_call label="Сохранить" name="Save"/> <menu_item_call label="Отменить вÑе изменениÑ" name="Revert All Changes"/> + <menu_item_call label="Загрузить из файла..." name="LoadFromFile"/> + <menu_item_call label="Сохранить в файл..." name="SaveToFile"/> </menu> <menu label="Изменить" name="Edit"> <menu_item_call label="Отменить" name="Undo"/> diff --git a/indra/newview/skins/default/xui/ru/panel_script_question_toast.xml b/indra/newview/skins/default/xui/ru/panel_script_question_toast.xml new file mode 100644 index 0000000000..a2d0237da0 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_script_question_toast.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel label="script_question_panel" name="panel_script_question_toast"> + <panel label="buttons_panel" name="buttons_panel"/> +</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_side_tray.xml b/indra/newview/skins/default/xui/ru/panel_side_tray.xml deleted file mode 100644 index 10c5775291..0000000000 --- a/indra/newview/skins/default/xui/ru/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Открыть/закрыть боковую панель" name="sidebar_openclose" tab_title="Открыть/закрыть боковую панель"/> - <sidetray_tab description="Дом." name="sidebar_home" tab_title="Дом"> - <panel label="дом" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Изменение Ñвоего Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð¸ подборки." name="sidebar_me" tab_title="Мой профиль"> - <panel_container name="panel_container"> - <panel label="Я" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="ПоиÑк друзей, контактов и находÑщихÑÑ Ð¿Ð¾Ð±Ð»Ð¸Ð·Ð¾Ñти людей." name="sidebar_people" tab_title="Люди"> - <panel_container name="panel_container"> - <panel label="Профиль группы" name="panel_group_info_sidetray"/> - <panel label="Черный ÑпиÑок жителей и объектов" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="ПоиÑк меÑÑ‚, которые можно было бы поÑетить или которые вы уже поÑещали ранее." label="МеÑта" name="sidebar_places" tab_title="МеÑта"> - <panel label="МеÑта" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="ПроÑмотрите Ñвой инвентарь." name="sidebar_inventory" tab_title="Мой инвентарь"> - <panel label="Изменить инвентарь" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Изменение внешнего вида и текущего образа." name="sidebar_appearance" tab_title="Мой внешний вид"> - <panel label="Изменить внешний вид" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> 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..9c84ff1fd8 100644 --- a/indra/newview/skins/default/xui/ru/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/ru/panel_status_bar.xml @@ -15,10 +15,10 @@ <panel.string name="buycurrencylabel"> L$ [AMT] </panel.string> - <panel name="balance_bg"> + <panel left="-450" name="balance_bg" width="240"> <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/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/ru/panel_volume_pulldown.xml new file mode 100644 index 0000000000..fe044cd083 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater"> + <slider label="ОбщаÑ" name="System Volume"/> + <slider label="Кнопки" name="UI Volume"/> + <slider label="ОкружающаÑ" name="Wind Volume"/> + <slider label="Звуки" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="Включить звуки от жеÑтов"/> + <slider label="Музыка" name="Music Volume"/> + <check_box name="enable_music" tool_tip="Включить потоковую музыку"/> + <slider label="Медиа" name="Media Volume"/> + <check_box name="enable_media" tool_tip="Включить потоковое медиа"/> + <slider label="ГолоÑ" name="Voice Volume"/> + <check_box name="enable_voice_check" tool_tip="Включить голоÑовой чат"/> +</panel> diff --git a/indra/newview/skins/default/xui/ru/sidepanel_inventory.xml b/indra/newview/skins/default/xui/ru/sidepanel_inventory.xml index a4150f6e2f..c106c2de79 100644 --- a/indra/newview/skins/default/xui/ru/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/ru/sidepanel_inventory.xml @@ -2,47 +2,24 @@ <panel label="Вещи" name="objects panel"> <panel label="" name="sidepanel__inventory_panel"> <layout_stack name="inventory_layout_stack"> - <layout_panel name="inbox_outbox_layout_panel"> - <layout_stack name="inbox_outbox_layout_stack"> - <layout_panel name="inbox_layout_panel"> - <panel label="" name="marketplace_inbox"> - <string name="InboxLabelWithArg"> - Полученные вещи ([NUM]) - </string> - <string name="InboxLabelNoArg"> - Полученные вещи - </string> - <button label="Полученные вещи" name="inbox_btn"/> - <text name="inbox_fresh_new_count"> - Ðовых: [NUM] - </text> - <panel tool_tip="Drag and drop items to your inventory to manage and use them"> - <text name="inbox_inventory_placeholder"> - Покупки из торгового центра будут доÑтавлены Ñюда. - </text> - </panel> - </panel> - </layout_panel> - <layout_panel name="outbox_layout_panel"> - <panel label="" name="marketplace_outbox"> - <string name="OutboxLabelWithArg"> - Торговые иÑходÑщие ([NUM]) - </string> - <string name="OutboxLabelNoArg"> - Торговые иÑходÑщие - </string> - <button label="Торговые иÑходÑщие" name="outbox_btn"/> - <button label="" name="outbox_sync_btn" tool_tip="Ð’Ñ‹Ñтавить на витрину моего магазина"/> - <panel> - <panel name="outbox_inventory_placeholder_panel"> - <text name="outbox_inventory_placeholder_title"> - Загрузка... - </text> - </panel> - </panel> - </panel> - </layout_panel> - </layout_stack> + <layout_panel name="inbox_layout_panel"> + <panel label="" name="marketplace_inbox"> + <string name="InboxLabelWithArg"> + Полученные вещи ([NUM]) + </string> + <string name="InboxLabelNoArg"> + Полученные вещи + </string> + <button label="Полученные вещи" name="inbox_btn"/> + <text name="inbox_fresh_new_count"> + Ðовых: [NUM] + </text> + <panel name="inbox_inventory_placeholder_panel" tool_tip="Перетащите вещи в ваш инвентарь Ð´Ð»Ñ Ð¸Ñ… иÑпользованиÑ"> + <text name="inbox_inventory_placeholder"> + Покупки из торгового центра будут доÑтавлены Ñюда. + </text> + </panel> + </panel> </layout_panel> </layout_stack> <panel name="button_panel"> diff --git a/indra/newview/skins/default/xui/ru/sidepanel_item_info.xml b/indra/newview/skins/default/xui/ru/sidepanel_item_info.xml index 62095acbaf..0106ed50ac 100644 --- a/indra/newview/skins/default/xui/ru/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/ru/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (неизвеÑтно) </panel.string> + <panel.string name="unknown_multiple"> + (неизвеÑтно/неÑколько) + </panel.string> <panel.string name="public"> (публичное) </panel.string> diff --git a/indra/newview/skins/default/xui/ru/sidepanel_task_info.xml b/indra/newview/skins/default/xui/ru/sidepanel_task_info.xml index 8e56dd80c0..e9dd3760b5 100644 --- a/indra/newview/skins/default/xui/ru/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/ru/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> Ðти объекты Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ñть </panel.string> + <panel.string name="text modify info 5"> + Ðтот объект Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ñть через границу региона + </panel.string> + <panel.string name="text modify info 6"> + Ðти объекты Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ñть через границу региона + </panel.string> <panel.string name="text modify warning"> Ðтот объект Ñодержит объединенные чаÑти </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Цена: L$" name="Edit Cost"/> <check_box label="Показать в результатах поиÑка" name="search_check" tool_tip="Показывать объект в результатах поиÑка"/> + <text name="pathfinding_attributes_label"> + Ðтрибуты поиÑка пути: + </text> <text name="B:"> Ð: </text> diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index 7fef5797a9..f9ded799bf 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -137,7 +137,7 @@ Выйти </string> <string name="create_account_url"> - http://join.secondlife.com/ + http://join.secondlife.com/index.php?lang=ru-RU&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> У клиента, которым вы пользуетеÑÑŒ, больше нет доÑтупа к игре Second Life. Загрузить новую верÑию клиента можно по адреÑу @@ -180,8 +180,8 @@ http://secondlife.com/viewer-access-faq Обновление ÑоÑтоÑÐ½Ð¸Ñ Ñм. на веб-Ñтранице www.secondlife.com/status. </string> <string name="LoginFailedPremiumOnly"> - Вход в Second Life временно ограничен, чтобы обеÑпечить наилучшее времÑпровождение в игровом мире. - + Вход в Second Life временно ограничен, чтобы Ñохранить наивыÑшее качеÑтво игрового мира Ð´Ð»Ñ Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ… пользователей. + Ð’ Ñто Ð²Ñ€ÐµÐ¼Ñ Ñƒ пользователей Ñ Ð±ÐµÑплатными аккаунтами не будет доÑтупа к Second Life, чтобы у тех, кто заплатил, было больше меÑта. </string> <string name="LoginFailedComputerProhibited"> @@ -339,17 +339,35 @@ support@secondlife.com. Сюда можно перетащить только одну вещь </string> <string name="TooltipPrice" value="L$[AMOUNT]:"/> + <string name="TooltipOutboxDragToWorld"> + ÐÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð»Ð¾Ð¶Ð¸Ñ‚ÑŒ предметы из папке «Торговые иÑходÑщие» + </string> <string name="TooltipOutboxNoTransfer"> - ЧаÑть Ñтих объектов Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¾Ð´Ð°Ñ‚ÑŒ, или они переданы другому пользователю. + ЧаÑть Ñтих объектов Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¾Ð´Ð°Ñ‚ÑŒ или передать. + </string> + <string name="TooltipOutboxNotInInventory"> + Ваша папка «Торговые иÑходÑщие» может получать вещи только непоÑредÑтвенно из вашего Ð¸Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ </string> <string name="TooltipOutboxWorn"> - ЧаÑть Ñтих объектов на ваÑ. Снимите их Ñо Ñвоего аватара и попробуйте перемеÑтить их еще раз. + ÐоÑимые предметы Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ð¾Ð¼ÐµÑтить в папку «Торговые иÑходÑщие» + </string> + <string name="TooltipOutboxCallingCard"> + Визитки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ð¾Ð¼ÐµÑтить в папку «Торговые иÑходÑщие» </string> <string name="TooltipOutboxFolderLevels"> - Ð’ Ñтой папке Ñлишком много уровней вложенных папок. Измените Ñтруктуру вложенных папок, ограничив ее глубину 4 уровнÑми (ÐºÐ¾Ñ€Ð½ÐµÐ²Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°, вложенные папки ÑƒÑ€Ð¾Ð²Ð½Ñ Ð, вложенные в них папки ÑƒÑ€Ð¾Ð²Ð½Ñ Ð‘, вложенные в них папки ÑƒÑ€Ð¾Ð²Ð½Ñ Ð’). + Глубина Ð²Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð°Ð¿Ð¾Ðº превышает 3 + </string> + <string name="TooltipOutboxTooManyFolders"> + Ð’ папке верхнего ÑƒÑ€Ð¾Ð²Ð½Ñ Ð±Ð¾Ð»ÐµÐµ 20 подпапок </string> <string name="TooltipOutboxTooManyObjects"> - Ðта папка Ñодержит более 200 объектов. Сложите некоторые вещи в коробки, чтобы уменьшить чиÑло объектов. + Ð’ папке верхнего ÑƒÑ€Ð¾Ð²Ð½Ñ Ð±Ð¾Ð»ÐµÐµ 200 предметов + </string> + <string name="TooltipDragOntoOwnChild"> + Папку Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑтить в ее подпапку + </string> + <string name="TooltipDragOntoSelf"> + Папку Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑтить Ñаму в ÑÐµÐ±Ñ </string> <string name="TooltipHttpUrl"> Щелкните, чтобы проÑмотреть Ñту веб-Ñтраницу @@ -814,6 +832,9 @@ support@secondlife.com. <string name="anim_yes_head"> СоглаÑие </string> + <string name="multiple_textures"> + ÐеÑколько + </string> <string name="texture_loading"> Загрузка... </string> @@ -862,6 +883,9 @@ support@secondlife.com. <string name="ScriptQuestionCautionChatDenied"> Объекту «[OBJECTNAME]», который принадлежит пользователю «[OWNERNAME]» и находитÑÑ Ð² [REGIONPOS] в регионе «[REGIONNAME]», отказано в разрешении: [PERMISSIONS]. </string> + <string name="AdditionalPermissionsRequestHeader"> + Разрешив доÑтуп к Ñвоему аккаунту, вы также разрешите объекту: + </string> <string name="ScriptTakeMoney"> У Ð²Ð°Ñ Ð±ÐµÑ€ÑƒÑ‚ Linden-деньги </string> @@ -895,6 +919,9 @@ support@secondlife.com. <string name="ControlYourCamera"> УправлÑть камерой </string> + <string name="TeleportYourAgent"> + Телепортировать Ð²Ð°Ñ + </string> <string name="NotConnected"> Ðет Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ </string> @@ -973,6 +1000,12 @@ support@secondlife.com. <string name="choose_the_directory"> Выбрать каталог </string> + <string name="script_files"> + Скрипты + </string> + <string name="dictionary_files"> + Словари + </string> <string name="AvatarSetNotAway"> Ðа меÑте </string> @@ -1211,43 +1244,36 @@ support@secondlife.com. Ð’ вашем инвентаре нет копии Ñтой текÑтуры </string> <string name="InventoryInboxNoItems"> - Покупки из торгового центра будут доÑтавлены Ñюда. + ЗдеÑÑŒ будут показаны ваши покупки из торгового центра. Их можно будет перетащить в ваш инвентарь Ð´Ð»Ñ Ð¸ÑпользованиÑ. </string> <string name="MarketplaceURL"> - http://marketplace.[DOMAIN_NAME] + https://marketplace.[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 + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4 </string> - <string name="InventoryOutboxCreationErrorTitle"> - Папка «Торговые иÑходÑщие» наÑтроена неправильно + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard </string> - <string name="InventoryOutboxCreationErrorTooltip"> - Ошибка конфигурации папки «Торговые иÑходÑщие» + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports </string> - <string name="InventoryOutboxCreationError"> - Чтобы иÑправить Ñту проблему, обратитеÑÑŒ в Ñлужбу поддержки. + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more </string> <string name="InventoryOutboxNotMerchantTitle"> - Продавать вещи в торговом центре может кто угодно - </string> - <string name="InventoryOutboxNotMerchantTooltip"> - Станьте торговцем! + Продавать вещи в торговом центре может кто угодно. </string> + <string name="InventoryOutboxNotMerchantTooltip"/> <string name="InventoryOutboxNotMerchant"> - [[MARKETPLACE_URL] Торговый центр Second Life] предлагает на продажу более миллиона виртуальных продуктов, и вÑе они Ñозданы жителÑми Second Life. Ð’Ñ‹ тоже можете продавать Ñозданные вами вещи, а также некоторые из вещей, купленных вами. Ðто ÑовÑем неÑложно. ÐаÑтройка выполнÑетÑÑ Ð±ÐµÑплатно. [[LEARN_MORE_URL] Узнайте подробноÑти] или [[CREATE_STORE_URL] Ñоздайте магазин] в торговом центре, чтобы начать торговлю. + ЕÑли вы хотите Ñтать торговцем, [[MARKETPLACE_CREATE_STORE_URL] Ñоздайте магазин]. </string> <string name="InventoryOutboxNoItemsTitle"> - Ðовый ÑпоÑоб отправки вещей в торговый центр - </string> - <string name="InventoryOutboxNoItemsTooltip"> - Перетащите вещи Ñюда, чтобы подготовить их Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð°Ð¶Ð¸ в торговом центре + Ваша папка «ИÑходÑщие» пуÑта. </string> + <string name="InventoryOutboxNoItemsTooltip"/> <string name="InventoryOutboxNoItems"> - ПеретаÑкивайте в Ñту облаÑть вещи и папки, которые хотите продать. При перетаÑкивании ÑоздаетÑÑ ÐºÐ¾Ð¿Ð¸Ñ Ð²ÐµÑ‰Ð¸ (за иÑключением вещей, недоÑтупных Ð´Ð»Ñ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ), поÑтому инвентарь не изменÑетÑÑ. Когда вÑе готово Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ вещей в торговый центр, нажмите кнопку «Передать». Вещи, перемещенные в инвентарь магазина, иÑчезают из Ñтой папки. + Перетащите папки в Ñту облаÑть и щелкните «Отправить в торговый центр», чтобы выÑтавить их на продажу в [[MARKETPLACE_DASHBOARD_URL] Торговом центре]. </string> <string name="Marketplace Error None"> Ошибок нет @@ -1385,6 +1411,12 @@ support@secondlife.com. <string name="InvFolder favorite"> Мое избранное </string> + <string name="InvFolder Favorites"> + Мое избранное + </string> + <string name="InvFolder favorites"> + Мое избранное + </string> <string name="InvFolder Current Outfit"> Текущий коÑтюм </string> @@ -1400,6 +1432,12 @@ support@secondlife.com. <string name="InvFolder Meshes"> Меши </string> + <string name="InvFolder Received Items"> + Полученные вещи + </string> + <string name="InvFolder Merchant Outbox"> + Торговые иÑходÑщие + </string> <string name="InvFolder Friends"> Ð”Ñ€ÑƒÐ·ÑŒÑ </string> @@ -1409,6 +1447,9 @@ support@secondlife.com. <string name="no_attachments"> Ðет прикрепленных объектов </string> + <string name="Attachments remain"> + ПриÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ (оÑталоÑÑŒ гнезд: [COUNT]) + </string> <string name="Buy"> Купить </string> @@ -1535,6 +1576,12 @@ support@secondlife.com. <string name="Right Pec"> ÐŸÑ€Ð°Ð²Ð°Ñ Ð³Ñ€ÑƒÐ´ÑŒ </string> + <string name="Neck"> + Ð¨ÐµÑ + </string> + <string name="Avatar Center"> + Центр аватара + </string> <string name="Invalid Attachment"> ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° приÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ </string> @@ -3826,6 +3873,12 @@ support@secondlife.com. <string name="LocationCtrlSeeAVsTooltip"> Ð’Ñе жители Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… учаÑтков могут видеть аватары и общатьÑÑ Ð² чате </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Возможны неполадки подвижных объектов в Ñтом регионе, пока регион не будет воÑÑтановлен. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + Ð’ Ñтом регионе не разрешен динамичеÑкий поиÑк пути. + </string> <string name="UpdaterWindowTitle"> Обновление [APP_NAME] </string> @@ -3892,6 +3945,9 @@ support@secondlife.com. <string name="Saved_message"> (Сохранено [LONG_TIMESTAMP]) </string> + <string name="IM_unblock_only_groups_friends"> + Ð”Ð»Ñ Ð¿Ñ€Ð¾Ñмотра Ñтого ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñнимите флажок «Только Ð´Ñ€ÑƒÐ·ÑŒÑ Ð¸ группы могут звонить мне и отправлÑть IM» в окне «ÐаÑтройки/ПриватноÑть». + </string> <string name="answered_call"> Ðа ваш звонок ответили </string> @@ -4024,6 +4080,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> @@ -4077,7 +4145,7 @@ support@secondlife.com. </string> <string name="uploading_abuse_report"> ЗагружаетÑÑ... - + Жалоба </string> <string name="New Shape"> @@ -4344,7 +4412,8 @@ support@secondlife.com. <string name="words_separator" value=","/> <string name="server_is_down"> ÐеÑÐ¼Ð¾Ñ‚Ñ€Ñ Ð½Ð° наши уÑилиÑ, что-то неожиданно пошло не так. - ОзнакомьтеÑÑŒ Ñ Ð¾Ð¿Ð¸Ñанием извеÑтных проблем в работе Ñтой Ñлужбы на Ñайте status.secondlifegrid.net. + + ОзнакомьтеÑÑŒ Ñ Ð¾Ð¿Ð¸Ñанием извеÑтных проблем в работе Ñтой Ñлужбы на Ñайте status.secondlifegrid.net. ЕÑли проблемы продолжаютÑÑ, то проверьте подключение к Ñети и наÑтройки брандмауÑра. </string> <string name="dateTimeWeekdaysNames"> @@ -4433,6 +4502,12 @@ support@secondlife.com. <string name="ExternalEditorFailedToRun"> Ðе удалоÑÑŒ запуÑтить внешний редактор. </string> + <string name="TranslationFailed"> + Ошибка телепортации: [REASON] + </string> + <string name="TranslationResponseParseError"> + Ошибка при анализе ответа переводчика. + </string> <string name="Esc"> ESC </string> @@ -4815,7 +4890,10 @@ support@secondlife.com. Миникарта </string> <string name="Command_Move_Label"> - ПеремеÑтить + Ходьба / бег / полет + </string> + <string name="Command_Outbox_Label"> + Торговые иÑходÑщие </string> <string name="Command_People_Label"> Люди @@ -4842,7 +4920,7 @@ support@secondlife.com. Говорить </string> <string name="Command_View_Label"> - Вид + Управление камерой </string> <string name="Command_Voice_Label"> ÐаÑтройки голоÑа @@ -4889,6 +4967,9 @@ support@secondlife.com. <string name="Command_Move_Tooltip"> Перемещение аватара </string> + <string name="Command_Outbox_Tooltip"> + ПеренеÑти предметы в торговый центр Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð°Ð¶Ð¸ + </string> <string name="Command_People_Tooltip"> ДрузьÑ, группы и люди поблизоÑти </string> @@ -4917,7 +4998,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 +5033,40 @@ support@secondlife.com. <string name="Normal"> Ðормальный </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Ðет + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + ВлиÑет на навигационную Ñетку + </string> + <string name="Pathfinding_Object_Attr_Character"> + ПерÑонаж + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (неÑколько) + </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> + <string name="TeleportMaturityExceeded"> + Житель не может поÑетить Ñтот регион. + </string> + <string name="UserDictionary"> + [Пользователь] + </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..40c9267408 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"> У Ð²Ð°Ñ Ð½ÐµÑ‚ доÑтупа к точке Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñтого телепорта. @@ -45,6 +45,9 @@ <message name="no_inventory_host"> СиÑтема Ð¸Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ ÑÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ´Ð¾Ñтупна. </message> + <message name="MustGetAgeRegion"> + Входить в Ñтот регион могут только жители 18 лет и Ñтарше. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -80,5 +83,8 @@ <message name="requesting"> Ð—Ð°Ð¿Ñ€Ð¾Ñ Ñ‚ÐµÐ»ÐµÐ¿Ð¾Ñ€Ñ‚Ð°Ñ†Ð¸Ð¸â€¦ </message> + <message name="pending"> + Ð¢ÐµÐ»ÐµÐ¿Ð¾Ñ€Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ðµ закончена... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/tr/floater_about.xml b/indra/newview/skins/default/xui/tr/floater_about.xml index 993ec42958..9cc9c7a220 100644 --- a/indra/newview/skins/default/xui/tr/floater_about.xml +++ b/indra/newview/skins/default/xui/tr/floater_about.xml @@ -63,33 +63,34 @@ Ses Sunucusu Sürümü: [VOICE_VERSION] </panel> <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. + 3Dconnexion SDK Telif Hakkı (C) 1992-2009 3Dconnexion + APR Telif Hakkı (C) 2011 The Apache Software Foundation + Collada DOM Telif Hakkı 2006 Sony Computer Entertainment Inc. + cURL Telif Hakkı (C) 1996-2010, 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, 2006 David Turner, Robert Wilhelm ve Werner Lemberg. + 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) 2002, Xiphophorus + OpenSSL Telif Hakkı (C) 1998-2008 The OpenSSL Project. + PCRE Telif Hakkı (c) 1997-2012 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-2012 Jean-loup Gailly ve Mark Adler. -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..481fc540d0 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"/> @@ -306,14 +306,13 @@ Sadece büyük parseller aramada görünür. <panel.string name="push_restrict_region_text"> İtme Yok (Bölge Geçersiz Kılma) </panel.string> - <panel.string name="see_avs_text"> - Parseldeki sakinleri gör ve onlarla sohbet et - </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 +328,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 +368,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: + BaÅŸka parsellerdeki avatarlar 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> @@ -447,20 +443,15 @@ Sadece büyük parseller aramada görünür. <panel.string name="access_estate_defined"> (Gayrimenkul tarafından tanımlanır) </panel.string> - <panel.string name="allow_public_access"> - Kamusal EriÅŸime İzin Ver ([MATURITY]) (Not: İşaret kaldırılırsa yasaklama çizgileri oluÅŸur) - </panel.string> <panel.string name="estate_override"> Bu seçeneklerden biri veya daha fazlası gayrimenkul düzeyinde ayarlanır </panel.string> - <text name="Limit access to this parcel to:"> - Bu Parsele EriÅŸim - </text> + <check_box label="Kamusal EriÅŸime İzin Ver (Bunun iÅŸaretinin kaldırılması yasaklama çizgileri oluÅŸturacaktır)" name="public_access"/> <text name="Only Allow"> - EriÅŸimi ÅŸununla doÄŸrulanan Sakinlerle Sınırla: + Sadece ÅŸu Sakinlere eriÅŸim izni verin: </text> - <check_box label="Dosyadaki ödeme bilgileri [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Tanınmayan Sakinleri Yasakla."/> - <check_box label="YaÅŸ doÄŸrulama [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Yaşını doÄŸrulamayan Sakinleri yasakla Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/> + <check_box label="Ödeme bilgileri kayıtlı [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Sakinlerin bu parsele eriÅŸebilmesi için ödeme bilgilerinin kayıtlı olması gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/> + <check_box label="18 veya üzeri bir yaÅŸta [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Sakinlerin bu parsele eriÅŸebilmesi için 18 veya üzeri bir yaÅŸta olmaları gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/> <check_box label="Grup EriÅŸimine İzin Ver: [GROUP]" name="GroupCheck" tool_tip="Genel sekmesinde grup ayarla."/> <check_box label="GeçiÅŸ haklr. ÅŸuna sat:" name="PassCheck" tool_tip="Bu parsele geçici eriÅŸim verir"/> <combo_box name="pass_combo"> diff --git a/indra/newview/skins/default/xui/tr/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/tr/floater_animation_anim_preview.xml new file mode 100644 index 0000000000..a63e1e107e --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_animation_anim_preview.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Anim Preview" title="ANIMATION.ANIM"> + <text name="name_label"> + Ad: + </text> + <text name="description_label"> + Açıklama: + </text> + <button label="Karşıya Yükle (L$[AMOUNT])" name="ok_btn"/> + <button label="İptal" label_selected="İptal" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_animation_preview.xml b/indra/newview/skins/default/xui/tr/floater_animation_bvh_preview.xml index f8800c674d..f8800c674d 100644 --- a/indra/newview/skins/default/xui/tr/floater_animation_preview.xml +++ b/indra/newview/skins/default/xui/tr/floater_animation_bvh_preview.xml diff --git a/indra/newview/skins/default/xui/tr/floater_autoreplace.xml b/indra/newview/skins/default/xui/tr/floater_autoreplace.xml new file mode 100644 index 0000000000..e52e05dc61 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="Otomatik Yerine Koyma Ayarları"> + <check_box label="Otomatik Yerine Koymayı EtkinleÅŸtir" name="autoreplace_enable" tool_tip="Siz sohbet metni girdikçe, girilen herhangi bir anahtar kelimenin yerine karşılık gelen deÄŸiÅŸtirmeyi koyabilirsiniz"/> + <button label="Listeyi İçeri Aktar..." name="autoreplace_import_list" tool_tip="Daha önce aktarılan bir listeyi yükler."/> + <button label="Listeyi Aktarın..." name="autoreplace_export_list" tool_tip="Seçilen listeyi bir dosyaya kaydederek paylaşın."/> + <button label="Yeni Liste..." name="autoreplace_new_list" tool_tip="Yeni bir liste oluÅŸturun."/> + <button label="Listeyi Sil" name="autoreplace_delete_list" tool_tip="Seçilen listeyi silin."/> + <button name="autoreplace_list_up" tool_tip="Bu listenin önceliÄŸini yükseltin."/> + <button name="autoreplace_list_down" tool_tip="Bu listenin önceliÄŸini azaltın."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Anahtar kelime" name="keyword"/> + <scroll_list.columns label="DeÄŸiÅŸtirme" name="replacement"/> + </scroll_list> + <button label="Ekle..." name="autoreplace_add_entry"/> + <button label="Kaldır" name="autoreplace_delete_entry"/> + <button label="GiriÅŸi Kaydet" name="autoreplace_save_entry" tool_tip="Bu giriÅŸi kaydet."/> + <button label="DeÄŸiÅŸiklikleri Kaydet" name="autoreplace_save_changes" tool_tip="Tüm deÄŸiÅŸiklikleri kaydet."/> + <button label="İptal" name="autoreplace_cancel" tool_tip="Tüm deÄŸiÅŸiklikleri iptal et."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </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 4161e6ea52..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> @@ -9,15 +9,6 @@ <floater.string name="move_tooltip"> Kamerayı Yukarı ve AÅŸağı, Sola ve SaÄŸa Hareket Ettir </floater.string> - <floater.string name="camera_modes_title"> - Kamera modları - </floater.string> - <floater.string name="pan_mode_title"> - Yörünge - YakınlÅŸ. - Kamerayı Çvr. - </floater.string> - <floater.string name="presets_mode_title"> - Ön Ayarlı Görünümler - </floater.string> <floater.string name="free_mode_title"> Nesneyi Göster </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..cd999b4b7a 100644 --- a/indra/newview/skins/default/xui/tr/floater_chat_bar.xml +++ b/indra/newview/skins/default/xui/tr/floater_chat_bar.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="chat_bar" title="YAKINDAKİ SOHBET"> - <panel> +<floater name="nearby_chat" title="YAKINDAKİ SOHBET"> + <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"/> + <button name="show_nearby_chat" tool_tip="Yakın sohbet günlüğünü gösterir/gizler"/> </panel> </floater> diff --git a/indra/newview/skins/default/xui/tr/floater_env_settings.xml b/indra/newview/skins/default/xui/tr/floater_env_settings.xml deleted file mode 100644 index d53629f6fe..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_env_settings.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Environment Editor Floater" title="ÇEVRE DÜZENLEYİCİ"> - <floater.string name="timeStr"> - [hour12,datetime,utc]:[min,datetime,utc] [ampm,datetime,utc] - </floater.string> - <text name="EnvTimeText"> - Günün Saati - </text> - <text name="EnvTimeText2"> - 12:00 PM - </text> - <text name="EnvCloudText"> - Bulut Örtüsü - </text> - <text name="EnvWaterColorText"> - Su Rengi - </text> - <color_swatch name="EnvWaterColor" tool_tip="Renk seçiciyi açmak için tıklayın"/> - <text name="EnvWaterFogText"> - Su Sisi - </text> - <button label="Gayrimenkul Saati Kullan" name="EnvUseEstateTimeButton"/> - <button label="GeliÅŸmiÅŸ Gökyüzü" name="EnvAdvancedSkyButton"/> - <button label="GeliÅŸmiÅŸ Su" name="EnvAdvancedWaterButton"/> -</floater> 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..b204389083 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"/> @@ -25,6 +25,10 @@ VBO EtkinleÅŸtir: </text> <check_box initial_value="true" label="OpenGL Vertex Tampon Nesnelerini EtkinleÅŸtir" name="vbo" tool_tip="Modern donanımlarda bunun etkinleÅŸtirilmesi performans artışı saÄŸlar. Ancak, eski donanımlardaki VBO uygulamaları yetersizdir ve etkinleÅŸtirildiÄŸinde bilgisayarınız çökebilir."/> + <text name="tc label"> + S3TC'ü EtkinleÅŸtir: + </text> + <check_box initial_value="true" label="Doku Sıkıştırmasını EtkinleÅŸtir (yeniden baÅŸlatma gerektirir)" name="texture compression" tool_tip="Video bellekteki dokuları sıkıştırır, renk kalitesinde bazı kayıplar olmasına karşın daha yüksek çözünürlükte dokuların yüklenmesine imkan tanır."/> <slider label="Doku BelleÄŸi (MB):" name="GraphicsCardTextureMemory" tool_tip="Dokular için tahsis edilecek bellek miktarı. Varsayılan deÄŸer video kartı belleÄŸidir. Bu deÄŸerin küçültülmesi performansı artırabilir, ama ayrıca dokuları bulanıklaÅŸtırabilir."/> <spinner label="Sis Mesafe Oranı:" name="fog"/> <button label="Tamam" label_selected="Tamam" name="OK"/> diff --git a/indra/newview/skins/default/xui/tr/floater_inventory.xml b/indra/newview/skins/default/xui/tr/floater_inventory.xml deleted file mode 100644 index cfb12d4b68..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_inventory.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="ENVANTERİM"> - <panel label="Envanter Paneli" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml new file mode 100644 index 0000000000..325d1d9ed9 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_merchant_outbox" title="SATICI GİDEN KUTUSU"> + <string name="OutboxFolderCount1"> + 1 klasör + </string> + <string name="OutboxFolderCountN"> + [NUM] klasör + </string> + <string name="OutboxImporting"> + Klasörler gönderiliyor... + </string> + <string name="OutboxInitializing"> + BaÅŸlatılıyor... + </string> + <panel label=""> + <panel> + <panel name="outbox_inventory_placeholder_panel"> + <text name="outbox_inventory_placeholder_title"> + Yükleniyor... + </text> + </panel> + </panel> + <panel> + <button label="Pazaryerine Gönder" name="outbox_import_btn" tool_tip="Pazaryeri Vitrinime Gönder"/> + </panel> + </panel> +</floater> 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..c00cadd3bd 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> @@ -89,19 +92,54 @@ <text initial_value="Üçgenler" name="triangles" value="Üçgenler"/> <text initial_value="Köşeler" name="vertices" value="Köşeler"/> <text initial_value="Yüksek" name="high_label" value="Yüksek"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Dosyadan yükle"/> + <item name="Generate" value="OluÅŸtur"/> + </combo_box> <button label="Gözat..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="Üçgen Limiti"/> + <item name="Error Threshold" value="Hata EÅŸiÄŸi"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Orta" name="medium_label" value="Orta"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Dosyadan yükle"/> + <item name="Generate" value="OluÅŸtur"/> + <item name="Use LoD above" value="Yukarıdaki ayrıntı seviyesini kullan"/> + </combo_box> <button label="Gözat..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="Üçgen Limiti"/> + <item name="Error Threshold" value="Hata EÅŸiÄŸi"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Düşük" name="low_label" value="Düşük"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Dosyadan yükle"/> + <item name="Generate" value="OluÅŸtur"/> + <item name="Use LoD above" value="Yukarıdaki ayrıntı seviyesini kullan"/> + </combo_box> <button label="Gözat..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="Üçgen Limiti"/> + <item name="Error Threshold" value="Hata EÅŸiÄŸi"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="En Düşük" name="lowest_label" value="En Düşük"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Dosyadan yükle"/> + <item name="Generate" value="OluÅŸtur"/> + <item name="Use LoD above" value="Yukarıdaki ayrıntı seviyesini kullan"/> + </combo_box> <button label="Gözat..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="Üçgen Limiti"/> + <item name="Error Threshold" value="Hata EÅŸiÄŸi"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Normalleri OluÅŸtur" name="gen_normals"/> diff --git a/indra/newview/skins/default/xui/tr/floater_model_wizard.xml b/indra/newview/skins/default/xui/tr/floater_model_wizard.xml deleted file mode 100644 index 108d20cfac..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_model_wizard.xml +++ /dev/null @@ -1,205 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Model Wizard" title="KARÅžIYA MODEL YÜKLEME SİHİRBAZI"> - <button label="5. Karşıya Yükle" name="upload_btn"/> - <button label="4. İncele" name="review_btn"/> - <button label="3. Fizik" name="physics_btn"/> - <button label="2. Optimize et" name="optimize_btn"/> - <button label="1. Dosya Seç" name="choose_file_btn"/> - <panel name="choose_file_panel"> - <panel name="header_panel"> - <text name="header_text"> - Model dosyasını seçin - </text> - </panel> - <panel name="content"> - <text name="advanced_users_text"> - GeliÅŸmiÅŸ kullanıcılar: EÄŸer 3B içerik oluÅŸturma araçlarını kullanmayı biliyorsanız, GeliÅŸmiÅŸ Karşıya Yükleyiciyi kullanmak isteyebilirsiniz. - </text> - <button label="GeliÅŸmiÅŸe geç" name="switch_to_advanced"/> - <text name="Cache location"> - Karşıya yüklenecek model dosyasını seçin - </text> - <button label="Gözat..." label_selected="Gözat..." name="browse"/> - <text name="dimensions"> - X Y Z - </text> - <text name="warning_label"> - UYARI: - </text> - <text name="warning_text"> - Bu modelin Second Life sunucularına nihai karşıya yükleme adımını tamamlayamayacaksınız. Hesabınızı örgü modellerinin karşıya yüklenmesi için ayarlamanın [secondlife:///app/floater/learn_more nasıl yapılacağını öğrenin]. - </text> - </panel> - </panel> - <panel name="optimize_panel"> - <panel name="header_panel"> - <text name="header_text"> - Modeli optimize et - </text> - </panel> - <text name="description"> - Modeli performans için optimize ettik. İstiyorsanız daha da ayarlayabilirsiniz. - </text> - <panel name="content"> - <text name="high_detail_text"> - Ayrıntı Seviyesi OluÅŸtur: Yüksek - </text> - <text name="medium_detail_text"> - Ayrıntı Seviyesi OluÅŸtur: Orta - </text> - <text name="low_detail_text"> - Ayrıntı Seviyesi OluÅŸtur: Düşük - </text> - <text name="lowest_detail_text"> - Ayrıntı Seviyesi OluÅŸtur: En Düşük - </text> - </panel> - <panel name="content2"> - <button label="Geometri hesaplarını tekrar yap" name="recalculate_geometry_btn"/> - <text name="lod_label"> - Geometri önizleme - </text> - <combo_box name="preview_lod_combo" tool_tip="Önizleme iÅŸlemesinde görülecek ayrıntı seviyesi"> - <combo_item name="high"> - Çok ayrıntı - </combo_item> - <combo_item name="medium"> - Orta düzey ayrıntı - </combo_item> - <combo_item name="low"> - Az ayrıntı - </combo_item> - <combo_item name="lowest"> - En az ayrıntı - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="physics_panel"> - <panel name="header_panel"> - <text name="header_text"> - Fizik ayarlarını yap - </text> - </panel> - <text name="description"> - Modelin dış gövdesi için bir ÅŸekil oluÅŸturacağız. Modelinizin amacına uygun olarak ÅŸeklin ayrıntı seviyesini belirleyin. - </text> - <panel name="content"> - <button label="Fizik hesaplarını tekrar yap" name="recalculate_physics_btn"/> - <button label="Tekrar hesaplanıyor..." name="recalculating_physics_btn"/> - <text name="lod_label"> - Fizik önizleme - </text> - <combo_box name="preview_lod_combo2" tool_tip="Önizleme iÅŸlemesinde görülecek ayrıntı seviyesi"> - <combo_item name="high"> - Çok ayrıntı - </combo_item> - <combo_item name="medium"> - Orta düzey ayrıntı - </combo_item> - <combo_item name="low"> - Az ayrıntı - </combo_item> - <combo_item name="lowest"> - En az ayrıntı - </combo_item> - </combo_box> - </panel> - </panel> - <panel name="review_panel"> - <panel name="header_panel"> - <text name="header_text"> - İncele - </text> - </panel> - <panel name="content"> - <text name="review_prim_equiv"> - Parsele/bölgeye etkisi: [EQUIV] prim eÅŸdeÄŸerleri - </text> - <text name="review_fee"> - Hesabınızdan L$ [FEE] karşıya yükleme ücreti düşülecektir. - </text> - <text name="review_confirmation"> - Karşıya yükleme düğmesine tıkladığınızda, modelde yer alan malzeme için ilgili haklara sahip olduÄŸunuzu teyid edersiniz. - </text> - </panel> - </panel> - <panel name="upload_panel"> - <panel name="header_panel"> - <text name="header_text"> - Karşıya yükleme bitti - </text> - </panel> - <text name="model_uploaded_text"> - Modeliniz karşıya yüklendi. - </text> - <text name="inventory_text"> - Bunu, envanterinizdeki Nesneler klasöründe bulacaksınız. - </text> - <text name="charged_fee"> - Hesabınızdan L$ [FEE] düşüldü. - </text> - </panel> - <button label="<< Geri" name="back"/> - <button label="Sonraki >>" name="next"/> - <button label="Ağırlıkları ve ücreti hesapla >>" name="calculate"/> - <button label="Hesaplanıyor..." name="calculating"/> - <button label="Karşıya Yükle" name="upload" tool_tip="Simülatöre karşıya yükle"/> - <button label="İptal" name="cancel"/> - <button label="Kapat" name="close"/> - <spinner name="import_scale" value="1.0"/> - <string name="status_idle"> - BoÅŸta - </string> - <string name="status_parse_error"> - Dae ayrıştırma sorunu - ayrıntılar için günlüğe bakın. - </string> - <string name="status_reading_file"> - Yükleniyor... - </string> - <string name="status_generating_meshes"> - Örgüler OluÅŸturuluyor... - </string> - <string name="status_vertex_number_overflow"> - Hata: Köşe numarası 65534'ten fazla, iÅŸlem durduruldu! - </string> - <string name="bad_element"> - Hata: Öğe geçersiz - </string> - <string name="high"> - Yüksek - </string> - <string name="medium"> - Orta - </string> - <string name="low"> - Düşük - </string> - <string name="lowest"> - En Düşük - </string> - <string name="mesh_status_good"> - Uygula! - </string> - <string name="mesh_status_na"> - G/D - </string> - <string name="mesh_status_none"> - Hiçbiri - </string> - <string name="mesh_status_submesh_mismatch"> - Ayrıntı seviyelerinde farklı sayıda dokulanabilir yüz var. - </string> - <string name="mesh_status_mesh_mismatch"> - Ayrıntı seviyelerinde farklı sayıda örgü örneÄŸi var. - </string> - <string name="mesh_status_too_many_vertices"> - Ayrıntı seviyesinde fazla sayıda köşe var. - </string> - <string name="mesh_status_missing_lod"> - Gereken ayrıntı seviyesi eksik. - </string> - <string name="layer_all"> - Tümü - </string> -</floater> 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'ye basın) </string> diff --git a/indra/newview/skins/default/xui/tr/floater_nearby_chat.xml b/indra/newview/skins/default/xui/tr/floater_nearby_chat.xml deleted file mode 100644 index 6b12ad0ef5..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="YAKINDAKİ SOHBET"> - <check_box label="Sohbeti çevir" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/tr/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..f38d8c84c6 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="Yol bulma karakterleri"> + <floater.string name="messaging_get_inprogress"> + Yol bulma karakterleri için sorgulama yapılıyor ... + </floater.string> + <floater.string name="messaging_get_error"> + Yol bulma karakterleri için sorgulama yapılırken hata saptandı. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Yol bulma karakterleri yok. + </floater.string> + <floater.string name="messaging_complete_available"> + Toplam [NUM_TOTAL] karakter içerisinden [NUM_SELECTED] adet seçildi. + </floater.string> + <floater.string name="messaging_not_enabled"> + Bu bölgede yol bulma etkin deÄŸil. + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Yükleniyor] + </floater.string> + <floater.string name="character_owner_unknown"> + [Bilinmiyor] + </floater.string> + <floater.string name="character_owner_group"> + [grup] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Ad" name="name"/> + <scroll_list.columns label="Açıklama" name="description"/> + <scroll_list.columns label="Sahip" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="İrtifa" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + Karakterler: + </text> + <button label="Listeyi yenile" name="refresh_objects_list"/> + <button label="Tümünü seç" name="select_all_objects"/> + <button label="Hiçbirini seçme" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + Seçilen karakterler üzerinde eylemler: + </text> + <check_box label="İşareti göster" name="show_beacon"/> + <check_box label="Fizik kapsülünü göster" name="show_physics_capsule"/> + <button label="Al" name="take_objects"/> + <button label="Kopya al" name="take_copy_objects"/> + <button label="Beni ona ışınla" name="teleport_me_to_object" tool_tip="Sadece bir karakter seçildiÄŸinde etkindir."/> + <button label="İade Et" name="return_objects"/> + <button label="Sil" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/tr/floater_pathfinding_console.xml new file mode 100644 index 0000000000..6eecc7fb77 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="Yol bulma görüntüleme / test"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + Yol bulma kütüphanesi uygulaması bulunamıyor. + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + Bu bölgede yol bulma etkin deÄŸil. + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + Bölgenin yüklenmesinin bitmesi bekleniyor. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Navigasyon örgüsünün durumu kontrol ediliyor. + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Navigasyon örgüsü indiriliyor. + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + Sunucudaki navigasyon örgüsü deÄŸiÅŸti. En son navigasyon örgüsü indiriliyor. + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + En son navigasyon örgüsü indirildi. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + Navigasyon örgüsü baÅŸarıyla indirilemedi. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + Navigasyon örgüsünde bekleyen deÄŸiÅŸiklikler var. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + Navigasyon örgüsü oluÅŸturuluyor. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + Bazı navigasyon örgüsü bölgelerinde bekleyen deÄŸiÅŸiklikler var. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + Bazı navigasyon örgüsü bölgeleri oluÅŸturuluyor. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + Bazı navigasyon örgüsü bölgelerinde bekleyen deÄŸiÅŸiklikler var, bazıları ise oluÅŸturuluyor. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + Navigasyon örgüsü güncel. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + Yol bulma kütüphanesi uygulaması bulunamıyor. + </floater.string> + <floater.string name="pathing_region_not_enabled"> + Bu bölgede yol bulma etkin deÄŸil. + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Lütfen baÅŸlangıç ve bitim noktalarını seçin. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Lütfen baÅŸlangıç noktasını seçin. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Lütfen bitim noktasını seçin. + </floater.string> + <floater.string name="pathing_path_valid"> + Yol turuncu olarak gösterilmiÅŸtir. + </floater.string> + <floater.string name="pathing_path_invalid"> + Seçilen noktalar arasında bir yol bulunamıyor. + </floater.string> + <floater.string name="pathing_error"> + Yol oluÅŸturma sırasında bir hata meydana geldi. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Görünüm" name="view_panel"> + <text name="show_label"> + Göster: + </text> + <check_box label="Dünya" name="show_world"/> + <check_box label="Sadece hareket ettirilebilir nesneler" name="show_world_movables_only"/> + <check_box label="Navigasyon örgüsü" name="show_navmesh"/> + <text name="show_walkability_label"> + Yürüyebilirlik haritasını göster: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="Gösterme" name="show_heatmap_mode_none"/> + <combo_box.item label="A karakter tipi" name="show_heatmap_mode_a"/> + <combo_box.item label="B karakter tipi" name="show_heatmap_mode_b"/> + <combo_box.item label="C karakter tipi" name="show_heatmap_mode_c"/> + <combo_box.item label="D karakter tipi" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Yürüyebilirler" name="show_walkables"/> + <check_box label="Maddi hacimler" name="show_material_volumes"/> + <check_box label="Statik engeller" name="show_static_obstacles"/> + <check_box label="Hariç tutma hacimleri" name="show_exclusion_volumes"/> + <check_box label="Su düzlemi" name="show_water_plane"/> + <check_box label="X-ışını görünümü ile" name="show_xray"/> + </panel> + <panel label="Yolu test et" name="test_panel"> + <text name="ctrl_click_label"> + BaÅŸlangıç noktasını seçmek için Ctrl tuÅŸuna basarak tıklayın. + </text> + <text name="shift_click_label"> + Bitim noktasını seçmek için Shift tuÅŸuna basarak tıklayın. + </text> + <text name="character_width_label"> + Karakter geniÅŸliÄŸi + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + Karakter tipi + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Hiçbiri" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Yolu temizle" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/tr/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..2e416c9311 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Yol bulma baÄŸlantı kümeleri"> + <floater.string name="messaging_get_inprogress"> + Yol bulma baÄŸlantı kümeleri için sorgulama yapılıyor ... + </floater.string> + <floater.string name="messaging_get_error"> + Yol bulma baÄŸlantı kümeleri için sorgulama yapılırken hata saptandı. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Seçilen yol bulma baÄŸlantı kümeleri deÄŸiÅŸtiriliyor ... + </floater.string> + <floater.string name="messaging_set_error"> + Seçilen yol bulma baÄŸlantı kümeleri deÄŸiÅŸtirilirken hata saptandı. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Yol bulma baÄŸlantı kümeleri yok. + </floater.string> + <floater.string name="messaging_complete_available"> + Toplam [NUM_TOTAL] baÄŸlantı kümesi içerisinden [NUM_SELECTED] adet seçildi. + </floater.string> + <floater.string name="messaging_not_enabled"> + Bu bölgede yol bulma etkin deÄŸil. + </floater.string> + <floater.string name="linkset_terrain_name"> + [Yüzey] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Yükleniyor] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Bilinmiyor] + </floater.string> + <floater.string name="linkset_owner_group"> + [grup] + </floater.string> + <floater.string name="linkset_is_scripted"> + Evet + </floater.string> + <floater.string name="linkset_is_not_scripted"> + Hayır + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + Bilinmiyor + </floater.string> + <floater.string name="linkset_use_walkable"> + Yürüyebilir + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Statik engel + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Hareket ettirilebilir engel + </floater.string> + <floater.string name="linkset_use_material_volume"> + Maddi hacim + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + Hariç tutma hacmi + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Hareket ettirilebilir fantom + </floater.string> + <floater.string name="linkset_is_terrain"> + [deÄŸiÅŸtirilemez] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [kısıtlı] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [konkav] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [kısıtlı, konkav] + </floater.string> + <floater.string name="linkset_choose_use"> + BaÄŸlantı kümesi kullanımını seç... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="BaÄŸlantı kümesi kullanımına göre filtrele..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Yürüyebilir" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Statik engel" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Hareket ettirilebilir engel" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Maddi hacim" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="Hariç tutma hacmi" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Hareket ettirilebilir fantom" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Uygula" name="apply_filters"/> + <button label="Temizle" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Ad (kök prim)" name="name"/> + <scroll_list.columns label="Açıklama (kök prim)" name="description"/> + <scroll_list.columns label="Sahip" name="owner"/> + <scroll_list.columns label="Komut Dosyalı" name="scripted"/> + <scroll_list.columns label="Etki" name="land_impact"/> + <scroll_list.columns label="Mesafe" name="dist_from_you"/> + <scroll_list.columns label="BaÄŸlantı kümesi kullanımı" name="linkset_use"/> + <scroll_list.columns label="% A" name="a_percent"/> + <scroll_list.columns label="% B" name="b_percent"/> + <scroll_list.columns label="% C" name="c_percent"/> + <scroll_list.columns label="% D" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + BaÄŸlantı kümeleri: + </text> + <button label="Listeyi yenile" name="refresh_objects_list"/> + <button label="Tümünü seç" name="select_all_objects"/> + <button label="Hiçbirini seçme" name="select_none_objects"/> + </panel> + <panel> + <check_box label="İşareti göster" name="show_beacon"/> + <button label="Al" name="take_objects"/> + <button label="Kopya al" name="take_copy_objects"/> + <button label="Beni ona ışınla" name="teleport_me_to_object"/> + <button label="İade Et" name="return_objects"/> + <button label="Sil" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + Yürüyebilirlik: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="A tipi karakterleri için yürüyebilirlik. Örnek karakter tipi humanoiddir."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="B tipi karakterleri için yürüyebilirlik. Örnek karakter tipi yaratıktır."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="C tipi karakterleri için yürüyebilirlik. Örnek karakter tipi mekaniktir."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="D tipi karakterleri için yürüyebilirlik. Örnek karakter tipi diÄŸerdir."/> + <button label="DeÄŸiÅŸiklikleri uygula" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Humanoid) + </text> + <text name="suggested_use_b_label"> + (Yaratık) + </text> + <text name="suggested_use_c_label"> + (Mekanik) + </text> + <text name="suggested_use_d_label"> + (DiÄŸer) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_preview_animation.xml b/indra/newview/skins/default/xui/tr/floater_preview_animation.xml index 1c526c75f9..23b4848333 100644 --- a/indra/newview/skins/default/xui/tr/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/tr/floater_preview_animation.xml @@ -6,6 +6,6 @@ <text name="desc txt"> Açıklama: </text> - <button label="SL Dünyasında Oynat" label_selected="Durdur" name="Anim play btn" tool_tip="Bu animasyonu baÅŸkaları görebilecek ÅŸekilde oynatın"/> - <button label="Yerel Olarak Oynat" label_selected="Durdur" name="Anim audition btn" tool_tip="Bu animasyonu sadece kendinizin görebileceÄŸi ÅŸekilde oynatın"/> + <button label="SL Dünyasında Oynat" label_selected="Durdur" name="Inworld" tool_tip="Bu animasyonu baÅŸkaları görebilecek ÅŸekilde oynatın"/> + <button label="Yerel Olarak Oynat" label_selected="Durdur" name="Locally" tool_tip="Bu animasyonu sadece kendinizin görebileceÄŸi ÅŸekilde oynatın"/> </floater> 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'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'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_spellcheck.xml b/indra/newview/skins/default/xui/tr/floater_spellcheck.xml new file mode 100644 index 0000000000..f5f0ba8fd9 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="Yazım Denetimcisi Ayarları"> + <check_box label="Yazım denetimcisini etkinleÅŸtir" name="spellcheck_enable"/> + <text name="spellcheck_main"> + Ana sözlük : + </text> + <text label="Günlükler:" name="spellcheck_additional"> + İlave sözlükler : + </text> + <text name="spellcheck_available"> + Mevcut + </text> + <text name="spellcheck_active"> + Etkin + </text> + <button label="Kaldır" name="spellcheck_remove_btn"/> + <button label="İçeri Aktar..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/tr/floater_spellcheck_import.xml new file mode 100644 index 0000000000..ded71cad40 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Sözlüğü İçeri Aktar"> + <button label="Gözat" label_selected="Gözat" name="dictionary_path_browse"/> + <button label="İçeri Aktar" name="ok_btn"/> + <button label="İptal" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_stats.xml b/indra/newview/skins/default/xui/tr/floater_stats.xml index 17f1166c46..afce87bdaa 100644 --- a/indra/newview/skins/default/xui/tr/floater_stats.xml +++ b/indra/newview/skins/default/xui/tr/floater_stats.xml @@ -14,8 +14,11 @@ <stat_bar label="Saniyede Bir Çizilen Üçgenler" name="ktrissec"/> <stat_bar label="Toplam Nesne" name="objs"/> <stat_bar label="Yeni Nesne" name="newobjs"/> + <stat_bar label="Nesne Önbellek İsabet Oranı" name="object_cache_hits"/> </stat_view> <stat_view label="Doku" name="texture"> + <stat_bar label="Önbellek İsabet Oranı" name="texture_cache_hits"/> + <stat_bar label="Önbellek Okuma Gecikme Süresi" name="texture_cache_read_latency"/> <stat_bar label="Sayım" name="numimagesstat"/> <stat_bar label="Ham Sayım" name="numrawimagesstat"/> <stat_bar label="GL BelleÄŸi" name="gltexmemstat"/> @@ -50,7 +53,13 @@ <stat_bar label="Nesneler" name="simobjects"/> <stat_bar label="Etkin Nesneler" name="simactiveobjects"/> <stat_bar label="Etkin Komut Dosyaları" name="simactivescripts"/> + <stat_bar label="Çalıştırılan Komut Dosyaları" name="simpctscriptsrun"/> <stat_bar label="Komut Dosyası Etkinlikleri" name="simscripteps"/> + <stat_view label="Yol bulma" name="simpathfinding"> + <stat_bar label="Yapay Zeka Adım Süresi" name="simsimaistepmsec"/> + <stat_bar label="Atlanan Siluet Adımları" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Güncellenen Karakterler" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_bar label="Gelen Paketler" name="siminpps"/> <stat_bar label="Giden Paketler" name="simoutpps"/> <stat_bar label="Bekleyen Karşıdan Yüklemeler" name="simpendingdownloads"/> diff --git a/indra/newview/skins/default/xui/tr/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/tr/floater_test_layout_stacks.xml new file mode 100644 index 0000000000..b479d5f6d6 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_test_layout_stacks.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="LAYOUTSTACK TESTS"/> diff --git a/indra/newview/skins/default/xui/tr/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/tr/floater_test_text_vertical_aligment.xml new file mode 100644 index 0000000000..fcb7d87287 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_test_text_vertical_aligment.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="TEST PENCERESİ"/> diff --git a/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml index 4ef789f585..889425f23a 100644 --- a/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml @@ -9,15 +9,27 @@ <text name="Multiple"> Birden çok doku </text> + <radio_group name="mode_selection"> + <radio_item label="Envanter" name="inventory" value="0"/> + <radio_item label="Yerel" name="local" value="1"/> + </radio_group> <text name="unknown"> Büyüklük: [DIMENSIONS] </text> <button label="Varsayılan" label_selected="Varsayılan" name="Default"/> - <button label="Hiçbiri" label_selected="Hiçbiri" name="None"/> <button label="BoÅŸ" label_selected="BoÅŸ" name="Blank"/> - <check_box initial_value="true" label="Åžimdi uygula" name="apply_immediate_check"/> + <button label="Hiçbiri" label_selected="Hiçbiri" name="None"/> + <check_box initial_value="true" label="Canlı Önizleme" name="apply_immediate_check"/> + <text name="preview_disabled" value="Önizleme Devre Dışı"/> <filter_editor label="Dokuları Filtrele" name="inventory search editor"/> <check_box initial_value="false" label="Klasörleri göster" name="show_folders_check"/> + <button label="Ekle" label_selected="Ekle" name="l_add_btn"/> + <button label="Kaldır" label_selected="Kaldır" name="l_rem_btn"/> + <button label="Karşıya Yükle" label_selected="Karşıya Yükle" name="l_upl_btn"/> + <scroll_list name="l_name_list"> + <column label="Ad" name="unit_name"/> + <column label="Kimlik" name="unit_id_HIDDEN"/> + </scroll_list> <button label="Tamam" label_selected="Tamam" name="Select"/> <button label="İptal" label_selected="İptal" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/tr/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/tr/floater_texture_fetch_debugger.xml new file mode 100644 index 0000000000..42426225c7 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_texture_fetch_debugger.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="TexFetchDebugger" title="Doku Alımı Hata Ayıklayıcı"> + <text name="total_num_fetched_label"> + 1, Alınan dokuların toplam sayısı: [NUM] + </text> + <text name="total_num_fetching_requests_label"> + 2, Toplam alım talebi sayısı: [NUM] + </text> + <text name="total_num_cache_hits_label"> + 3, Toplam önbellek isabet sayısı: [NUM] + </text> + <text name="total_num_visible_tex_label"> + 4, Görünür dokuların toplam sayısı: [NUM] + </text> + <text name="total_num_visible_tex_fetch_req_label"> + 5, Görünür dokuların alınması için toplam talep sayısı: [NUM] + </text> + <text name="total_fetched_data_label"> + 6, Alınan verilerin toplam sayısı: [SIZE1]KB, Åžifresi Çözülen Veri: [SIZE2]KB, [PIXEL]MPiksel + </text> + <text name="total_fetched_vis_data_label"> + 7, Görünür verilerin toplam sayısı: [SIZE1]KB, Åžifresi Çözülen Veri: [SIZE2]KB + </text> + <text name="total_fetched_rendered_data_label"> + 8, İşlenen verilerin toplam sayısı: [SIZE1]KB, Åžifresi Çözülen Veri: [SIZE2]KB, [PIXEL]MPiksel + </text> + <text name="total_time_cache_read_label"> + 9, Önbellek okunması için toplam süre: [TIME] saniye + </text> + <text name="total_time_cache_write_label"> + 10, Önbellek yazılması için toplam süre: [TIME] saniye + </text> + <text name="total_time_decode_label"> + 11, Åžifre çözülmesi için toplam süre: [TIME] saniye + </text> + <text name="total_time_gl_label"> + 12, GL doku oluÅŸturma için toplam süre: [TIME] saniye + </text> + <text name="total_time_http_label"> + 13, HTTP alımı için toplam süre: [TIME] saniye + </text> + <text name="total_time_fetch_label"> + 14, Tüm alımlar için toplam süre: [TIME] saniye + </text> + <text name="total_time_refetch_vis_cache_label"> + 15, Görünür dokuların önbellekten tekrar alınması, Süre: [TIME] saniye, Alınan: [SIZE]KB, [PIXEL]MPiksel + </text> + <text name="total_time_refetch_all_cache_label"> + 16, Tüm dokuların önbellekten tekrar alınması, Süre: [TIME] saniye, Alınan: [SIZE]KB, [PIXEL]MPiksel + </text> + <text name="total_time_refetch_vis_http_label"> + 17, Görünür dokuların HTTP'den tekrar alınması, Süre: [TIME] saniye, Alınan: [SIZE]KB, [PIXEL]MPiksel + </text> + <text name="total_time_refetch_all_http_label"> + 18, Tüm dokuların HTTP'den tekrar alınması, Süre: [TIME] saniye, Alınan: [SIZE]KB, [PIXEL]MPiksel + </text> + <spinner label="19, Teksel/Piksel Oranı:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, Doku Kaynağı: + </text> + <radio_group name="texture_source"> + <radio_item label="Önbellek + HTTP" name="0"/> + <radio_item label="Sadece HTTP" name="1"/> + </radio_group> + <button label="BaÅŸla" name="start_btn"/> + <button label="Sıfırla" name="clear_btn"/> + <button label="Kapat" name="close_btn"/> + <button label="Önbellek Okunması" name="cacheread_btn"/> + <button label="Önbellek Yazılması" name="cachewrite_btn"/> + <button label="HTTP" name="http_btn"/> + <button label="Åžifre Çöz" name="decode_btn"/> + <button label="GL Dokusu" name="gl_btn"/> + <button label="Görünür Dokuları Önbellekten Tekrar Al" name="refetchviscache_btn"/> + <button label="Tüm ÖnbelleÄŸi Tekrar Al" name="refetchallcache_btn"/> + <button label="Görünür Dokuları HTTP'den Tekrar Al" name="refetchvishttp_btn"/> + <button label="Tüm HTTP'yi Tekrar Al" name="refetchallhttp_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_tools.xml b/indra/newview/skins/default/xui/tr/floater_tools.xml index d4ee9995dd..4bf0372a8a 100644 --- a/indra/newview/skins/default/xui/tr/floater_tools.xml +++ b/indra/newview/skins/default/xui/tr/floater_tools.xml @@ -1,5 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="toolbox floater" short_title="İNÅžA ET ARAÇLARI"> + <floater.string name="grid_screen_text"> + Ekran + </floater.string> + <floater.string name="grid_local_text"> + Yerel + </floater.string> + <floater.string name="grid_world_text"> + Dünya + </floater.string> + <floater.string name="grid_reference_text"> + Referans + </floater.string> + <floater.string name="grid_attachment_text"> + Aksesuar + </floater.string> <floater.string name="status_rotate"> Nesneyi döndürmek için renkli bantları sürükleyin </floater.string> @@ -63,7 +78,12 @@ </text> <check_box initial_value="true" label="Dokuları Uzat" name="checkbox stretch textures"/> <check_box initial_value="true" label="Yasla" name="checkbox snap to grid"/> - <button label="Seçenekler..." name="Options..." tool_tip="İlave aÄŸ seçeneklerine bak"/> + <combo_box name="combobox grid mode" tool_tip="Nesneyi konumlandırmak için aÄŸ cetvelini seçin"> + <combo_box.item label="Dünya" name="World"/> + <combo_box.item label="Yerel" name="Local"/> + <combo_box.item label="Referans" name="Reference"/> + </combo_box> + <button label="" name="Options..." tool_tip="İlave aÄŸ seçeneklerine bak"/> <button name="ToolCube" tool_tip="Küp"/> <button name="ToolPrism" tool_tip="Prizma"/> <button name="ToolPyramid" tool_tip="Piramit"/> @@ -130,6 +150,12 @@ <panel.string name="text modify info 4"> Bu nesneleri deÄŸiÅŸtiremezsiniz </panel.string> + <panel.string name="text modify info 5"> + Bir bölge sınırı üzerinden bu nesneyi deÄŸiÅŸtiremezsiniz + </panel.string> + <panel.string name="text modify info 6"> + Bir bölge sınırı üzerinden bu nesneleri deÄŸiÅŸtiremezsiniz + </panel.string> <panel.string name="text modify warning"> İzinleri ayarlamak için tüm nesneyi seçmelisiniz </panel.string> @@ -179,12 +205,12 @@ <combo_box.item label="YakınlaÅŸtır" name="Zoom"/> </combo_box> <check_box label="Satılık:" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Kopyala" name="Copy"/> <combo_box.item label="İçerik" name="Contents"/> <combo_box.item label="Orijinal" name="Original"/> </combo_box> - <spinner label="Fiyat: L$" name="Edit Cost"/> <check_box label="Aramada göster" name="search_check" tool_tip="KiÅŸiler arama sonuçlarında bu nesneyi görebilsin"/> <panel name="perms_build"> <text name="perm_modify"> @@ -220,6 +246,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Yol bulma özellikleri: + </text> + </panel> </panel> <panel label="Nesne" name="Object"> <check_box label="Kilitli" name="checkbox locked" tool_tip="Nesnenin hareket ettirilmesini veya silinmesini engeller. Arzulanmayan düzenlemelerden kaçınmak için inÅŸa iÅŸlemleri sırasında oldukça faydalıdır."/> diff --git a/indra/newview/skins/default/xui/tr/floater_top_objects.xml b/indra/newview/skins/default/xui/tr/floater_top_objects.xml index e726f583cc..19420c68e3 100644 --- a/indra/newview/skins/default/xui/tr/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/tr/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> Süre </floater.string> - <floater.string name="scripts_mono_time_label"> - Mono Süre - </floater.string> <floater.string name="top_colliders_title"> En Çok Çarpışanlar </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="Ad" name="name"/> <scroll_list.columns label="Sahip" name="owner"/> <scroll_list.columns label="Konum" name="location"/> + <scroll_list.columns label="Parsel" name="parcel"/> <scroll_list.columns label="Süre" name="time"/> - <scroll_list.columns label="Mono Süre" name="mono_time"/> <scroll_list.columns label="URL'ler" name="URLs"/> + <scroll_list.columns label="Bellek (KB)" name="memory"/> </scroll_list> <text name="id_text"> Nesne KimliÄŸi: @@ -48,6 +46,10 @@ Sahip: </text> <button label="Filtrele" name="filter_owner_btn"/> + <text name="parcel_name_text"> + Parsel: + </text> + <button label="Filtrele" name="filter_parcel_btn"/> <button label="Seçileni İade Et" name="return_selected_btn"/> <button label="Tümünü İade Et" name="return_all_btn"/> <button label="Seçileni Devre Dışı Bırak" name="disable_selected_btn"/> 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/floater_voice_effect.xml b/indra/newview/skins/default/xui/tr/floater_voice_effect.xml index a10da39a69..3534a3fe90 100644 --- a/indra/newview/skins/default/xui/tr/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/tr/floater_voice_effect.xml @@ -42,13 +42,16 @@ <string name="effect_Demon"> İblis </string> + <string name="effect_Female Elf"> + DiÅŸi Cin + </string> <string name="effect_Flirty"> Cilveli </string> <string name="effect_Foxy"> Alımlı </string> - <string name="effect_Halloween_2010_Bonus"> + <string name="effect_Halloween 2010 Bonus"> Halloween_2010_Bonus </string> <string name="effect_Helium"> @@ -57,9 +60,18 @@ <string name="effect_Husky"> Güçlü </string> + <string name="effect_Husky Whisper"> + BoÄŸuk Fısıltı + </string> <string name="effect_Intercom"> İnterkom </string> + <string name="effect_Julia"> + Julia + </string> + <string name="effect_Lo Lilt"> + YavaÅŸ Mırıltı + </string> <string name="effect_Macho"> Maço </string> @@ -69,6 +81,9 @@ <string name="effect_Mini"> Mini </string> + <string name="effect_Model"> + Model + </string> <string name="effect_Nano"> Nano </string> @@ -90,6 +105,9 @@ <string name="effect_Roxanne"> Roxanne </string> + <string name="effect_Rumble"> + Gurultu + </string> <string name="effect_Sabrina"> Sabrina </string> @@ -102,6 +120,9 @@ <string name="effect_Shorty"> Bücür </string> + <string name="effect_Smaller"> + Daha Küçük + </string> <string name="effect_Sneaky"> Sinsi </string> diff --git a/indra/newview/skins/default/xui/tr/floater_water.xml b/indra/newview/skins/default/xui/tr/floater_water.xml deleted file mode 100644 index 66d6c1e30d..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_water.xml +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Water Floater" title="GELİŞMİŞ SU DÜZENLEYİCİ"> - <floater.string name="WLDefaultWaterNames"> - Varsayılan:Camsı:Havuz:çamurlu:İkinci Veba:YILAN!!!:Valdez - </floater.string> - <text name="KeyFramePresetsText"> - Su Ön Ayarları: - </text> - <button label="Yeni" label_selected="Yeni" name="WaterNewPreset"/> - <button label="Kaydet" label_selected="Kaydet" name="WaterSavePreset"/> - <button label="Sil" label_selected="Sil" name="WaterDeletePreset"/> - <tab_container name="Water Tabs"> - <panel label="AYARLAR" name="Settings"> - <text name="BHText"> - Su Sisi Rengi - </text> - <color_swatch name="WaterFogColor" tool_tip="Renk seçiciyi açmak için tıklayın"/> - <text name="WaterFogDensText"> - Su YoÄŸunluk Üssü - </text> - <text name="WaterUnderWaterFogModText"> - Sualtı Sis DeÄŸiÅŸtiricisi - </text> - <text name="BDensText"> - Yansıma Dalgacığı ÖlçeÄŸi - </text> - <slider label="1" name="WaterNormalScaleX"/> - <slider label="2" name="WaterNormalScaleY"/> - <slider label="3" name="WaterNormalScaleZ"/> - <text name="HDText"> - Fresnel ÖlçeÄŸi - </text> - <text name="FresnelOffsetText"> - Fresnel Dengeleyicisi - </text> - <text name="DensMultText"> - Yukarıdan Kırılma ÖlçeÄŸi - </text> - <text name="WaterScaleBelowText"> - AÅŸağıdan Kırılma ÖlçeÄŸi - </text> - <text name="MaxAltText"> - BulanıklaÅŸtırma Çarpanı - </text> - </panel> - <panel label="GÖRÜNTÜ" name="Waves"> - <text name="BHText"> - Büyük Dalga Yönü - </text> - <text name="WaterWave1DirXText"> - X - </text> - <text name="WaterWave1DirYText"> - Y - </text> - <text name="BHText2"> - Küçük Dalga Yönü - </text> - <text name="WaterWave2DirXText"> - X - </text> - <text name="WaterWave2DirYText"> - Y - </text> - <text name="BHText3"> - Normal Harita - </text> - </panel> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_windlight_options.xml b/indra/newview/skins/default/xui/tr/floater_windlight_options.xml deleted file mode 100644 index 6c5fba374c..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_windlight_options.xml +++ /dev/null @@ -1,167 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="WindLight floater" title="GELİŞMİŞ GÖKYÜZÜ DÜZENLEYİCİ"> - <floater.string name="WLDefaultSkyNames"> - A-12:A-24:A-3:A-15:A-16.30:A-6:A-18:A-9:A-21:Barselona:Tipi:Mavi Gün Ortası:Sahilde Öğleden Sonra:Sahilde Gün Batımı:Varsayılan:Çölde Gün Batımı:Güzel Bir Gün:Kabarık Büyük Bulutlar:Sisli:Şık Şık:Şık Şık Şık:Dondurma:Hayalet:Uygunsuz Gerçekler:Gün Ortası1:Gün Ortası 2:Gün Ortası 3:Gün Ortası 4:Gece:Korsan:Mor:Denizcinin Keyfi:Saf Tensel - </floater.string> - <text name="KeyFramePresetsText"> - Gökyüzü Ön Ayarları: - </text> - <button label="Yeni" label_selected="Yeni" name="WLNewPreset"/> - <button label="Kaydet" label_selected="Kaydet" name="WLSavePreset"/> - <button label="Sil" label_selected="Sil" name="WLDeletePreset"/> - <button label="Gün Döngüsü Düzenleyici" label_selected="Gün Döngüsü Düzenleyici" name="WLDayCycleMenuButton"/> - <tab_container name="WindLight Tabs"> - <panel label="ATMOSFER" name="Atmosphere"> - <text name="BHText"> - Mavi Ufuk - </text> - <text name="BHText2"> - R - </text> - <text name="BHText3"> - G - </text> - <text name="BHText4"> - B - </text> - <text name="BHText5"> - I - </text> - <text name="BDensText"> - Puslu Ufuk - </text> - <text name="BDensText2"> - Mavi YoÄŸunluÄŸu - </text> - <text name="BHText6"> - R - </text> - <text name="BHText7"> - G - </text> - <text name="BHText8"> - B - </text> - <text name="BHText9"> - I - </text> - <text name="HDText"> - Pus YoÄŸunluÄŸu - </text> - <text name="DensMultText"> - YoÄŸunluk Çarpanı - </text> - <text name="WLDistanceMultText"> - Mesafe Çarpanı - </text> - <text name="MaxAltText"> - Maks İrtifa - </text> - </panel> - <panel label="AYDINLATMA" name="Lighting"> - <text name="SLCText"> - GüneÅŸ/Ay Rengi - </text> - <text name="BHText"> - R - </text> - <text name="BHText2"> - G - </text> - <text name="BHText3"> - B - </text> - <text name="BHText4"> - I - </text> - <text name="TODText"> - GüneÅŸ/Ay Konumu - </text> - <text name="WLAmbientText"> - Ortam - </text> - <text name="BHText5"> - R - </text> - <text name="BHText6"> - G - </text> - <text name="BHText7"> - B - </text> - <text name="BHText8"> - I - </text> - <text name="WLEastAngleText"> - DoÄŸu Açısı - </text> - <text name="SunGlowText"> - GüneÅŸ Parıltısı - </text> - <slider label="Odak" name="WLGlowB"/> - <slider label="Büyüklük" name="WLGlowR"/> - <text name="SceneGammaText"> - Sahne Gaması - </text> - <text name="WLStarText"> - Yıldız Parlaklığı - </text> - </panel> - <panel label="BULUTLAR" name="Clouds"> - <text name="WLCloudColorText"> - Bulut Rengi - </text> - <text name="BHText"> - R - </text> - <text name="BHText2"> - G - </text> - <text name="BHText3"> - B - </text> - <text name="BHText4"> - I - </text> - <text name="WLCloudColorText2"> - Bulut XY/YoÄŸunluÄŸu - </text> - <text name="BHText5"> - X - </text> - <text name="BHText6"> - Y - </text> - <text name="BHText7"> - D - </text> - <text name="WLCloudCoverageText"> - Bulut Örtüsü - </text> - <text name="WLCloudScaleText"> - Bulut YüksekliÄŸi - </text> - <text name="WLCloudDetailText"> - Bulut Ayrıntısı (XY/YoÄŸunluÄŸu) - </text> - <text name="BHText8"> - X - </text> - <text name="BHText9"> - Y - </text> - <text name="BHText10"> - D - </text> - <text name="WLCloudScrollXText"> - Bulut Kaydırma X - </text> - <check_box label="Kilitle" name="WLCloudLockX"/> - <text name="WLCloudScrollYText"> - Bulut Kaydırma Y - </text> - <check_box label="Kilitle" name="WLCloudLockY"/> - <check_box label="Klasik Bulutlar Çiz" name="DrawClassicClouds"/> - </panel> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_window_size.xml b/indra/newview/skins/default/xui/tr/floater_window_size.xml index acc2cc3376..aff20e7960 100644 --- a/indra/newview/skins/default/xui/tr/floater_window_size.xml +++ b/indra/newview/skins/default/xui/tr/floater_window_size.xml @@ -7,10 +7,17 @@ Pencere büyüklüğünü ayarla: </text> <combo_box name="window_size_combo" tool_tip="geniÅŸlik x yükseklik"> - <combo_box.item label="1000 x 700 (varsayılan)" name="item0"/> - <combo_box.item label="1024 x 768" name="item1"/> - <combo_box.item label="1280 x 720 (720p)" name="item2"/> - <combo_box.item label="1920 x 1080 (1080p)" name="item3"/> + <combo_box.item label="1000 x 700 (varsayılan)" name="item1"/> + <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/> + <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/> + <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/> + <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/> + <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/> + <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/> + <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/> + <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/> + <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/> + <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/> </combo_box> <button label="Ayarla" name="set_btn"/> <button label="İptal" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/tr/menu_bottomtray.xml b/indra/newview/skins/default/xui/tr/menu_bottomtray.xml deleted file mode 100644 index f17c0f9971..0000000000 --- a/indra/newview/skins/default/xui/tr/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="KonuÅŸma Düğmesi" name="EnableVoiceChat"/> - <menu_item_check label="Mimik düğmesi" name="ShowGestureButton"/> - <menu_item_check label="Taşıma düğmesi" name="ShowMoveButton"/> - <menu_item_check label="Görüntüleme düğmesi" name="ShowCameraButton"/> - <menu_item_check label="Anlık görüntü düğmesi" name="ShowSnapshotButton"/> - <menu_item_check label="İnÅŸa Et düğmesi" name="ShowBuildButton"/> - <menu_item_check label="Arama düğmesi" name="ShowSearchButton"/> - <menu_item_check label="Harita düğmesi" name="ShowWorldMapButton"/> - <menu_item_check label="Mini-harita düğmesi" name="ShowMiniMapButton"/> - <menu_item_call label="Kes" name="NearbyChatBar_Cut"/> - <menu_item_call label="Kopyala" name="NearbyChatBar_Copy"/> - <menu_item_call label="Yapıştır" name="NearbyChatBar_Paste"/> - <menu_item_call label="Sil" name="NearbyChatBar_Delete"/> - <menu_item_call label="Tümünü Seç" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/tr/menu_im_well_button.xml b/indra/newview/skins/default/xui/tr/menu_im_well_button.xml deleted file mode 100644 index c3e559a723..0000000000 --- a/indra/newview/skins/default/xui/tr/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<context_menu name="IM Well Button Context Menu"> - <menu_item_call label="Tümünü Kapat" name="Close All"/> -</context_menu> diff --git a/indra/newview/skins/default/xui/tr/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/tr/menu_inspect_object_gear.xml index 02e5415598..d1d3f9ac8d 100644 --- a/indra/newview/skins/default/xui/tr/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/tr/menu_inspect_object_gear.xml @@ -12,6 +12,7 @@ <menu_item_call label="Ekle" name="add"/> <menu_item_call label="Raporla" name="report"/> <menu_item_call label="Engelle" name="block"/> + <menu_item_call label="Engellemeyi Kaldır" name="unblock"/> <menu_item_call label="YakınlaÅŸtır" name="zoom_in"/> <menu_item_call label="Kaldır" name="remove"/> <menu_item_call label="Ek Bilgi" name="more_info"/> diff --git a/indra/newview/skins/default/xui/tr/menu_inventory.xml b/indra/newview/skins/default/xui/tr/menu_inventory.xml index f14066fd7b..51049427af 100644 --- a/indra/newview/skins/default/xui/tr/menu_inventory.xml +++ b/indra/newview/skins/default/xui/tr/menu_inventory.xml @@ -59,6 +59,7 @@ <menu_item_call label="Özellikler" name="Properties"/> <menu_item_call label="Yeniden Adlandır" name="Rename"/> <menu_item_call label="Varlık UUID'sini Kopyala" name="Copy Asset UUID"/> + <menu_item_call label="Kes" name="Cut"/> <menu_item_call label="Kopyala" name="Copy"/> <menu_item_call label="Yapıştır" name="Paste"/> <menu_item_call label="BaÄŸlantı Olarak Yapıştır" name="Paste As Link"/> @@ -67,6 +68,7 @@ <menu_item_call label="Sistem Klasörünü Sil" name="Delete System Folder"/> <menu_item_call label="Konferans Sohbeti BaÅŸlat" name="Conference Chat Folder"/> <menu_item_call label="Oyna" name="Sound Play"/> + <menu_item_call label="SLurl'i Kopyala" name="url_copy"/> <menu_item_call label="Yer İmi Hakkında" name="About Landmark"/> <menu_item_call label="SL Dünyasında Oynat" name="Animation Play"/> <menu_item_call label="Yerel Olarak Oynat" name="Animation Audition"/> @@ -84,6 +86,6 @@ <menu_item_call label="Ekle" name="Wearable Add"/> <menu_item_call label="Çıkar" name="Take Off"/> <menu_item_call label="Satıcı Giden Kutusuna Kopyala" name="Merchant Copy"/> - <menu_item_call label="Satıcı Giden Kutusuna Taşı" name="Merchant Move"/> + <menu_item_call label="Pazaryerine Gönder" name="Marketplace Send"/> <menu_item_call label="--seçenek yok--" name="--no options--"/> </menu> diff --git a/indra/newview/skins/default/xui/tr/menu_login.xml b/indra/newview/skins/default/xui/tr/menu_login.xml index 4c3539b38b..f27908bf7a 100644 --- a/indra/newview/skins/default/xui/tr/menu_login.xml +++ b/indra/newview/skins/default/xui/tr/menu_login.xml @@ -17,8 +17,8 @@ <menu_item_call label="Pencere Büyüklüğünü Ayarla..." name="Set Window Size..."/> <menu_item_call label="Hizmet Åžartlarını Göster" name="TOS"/> <menu_item_call label="Kritik İletiyi Göster" name="Critical"/> - <menu_item_call label="Ortam Tarayıcı Testi" name="Web Browser Test"/> <menu_item_call label="Web İçeriÄŸi Gezdiricisi Hata Ayıklama Testi" name="Web Content Floater Debug Test"/> + <menu label="Günlük Tutma Seviyesini Seç" name="Set Logging Level"/> <menu_item_check label="Izgara Seçiciyi Göster" name="Show Grid Picker"/> <menu_item_call label="Bildirimler Konsolunu Göster" name="Show Notifications Console"/> </menu> diff --git a/indra/newview/skins/default/xui/tr/menu_mode_change.xml b/indra/newview/skins/default/xui/tr/menu_mode_change.xml deleted file mode 100644 index 678950b633..0000000000 --- a/indra/newview/skins/default/xui/tr/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="Temel" name="BasicMode"/> - <menu_item_check label="GeliÅŸmiÅŸ" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/tr/menu_object.xml b/indra/newview/skins/default/xui/tr/menu_object.xml index d60c68e5e9..72f7adf016 100644 --- a/indra/newview/skins/default/xui/tr/menu_object.xml +++ b/indra/newview/skins/default/xui/tr/menu_object.xml @@ -3,6 +3,8 @@ <menu_item_call label="Dokun" name="Object Touch"/> <menu_item_call label="Düzenle" name="Edit..."/> <menu_item_call label="İnÅŸa Et" name="Build"/> + <menu_item_call label="BaÄŸlantı kümelerinde göster" name="show_in_linksets"/> + <menu_item_call label="Karakterlerde göster" name="show_in_characters"/> <menu_item_call label="Aç" name="Open"/> <menu_item_call label="Buraya Otur" name="Object Sit"/> <menu_item_call label="Kalk" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/tr/menu_text_editor.xml b/indra/newview/skins/default/xui/tr/menu_text_editor.xml index ffbf309e84..76c7b43e1e 100644 --- a/indra/newview/skins/default/xui/tr/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/tr/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(bilinmiyor)" name="Suggestion 1"/> + <menu_item_call label="(bilinmiyor)" name="Suggestion 2"/> + <menu_item_call label="(bilinmiyor)" name="Suggestion 3"/> + <menu_item_call label="(bilinmiyor)" name="Suggestion 4"/> + <menu_item_call label="(bilinmiyor)" name="Suggestion 5"/> + <menu_item_call label="Sözlüğe Ekle" name="Add to Dictionary"/> + <menu_item_call label="Yok saya ekle" name="Add to Ignore"/> <menu_item_call label="Kes" name="Cut"/> <menu_item_call label="Kopyala" name="Copy"/> <menu_item_call label="Yapıştır" name="Paste"/> 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..7a7faf6ac4 100644 --- a/indra/newview/skins/default/xui/tr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml @@ -1,53 +1,60 @@ <?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"/> <menu_item_check label="Daima KoÅŸ" name="Always Run"/> <menu_item_call label="Beni Anime Etmeyi Durdur" name="Stop Animating My Avatar"/> + <menu_item_call label="Yürü / koÅŸ / uç..." name="Walk / run / fly"/> </menu> <menu label="Durum" name="Status"> <menu_item_call label="Uzakta" name="Set Away"/> <menu_item_call label="MeÅŸgul" name="Set Busy"/> </menu> - <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="L$ Satın Al..." name="Buy and Sell L$"/> + <menu_item_call label="Satıcı Giden Kutusu..." name="MerchantOutbox"/> + <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_check label="BÜG Aksesuarlarını Göster" name="Show HUD Attachments"/> <menu_item_call label="[APP_NAME]'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_item_call label="Engelleme Listesi" name="Block List"/> </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 +63,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 label="GüneÅŸ" name="Sun"> <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" 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"/> @@ -118,6 +124,11 @@ <menu_item_call label="Komut Dosyalarını Çalışıyor Olarak Ayarla" name="Set Scripts to Running"/> <menu_item_call label="Komut Dosyalarını Çalışmıyor Olarak Ayarla" name="Set Scripts to Not Running"/> </menu> + <menu label="Yol bulma" name="Pathfinding"> + <menu_item_call label="BaÄŸlantı kümeleri..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="Karakterler..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="Görüntüleme / test..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Seçenklr." name="Options"> <menu_item_check label="GeliÅŸmiÅŸ İzinleri Göster" name="DebugPermissions"/> <menu_item_check label="Sadece Nesnelerimi Seç" name="Select Only My Objects"/> @@ -144,6 +155,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"/> @@ -167,26 +179,25 @@ <menu_item_check label="Parçacıkları Gizle" name="Hide Particles"/> <menu_item_check label="Seçilenleri Gizle" name="Hide Selected"/> <menu_item_check label="Saydamı Vurgula" name="Highlight Transparent"/> - <menu_item_check label="BÜG Aksesuarlarını Göster" name="Show HUD Attachments"/> <menu_item_check label="Fare Üzerinden Görünüm Artı İşaretini Göster" name="ShowCrosshairs"/> </menu> <menu label="İşleme Türleri" name="Rendering Types"> - <menu_item_check label="Basit" name="Simple"/> - <menu_item_check label="Alfa" name="Alpha"/> - <menu_item_check label="AÄŸaç" name="Tree"/> - <menu_item_check label="Avatarlar" name="Character"/> - <menu_item_check label="Yüzey Yaması" name="Surface Patch"/> - <menu_item_check label="Gökyüzü" name="Sky"/> - <menu_item_check label="Su" name="Water"/> - <menu_item_check label="Toprak" name="Ground"/> - <menu_item_check label="Hacim" name="Volume"/> - <menu_item_check label="Çimen" name="Grass"/> - <menu_item_check label="Bulutlar" name="Clouds"/> - <menu_item_check label="Parçacıklar" name="Particles"/> - <menu_item_check label="Tümsek" name="Bump"/> + <menu_item_check label="Basit" name="Rendering Type Simple"/> + <menu_item_check label="Alfa" name="Rendering Type Alpha"/> + <menu_item_check label="AÄŸaç" name="Rendering Type Tree"/> + <menu_item_check label="Avatarlar" name="Rendering Type Character"/> + <menu_item_check label="Yüzey Yaması" name="Rendering Type Surface Patch"/> + <menu_item_check label="Gökyüzü" name="Rendering Type Sky"/> + <menu_item_check label="Su" name="Rendering Type Water"/> + <menu_item_check label="Toprak" name="Rendering Type Ground"/> + <menu_item_check label="Hacim" name="Rendering Type Volume"/> + <menu_item_check label="Çimen" name="Rendering Type Grass"/> + <menu_item_check label="Bulutlar" name="Rendering Type Clouds"/> + <menu_item_check label="Parçacıklar" name="Rendering Type Particles"/> + <menu_item_check label="Tümsek" name="Rendering Type Bump"/> </menu> <menu label="İşleme Özellikleri" name="Rendering Features"> - <menu_item_check label="KA" name="UI"/> + <menu_item_check label="KA" name="ToggleUI"/> <menu_item_check label="Seçili" name="Selected"/> <menu_item_check label="Vurgulanmış" name="Highlighted"/> <menu_item_check label="Dinamik Dokular" name="Dynamic Textures"/> @@ -198,11 +209,8 @@ <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"/> @@ -211,13 +219,6 @@ <menu_item_check label="Oyun ÇubuÄŸu Flycam" name="Joystick Flycam"/> <menu_item_call label="Görünümü Sıfırla" name="Reset View"/> <menu_item_call label="Son Sohbet Edene Bak" name="Look at Last Chatter"/> - <menu label="İnÅŸa Et Aracını Seç" name="Select Tool"> - <menu_item_call label="Odaklanma Aracı" name="Focus"/> - <menu_item_call label="Hareket Ettirme Aracı" name="Move"/> - <menu_item_call label="Düzenleme Aracı" name="Edit"/> - <menu_item_call label="OluÅŸturma Aracı" name="Create"/> - <menu_item_call label="Arazi Aracı" name="Land"/> - </menu> <menu_item_call label="YakınlaÅŸtır" name="Zoom In"/> <menu_item_call label="Varsayılan YakınlaÅŸtırma" name="Zoom Default"/> <menu_item_call label="UzaklaÅŸtırma" name="Zoom Out"/> @@ -230,11 +231,10 @@ <menu_item_check label="Doku Konsolu" name="Texture Console"/> <menu_item_check label="Hata Ayıklama Konsolu" name="Debug Console"/> <menu_item_call label="Bildirimler Konsolu" name="Notifications"/> - <menu_item_check label="Doku Büyüklüğü Konsolu" name="Texture Size"/> - <menu_item_check label="Doku Kategorisi Konsolu" name="Texture Category"/> <menu_item_check label="Hızlı Zamanlayıcılar" name="Fast Timers"/> <menu_item_check label="Bellek" name="Memory"/> <menu_item_check label="Sahne İstatistikleri" name="Scene Statistics"/> + <menu_item_call label="Doku Alınması Hata Ayıklama Konsolu" name="Texture Fetch Debug Console"/> <menu_item_call label="Hata Ayıklama Konsoluna giden Bölge Bilgisi" name="Region Info to Debug Console"/> <menu_item_call label="Hata Ayıklama Konsoluna giden Grup Bilgisi" name="Group Info to Debug Console"/> <menu_item_call label="Hata Ayıklama Konsoluna giden Özellikler Bilgisi" name="Capabilities Info to Debug Console"/> @@ -288,8 +288,16 @@ <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="Aksesuar Bayt Büyüklüğü" name="attachment bytes"/> <menu_item_check label="Åžekillendir" name="Sculpt"/> + <menu label="Doku YoÄŸunluÄŸu" name="Texture Density"> + <menu_item_check label="Yok" name="None"/> + <menu_item_check label="Mevcut" name="Current"/> + <menu_item_check label="Arzulanan" name="Desired"/> + <menu_item_check label="Tam" name="Full"/> + </menu> </menu> <menu label="İşleme" name="Rendering"> <menu_item_check label="Eksenler" name="Axes"/> @@ -300,7 +308,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)"/> @@ -308,7 +315,6 @@ <menu_item_check label="Animasyon Dokuları" name="Animation Textures"/> <menu_item_check label="Dokuları Devre Dışı Bırak" name="Disable Textures"/> <menu_item_check label="Tam Çöz. Dokular" name="Rull Res Textures"/> - <menu_item_check label="Dokuları Denetle" name="Audit Textures"/> <menu_item_check label="Doku Atlas (deneysel)" name="Texture Atlas"/> <menu_item_check label="EklenmiÅŸ Işıkları İşle" name="Render Attached Lights"/> <menu_item_check label="EklenmiÅŸ Parçacıkları İşle" name="Render Attached Particles"/> @@ -331,9 +337,8 @@ <menu_item_call label="Kaydı BaÅŸlat" name="Start Record"/> <menu_item_call label="Kaydı Durdur" name="Stop Record"/> </menu> - <menu label="Dünya" name="World"> + <menu label="Dünya" name="DevelopWorld"> <menu_item_check label="Sim GüneÅŸi Geçersiz Kıl" name="Sim Sun Override"/> - <menu_item_check label="Yanıp Sönen İşaret" name="Cheesy Beacon"/> <menu_item_check label="Sabit Hava Durumu" name="Fixed Weather"/> <menu_item_call label="Bölge Nesne ÖnbelleÄŸinin Dökümünü Al" name="Dump Region Object Cache"/> </menu> @@ -365,18 +370,17 @@ </menu> <menu label="Avatar" name="Character"> <menu label="KaydedilmiÅŸ Dokuyu Al" name="Grab Baked Texture"> - <menu_item_call label="İris" name="Iris"/> - <menu_item_call label="BaÅŸ" name="Head"/> - <menu_item_call label="Üst Gövde" name="Upper Body"/> - <menu_item_call label="Alt Gövde" name="Lower Body"/> - <menu_item_call label="Etek" name="Skirt"/> + <menu_item_call label="İris" name="Grab Iris"/> + <menu_item_call label="BaÅŸ" name="Grab Head"/> + <menu_item_call label="Üst Gövde" name="Grab Upper Body"/> + <menu_item_call label="Alt Gövde" name="Grab Lower Body"/> + <menu_item_call label="Etek" name="Grab Skirt"/> </menu> <menu label="Karakter Testleri" name="Character Tests"> <menu_item_call label="XML'de Görünüm" name="Appearance To XML"/> <menu_item_call label="Karakter Geometrisini Aç/Kapa" name="Toggle Character Geometry"/> <menu_item_call label="Test ErkeÄŸi" name="Test Male"/> <menu_item_call label="Test DiÅŸisi" name="Test Female"/> - <menu_item_call label="PG'yi Aç/Kapa" name="Toggle PG"/> <menu_item_check label="Avatar Seçimine İzin Ver" name="Allow Select Avatar"/> </menu> <menu_item_call label="Parametreleri Varsayılana Zorla" name="Force Params to Default"/> @@ -397,17 +401,25 @@ <menu_item_check label="HTTP Dokuları" name="HTTP Textures"/> <menu_item_check label="HTTP Envanteri" name="HTTP Inventory"/> <menu_item_call label="Görüntüleri Sıkıştır" name="Compress Images"/> + <menu_item_call label="Visual Leak Detector'ı EtkinleÅŸtir" name="Enable Visual Leak Detector"/> <menu_item_check label="Mini Döküm Dosyası Hata Ayıklama Çıktısı" name="Output Debug Minidump"/> <menu_item_check label="Sonraki Çalışmada Konsol Penceresi" name="Console Window"/> + <menu label="Günlük Tutma Seviyesini Seç" name="Set Logging Level"> + <menu_item_check label="Hata ayıkla" name="Debug"/> + <menu_item_check label="Bilgi" name="Info"/> + <menu_item_check label="Uyarı" name="Warning"/> + <menu_item_check label="Hata" name="Error"/> + <menu_item_check label="Hiçbiri" name="None"/> + </menu> <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_check label="Yönetici Menüsünü Göster" name="View Admin Options"/> </menu> <menu label="Yönetici" name="Admin"> - <menu label="Object"> - <menu_item_call label="Kopya Al" name="Take Copy"/> - <menu_item_call label="Mülkiyetime Geçir" name="Force Owner To Me"/> - <menu_item_call label="İzinlerle Birlikte Mülkiyetime Geçir" name="Force Owner Permissive"/> + <menu label="Nesne" name="AdminObject"> + <menu_item_call label="Kopya Al" name="Admin Take Copy"/> + <menu_item_call label="Zorunlu Olarak Mülkiyetime Geçir" name="Force Owner To Me"/> + <menu_item_call label="Sahibin İzinlerini Zorunlu Kıl" name="Force Owner Permissive"/> <menu_item_call label="Sil" name="Delete"/> <menu_item_call label="Kilitle" name="Lock"/> <menu_item_call label="Varlık Kimliklerini Al" name="Get Assets IDs"/> @@ -441,7 +453,7 @@ <menu_item_call label="Fizik" name="Physics"/> <menu_item_call label="Tüm Giysiler" name="All Clothes"/> </menu> - <menu label="Yardım" name="Help"> + <menu label="Yardım" name="DeprecatedHelp"> <menu_item_call label="Resmi Linden Blog'u" name="Official Linden Blog"/> <menu_item_call label="Komut Dosyası Portalı" name="Scripting Portal"/> <menu label="Hata Raporlama" name="Bug Reporting"> diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml index b62ff01ab9..488702f9ca 100644 --- a/indra/newview/skins/default/xui/tr/notifications.xml +++ b/indra/newview/skins/default/xui/tr/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -86,17 +92,38 @@ Hata ayrıntıları: '[_NAME]' adlı bildirim notifications.xml içind <usetemplate canceltext="İptal" name="yesnocancelbuttons" notext="Kaydetme" yestext="Kaydet"/> </notification> <notification name="ConfirmNoCopyToOutbox"> - Bu öğeyi Pazaryeri Giden Kutunuza kopyalama izniniz yok. AÅŸağıdaki öğeyi taşımak istediÄŸinize emin misiniz? - [ITEM_NAME] - <usetemplate name="okcancelbuttons" notext="Hayır" yestext="Evet"/> + Bu öğelerden bir veya daha fazlasını Satıcı Giden Kutusuna kopyalama izniniz yok. Bunları taşıyabilir veya bırakabilirsiniz. + <usetemplate name="okcancelbuttons" notext="Öğeleri taşıma" yestext="Öğeleri taşı"/> + </notification> + <notification name="OutboxFolderCreated"> + Satıcı Giden Kutunuzun üst seviyesine aktardığınız her bir öğe için yeni bir klasör oluÅŸturuldu. + <usetemplate ignoretext="Satıcı Giden Kutusunda yeni bir klasör oluÅŸturuldu" name="okignore" yestext="Tamam"/> + </notification> + <notification name="OutboxImportComplete"> + BaÅŸarılı oldu + +Tüm klasörler baÅŸarıyla Pazaryerine gönderildi. + <usetemplate ignoretext="Tüm klasörler Pazaryerine gönderildi" name="okignore" yestext="Tamam"/> + </notification> + <notification name="OutboxImportHadErrors"> + Bazı klasörler aktarılmadı + +Bazı klasörler Pazaryerine gönderildiÄŸinde hatalar meydana geldi. Bu klasörler hala Satıcı Giden Kutunuzda. + +Daha fazla bilgi için bkz. [[MARKETPLACE_IMPORTS_URL] hata günlüğü]. + <usetemplate name="okbutton" yestext="Tamam"/> </notification> - <notification name="OutboxUploadComplete"> - Pazaryerinin karşıya yüklenmesi tamamlandı. - <usetemplate name="okbutton" yestext="YaÅŸasın!"/> + <notification name="OutboxImportFailed"> + Aktarım baÅŸarılamadı + +Bir sistem veya aÄŸ hatası nedeniyle Pazaryerine hiçbir klasör gönderilemedi. Daha sonra tekrar deneyin. + <usetemplate name="okbutton" yestext="Tamam"/> </notification> - <notification name="OutboxUploadHadErrors"> - Pazaryerinin karşıya yüklenmesi hatalarla tamamlandı! Lütfen giden kutunuzdaki sorunları düzeltin ve tekrar deneyin. TeÅŸekkürler. - <usetemplate name="okbutton" yestext="Yuh!"/> + <notification name="OutboxInitFailed"> + Pazaryeri baÅŸlatılamadı. + +Bir sistem veya aÄŸ hatası nedeniyle Pazaryeri baÅŸlatılamadı. Daha sonra tekrar deneyin. + <usetemplate name="okbutton" yestext="Tamam"/> </notification> <notification name="CompileQueueSaveText"> AÅŸağıdaki nedenden dolayı, bir komut dosyası için metin karşıya yüklenirken bir sorun oluÅŸtu: [REASON]. Lütfen daha sonra tekrar deneyin. @@ -339,13 +366,19 @@ Avatarınızın Kullanıcı adını girmeniz gerekmektedir. [SECOND_LIFE]'a giriÅŸ yapmak için bir hesabınız olması gerekir. Åžimdi bir hesap oluÅŸturmak ister misiniz? <url name="url"> - http://join.secondlife.com/ + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Tekrar dene" yestext="Yeni bir hesap oluÅŸtur"/> </notification> <notification name="InvalidCredentialFormat"> Kullanıcı adı alanına Avatarınızın Kullanıcı adını ya da Ad ve Soyadını girmeniz ve yeniden oturum açmanız gerekmektedir. </notification> + <notification name="InvalidGrid"> + '[GRID]' geçerli bir aÄŸ tanımlayıcısı deÄŸil. + </notification> + <notification name="InvalidLocationSLURL"> + BaÅŸlangıç konumunuz için geçerli bir aÄŸ belirtilmedi. + </notification> <notification name="DeleteClassified"> '[NAME]' ilanı silinsin mi? Ödenen ücretler iade edilmeyecektir. @@ -451,8 +484,8 @@ Nesne aralık dışında ya da silinmiÅŸ olabilir. AÅŸağıdaki nedenden dolayı, derlenen komut dosyası kaydedilirken bir sorun oluÅŸtu: [REASON]. Lütfen komut dosyasını kaydetmeyi daha sonra tekrar deneyin. </notification> <notification name="StartRegionEmpty"> - Hata. BaÅŸlangıç Bölgeniz tanımlanmamış. -Lütfen BaÅŸlangıç Konumu kutusuna Bölge adını yazın ya da Son Konumum veya Ana Konumumu BaÅŸlangıç Konumu olarak seçin. + BaÅŸlangıç Bölgeniz tanımlanmamış. +Lütfen BaÅŸlangıç Konumu kutusuna Bölge adını yazın ya da Son BulunduÄŸum Konum veya Ana Konumumu BaÅŸlangıç Konumu olarak seçin. <usetemplate name="okbutton" yestext="Tamam"/> </notification> <notification name="CouldNotStartStopScript"> @@ -474,6 +507,15 @@ Daha fazla bilgi için [_URL] adresini ziyaret etmek ister misiniz? </url> <usetemplate ignoretext="Bilgisayar donanımım desteklenmiyor" name="okcancelignore" notext="Hayır" yestext="Evet"/> </notification> + <notification name="IntelOldDriver"> + Grafik yonganız için muhtemelen daha yeni bir sürücü mevcut. Grafik sürücüleri güncellemek performansınızı kayda deÄŸer ÅŸekilde artırabilir. + + Sürücü güncellemeleri için [_URL] adresini ziyaret etmek ister misiniz? + <url name="url"> + http://www.intel.com/p/en_US/support/detect/graphics + </url> + <usetemplate ignoretext="Grafik sürücüm güncel deÄŸil" name="okcancelignore" notext="Hayır" yestext="Evet"/> + </notification> <notification name="UnknownGPU"> Sisteminiz [APP_NAME] uygulamasının tanımadığı bir grafik kartı içeriyor. Bu durum genellikle [APP_NAME] uygulaması ile henüz denenmemiÅŸ yeni donanımlar kullanıldığında ortaya çıkar. Büyük olasılıkla bir sorun çıkmayacaktır, fakat grafik ayarlarınızı deÄŸiÅŸtirmeniz gerekebilir. @@ -570,6 +612,9 @@ En fazla [MAX] nesneyi birbirine baÄŸlayabilirsiniz. Lütfen hiçbirinin kilitli olmadığından ve hepsine sahip olduÄŸunuzdan emin olun. </notification> + <notification name="CannotLinkPermanent"> + Nesneler bölge sınırları üzerinden baÄŸlantılandırılamaz. + </notification> <notification name="CannotLinkDifferentOwners"> Nesnelerin hepsinin sahibi aynı olmadığı için nesneler birbirine baÄŸlanamıyor. @@ -649,7 +694,7 @@ Beklenen [VALIDS] Çıkış dosyası oluÅŸturulamıyor: [FILE] </notification> <notification name="DoNotSupportBulkAnimationUpload"> - [APP_NAME] ÅŸu an için animasyon dosyalarının toplu olarak karşıya yüklenmesini desteklemiyor. + [APP_NAME] ÅŸu an için BVH formatında animasyon dosyalarının toplu olarak yüklenmesini desteklemiyor. </notification> <notification name="CannotUploadReason"> AÅŸağıdaki nedenden dolayı [FILE] dosyası karşıya yüklenemedi: [REASON] @@ -948,6 +993,41 @@ Etkin grubunuz adına arazi satın almak için gerekli izne sahip deÄŸilsiniz. <button name="Cancel" text="İptal"/> </form> </notification> + <notification label="Otomatik Yerine Koyma Listesine Ekle" name="AddAutoReplaceList"> + Yeni liste için isim: + <form name="form"> + <button name="SetName" text="Tamam"/> + </form> + </notification> + <notification label="Otomatik Yerine Koyma Listesinin Adını DeÄŸiÅŸtir" name="RenameAutoReplaceList"> + '[DUPNAME]' adı kullanılıyor + Benzersiz yeni bir ad girin: + <form name="form"> + <button name="ReplaceList" text="Mevcut Listenin Yerine Koy"/> + <button name="SetName" text="Yeni Adı Kullan"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + Anahtar kelime tek bir kelime olmalıdır; deÄŸiÅŸtirme boÅŸ olamaz. + </notification> + <notification name="InvalidAutoReplaceList"> + Bu deÄŸiÅŸtirme listesi geçerli deÄŸil. + </notification> + <notification name="SpellingDictImportRequired"> + Bir dosya, ad ve dil belirtmelisiniz. + </notification> + <notification name="SpellingDictIsSecondary"> + [DIC_NAME] sözlüğünde bir "aff" dosyası yok gibi görünüyor; bu da "ikincil" bir sözlük olduÄŸu anlamına gelir. +İlave bir sözlük olarak kullanılabilir; ancak Ana sözlüğünüz olarak kullanılamaz. + +Bkz. https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + Åžu kopyalama yapılamıyor: + [FROM_NAME] + kaynağından ÅŸuraya: + [TO_NAME] + </notification> <notification label="Dış Görünümü Kaydet" name="SaveOutfitAs"> Üzerimdekileri yeni bir Dış Görünüm olarak kaydet: <form name="form"> @@ -979,7 +1059,7 @@ Etkin grubunuz adına arazi satın almak için gerekli izne sahip deÄŸilsiniz. </form> </notification> <notification name="RemoveFromFriends"> - [NAME] adlı kiÅŸiyi ArkadaÅŸ Listenizden çıkarmak istiyor musunuz? + <nolink>[NAME]</nolink> adlı kiÅŸiyi ArkadaÅŸ Listenizden çıkarmak istiyor musunuz? <usetemplate name="okcancelbuttons" notext="İptal" yestext="Tamam"/> </notification> <notification name="RemoveMultipleFromFriends"> @@ -1110,8 +1190,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: '[LAST_GPU]' +sonraki: '[THIS_GPU]' + </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] @@ -1122,7 +1207,7 @@ Arazinin satış bedeli sahibine geri ödenmez. Devredilen bir parsel satılırs Yakınındaki baÅŸka bir bölgeye taşındınız. </notification> <notification name="AvatarMovedLast"> - Son konumunuz ÅŸu anda kullanılamıyor. + Talep ettiÄŸiniz konum ÅŸu anda kullanılamıyor. Yakınındaki baÅŸka bir bölgeye taşındınız. </notification> <notification name="AvatarMovedHome"> @@ -1138,11 +1223,10 @@ Yeni bir ana konum ayarlamak isteyebilirsiniz. </form> </notification> <notification name="FirstRun"> - [APP_NAME] kurulumu tamamlandı. + [APP_NAME] yüklemesi tamamlandı. [SECOND_LIFE]'ı ilk kez kullanıyorsanız, oturum açmadan önce bir hesap oluÅŸturmalısınız. -Yeni bir hesap oluÅŸturmak için [http://join.secondlife.com secondlife.com] adresine dönülsün mü? - <usetemplate name="okcancelbuttons" notext="Devam" yestext="Yeni Hesap..."/> + <usetemplate name="okcancelbuttons" notext="Devam" yestext="Hesap OluÅŸtur..."/> </notification> <notification name="LoginPacketNeverReceived"> BaÄŸlantıda sorun yaşıyoruz. İnternet baÄŸlantınızda ya da [SECOND_LIFE_GRID] uygulamasında bir problem olabilir. @@ -1431,7 +1515,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 <nolink>[GROUP]</nolink> grubunun bir üyesisiniz. Gruptan ayrılmak istiyor musunuz? <usetemplate name="okcancelbuttons" notext="İptal" yestext="Tamam"/> </notification> @@ -1659,83 +1743,128 @@ Binlerce bölgeyi deÄŸiÅŸtirecek ve alan sunucusunu kesintiye uÄŸratacaktır. <usetemplate name="okcancelbuttons" notext="İptal" yestext="Tamam"/> </notification> <notification name="RegionEntryAccessBlocked"> - EriÅŸkinlik Seviyesi ayarlarınızdan dolayı bu Bölgeye giremezsiniz. Bu sorun yaşınızı doÄŸrulamak için gerekli bilgilerin eksik olmasından kaynaklanabilir. - -Lütfen en son Görüntüleyicinin yüklü olduÄŸunu doÄŸrulayın ve bu eriÅŸkinlik seviyesi ile eriÅŸilecek alanlar hakkında ayrıntılı bilgi edinmek için Bilgi Bankası'nı ziyaret edin. + Ziyaret etmeye çalıştığınız bölge, mevcut tercihlerinizi aÅŸan içeriÄŸe sahip. Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi deÄŸiÅŸtirebilirsiniz. <usetemplate name="okbutton" yestext="Tamam"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - EriÅŸkinlik Seviyesi ayarlarınızdan dolayı bu bölgeye giremezsiniz. - -EriÅŸkinlik Seviyeleri hakkında daha fazla bilgi edinmek için Bilgi Bankası'nı ziyaret etmek ister misiniz? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + Ziyaret etmeye çalıştığınız bölge [REGIONMATURITY] içeriÄŸe sahip, buna sadece yetiÅŸkinler eriÅŸebilir. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="EriÅŸkinlik Seviyesi ile ilgili kısıtlamalardan dolayı bu Bölgeye giremiyorum" name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> + <usetemplate ignoretext="Bölge geçiÅŸi: Ziyaret etmeye çalıştığınız bölge, sadece yetiÅŸkinlerin eriÅŸebileceÄŸi içeriÄŸe sahip." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - EriÅŸkinlik Seviyesi ayarlarınızdan dolayı bu bölgeye giremezsiniz. + Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriÄŸi mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriÄŸini dışlayacak ÅŸekilde ayarlanmış. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + Ziyaret etmeye çalıştığınız bölge [REGIONMATURITY] içeriÄŸe sahip, buna sadece yetiÅŸkinler eriÅŸebilir. </notification> <notification name="RegionEntryAccessBlocked_Change"> - EriÅŸkinlik Seviyesi tercihlerinizden dolayı bu Bölgeye giremezsiniz. - -İstenilen bölgeye girmek için, lütfen eriÅŸkinlik Seviyesi tercihinizi deÄŸiÅŸtirin. Bu tercih [REGIONMATURITY] içerikli alanlar içinde arama yapabilmenizi ve bu alanlara eriÅŸebilmenizi saÄŸlayacak. DeÄŸiÅŸiklikleri geri almak için, Ben > Tercihler > Genel sekmesine gidin. + Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriÄŸi mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriÄŸini dışlayacak ÅŸekilde ayarlanmış. Tercihlerinizi deÄŸiÅŸtirebilirsiniz veya iptal edebilirsiniz. Tercihleriniz deÄŸiÅŸtikten sonra bölgeye tekrar girmeye çalışabilirsiniz. <form name="form"> - <button name="OK" text="Tercihi DeÄŸiÅŸtir"/> - <button name="Cancel" text="Kapat"/> - <ignore name="ignore" text="SeçtiÄŸim Seviye tercihleri bir bölgeye girmemi engelliyor"/> + <button name="OK" text="Tercihleri deÄŸiÅŸtirin"/> + <button name="Cancel" text="İptal"/> + <ignore name="ignore" text="Bölge geçiÅŸi: Ziyaret etmeye çalıştığınız bölge, mevcut tercihleriniz tarafından dışlanan içeriÄŸe sahip."/> + </form> + </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + Tercihleriniz ile sunucu arasında senkronizasyon eksikliÄŸi olduÄŸu için ışınlama iÅŸleminizde teknik sorunlar yaÅŸanıyoruz. + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + Ziyaret etmeye çalıştığınız bölge, mevcut tercihlerinizi aÅŸan içeriÄŸe sahip. Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi deÄŸiÅŸtirebilirsiniz. + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + Ziyaret etmeye çalıştığınız bölge [REGIONMATURITY] içeriÄŸe sahip, buna sadece yetiÅŸkinler eriÅŸebilir. + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="Işınla: Ziyaret etmeye çalıştığınız bölge, sadece yetiÅŸkinlerin eriÅŸebileceÄŸi içeriÄŸe sahip." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriÄŸi mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriÄŸini dışlayacak ÅŸekilde ayarlanmış. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + Ziyaret etmeye çalıştığınız bölge [REGIONMATURITY] içeriÄŸe sahip, buna sadece yetiÅŸkinler eriÅŸebilir. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriÄŸi mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriÄŸini dışlayacak ÅŸekilde ayarlanmış. Tercihlerinizi deÄŸiÅŸtirebilirsiniz ve ışınlamaya devam edebilirsiniz veya bu ışınlama iÅŸlemini iptal edebilirsiniz. + <form name="form"> + <button name="OK" text="DeÄŸiÅŸtir ve devam et"/> + <button name="Cancel" text="İptal"/> + <ignore name="ignore" text="Işınlama (yeniden baÅŸlatılabilir): Ziyaret etmeye çalıştığınız bölge, mevcut tercihleriniz tarafından dışlanan içeriÄŸe sahip."/> </form> </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriÄŸi mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriÄŸini dışlayacak ÅŸekilde ayarlanmış. Tercihlerinizi deÄŸiÅŸtirebilirsiniz veya ışınlamayı iptal edebilirsiniz. Tercihleriniz deÄŸiÅŸtikten sonra ışınlamayı tekrar yapmaya kalkışmanız gerekecek. + <form name="form"> + <button name="OK" text="Tercihleri deÄŸiÅŸtirin"/> + <button name="Cancel" text="İptal"/> + <ignore name="ignore" text="Işınlama (yeniden baÅŸlatılamaz): Ziyaret etmeye çalıştığınız bölge, mevcut tercihleriniz tarafından dışlanan içeriÄŸe sahip."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + Tercihleriniz ile sunucu arasında senkronizasyon eksikliÄŸi olduÄŸu için ışınlama iÅŸleminizde teknik sorunlar yaÅŸanıyoruz. + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> <notification name="PreferredMaturityChanged"> - EriÅŸkinlik Seviyesi tercihiniz artık [RATING]. + [RATING] içeriÄŸine sahip bir bölgeyi ziyaret edeceÄŸiniz hakkında baÅŸka bildirim almayacaksınız. Daha sonra menü çubuÄŸunda Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi deÄŸiÅŸtirebilirsiniz. + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> + <notification name="MaturityChangeError"> + Åžu anda [PREFERRED_MATURITY] içeriÄŸini görüntüleyecek ÅŸekilde tercihlerinizi deÄŸiÅŸtiremedik. Tercihleriniz, [ACTUAL_MATURITY] içeriÄŸini görüntüleyecek ÅŸekilde sıfırlandı. Menü çubuÄŸunda Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi tekrar deÄŸiÅŸtirmeyi deneyebilirsiniz. + <usetemplate name="okbutton" yestext="Tamam"/> </notification> <notification name="LandClaimAccessBlocked"> - EriÅŸkinlik Seviyesi ayarlarınızdan dolayı bu arazi üzerinde hak talebinde bulunamazsınız. Bu sorun yaşınızı doÄŸrulamak için gerekli bilgilerin eksik olmasından kaynaklanabilir. - -Lütfen en son Görüntüleyicinin yüklü olduÄŸunu doÄŸrulayın ve bu eriÅŸkinlik seviyesi ile eriÅŸilecek alanlar hakkında ayrıntılı bilgi edinmek için Bilgi Bankası'nı ziyaret edin. + Hak talebinde bulunduÄŸunuz arazinin eriÅŸkinlik seviyesi mevcut tercihlerinizi aşıyor. Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi deÄŸiÅŸtirebilirsiniz. <usetemplate name="okbutton" yestext="Tamam"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - EriÅŸkinlik Seviyesi ayarlarınızdan dolayı bu arazi üzerinde hak talebinde bulunamazsınız. - -EriÅŸkinlik Seviyeleri hakkında daha fazla bilgi edinmek için Bilgi Bankası'nı ziyaret etmek ister misiniz? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + Bu arazi üzerinde sadece yetiÅŸkinler hak talebinde bulunabilir. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="EriÅŸkinlik Seviyesi ile ilgili kısıtlandırmalardan dolayı bu Arazi üzerinde hak talebinde bulunamıyorum." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> + <usetemplate ignoretext="Bu arazi üzerinde sadece yetiÅŸkinler hak talebinde bulunabilir." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - EriÅŸkinlik Seviyesi ayarlarınızdan dolayı bu arazi üzerinde hak talebinde bulunamazsınız. + Hak talebinde bulunduÄŸunuz arazide [REGIONMATURITY] içeriÄŸi mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriÄŸini dışlayacak ÅŸekilde ayarlanmış. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + Hak talebinde bulunduÄŸunuz arazi [REGIONMATURITY] içeriÄŸe sahip, buna sadece yetiÅŸkinler eriÅŸebilir. </notification> <notification name="LandClaimAccessBlocked_Change"> - EriÅŸkinlik Seviyesi tercihinizden dolayı bu arazi üzerinde hak talebinde bulunamazsınız. - -EriÅŸkinlik Seviyesi tercihinizi ÅŸimdi yükseltmek ve araziye girebilmek için 'Tercihi DeÄŸiÅŸtir' seçeneÄŸini tıklatabilirsiniz. Böylece [REGIONMATURITY] içerikli alanlar içinde arama yapabilecek ve bu alanlara eriÅŸebileceksiniz. İleride bu ayarı eski haline döndürmek isterseniz, Ben > Tercihler > Genel sekmesine gidin. - <usetemplate ignoretext="SeçtiÄŸim Seviye tercihi Arazi üzerinde hak talebinde bulunmamı engelliyor" name="okcancelignore" notext="Kapat" yestext="Tercihi DeÄŸiÅŸtir"/> + Hak talebinde bulunduÄŸunuz arazide [REGIONMATURITY] içeriÄŸi mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriÄŸini dışlayacak ÅŸekilde ayarlanmış. Tercihlerinizi deÄŸiÅŸtirebilirsiniz, sonra arazi üzerinde tekar hak talebinde bulunabilirsiniz. + <form name="form"> + <button name="OK" text="Tercihleri deÄŸiÅŸtirin"/> + <button name="Cancel" text="İptal"/> + <ignore name="ignore" text="Hak talebinde bulunduÄŸunuz arazi, mevcut tercihleriniz tarafından dışlanan içeriÄŸe sahip."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - EriÅŸkinlik Seviyesi ayarlarınızdan dolayı bu araziyi satın alamazsınız. Bu sorun yaşınızı doÄŸrulamak için gerekli bilgilerin eksik olmasından kaynaklanabilir. - -Lütfen en son Görüntüleyicinin yüklü olduÄŸunu doÄŸrulayın ve bu eriÅŸkinlik seviyesi ile eriÅŸilecek alanlar hakkında ayrıntılı bilgi edinmek için Bilgi Bankası'nı ziyaret edin. + Satın almaya çalıştığınız arazinin eriÅŸkinlik seviyesi mevcut tercihlerinizi aşıyor. Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi deÄŸiÅŸtirebilirsiniz. <usetemplate name="okbutton" yestext="Tamam"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - EriÅŸkinlik Seviyesi ayarlarınızdan dolayı bu araziyi satın alamazsınız. - -EriÅŸkinlik Seviyeleri hakkında daha fazla bilgi edinmek için Bilgi Bankası'nı ziyaret etmek ister misiniz? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Bu araziyi sadece yetiÅŸkinler satın alabilir. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="EriÅŸkinlik Seviyesi ile ilgili kısıtlandırmalardan dolayı bu Araziyi satın alamıyorum" name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> + <usetemplate ignoretext="Bu araziyi sadece yetiÅŸkinler satın alabilir." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - EriÅŸkinlik Seviyesi ayarlarınızdan dolayı bu araziyi satın alamazsınız. + Satın almaya çalıştığınız arazide [REGIONMATURITY] içeriÄŸi mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriÄŸini dışlayacak ÅŸekilde ayarlanmış. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + Ziyaret etmeye çalıştığınız arazi [REGIONMATURITY] içeriÄŸe sahip, buna sadece yetiÅŸkinler eriÅŸebilir. </notification> <notification name="LandBuyAccessBlocked_Change"> - EriÅŸkinlik Seviyesi tercihinizden dolayı bu araziyi satın alamazsınız. - -EriÅŸkinlik Seviyesi tercihinizi ÅŸimdi yükseltmek ve araziye girebilmek için 'Tercihi DeÄŸiÅŸtir' seçeneÄŸini tıklatabilirsiniz. Böylece [REGIONMATURITY] içerikli alanlar içinde arama yapabilecek ve bu alanlara eriÅŸebileceksiniz. İleride bu ayarı eski haline döndürmek isterseniz, Ben > Tercihler > Genel sekmesine gidin. - <usetemplate ignoretext="SeçtiÄŸim Seviye tercihi Araziyi satın almamı engelliyor" name="okcancelignore" notext="Kapat" yestext="Tercihi DeÄŸiÅŸtir"/> + Satın almaya çalıştığınız arazide [REGIONMATURITY] içeriÄŸi mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriÄŸini dışlayacak ÅŸekilde ayarlanmış. Tercihlerinizi deÄŸiÅŸtirebilirsiniz, sonra araziyi tekrar satın almaya çalışabilirsiniz. + <form name="form"> + <button name="OK" text="Tercihleri deÄŸiÅŸtirin"/> + <button name="Cancel" text="İptal"/> + <ignore name="ignore" text="Satın almaya çalıştığınız arazi, mevcut tercihleriniz tarafından dışlanan içeriÄŸe sahip."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Çok fazla prim seçilmiÅŸ. Lütfen [MAX_PRIM_COUNT] ya da daha az prim seçin ve tekrar deneyin @@ -1789,10 +1918,9 @@ EriÅŸkinlik Seviyesi tercihinizi ÅŸimdi yükseltmek ve araziye girebilmek için </form> </notification> <notification label="Bölgenin EriÅŸkinlik Seviyesi DeÄŸiÅŸti" name="RegionMaturityChange"> - Bu bölgenin eriÅŸkinlik seviyesi güncellendi. -DeÄŸiÅŸikliÄŸin harita üzerine yansıtılması biraz zaman alabilir. - -YetiÅŸkin bölgelerine girebilmek için, Sakinlerin yaÅŸ doÄŸrulama ya da ödeme doÄŸrulama yoluyla DoÄŸrulanmış bir Hesaba sahip olmaları gerekmektedir. + Bu bölgenin yetiÅŸkin içerik seviyesi deÄŸiÅŸti. +Bu deÄŸiÅŸikliÄŸin harita üzerine yansıtılması biraz zaman alabilir. + <usetemplate name="okbutton" yestext="Tamam"/> </notification> <notification label="Sesli Sohbet Sürüm UyumsuzluÄŸu" name="VoiceVersionMismatch"> [APP_NAME] uygulamasının bu sürümü bu bölgedeki Sesli Sohbet özelliÄŸi ile uyumlu deÄŸil. Sesli Sohbet özelliÄŸinin düzgün bir ÅŸekilde çalışabilmesi için [APP_NAME] uygulamasını güncellemeniz gerekiyor. @@ -1910,7 +2038,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"/> @@ -2076,14 +2210,11 @@ DiÄŸer kiÅŸilerin bu konuma kolayca eriÅŸmesini saÄŸlamak için bu adrese bir we <usetemplate ignoretext="Görünümümü düzenlerken oluÅŸturduÄŸum giysiyi giy" name="okcancelignore" notext="Hayır" yestext="Evet"/> </notification> <notification name="NotAgeVerified"> - Second Life içinde yetiÅŸkinlere yönelik içeriÄŸe ve bölgelere eriÅŸmek için en az 18 yaşında olmalısınız. 18 yaşından büyük olduÄŸunuzu onaylamak için lütfen yaÅŸ doÄŸrulama sayfamızı ziyaret edin. -Bu adımda web tarayıcınızın baÅŸlatılacağına dikkat edin. - -[_URL] - <url name="url"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="Yaşımı doÄŸrulatmadım" name="okcancelignore" notext="İptal" yestext="YaÅŸ DoÄŸrulamasına Git"/> + Ziyaret etmeye çalıştığınız konum, yaşı 18 ve üzeri olan sakinlere kısıtlanmıştır. + <usetemplate ignoretext="YaÅŸ kısıtı olan alanları ziyaret etmek için yaşım yeterli deÄŸil." name="okignore" yestext="Tamam"/> + </notification> + <notification name="NotAgeVerified_Notify"> + Konum, 18 veya üzeri bir yaÅŸta olanlara kısıtlanmıştır. </notification> <notification name="Cannot enter parcel: no payment info on file"> Bu alanı ziyaret edebilmek için ödeme bilgilerinizin kayıtlı olması gerekir. [SECOND_LIFE] web sitesine gitmek ve bunu ayarlamak istiyor musunuz? @@ -2119,10 +2250,10 @@ Bu adımda web tarayıcınızın baÅŸlatılacağına dikkat edin. Konu: [SUBJECT], İleti: [MESSAGE] </notification> <notification name="FriendOnline"> - [NAME] Çevrimiçi + <nolink>[NAME]</nolink> çevrimiçi </notification> <notification name="FriendOffline"> - [NAME] Çevrimdışı + <nolink>[NAME]</nolink> çevrimdışı </notification> <notification name="AddSelfFriend"> Çok iyi biri olduÄŸunuza eminiz fakat kendinizi arkadaÅŸ olarak ekleyemezsiniz. @@ -2144,7 +2275,7 @@ Bu adımda web tarayıcınızın baÅŸlatılacağına dikkat edin. Terrain.raw karşıdan yüklendi </notification> <notification name="GestureMissing"> - Hmm. [NAME] mimiÄŸi veri tabanında yok. + [NAME] mimiÄŸi veri tabanında yok. </notification> <notification name="UnableToLoadGesture"> [NAME] mimiÄŸi karşıya yüklenemiyor. @@ -2236,14 +2367,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 '[NAME]' gibi konumlara ışınlanabilirsiniz. -Seçmek için herhangi bir yer iminin üzerini tıklatın ve ardından panelin en altındaki 'Işınla' düğmesini tıklatın. -(Yer iminin üzerini çift tıklatabilir veya saÄŸ tıklayıp 'Işınla'yı seçebilirsiniz.) + '[NAME]' gibi konumlara ışınlanmak için "Yerler" 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 'Işınla' düğmesine tıklayın. + (Ayrıca yer imine çift tıklayabilir veya saÄŸ tıklayarak + 'Işınla' seçimini yapabilirsiniz.) </notification> <notification name="TeleportToPerson"> - Ekranınızın saÄŸ tarafındaki İnsanlar panelini açarak '[NAME]' gibi Sakinler ile iletiÅŸim kurabilirsiniz. -Sakini listeden seçin ve panelin altındaki 'Aİ" düğmesini tıklatın. -(Listede adlarını çift tıklatarak veya saÄŸ tıklatıp "Aİ"yi seçerek de bunu yapabilirsiniz.) + '[NAME]' gibi sakinlerle baÄŸlantıya geçmek için "KiÅŸiler" düğmesine tıklayın, açılan pencereden bir Sakin seçin ve sonra + pencerenin altında 'Anlık İleti" üzerine tıklayın. + (Listede adlarına çift tıklayarak veya saÄŸ tıklayıp "Anlık İleti"yi seçerek de bunu yapabilirsiniz.) </notification> <notification name="CantSelectLandFromMultipleRegions"> Sunucunun sınırları dışındaki arazi seçilemez. @@ -2264,6 +2397,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 @@ -2340,6 +2476,23 @@ Burada uçamazsınız. <notification name="NoBuild"> Bu alanda inÅŸa etme özelliÄŸi devre dışı. Burada nesne inÅŸa edemez ve oluÅŸturamazsınız. </notification> + <notification name="PathfindingDirty"> + Bu bölgede bekleyen yol bulma deÄŸiÅŸiklikleri var. EÄŸer oluÅŸturma haklarına sahipseniz, “Bölgeyi yeniden kaydet†düğmesine tıklayarak bölgeyi yeniden kaydedebilirsiniz. + </notification> + <notification name="DynamicPathfindingDisabled"> + Bu bölgede dinamik yol bulma etkin deÄŸil. Yol bulma LSL çaÄŸrılarını kullanan komut dosyalı nesneler, bu bölgede beklendiiÄŸi gibi çalışmayabilir. + </notification> + <notification name="PathfindingRebakeNavmesh"> + Bu bölgede belirli diÄŸer nesneleri deÄŸiÅŸtirmek, hareket eden baÅŸka nesnelerin yanlış davranmasına neden olabilir. Hareket eden baÅŸka nesnelerin doÄŸru davranmasını saÄŸlamak için “Bölgeyi yeniden kaydet†düğmesine tıklayın. Daha fazla bilgi edinmek için “Yardım†seçimini yapın. + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Yardım" ignoretext="Bu bölgede belirli diÄŸer nesneleri deÄŸiÅŸtirmek, hareket eden baÅŸka nesnelerin yanlış davranmasına neden olabilir." name="okhelpignore" yestext="Tamam"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Bir hata meydana geldi. Bir aÄŸ veya sunucu sorunu olabilir ya da oluÅŸturma haklarına sahip olmayabilirsiniz. Bazen oturumu kapatıp, tekrar açmak bu sorunu çözer. + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> <notification name="SeeAvatars"> Bu parsel, avatarları ve metin sohbetini baÅŸka bir parselden saklar. Parselin dışındaki diÄŸer sakinleri göremezsiniz, dışardakiler de sizi göremez. 0. kanaldaki normal metin sohbeti de engellenmiÅŸtir. </notification> @@ -2358,9 +2511,7 @@ Arazi sahibine ait olanlar dışında hiçbir komut dosyası çalışmayacak. İçinde bulunduÄŸunuz Bölgede sadece kamuya ait araziler üzerinde hak talebinde bulunabilirsiniz. </notification> <notification name="RegionTPAccessBlocked"> - EriÅŸkinlik Seviyesi ayarlarınızdan dolayı bu Bölgeye giremezsiniz. Yaşınızı doÄŸrulatmanız ve/veya en son Görüntüleyici'yi yüklemeniz gerekebilir. - -Lütfen bu eriÅŸkinlik Seviyesi ile eriÅŸilecek alanlar hakkında ayrıntılı bilgi edinmek için Bilgi Bankası'na gidin. + Ziyaret etmeye çalıştığınız bölge, mevcut tercihlerinizi aÅŸan içeriÄŸe sahip. Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi deÄŸiÅŸtirebilirsiniz. </notification> <notification name="URBannedFromRegion"> Bu bölgeye eriÅŸiminiz yasaklandı. @@ -2371,11 +2522,11 @@ Lütfen bu eriÅŸkinlik Seviyesi ile eriÅŸilecek alanlar hakkında ayrıntılı b <notification name="ImproperPaymentStatus"> Bu bölgeye girmek için gerekli ödeme durumuna sahip deÄŸilsiniz. </notification> - <notification name="MustGetAgeRgion"> - Bu bölgeye girebilmek için yaÅŸ doÄŸrulamanızın yapılmış olması gerekir. + <notification name="MustGetAgeRegion"> + Bu bölgeye girebilmek için 18 veya üzeri bir yaÅŸta olmanız gerekir. </notification> <notification name="MustGetAgeParcel"> - Bu parsele girebilmek için yaÅŸ doÄŸrulamanızın yapılmış olması gerekir. + Bu parsele girebilmek için 18 veya üzeri bir yaÅŸta olmanız gerekir. </notification> <notification name="NoDestRegion"> Seçili hedef bölge yok. @@ -2477,12 +2628,33 @@ Lütfen biraz sonra tekrar deneyin. <notification name="TeleportOffered"> [NAME_SLURL] size kendi konumuna ışınlanmayı teklif etti: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="Işınla"/> <button name="Cancel" text="İptal"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] size kendi konumuna ışınlanmayı teklif etti: + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Bu bölgede [REGION_CONTENT_MATURITY] içeriÄŸi mevcut, ama mevcut tercihleriniz [REGION_CONTENT_MATURITY] içeriÄŸini dışlayacak ÅŸekilde ayarlanmış durumda. Tercihlerinizi deÄŸiÅŸtirebilirsiniz ve ışınlamaya devam edebilirsiniz veya bu ışınlama iÅŸlemini iptal edebilirsiniz. + <form name="form"> + <button name="Teleport" text="DeÄŸiÅŸtir ve Devam Et"/> + <button name="Cancel" text="İptal"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] size kendi konumuna ışınlanmayı teklif etti: + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Ancak bu bölge sadece yetiÅŸkinlerin eriÅŸebileceÄŸi içeriÄŸe sahip. + </notification> <notification name="TeleportOfferSent"> Işınlanma teklifi [TO_NAME] adlı kiÅŸiye gönderildi </notification> @@ -2518,10 +2690,10 @@ Lütfen biraz sonra tekrar deneyin. </form> </notification> <notification name="FriendshipAccepted"> - [NAME] arkadaÅŸlık teklifinizi kabul etti. + <nolink>[NAME]</nolink> arkadaÅŸlık teklifinizi kabul etti. </notification> <notification name="FriendshipDeclined"> - [NAME] arkadaÅŸlık teklifinizi reddetti. + <nolink>[NAME]</nolink> arkadaÅŸlık teklifinizi reddetti. </notification> <notification name="FriendshipAcceptedByMe"> ArkadaÅŸlık teklifi kabul edildi. @@ -2577,32 +2749,28 @@ Kabul ediyor musunuz? </form> </notification> <notification name="ScriptQuestionCaution"> - '[NAME]' adlı kiÅŸiye ait '<nolink>[OBJECTNAME]</nolink>' adındaki bir nesne ÅŸunu yapmak istiyor: - -[QUESTIONS] -Bu nesneye ya da onu oluÅŸturan kiÅŸiye güvenmiyorsanız, bu talebi reddetmelisiniz. - -Talep kabul edilsin mi? + Uyarı: '<nolink>[OBJECTNAME]</nolink>' nesnesi, Linden Dolar hesabınıza tam eriÅŸim istiyor. EÄŸer eriÅŸime izin verirseniz, süregelen bir ÅŸekilde, ilave uyarı olmaksızın, hesabınızdan herhangi bir zamanda fon çekebilir veya hesabınızı tamamen boÅŸaltabilir. + +Bu türden bir talebin yerinde olması nadir bir durumdur. EÄŸer hesabınıza neden eriÅŸmek istediÄŸini tam olarak anlamıyorsanız, eriÅŸime izin vermeyin. <form name="form"> - <button name="Grant" text="Kabul Et"/> + <button name="Grant" text="Tam eriÅŸime izin ver"/> <button name="Deny" text="Reddet"/> - <button name="Details" text="Ayrıntılar..."/> </form> </notification> <notification name="ScriptDialog"> [NAME] adlı kiÅŸiye ait '<nolink>[TITLE]</nolink>' [MESSAGE] <form name="form"> - <button name="Mute" text="Engelle"/> - <button name="Ignore" text="Yok say"/> + <button name="Client_Side_Mute" text="Engelle"/> + <button name="Client_Side_Ignore" text="Yok say"/> </form> </notification> <notification name="ScriptDialogGroup"> [GROUPNAME] grubuna ait '<nolink>[TITLE]</nolink>' [MESSAGE] <form name="form"> - <button name="Mute" text="Engelle"/> - <button name="Ignore" text="Yok say"/> + <button name="Client_Side_Mute" text="Engelle"/> + <button name="Client_Side_Ignore" text="Yok say"/> </form> </notification> <notification name="BuyLindenDollarSuccess"> @@ -2800,6 +2968,18 @@ PaylaÅŸmanın yapılacağı Sakinler: [RESIDENTS] <usetemplate name="okcancelbuttons" notext="İptal" yestext="Tamam"/> </notification> + <notification name="ShareFolderConfirmation"> + Bir defada sadece bir klasör paylaşılabilir. + +AÅŸağıdaki öğeleri paylaÅŸmak istediÄŸinize emin misiniz? + +<nolink>[ITEMS]</nolink> + +PaylaÅŸmanın yapılacağı Second Life Sakinleri: + +[RESIDENTS] + <usetemplate name="okcancelbuttons" notext="İptal" yestext="Tamam"/> + </notification> <notification name="ItemsShared"> Öğeler baÅŸarılı bir ÅŸekilde paylaşıldı. </notification> @@ -2878,6 +3058,10 @@ Lütfen aÄŸ ve güvenlik duvarı ayarlarınızı kontrol edin. ( [EXISTENCE] saniyedir hayatta ) '[BODYREGION]' için [RESOLUTION] çözünürlükte kaydedilmiÅŸ bir dokuyu [TIME] saniye sonra yerel olarak güncellediniz. </notification> + <notification name="LivePreviewUnavailable"> + Kopyalanamaz ve/veya aktarılamaz olduÄŸu için bu dokunun bir önizlemesini görüntüleyemiyoruz. + <usetemplate ignoretext="Kopyalanamayan ve/veya aktarılamayan dokular için Canlı Önizleme modu mevcut olmayınca beni uyar" name="okignore" yestext="Tamam"/> + </notification> <notification name="ConfirmLeaveCall"> Bu aramadan çıkmak istediÄŸinize emin misiniz? <usetemplate ignoretext="Aramadan çıkmadan önce doÄŸrulama iste" name="okcancelignore" notext="Hayır" yestext="Evet"/> @@ -3049,6 +3233,62 @@ Görünümünüzü döndürmek için dünya üzerindeki herhangi bir yeri tıkla Bu eylem tüm menü öğelerini ve düğmelerini gizler. Bunları geri almak için [SHORTCUT] üzerine tekrar tıklayın. <usetemplate ignoretext="KA'ni gizlemeden önce onayla" name="okcancelignore" notext="İptal" yestext="Tamam"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + Bazı seçili baÄŸlantı kümelerinin Fantom bayrağı dönüştürülecek. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Bazı seçili baÄŸlantı kümelerinin fantom bayrağı dönüştürülecek." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Seçilen bazı baÄŸlantı kümeleri, baÄŸlantı kümesi için izin kısıtlamaları nedeniyle '[REQUESTED_TYPE]' olarak ayarlanamıyor. Bunun yerine bu baÄŸlantı kümeleri '[RESTRICTED_TYPE]' olarak ayarlanacak. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Seçilen bazı baÄŸlantı kümeleri, baÄŸlantı kümesi için izin kısıtlamaları nedeniyle ayarlanamıyor." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Seçilen bazı baÄŸlantı kümeleri '[REQUESTED_TYPE]' olarak ayarlanamaz, çünkü ÅŸekil konveks deÄŸil. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Seçilen bazı baÄŸlantı kümeleri ayarlanamaz, çünkü ÅŸekil konveks deÄŸil." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + Bazı seçili baÄŸlantı kümelerinin Fantom bayrağı dönüştürülecek. + +Seçilen bazı baÄŸlantı kümeleri, baÄŸlantı kümesi için izin kısıtlamaları nedeniyle '[REQUESTED_TYPE]' olarak ayarlanamıyor. Bunun yerine bu baÄŸlantı kümeleri '[RESTRICTED_TYPE]' olarak ayarlanacak. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Bazı seçili baÄŸlantı kümelerinin fantom bayrağı dönüştürülecek, diÄŸerleri ise baÄŸlantı kümesi için izin kısıtlamaları nedeniyle ayarlanamıyor." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + Bazı seçili baÄŸlantı kümelerinin Fantom bayrağı dönüştürülecek. + +Seçilen bazı baÄŸlantı kümeleri '[REQUESTED_TYPE]' olarak ayarlanamaz, çünkü ÅŸekil konveks deÄŸil. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Bazı seçili baÄŸlantı kümelerinin fantom bayrağı dönüştürülecek, diÄŸerleri ise ÅŸekil konveks olmadığı için ayarlanamıyor" name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Seçilen bazı baÄŸlantı kümeleri, baÄŸlantı kümesi için izin kısıtlamaları nedeniyle '[REQUESTED_TYPE]' olarak ayarlanamıyor. Bunun yerine bu baÄŸlantı kümeleri '[RESTRICTED_TYPE]' olarak ayarlanacak. + +Seçilen bazı baÄŸlantı kümeleri '[REQUESTED_TYPE]' olarak ayarlanamaz, çünkü ÅŸekil konveks deÄŸil. Bu baÄŸlantı kümelerinin kullanım tipleri deÄŸiÅŸmez. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Seçilen bazı baÄŸlantı kümeleri, baÄŸlantı kümesi için izin kısıtlamaları nedeniyle ve ÅŸekil konveks olmadığı için ayarlanamıyor." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + Bazı seçili baÄŸlantı kümelerinin Fantom bayrağı dönüştürülecek. + +Seçilen bazı baÄŸlantı kümeleri, baÄŸlantı kümesi için izin kısıtlamaları nedeniyle '[REQUESTED_TYPE]' olarak ayarlanamıyor. Bunun yerine bu baÄŸlantı kümeleri '[RESTRICTED_TYPE]' olarak ayarlanacak. + +Seçilen bazı baÄŸlantı kümeleri '[REQUESTED_TYPE]' olarak ayarlanamaz, çünkü ÅŸekil konveks deÄŸil. Bu baÄŸlantı kümelerinin kullanım tipleri deÄŸiÅŸmez. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Bazı seçili baÄŸlantı kümelerinin fantom bayrağı dönüştürülecek, diÄŸerleri ise baÄŸlantı kümesi için izin kısıtlamaları nedeniyle ve ÅŸekil konveks olmadığı için ayarlanamıyor." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + Seçilen nesne navigasyon örgüsünü etkiliyor. Bunu bir Esnek Yol olarak deÄŸiÅŸtirirseniz, navigasyon örgüsünden çıkartmış olursunuz. + <usetemplate ignoretext="Seçilen nesne navigasyon örgüsünü etkiliyor. Bunu bir Esnek Yol olarak deÄŸiÅŸtirirseniz, navigasyon örgüsünden çıkartmış olursunuz." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> <global name="UnsupportedGLRequirements"> [APP_NAME] uygulaması için gerekli donanım gereksinimlerine sahip olmadığınız görünüyor. [APP_NAME] çoklu doku desteÄŸi sunan bir OpenGL grafik kartı gerektiriyor. EÄŸer grafik kartınız bu özellikteyse, grafik kartınızın en son sürücülerine ve iÅŸletim sisteminiz için gerekli Service Pack ve yamalara sahip olup olmadığınızı kontrol etmeyi deneyebilirsiniz. @@ -3073,4 +3313,24 @@ Bir araziye sahip deÄŸilseniz, Harita'ya bakıp "Bilgi İstasyonu" <global name="You died and have been teleported to your home location"> Hayatınızı kaybettiniz ve ana konumunuza ışınlandınız. </global> + <notification name="LocalBitmapsUpdateFileNotFound"> + [FNAME] güncellenemedi çünkü bu dosya artık bulunamıyor. +Bundan sonra bu dosya için güncellemeler devre dışı bırakılacak. + </notification> + <notification name="LocalBitmapsUpdateFailedFinal"> + [NRETRIES] giriÅŸimde [FNAME] açılamadı veya ÅŸifresi çözülemedi, bu dosya artık bozuk olarak deÄŸerlendiriliyor. +Bundan sonra bu dosya için güncellemeler devre dışı bırakılacak. + </notification> + <notification name="LocalBitmapsVerifyFail"> + Geçersiz veya okunamayan bir görüntü dosyası [FNAME] eklenmeye kalkışıldı, ancak dosya açılamadı veya ÅŸifresi çözülemedi. +GiriÅŸim iptal edildi. + </notification> + <notification name="PathfindingReturnMultipleItems"> + [NUM_ITEMS] öğeyi iade ediyorsunuz. Devam etmek istediÄŸinize emin misiniz? + <usetemplate ignoretext="Birden çok öğeyi iade etmek istediÄŸinize emin misiniz?" name="okcancelignore" notext="Hayır" yestext="Evet"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + [NUM_ITEMS] öğeyi siliyorsunuz. Devam etmek istediÄŸinize emin misiniz? + <usetemplate ignoretext="Birden çok öğeyi silmek istediÄŸinize emin misiniz?" name="okcancelignore" notext="Hayır" yestext="Evet"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/tr/panel_bottomtray.xml b/indra/newview/skins/default/xui/tr/panel_bottomtray.xml deleted file mode 100644 index 26118d8b39..0000000000 --- a/indra/newview/skins/default/xui/tr/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Mikrofonu açar/kapatır"/> - <string name="VoiceControlBtnToolTip" value="Ses kontrol panelini gösterir/gizler"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="KonuÅŸ" label_selected="KonuÅŸ" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="Mimik" name="Gesture" tool_tip="Mimikleri gösterir/gizler"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Hareket Et" name="movement_btn" tool_tip="Hareket kontrollerini gösterir/gizler"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Görünüm" name="camera_btn" tool_tip="Kamera kontrollerini gösterir/gizler"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button name="snapshots" tool_tip="Anlık görüntü al"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="İnÅŸa Et" name="build_btn" tool_tip="İnÅŸa Et Aracını gösterir/gizler"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="Ara" name="search_btn" tool_tip="Aramayı gösterir/gizler"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Harita" name="world_map_btn" tool_tip="Dünya Haritasını gösterir/gizler"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Mini-Harita" name="mini_map_btn" tool_tip="Mini Haritayı gösterir/gizler"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Sohbetler"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="Bildirimler"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> 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_group_invite.xml b/indra/newview/skins/default/xui/tr/panel_group_invite.xml index 9b0c7f799a..4ba5761edb 100644 --- a/indra/newview/skins/default/xui/tr/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/tr/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> SeçtiÄŸiniz bazı Sakinler zaten grupta yer alıyor, bu yüzden bunlara davetiye gönderilmedi. </panel.string> + <panel.string name="invite_selection_too_large"> + Gönderilmeyen Grup Davetiyeleri: Çok fazla Sakin seçilmiÅŸ. Grup Davetiyelerinde talep başına 100 sınırı vardır. + </panel.string> <text name="help_text"> Grubunuza davet etmek için birden fazla Sakin seçebilirsiniz. BaÅŸlamak için "Sakin Seçiciyi Aç" üzerine tıklayın. </text> diff --git a/indra/newview/skins/default/xui/tr/panel_login.xml b/indra/newview/skins/default/xui/tr/panel_login.xml index acd6aa1921..28d316e46b 100644 --- a/indra/newview/skins/default/xui/tr/panel_login.xml +++ b/indra/newview/skins/default/xui/tr/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + OTURUM AÇ + </text> <text name="username_text"> Kullanıcı Adı: </text> @@ -15,15 +15,8 @@ <text name="password_text"> Parola: </text> - <check_box label="Parolayı hatırla" name="remember_check"/> - <button label="Oturum Aç" name="connect_btn"/> - <text name="mode_selection_text"> - Mod: - </text> - <combo_box name="mode_combo" tool_tip="Modunuzu seçin. Hızlı, kolay keÅŸif yapmak ve sohbet için Temel seçimini yapın. Daha fazla özelliÄŸe eriÅŸmek için GeliÅŸmiÅŸ seçimini yapın."> - <combo_box.item label="Temel" name="Basic"/> - <combo_box.item label="GeliÅŸmiÅŸ" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Buradan baÅŸla: </text> @@ -33,16 +26,21 @@ <combo_box.item label="<Bölge adını girin>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Kaydolun + <layout_panel name="links_login_panel"> + <text name="login_help"> + Oturum açarken yardım mı gerekiyor? </text> <text name="forgot_password_text"> Kullanıcı adınızı veya parolanızı mı unuttunuz? </text> - <text name="login_help"> - Oturum açarken yardım mı gerekiyor? + <button label="Oturum Aç" name="connect_btn"/> + <check_box label="Parolayı hatırla" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + HESABINIZI OLUÅžTURUN </text> + <button label="Åžimdi baÅŸla" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/tr/panel_my_profile.xml b/indra/newview/skins/default/xui/tr/panel_my_profile.xml deleted file mode 100644 index fc0b9b6e03..0000000000 --- a/indra/newview/skins/default/xui/tr/panel_my_profile.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Profil" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=en - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=en - </string> - <string name="my_account_link_url" value="http://secondlife.com/account"/> - <string name="no_partner_text" value="Hiçbiri"/> - <string name="no_group_text" value="Hiçbiri"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="scroll_content_panel"> - <panel name="second_life_image_panel"> - <text name="display_name_descr_text"> - Kullanıcı adı - </text> - <text name="name_descr_text"> - Görüntü Adı - </text> - <button label="Profil" name="see_profile_btn" tool_tip="Bu avatar profiline bak"/> - </panel> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_nearby_chat.xml b/indra/newview/skins/default/xui/tr/panel_nearby_chat.xml index c405105e00..d238388b0e 100644 --- a/indra/newview/skins/default/xui/tr/panel_nearby_chat.xml +++ b/indra/newview/skins/default/xui/tr/panel_nearby_chat.xml @@ -1,4 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="nearby_chat"> - <check_box label="Sohbeti çevir" name="translate_chat_checkbox"/> + <layout_stack name="stack"> + <layout_panel name="translate_chat_checkbox_lp"> + <check_box label="Sohbeti çevir" name="translate_chat_checkbox"/> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml index fd954475ac..7d191191c4 100644 --- a/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="chat_bar"> +<panel name="nearby_chat"> <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/panel_notes.xml b/indra/newview/skins/default/xui/tr/panel_notes.xml deleted file mode 100644 index ff5b60996a..0000000000 --- a/indra/newview/skins/default/xui/tr/panel_notes.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Notlar ve Gizlilik" name="panel_notes"> - <layout_stack name="layout"> - <layout_panel name="notes_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <text name="status_message" value="Özel notlarım:"/> - <text name="status_message2" value="Bu kiÅŸiye ÅŸu izinler verilsin:"/> - <check_box label="Çevrimiçi durumumu görme" name="status_check"/> - <check_box label="Beni haritada görme" name="map_check"/> - <check_box label="Nesnelerimi düzenleme, silme veya alma" name="objects_check"/> - </panel> - </scroll_container> - </layout_panel> - <layout_panel name="notes_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="ArkadaÅŸ Ekle" name="add_friend" tool_tip="Sakine arkadaÅŸlık öner"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="Aİ" name="im" tool_tip="Anlık ileti oturumu aç"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Ara" name="call" tool_tip="Bu Sakini ara"/> - </layout_panel> - <layout_panel name="show_on_map_btn_lp"> - <button label="Harita" name="show_on_map_btn" tool_tip="Sakini haritada göster"/> - </layout_panel> - <layout_panel name="teleport_btn_lp"> - <button label="Işınla" name="teleport" tool_tip="Işınlama teklif et"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/tr/floater_postcard.xml b/indra/newview/skins/default/xui/tr/panel_postcard_message.xml index ef11c68afe..2361f4c1c3 100644 --- a/indra/newview/skins/default/xui/tr/floater_postcard.xml +++ b/indra/newview/skins/default/xui/tr/panel_postcard_message.xml @@ -1,22 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="ANLIK GÖRÜNTÜYÜ E-POSTAYLA GÖNDER"> - <floater.string name="default_subject"> - SECOND_LIFE]'dan posta kartı. - </floater.string> - <floater.string name="default_message"> - Buna bakın! - </floater.string> - <floater.string name="upload_message"> - Gönderiyor... - </floater.string> +<panel name="panel_postcard_message"> <text name="to_label"> - Alıcının E-postası: - </text> - <text name="from_label"> - E-postanız: + Kime: </text> <text name="name_label"> - Adınız: + Kimden: </text> <text name="subject_label"> Konu: @@ -30,4 +18,4 @@ </text_editor> <button label="İptal" name="cancel_btn"/> <button label="Gönder" name="send_btn"/> -</floater> +</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..231e8fc5fe 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,7 @@ <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="Çeviri..." name="ok_btn"/> + <button label="Otomatik Yerine Koy..." name="autoreplace_showgui"/> + <button label="Yazım Denetimi Yapılıyor..." name="spellcheck_showgui"/> </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_profile.xml b/indra/newview/skins/default/xui/tr/panel_profile.xml deleted file mode 100644 index 4b7a964537..0000000000 --- a/indra/newview/skins/default/xui/tr/panel_profile.xml +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Profil" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=en - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=en - </string> - <string name="my_account_link_url" value="http://secondlife.com/account"/> - <string name="no_partner_text" value="Hiçbiri"/> - <string name="no_group_text" value="Hiçbiri"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <panel name="second_life_image_panel"> - <text name="title_sl_descr_text" value="[SECOND_LIFE]:"/> - </panel> - <panel name="first_life_image_panel"> - <text name="title_rw_descr_text" value="Gerçek Dünya:"/> - </panel> - <text name="title_member_text" value="Ne Zamandan Beri SL Sakini:"/> - <text name="title_acc_status_text" value="Hesap Durumu:"/> - <text name="title_partner_text" value="Partner:"/> - <panel name="partner_data_panel"> - <text initial_value="(alınıyor)" name="partner_text"/> - </panel> - <text name="title_groups_text" value="Gruplar:"/> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> - <layout_stack name="layout_verb_buttons"> - <layout_panel name="profile_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="ArkadaÅŸ Ekle" name="add_friend" tool_tip="Sakine arkadaÅŸlık öner"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="Aİ" name="im" tool_tip="Anlık ileti oturumu aç"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="Ara" name="call" tool_tip="Bu Sakini ara"/> - </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="Işınla" name="teleport" tool_tip="Işınlama teklif et"/> - </layout_panel> - <layout_panel name="overflow_btn_lp"> - <menu_button label="â–¼" name="overflow_btn" tool_tip="Sakine para öde veya envanteri paylaÅŸ"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_profile_view.xml b/indra/newview/skins/default/xui/tr/panel_profile_view.xml deleted file mode 100644 index 17c5002bd7..0000000000 --- a/indra/newview/skins/default/xui/tr/panel_profile_view.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_target_profile"> - <string name="status_online"> - Çevrimiçi - </string> - <string name="status_offline"> - Çevrimdışı - </string> - <text name="display_name_label" value="Ekran Adı:"/> - <text name="solo_username_label" value="Kullanıcı Adı:"/> - <text name="status" value="Çevrimiçi"/> - <text name="user_name_small" value="Bak arkadaşım bu çok uzun bir ad"/> - <button name="copy_to_clipboard" tool_tip="Panoya Kopyala"/> - <text name="user_label" value="Kullanıcı Adı:"/> - <tab_container name="tabs"> - <panel label="PROFİL" name="panel_profile"/> - <panel label="SEÇMELER" name="panel_picks"/> - <panel label="NOTLAR & GİZLİLİK" name="panel_notes"/> - </tab_container> -</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_region_debug.xml b/indra/newview/skins/default/xui/tr/panel_region_debug.xml index 6e15e0f6f6..834ece563f 100644 --- a/indra/newview/skins/default/xui/tr/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/tr/panel_region_debug.xml @@ -30,5 +30,5 @@ <button label="En Çok Çarpışanlar..." name="top_colliders_btn" tool_tip="En çok potansiyel çarpışma yaÅŸayan nesnelerin listesi"/> <button label="En Çok Komut Dsy. ÇalÅŸtr...." name="top_scripts_btn" tool_tip="Komut dosyalarını çalıştırırken en çok zaman harcayan nesnelerin listesi"/> <button label="Bölgeyi Yeniden BaÅŸlat" name="restart_btn" tool_tip="2 dakikalık bir geri sayımdan sonra bölgeyi yeniden baÅŸlat"/> - <button label="Yeniden BaÅŸlatmayı Ertele" name="cancel_restart_btn" tool_tip="Bölgenin yeniden baÅŸlatılmasını 1 saat ertele"/> + <button label="Yeniden BaÅŸlatmayı İptal Et" name="cancel_restart_btn" tool_tip="Bölge yeniden baÅŸlatmasını iptal et"/> </panel> diff --git a/indra/newview/skins/default/xui/tr/panel_region_estate.xml b/indra/newview/skins/default/xui/tr/panel_region_estate.xml index 4ba55cafb6..4a9028643f 100644 --- a/indra/newview/skins/default/xui/tr/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/tr/panel_region_estate.xml @@ -20,10 +20,10 @@ <slider label="Faz" name="sun_hour_slider"/> <check_box label="Kamusal EriÅŸime İzin Ver" name="externally_visible_check"/> <text name="Only Allow"> - EriÅŸimi ÅŸununla doÄŸrulanan hesaplarla sınırla: + Sadece ÅŸu Sakinlere eriÅŸim izni verin: </text> - <check_box label="Dosyadaki Ödeme Bilgileri" name="limit_payment" tool_tip="Tanınmayan Sakinleri Yasakla"/> - <check_box label="YaÅŸ DoÄŸrulama" name="limit_age_verified" tool_tip="Yaşını doÄŸrulamayan Sakinleri yasakla Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/> + <check_box label="Ödeme bilgileri kayıtlı" name="limit_payment" tool_tip="Sakinlerin bu gayrimenkule eriÅŸebilmesi için ödeme bilgilerinin kayıtlı olması gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/> + <check_box label="18 veya üzeri bir yaÅŸta" name="limit_age_verified" tool_tip="Sakinlerin bu gayrimenkule eriÅŸebilmesi için 18 veya üzeri bir yaÅŸta olmaları gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/> <check_box label="Sesli Sohbete İzin Ver" name="voice_chat_check"/> <check_box label="DoÄŸrudan Işınlamaya İzin Ver" name="allow_direct_teleport"/> <button label="Uygula" name="apply_btn"/> diff --git a/indra/newview/skins/default/xui/tr/panel_region_texture.xml b/indra/newview/skins/default/xui/tr/panel_region_texture.xml deleted file mode 100644 index fd7ca2a893..0000000000 --- a/indra/newview/skins/default/xui/tr/panel_region_texture.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Zemin Dokuları" name="Textures"> - <text name="region_text_lbl"> - Bölge: - </text> - <text name="region_text"> - bilinmiyor - </text> - <text name="detail_texture_text"> - Yüzey Dokuları (512x512, 24 bit .tga dosyalar gerektirir) - </text> - <text name="height_text_lbl"> - 1 (Düşük) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (Yüksek) - </text> - <text name="height_text_lbl5"> - Doku Yükselti Aralıkları - </text> - <text name="height_text_lbl6"> - Kuzeybatı - </text> - <text name="height_text_lbl7"> - KuzeydoÄŸu - </text> - <spinner label="Düşük" name="height_start_spin_1"/> - <spinner label="Düşük" name="height_start_spin_3"/> - <spinner label="Yüksek" name="height_range_spin_1"/> - <spinner label="Yüksek" name="height_range_spin_3"/> - <text name="height_text_lbl8"> - Güneybatı - </text> - <text name="height_text_lbl9"> - GüneydoÄŸu - </text> - <spinner label="Düşük" name="height_start_spin_0"/> - <spinner label="Düşük" name="height_start_spin_2"/> - <spinner label="Yüksek" name="height_range_spin_0"/> - <spinner label="Yüksek" name="height_range_spin_2"/> - <text name="height_text_lbl10"> - Bu deÄŸerler yukarıdaki dokular için karışım aralığını temsil eder. - </text> - <text name="height_text_lbl11"> - Metre cinsinden olan bu deÄŸerler için, DÜŞÜK deÄŸer 1. Dokunun MAKSİMUM yüksekliÄŸi, YÜKSEK deÄŸer ise 4. Dokunun MİNİMUM yüksekliÄŸidir. - </text> - <button label="Uygula" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_script_ed.xml b/indra/newview/skins/default/xui/tr/panel_script_ed.xml index bc30320fa5..7aa1da6fb2 100644 --- a/indra/newview/skins/default/xui/tr/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/tr/panel_script_ed.xml @@ -22,6 +22,8 @@ <menu label="Dosya" name="File"> <menu_item_call label="Kaydet" name="Save"/> <menu_item_call label="Tüm DeÄŸiÅŸiklikleri Geri Çevir" name="Revert All Changes"/> + <menu_item_call label="Dosyadan yükle..." name="LoadFromFile"/> + <menu_item_call label="Dosyaya kaydet..." name="SaveToFile"/> </menu> <menu label="Düzenle" name="Edit"> <menu_item_call label="Geri Al" name="Undo"/> diff --git a/indra/newview/skins/default/xui/tr/panel_script_question_toast.xml b/indra/newview/skins/default/xui/tr/panel_script_question_toast.xml new file mode 100644 index 0000000000..a2d0237da0 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_script_question_toast.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel label="script_question_panel" name="panel_script_question_toast"> + <panel label="buttons_panel" name="buttons_panel"/> +</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_side_tray.xml b/indra/newview/skins/default/xui/tr/panel_side_tray.xml deleted file mode 100644 index 97bca38a50..0000000000 --- a/indra/newview/skins/default/xui/tr/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Yan ÇubuÄŸu Aç/Kapa." name="sidebar_openclose" tab_title="Yan ÇubuÄŸu Aç/Kapa"/> - <sidetray_tab description="Ana konum." name="sidebar_home" tab_title="Ana konum"> - <panel label="ana konum" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Kamuya açık profilinizi ve Favorilerinizi düzenleyin." name="sidebar_me" tab_title="Profilim"> - <panel_container name="panel_container"> - <panel label="Ben" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Yakındaki arkadaÅŸlarınızı, irtibatları ve kiÅŸileri bulun." name="sidebar_people" tab_title="KiÅŸiler"> - <panel_container name="panel_container"> - <panel label="Grup Profili" name="panel_group_info_sidetray"/> - <panel label="EngellenmiÅŸ Sakinler ve Nesneler" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Gitmek istediÄŸiniz yerleri ve daha önce uÄŸradığınız yerleri bulun." label="Yerler" name="sidebar_places" tab_title="Yerler"> - <panel label="Yerler" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="Envanterinize göz atın." name="sidebar_inventory" tab_title="Envanterim"> - <panel label="Envanteri Düzenle" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Görünümünüzü deÄŸiÅŸtirin." name="sidebar_appearance" tab_title="Görünümüm"> - <panel label="Görünümü Düzenle" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> 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]'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..178cbda4a2 100644 --- a/indra/newview/skins/default/xui/tr/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/tr/panel_status_bar.xml @@ -15,10 +15,10 @@ <panel.string name="buycurrencylabel"> L$ [AMT] </panel.string> - <panel name="balance_bg"> + <panel left="-425" name="balance_bg" width="215"> <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/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/tr/panel_volume_pulldown.xml new file mode 100644 index 0000000000..0c8c7b68b5 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater"> + <slider label="Ana" name="System Volume"/> + <slider label="Düğmeler" name="UI Volume"/> + <slider label="Ortam" name="Wind Volume"/> + <slider label="Sesler" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="Mimiklerdeki sesleri etkinleÅŸtir"/> + <slider label="Müzik" name="Music Volume"/> + <check_box name="enable_music" tool_tip="Müzik Akışını EtkinleÅŸtir"/> + <slider label="Ortam" name="Media Volume"/> + <check_box name="enable_media" tool_tip="Akış Ortamını EtkinleÅŸtir"/> + <slider label="Ses" name="Voice Volume"/> + <check_box name="enable_voice_check" tool_tip="Sesli Sohbeti EtkinleÅŸtir"/> +</panel> diff --git a/indra/newview/skins/default/xui/tr/sidepanel_inventory.xml b/indra/newview/skins/default/xui/tr/sidepanel_inventory.xml index 70c449b402..938b5a76d8 100644 --- a/indra/newview/skins/default/xui/tr/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/tr/sidepanel_inventory.xml @@ -2,47 +2,24 @@ <panel label="EÅŸyalar" name="objects panel"> <panel label="" name="sidepanel__inventory_panel"> <layout_stack name="inventory_layout_stack"> - <layout_panel name="inbox_outbox_layout_panel"> - <layout_stack name="inbox_outbox_layout_stack"> - <layout_panel name="inbox_layout_panel"> - <panel label="" name="marketplace_inbox"> - <string name="InboxLabelWithArg"> - Alınan öğeler ([NUM]) - </string> - <string name="InboxLabelNoArg"> - Alınan öğeler - </string> - <button label="Alınan öğeler" name="inbox_btn"/> - <text name="inbox_fresh_new_count"> - [NUM] yeni - </text> - <panel tool_tip="Drag and drop items to your inventory to manage and use them"> - <text name="inbox_inventory_placeholder"> - Pazaryerinden satın alınan öğeler buraya teslim edilir. - </text> - </panel> - </panel> - </layout_panel> - <layout_panel name="outbox_layout_panel"> - <panel label="" name="marketplace_outbox"> - <string name="OutboxLabelWithArg"> - Satıcı giden kutusu ([NUM]) - </string> - <string name="OutboxLabelNoArg"> - Satıcı giden kutusu - </string> - <button label="Satıcı giden kutusu" name="outbox_btn"/> - <button label="" name="outbox_sync_btn" tool_tip="Pazaryeri Vitrinime Gönder"/> - <panel> - <panel name="outbox_inventory_placeholder_panel"> - <text name="outbox_inventory_placeholder_title"> - Yükleniyor... - </text> - </panel> - </panel> - </panel> - </layout_panel> - </layout_stack> + <layout_panel name="inbox_layout_panel"> + <panel label="" name="marketplace_inbox"> + <string name="InboxLabelWithArg"> + Alınan öğeler ([NUM]) + </string> + <string name="InboxLabelNoArg"> + Alınan öğeler + </string> + <button label="Alınan öğeler" name="inbox_btn"/> + <text name="inbox_fresh_new_count"> + [NUM] yeni + </text> + <panel name="inbox_inventory_placeholder_panel" tool_tip="Öğeleri kullanmak için bunları sürükleyin ve envanterinize bırakın"> + <text name="inbox_inventory_placeholder"> + Pazaryerinden satın alınan öğeler buraya teslim edilir. + </text> + </panel> + </panel> </layout_panel> </layout_stack> <panel name="button_panel"> diff --git a/indra/newview/skins/default/xui/tr/sidepanel_item_info.xml b/indra/newview/skins/default/xui/tr/sidepanel_item_info.xml index 81291a431c..86b684c497 100644 --- a/indra/newview/skins/default/xui/tr/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/tr/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (bilinmiyor) </panel.string> + <panel.string name="unknown_multiple"> + (bilinmiyor veya birden çok deÄŸer) + </panel.string> <panel.string name="public"> (kamuya açık) </panel.string> diff --git a/indra/newview/skins/default/xui/tr/sidepanel_task_info.xml b/indra/newview/skins/default/xui/tr/sidepanel_task_info.xml index 2fa6281f05..b0b9ab7716 100644 --- a/indra/newview/skins/default/xui/tr/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/tr/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> Bu nesneleri deÄŸiÅŸtiremezsiniz </panel.string> + <panel.string name="text modify info 5"> + Bir bölge sınırı üzerinden bu nesneyi deÄŸiÅŸtiremezsiniz + </panel.string> + <panel.string name="text modify info 6"> + Bir bölge sınırı üzerinden bu nesneleri deÄŸiÅŸtiremezsiniz + </panel.string> <panel.string name="text modify warning"> Bu nesne baÄŸlantılı parçalara sahip </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Fiyat: L$" name="Edit Cost"/> <check_box label="Aramada göster" name="search_check" tool_tip="KiÅŸiler arama sonuçlarında bu nesneyi görebilsin"/> + <text name="pathfinding_attributes_label"> + Yol bulma özellikleri: + </text> <text name="B:"> B: </text> diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index bf331dc3cf..1be8f5974c 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -137,7 +137,7 @@ Çık </string> <string name="create_account_url"> - http://join.secondlife.com/ + http://join.secondlife.com/index.php?lang=tr-TR&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> Kullandığınız görüntüleyici ile artık Second Life'a eriÅŸemezsiniz. Yeni bir görüntüleyiciyi karşıdan yüklemek için lütfen ÅŸu sayfayı ziyaret edin: @@ -181,7 +181,7 @@ GüncelleÅŸtirmeler için www.secondlife.com/status adresini kontrol edin. </string> <string name="LoginFailedPremiumOnly"> Second Life üzerindeki aktif kullanıcıların olası en iyi deneyimi yaÅŸamasını saÄŸlamak için, oturum açılması geçici olarak kısıtlanmıştır. - + Second Life için ödeme yapmış olan kiÅŸilere öncelik tanımak amacıyla, ücretsiz hesaplara sahip kiÅŸiler bu süre içerisinde Second Life'a eriÅŸemeyecekler. </string> <string name="LoginFailedComputerProhibited"> @@ -339,17 +339,35 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. Buraya sadece bir öğe sürüklenebilir. </string> <string name="TooltipPrice" value="L$[AMOUNT]:"/> + <string name="TooltipOutboxDragToWorld"> + Satıcı giden kutunuzda öğeler oluÅŸturamazsınız + </string> <string name="TooltipOutboxNoTransfer"> - Bu nesnelerden bir veya daha fazlası baÅŸka bir kullanıcıya satılamaz veya aktarılamaz. + Bu nesnelerden bir veya daha fazlası satılamaz veya aktarılamaz. + </string> + <string name="TooltipOutboxNotInInventory"> + Satıcı giden kutunuza sadece doÄŸrudan kendi envanterinizden öğeler koyabilirsiniz </string> <string name="TooltipOutboxWorn"> - Bu nesnelerden bir veya daha fazlasını giyiyorsunuz. Bunları avatarınızdan kaldırın ve tekrar taşımayı deneyin. + Giymekte olduÄŸunuz öğeleri Satıcı giden kutunuza koyamazsınız. + </string> + <string name="TooltipOutboxCallingCard"> + Satıcı giden kutunuza arama kartları koyamazsınız </string> <string name="TooltipOutboxFolderLevels"> - Bu klasörde çok fazla alt klasör seviyesi var. Dahili klasörleri tekrar düzenleyerek maksimum 4 seviye derinliÄŸe azaltın (Kök Klasör içinde A içinde B içinde C ÅŸeklinde). + İç içe geçmiÅŸ klasörlerin derinliÄŸi üçü geçiyor + </string> + <string name="TooltipOutboxTooManyFolders"> + Üst seviyedeki klasördeki alt klasör sayısı 20'yi geçiyor </string> <string name="TooltipOutboxTooManyObjects"> - Bu klasörde 200'den fazla nesne var. Nesne sayısını azaltmak için öğelerden bazılarını kutuya koyun. + Üst seviyedeki klasördeki öğe sayısı 200'ü geçiyor + </string> + <string name="TooltipDragOntoOwnChild"> + Bir klasörü alt klasörüne taşıyamazsınız + </string> + <string name="TooltipDragOntoSelf"> + Bir klasörü kendi içine taşıyamazsınız </string> <string name="TooltipHttpUrl"> Bu web sayfasını görmek için tıklayın @@ -814,6 +832,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="anim_yes_head"> Evet </string> + <string name="multiple_textures"> + Birden Çok + </string> <string name="texture_loading"> Yükleniyor... </string> @@ -862,6 +883,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="ScriptQuestionCautionChatDenied"> '[OWNERNAME]' adlı kiÅŸiye ait, [REGIONPOS] üzerinde [REGIONNAME] içerisinde bulunan '[OBJECTNAME]' nesnesine ÅŸunu yapma izni verilmedi: [PERMISSIONS]. </string> + <string name="AdditionalPermissionsRequestHeader"> + EÄŸer hesabınıza eriÅŸime izin verirseniz, bu nesneye aynı zamanda ÅŸunun için izin vermiÅŸ olacaksınız: + </string> <string name="ScriptTakeMoney"> Sizden Linden dolar (L$) almak </string> @@ -895,6 +919,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="ControlYourCamera"> Kameranızı kontrol etmek </string> + <string name="TeleportYourAgent"> + Sizi ışınlama + </string> <string name="NotConnected"> BaÄŸlı DeÄŸil </string> @@ -973,6 +1000,12 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="choose_the_directory"> Dizin Seç </string> + <string name="script_files"> + Komut Dosyaları + </string> + <string name="dictionary_files"> + Sözlükler + </string> <string name="AvatarSetNotAway"> Uzakta DeÄŸil </string> @@ -1211,43 +1244,36 @@ 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. + Pazaryerinda satın aldıklarınız burada görünecektir. Bunları kullanmak için envanterinize sürükleyebilirsiniz. </string> <string name="MarketplaceURL"> - http://marketplace.[DOMAIN_NAME] + https://marketplace.[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 + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4 </string> - <string name="InventoryOutboxCreationErrorTitle"> - Satıcı Giden Kutunuz düzgün yapılandırılmamıştır + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard </string> - <string name="InventoryOutboxCreationErrorTooltip"> - Satıcı Giden Kutusu yapılandırma hatası + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports </string> - <string name="InventoryOutboxCreationError"> - Sorunu düzeltmek için lütfen Müşteri Hizmetlerine baÅŸvurun. + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more </string> <string name="InventoryOutboxNotMerchantTitle"> - Pazaryerinde herkes öğe satabilir - </string> - <string name="InventoryOutboxNotMerchantTooltip"> - Bir satıcı olun! + Pazaryerinde herkes öğe satabilir. </string> + <string name="InventoryOutboxNotMerchantTooltip"/> <string name="InventoryOutboxNotMerchant"> - [[MARKETPLACE_URL] Second Life Pazaryeri] içerisinde bir milyondan fazla sanal ürün satışa sunulmuÅŸtur, bunların tümü Sakinler tarafından oluÅŸturulmuÅŸtur. Siz de oluÅŸturduÄŸunuz öğeleri ve satın aldığınız öğelerin bazılarını satabilirsiniz. Bunu yapmak kolaydır, kurulum da ücretsizdir. [[LEARN_MORE_URL] Daha fazla bilgi edinin] veya baÅŸlamak için Pazaryerinde [[CREATE_STORE_URL] bir maÄŸaza açın]. + EÄŸer bir satıcı olmak istiyorsanız, [Pazaryerinde [MARKETPLACE_CREATE_STORE_URL] bir maÄŸaza açmanız gerekir]. </string> <string name="InventoryOutboxNoItemsTitle"> - Pazaryerine öğe göndermek için yeni bir yol - </string> - <string name="InventoryOutboxNoItemsTooltip"> - Öğeleri Pazaryerinde satışa hazırlamak için sürükleyip buraya bırakın + Giden kutunuz boÅŸ. </string> + <string name="InventoryOutboxNoItemsTooltip"/> <string name="InventoryOutboxNoItems"> - Satmak istediÄŸiniz öğeleri veya klasörleri bu alana sürükleyin. Öğenin bir kopyası burada görünür ve kopyalanamaz bir öğeyi sürüklemediyseniz, envanteriniz aynı kalır. Öğeleri Pazaryerine göndermeye hazır olduÄŸunuzda Karşıya Yükle düğmesine tıklayın. Öğeleriniz Pazaryeri Envanterinize taşındığında bu klasörden kaybolurlar. + Bu alana klasörleri sürükleyin ve bunları [[MARKETPLACE_DASHBOARD_URL] Pazaryerinde] satılık olarak duyurmak için "Pazaryerine Gönder" üzerine tıklayın. </string> <string name="Marketplace Error None"> Hata yok @@ -1385,6 +1411,12 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="InvFolder favorite"> Favorilerim </string> + <string name="InvFolder Favorites"> + Sık Kullanılanlarım + </string> + <string name="InvFolder favorites"> + Sık Kullanılanlarım + </string> <string name="InvFolder Current Outfit"> Mevcut Dış Görünüm </string> @@ -1400,6 +1432,12 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="InvFolder Meshes"> Örgüler </string> + <string name="InvFolder Received Items"> + Alınan Öğeler + </string> + <string name="InvFolder Merchant Outbox"> + Satıcı Giden Kutusu + </string> <string name="InvFolder Friends"> ArkadaÅŸlar </string> @@ -1409,6 +1447,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 +1576,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> @@ -3829,6 +3876,12 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne baÅŸvurun. <string name="LocationCtrlSeeAVsTooltip"> Bu parselin dışında avatarlar görünür durumda ve sohbete izin veriliyor </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Bölge yeniden kaydedilinceye kadar hareket eden nesneler bu bölgede doÄŸru davranmayabilir. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + Bu bölgede dinamik yol bulma etkin deÄŸil. + </string> <string name="UpdaterWindowTitle"> [APP_NAME] GüncelleÅŸtirme </string> @@ -3895,6 +3948,9 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne baÅŸvurun. <string name="Saved_message"> (Kaydedildi [LONG_TIMESTAMP]) </string> + <string name="IM_unblock_only_groups_friends"> + Bu mesajı görmek için Tercihler/Gizlilik'de 'Sadece arkadaÅŸlar ve gruplar beni arasın veya Aİ göndersin' seçeneÄŸinin iÅŸaretini kaldırmalısınız. + </string> <string name="answered_call"> Aramanız yanıtlandı </string> @@ -4027,6 +4083,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]'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]'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> @@ -4079,9 +4147,7 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne baÅŸvurun. Çevrimiçi </string> <string name="uploading_abuse_report"> - Karşıya Yükleniyor... - -Kötüye Kullanımı Bildirme + Kötüye Kullanım Bildirimi Karşıya Yükleniyor... </string> <string name="New Shape"> Yeni Åžekil @@ -4348,7 +4414,7 @@ Kötüye Kullanımı Bildirme <string name="server_is_down"> Tüm çabalarımıza raÄŸmen beklenmeyen bir hata meydana geldi. - Hizmetle iliÅŸkili bilinen bir sorun olup olmadığını görmek için lütfen status.secondlifegrid.net adresine bakın. + Hizmetle iliÅŸkili bilinen bir sorun olup olmadığını görmek için lütfen status.secondlifegrid.net adresine bakın. Sorun yaÅŸamaya devam ederseniz lütfen ağınızın ve güvenlik duvarınızın ayarlarına bakın. </string> <string name="dateTimeWeekdaysNames"> @@ -4437,6 +4503,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 +4891,10 @@ 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_Outbox_Label"> + Satıcı giden kutusu </string> <string name="Command_People_Label"> KiÅŸiler @@ -4846,10 +4921,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 @@ -4893,6 +4968,9 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin. <string name="Command_Move_Tooltip"> Avatarınızı hareket ettirmek </string> + <string name="Command_Outbox_Tooltip"> + Satmak amacıyla Pazaryerinize öğeler taşıyın + </string> <string name="Command_People_Tooltip"> ArkadaÅŸlar, gruplar ve yakındaki kiÅŸiler </string> @@ -4921,7 +4999,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 +5034,40 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin. <string name="Normal"> Normal </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Hiçbiri + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Navigasyon örgüsünü etkiler + </string> + <string name="Pathfinding_Object_Attr_Character"> + Karakter + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Birden çok) + </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> + <string name="TeleportMaturityExceeded"> + Sakin bu bölgeyi ziyaret edemez. + </string> + <string name="UserDictionary"> + [User] + </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..20d09b1ee2 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 'Welcome Island Public' to repeat the tutorial. + Karşılama Ada'sına geri ışınlanamazsınız. +Öğreticiyi tekrarlamak için 'Karşılama Ada'sı Kamusal Alanı'na gidin. </message> <message name="noaccess_tport"> Üzgünüz, bu ışınlanma hedef konumuna eriÅŸim hakkına sahip deÄŸilsiniz. @@ -45,6 +45,9 @@ Go to 'Welcome Island Public' to repeat the tutorial. <message name="no_inventory_host"> Envanter sistemi ÅŸu anda kullanılamıyor. </message> + <message name="MustGetAgeRegion"> + Bu bölgeye girebilmek için 18 veya üzeri bir yaÅŸta olmanız gerekir. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -80,5 +83,8 @@ Go to 'Welcome Island Public' to repeat the tutorial. <message name="requesting"> Işınlanma talep ediliyor... </message> + <message name="pending"> + Işınlama Bekliyor... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/zh/floater_aaa.xml b/indra/newview/skins/default/xui/zh/floater_aaa.xml index 0d110c0456..e2d6a2b004 100644 --- a/indra/newview/skins/default/xui/zh/floater_aaa.xml +++ b/indra/newview/skins/default/xui/zh/floater_aaa.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Test Floater" title="測試浮動視窗"> <string name="test_the_vlt"> - This string CHANGE2 is extracted. + å—串 CHANGE2 已抽å–。 </string> <string name="testing_eli"> é€™åªæ˜¯æ¸¬è©¦ - 變更。 diff --git a/indra/newview/skins/default/xui/zh/floater_about.xml b/indra/newview/skins/default/xui/zh/floater_about.xml index 7e19c124a1..643881e416 100644 --- a/indra/newview/skins/default/xui/zh/floater_about.xml +++ b/indra/newview/skins/default/xui/zh/floater_about.xml @@ -5,10 +5,10 @@ [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </floater.string> <floater.string name="AboutCompiler"> - Built with [COMPILER] version [COMPILER_VERSION] + 以 [COMPILER_VERSION] 版本 [COMPILER] 建置 </floater.string> <floater.string name="AboutPosition"> - You are at [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] located at <nolink>[HOSTNAME]</nolink> ([HOSTIP]) + ä½ çš„æ–¹ä½æ˜¯ [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1],地å€å:[REGION],主機:<nolink>[HOSTNAME]</nolink> ([HOSTIP]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </floater.string> @@ -20,10 +20,10 @@ 顯示å¡ï¼š[GRAPHICS_CARD] </floater.string> <floater.string name="AboutDriver"> - Windows Graphics Driver Version: [GRAPHICS_DRIVER_VERSION] + Windows 顯示驅動程å¼ç‰ˆæœ¬ï¼š[GRAPHICS_DRIVER_VERSION] </floater.string> <floater.string name="AboutLibs"> - OpenGL Version: [OPENGL_VERSION] + OpenGL 版本:[OPENGL_VERSION] libcurl 版本: [LIBCURL_VERSION] J2C 解碼器版本: [J2C_VERSION] @@ -37,47 +37,60 @@ Qt Webkit 版本: [QT_WEBKIT_VERSION] <floater.string name="AboutTraffic"> å°åŒ…æå¤±ï¼š[PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) </floater.string> + <floater.string name="ErrorFetchingServerReleaseNotesURL"> + æ“·å–伺æœå™¨ç‰ˆæœ¬èªªæ˜Ž URL 時出錯。 + </floater.string> <tab_container name="about_tab"> <panel label="資訊" name="support_panel"> <button label="覆製到剪貼簿" name="copy_btn"/> </panel> - <panel label="Credits" name="credits_panel"> - <text_editor name="credits_editor"> - Second Life is brought to you by ..., and many others. - -Thank you to the following Residents for helping to ensure that this is the best version yet: ..., and many others. - - - - -"The work goes on, the cause endures, the hope still lives, and the dreams shall never die" - Edward Kennedy + <panel label="貸記" name="credits_panel"> + <text name="linden_intro"> + 「第二人生ã€ç”±ä»¥ä¸‹çš„ Linden å®¶æ—å¸¶çµ¦ä½ ï¼š + </text> + <text name="contrib_intro"> + 這些人士åšäº†é–‹æ”¾æºç¢¼çš„è²¢ç»ï¼š + </text> + <text_editor name="contrib_names"> + 執行時期被å–代的å‡å稱 + </text_editor> + <text name="trans_intro"> + 以下人士æä¾›ç¿»è¯ï¼š + </text> + <text_editor name="trans_names"> + 執行時期被å–代的å‡å稱 </text_editor> </panel> - <panel label="Licenses" name="licenses_panel"> + <panel label="許å¯" name="licenses_panel"> <text_editor name="credits_editor"> - 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion -APR Copyright (C) 2000-2004 The Apache Software Foundation -cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se) -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. -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. -Pth Copyright (C) 1999-2006 Ralf S. Engelschall <rse@gnu.org> -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-2009 3Dconnexion + APR Copyright (C) 2011 The Apache Software Foundation + Collada DOM Copyright 2006 Sony Computer Entertainment Inc. + cURL Copyright (C) 1996-2010, 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, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. + 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) 2002, Xiphophorus + OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. + PCRE Copyright (c) 1997-2012 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-2012 Jean-loup Gailly and Mark Adler. + + 第二人生 Viewer 採用 Havok (TM) 物ç†å¼•擎。 (c)Copyright 1999-2010 Havok.com Inc.(åŠå…¶æ”¾ç…§äººï¼‰ã€‚ ä¿ç•™ä¸€åˆ‡æ¬Šåˆ©ã€‚ 詳情見 www.havok.com。 + + æœ¬è»Ÿé«”å«æœ‰ NVIDIA Corporation æä¾›çš„æºç¨‹å¼ç¢¼ã€‚ -All rights reserved. See licenses.txt for details. + ä¿ç•™ä¸€åˆ‡æ¬Šåˆ©ã€‚ 詳情見 licenses.txt。 -語音èŠå¤©éŸ³é »ç·¨ç¢¼ï¼šPolycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex 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/zh/floater_about_land.xml b/indra/newview/skins/default/xui/zh/floater_about_land.xml index 2568d492f0..76db621951 100644 --- a/indra/newview/skins/default/xui/zh/floater_about_land.xml +++ b/indra/newview/skins/default/xui/zh/floater_about_land.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floaterland" title="關於土地"> +<floater name="floaterland" title="土地資料"> <floater.string name="maturity_icon_general"> "Parcel_PG_Dark" </floater.string> @@ -10,39 +10,39 @@ "Parcel_R_Dark" </floater.string> <floater.string name="Minutes"> - [MINUTES] minutes + [MINUTES] åˆ†é˜ </floater.string> <floater.string name="Minute"> - minute + åˆ†é˜ </floater.string> <floater.string name="Seconds"> - [SECONDS] seconds + [SECONDS] ç§’ </floater.string> <floater.string name="Remaining"> - remaining + 剩餘時間 </floater.string> <tab_container name="landtab"> <panel label="一般" name="land_general_panel"> <panel.string name="new users only"> - New Residents only + åƒ…é™æ–°å±…æ°‘ </panel.string> <panel.string name="anyone"> - Anyone + 任何人 </panel.string> <panel.string name="area_text"> å€åŸŸ </panel.string> <panel.string name="area_size_text"> - [AREA] m² + [AREA] 平方公尺 </panel.string> <panel.string name="auction_id_text"> - Auction ID: [ID] + æ‹è³£ ID:[ID] </panel.string> <panel.string name="need_tier_to_modify"> - You must approve your purchase to modify this land. + ä½ å¿…é ˆæ‰¹å‡†è³¼è²·æ‰èƒ½ä¿®æ”¹é€™å¡ŠåœŸåœ°ã€‚ </panel.string> <panel.string name="group_owned_text"> - ï¼ˆç¾¤çµ„æ‰€æ“æœ‰ï¼‰ + ï¼ˆç”±ç¾¤çµ„æ‰€æ“æœ‰ï¼‰ </panel.string> <panel.string name="profile_text"> 檔案 @@ -57,10 +57,10 @@ (無) </panel.string> <panel.string name="sale_pending_text"> - (Sale Pending) + (擱置銷售) </panel.string> <panel.string name="no_selection_text"> - No parcel selected. + æœªé¸æ“‡åœ°æ®µã€‚ </panel.string> <panel.string name="time_stamp_template"> [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] @@ -75,7 +75,7 @@ 類型: </text> <text name="LandTypeText"> - Mainland / Homestead + 大陸 / 家園 </text> <text name="ContentRating"> 分級: @@ -84,37 +84,37 @@ 完全æˆäºº </text> <text name="Owner:"> - æ“æœ‰è€…: + 所有人: </text> <text name="Group:"> 群組: </text> <button label="è¨å®š" name="Set..."/> - <check_box label="å…許讓渡給群組" name="check deed" tool_tip="A group officer can deed this land to the group, so it will be supported by the group's land allocation."/> - <button label="讓渡" name="Deed..." tool_tip="You may only deed land if you are an officer in the selected group."/> - <check_box label="Owner Makes Contribution With Deed" name="check contrib" tool_tip="When the land is deeded to the group, the former owner contributes enough land allocation to support it."/> + <check_box label="å…許讓渡給群組" name="check deed" tool_tip="群組工作人員å¯å°‡é€™åœŸåœ°è®“渡給群組,使其得到群組土地é…置的支æ´ã€‚"/> + <button label="讓渡" name="Deed..." tool_tip="ä½ å¿…é ˆæ˜¯æ‰€é¸ç¾¤çµ„的工作人員æ‰èƒ½è®“渡土地。"/> + <check_box label="所有人é€éŽè®“渡動作進行æç»" name="check contrib" tool_tip="將土地讓渡給群組,表示上一個所有人會æç»è¶³å¤ 土地來支æŒè®“渡。"/> <text name="For Sale:"> - 出售: + 出售ä¸ï¼š </text> <text name="Not for sale."> ä¸å‡ºå”® </text> <text name="For Sale: Price L$[PRICE]."> - Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²) + åƒ¹æ ¼ï¼šL$[PRICE] (L$[PRICE_PER_SQM]/平方公尺) </text> <button label="出售土地" name="Sell Land..."/> <text name="For sale to"> 出售給:[BUYER] </text> <text name="Sell with landowners objects in parcel."> - Objects included in sale + 物件連帶一起出售 </text> <text name="Selling with no objects in parcel."> - Objects not included in sale + æ¤æ¬¡å‡ºå”®ä¸å«ç‰©ä»¶ </text> - <button label="Cancel Land Sale" label_selected="Cancel Land Sale" name="Cancel Land Sale"/> + <button label="å–æ¶ˆåœŸåœ°å‡ºå”®" label_selected="å–æ¶ˆåœŸåœ°å‡ºå”®" name="Cancel Land Sale"/> <text name="Claimed:"> - Claimed: + 已收å–: </text> <text name="DateClaimText"> Tue Aug 15 13:47:25 2006 @@ -123,52 +123,52 @@ é¢ç©ï¼š </text> <text name="PriceText"> - 4048 m² + 4048 平方公尺 </text> <text name="Traffic:"> æµé‡ï¼š </text> <text name="DwellText"> - 0 + 載入ä¸... </text> <button label="購買土地" name="Buy Land..."/> + <button label="Linden 出售" name="Linden Sale..." tool_tip="åœŸåœ°å¿…é ˆæœ‰äººæ“æœ‰ã€å·²è¨æœ‰å…§å®¹ï¼Œä¸¦ä¸”ä¸åœ¨æ‹è³£ä¸ã€‚"/> <button label="腳本資訊" name="Scripts..."/> <button label="為群組購買" name="Buy For Group..."/> <button label="購買通行權" name="Buy Pass..." tool_tip="通行權å…è¨±ä½ æš«æ™‚å¯å‡ºå…¥é€™å¡ŠåœŸåœ°ã€‚"/> <button label="放棄土地" name="Abandon Land..."/> - <button label="Reclaim Land" name="Reclaim Land..."/> - <button label="Linden Sale" name="Linden Sale..." tool_tip="Land must be owned, set content, and not already for auction."/> + <button label="收回土地" name="Reclaim Land..."/> </panel> <panel label="契約" name="land_covenant_panel"> <panel.string name="can_resell"> - Purchased land in this region may be resold. + 購買這地å€çš„土地å…許轉售。 </panel.string> <panel.string name="can_not_resell"> - Purchased land in this region may not be resold. + 購買這地å€çš„土地ä¸å…許轉售。 </panel.string> <panel.string name="can_change"> - Purchased land in this region may be joined or subdivided. + 購買這地å€çš„土地å…許進行åˆä½µæˆ–分割。 </panel.string> <panel.string name="can_not_change"> - Purchased land in this region may not be joined or subdivided. + 購買這地å€çš„土地ä¸å…許進行åˆä½µæˆ–分割。 </panel.string> <text name="estate_section_lbl"> é ˜åœ°ï¼š </text> <text name="estate_name_text"> - mainland + 大陸 </text> <text name="estate_owner_lbl"> - æ“æœ‰è€…: + 所有人: </text> <text name="estate_owner_text"> (無) </text> <text_editor name="covenant_editor"> - There is no Covenant provided for this Estate. + æ¤é ˜åœ°æ²’æœ‰ä»»ä½•å¥‘ç´„è¦æ±‚。 </text_editor> <text name="covenant_timestamp_text"> - Last Modified Wed Dec 31 16:00:00 1969 + 上次修改於 Wed Dec 31 16:00:00 1969 </text> <text name="region_section_lbl"> 地å€ï¼š @@ -180,7 +180,7 @@ 類型: </text> <text name="region_landtype_text"> - Mainland / Homestead + 大陸 / 家園 </text> <text name="region_maturity_lbl"> 分級: @@ -189,54 +189,54 @@ 完全æˆäºº </text> <text name="resellable_lbl"> - Resale: + 轉售: </text> <text name="resellable_clause"> - Land in this region may not be resold. + 這地å€çš„土地ä¸èƒ½è½‰å”®ã€‚ </text> <text name="changeable_lbl"> - Subdivide: + 分割: </text> <text name="changeable_clause"> - Land in this region may not be joined/subdivided. + 這地å€çš„土地ä¸èƒ½åˆä½µæˆ–分割。 </text> </panel> <panel label="物件" name="land_objects_panel"> <panel.string name="objects_available_text"> - [COUNT] out of [MAX] ([AVAILABLE] available) + 使用 [MAX] ä¸çš„ [COUNT] (剩餘 [AVAILABLE] å¯ç”¨ï¼‰ </panel.string> <panel.string name="objects_deleted_text"> - [COUNT] out of [MAX] ([DELETED] will be deleted) + ç›®å‰ [COUNT],最多å…許 [MAX] ([DELETED] 將被刪除) </panel.string> <text name="parcel_object_bonus"> - Region Object Bonus Factor: [BONUS] + 地å€ç‰©ä»¶è² è·å€æ•¸ï¼š[BONUS] </text> <text name="Simulator primitive usage:"> - 幾何元件使用: + 地å€å®¹ç´é‡ï¼š </text> <text name="objects_available"> 使用 [MAX] ä¸çš„ [COUNT] (剩餘 [AVAILABLE] å¯ç”¨ï¼‰ </text> <text name="Primitives parcel supports:"> - 地段所æä¾›çš„幾何元件數: + 地段土地容ç´é‡ï¼š </text> <text name="object_contrib_text"> [COUNT] </text> <text name="Primitives on parcel:"> - 地段上的幾何元件數: + åœ°æ®µåœŸåœ°è¡æ“Šé‡ï¼š </text> <text name="total_objects_text"> [COUNT] </text> <text name="Owned by parcel owner:"> - åœ°æ®µæ“æœ‰è€…æ‰€æ“æœ‰ï¼š + åœ°æ®µæ‰€æœ‰äººæ‰€æ“æœ‰ï¼š </text> <text name="owner_objects_text"> [COUNT] </text> <button label="顯示" label_selected="顯示" name="ShowOwner"/> - <button label="退回" name="ReturnOwner..." tool_tip="é€€å›žç‰©ä»¶çµ¦å®ƒå€‘çš„æ“æœ‰è€…。"/> + <button label="退回" name="ReturnOwner..." tool_tip="退回物件給它們的所有人。"/> <text name="Set to group:"> è¨å®šç¾¤çµ„: </text> @@ -244,7 +244,7 @@ [COUNT] </text> <button label="顯示" label_selected="顯示" name="ShowGroup"/> - <button label="退回" name="ReturnGroup..." tool_tip="é€€å›žç‰©ä»¶çµ¦å®ƒå€‘çš„æ“æœ‰è€…。"/> + <button label="退回" name="ReturnGroup..." tool_tip="退回物件給它們的所有人。"/> <text name="Owned by others:"> å…¶ä»–äººæ‰€æ“æœ‰ï¼š </text> @@ -252,26 +252,26 @@ [COUNT] </text> <button label="顯示" label_selected="顯示" name="ShowOther"/> - <button label="退回" name="ReturnOther..." tool_tip="é€€å›žç‰©ä»¶çµ¦å®ƒå€‘çš„æ“æœ‰è€…。"/> + <button label="退回" name="ReturnOther..." tool_tip="退回物件給它們的所有人。"/> <text name="Selected / sat upon:"> - Selected / sat upon: + å·²é¸ / å在上é¢ï¼š </text> <text name="selected_objects_text"> [COUNT] </text> <text name="Autoreturn"> - Auto return other Residents' objects (minutes, 0 for off): + 自動é€è¿”其他居民的物件(分é˜ï¼Œè¨ç‚º 0 å¯å–消自動): </text> <text name="Object Owners:"> - ç‰©ä»¶æ“æœ‰è€…: + 物件所有人: </text> <button name="Refresh List" tool_tip="刷新物件清單"/> <button label="退回物件" name="Return objects..."/> <name_list name="owner list"> - <name_list.columns label="Type" name="type"/> + <name_list.columns label="類型" name="type"/> <name_list.columns label="å稱" name="name"/> - <name_list.columns label="Count" name="count"/> - <name_list.columns label="Most Recent" name="mostrecent"/> + <name_list.columns label="計數" name="count"/> + <name_list.columns label="最近" name="mostrecent"/> </name_list> </panel> <panel label="é¸é …" name="land_options_panel"> @@ -279,8 +279,8 @@ 讓其他人å¯ä»¥åœ¨æœå°‹çµæžœä¸çœ‹åˆ°é€™å¡Šåœ°æ®µ </panel.string> <panel.string name="search_disabled_small_tooltip"> - This option is disabled because this parcel's area is 128 m² or smaller. -Only large parcels can be listed in search. + 這個é¸é …å·²åœç”¨ï¼Œå› 為這個地段é¢ç©å°æ–¼ 128 平方公尺。 +大é¢ç©åœ°æ®µæ‰å¯åˆ—å…¥æœå°‹çµæžœã€‚ </panel.string> <panel.string name="search_disabled_permissions_tooltip"> 這個é¸é …å·²é—œé–‰å› ç‚ºä½ ä¸èƒ½ä¿®æ”¹é€™å€‹åœ°æ®µçš„é¸é …。 @@ -292,10 +292,10 @@ Only large parcels can be listed in search. 完全æˆäººå…§å®¹ </panel.string> <panel.string name="mature_check_mature_tooltip"> - Your parcel information or content is considered moderate. + ä½ çš„åœ°æ®µè³‡è¨Šæˆ–å…§å®¹è¢«è¦–ç‚ºé©åº¦æˆäººåˆ†ç´šã€‚ </panel.string> <panel.string name="mature_check_adult_tooltip"> - Your parcel information or content is considered adult. + ä½ çš„åœ°æ®µè³‡è¨Šæˆ–å…§å®¹è¢«è¦–ç‚ºå®Œå…¨æˆäººåˆ†ç´šã€‚ </panel.string> <panel.string name="landing_point_none"> (無) @@ -309,8 +309,10 @@ Only large parcels can be listed in search. <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> @@ -326,67 +328,68 @@ Only large parcels can be listed in search. </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="安全(無傷害)" name="check safe" tool_tip="若勾é¸ï¼Œå°‡æŠŠåœŸåœ°è¨ç‚ºå®‰å…¨ï¼Œç¦çµ•傷害性的戰鬥。 若未勾é¸ï¼Œå‰‡å…許傷害性的戰鬥。"/> + <check_box label="ç¦æ¢æŽ¨æ’ž" name="PushRestrictCheck" tool_tip="ç¦æ¢ä½¿ç”¨è…³æœ¬æŽ¨æ’žã€‚ 勾é¸é€™é¸é …坿œ‰æ•ˆé˜²æ¢ä½ åœŸåœ°ä¸Šå‡ºç¾æ»‹äº‹è¡Œç‚ºã€‚"/> <check_box label="將地點刊登顯示在æœå°‹ä¸ï¼ˆL$30 / æ¯é€±ï¼‰" name="ShowDirectoryCheck" tool_tip="讓其他人å¯ä»¥åœ¨æœå°‹çµæžœä¸çœ‹åˆ°é€™å¡Šåœ°æ®µ"/> <combo_box name="land category with adult"> <combo_box.item label="任何類別" name="item0"/> - <combo_box.item label="Linden Location" name="item1"/> + <combo_box.item label="æž—ç™»ä½ç½®" name="item1"/> <combo_box.item label="完全æˆäºº" name="item2"/> <combo_box.item label="è—術與文化" name="item3"/> <combo_box.item label="商æ¥" name="item4"/> <combo_box.item label="教育" name="item5"/> <combo_box.item label="éŠæˆ²" name="item6"/> <combo_box.item label="èšæœƒæ‰€" name="item7"/> - <combo_box.item label="新手å‹å–„" name="item8"/> - <combo_box.item label="公園與自然" name="item9"/> + <combo_box.item label="æ¡è¿Žæ–°æ‰‹å…‰è‡¨" name="item8"/> + <combo_box.item label="公園與自然景觀" name="item9"/> <combo_box.item label="ä½å®…" name="item10"/> - <combo_box.item label="採購" name="item11"/> - <combo_box.item label="Rental" name="item13"/> - <combo_box.item label="Other" name="item12"/> + <combo_box.item label="購物" name="item11"/> + <combo_box.item label="出租" name="item13"/> + <combo_box.item label="å…¶ä»–" name="item12"/> </combo_box> <combo_box name="land category"> <combo_box.item label="任何類別" name="item0"/> - <combo_box.item label="Linden Location" name="item1"/> + <combo_box.item label="æž—ç™»ä½ç½®" name="item1"/> <combo_box.item label="è—術與文化" name="item3"/> <combo_box.item label="商æ¥" name="item4"/> <combo_box.item label="教育" name="item5"/> <combo_box.item label="éŠæˆ²" name="item6"/> <combo_box.item label="èšæœƒæ‰€" name="item7"/> - <combo_box.item label="新手å‹å–„" name="item8"/> - <combo_box.item label="公園與自然" name="item9"/> + <combo_box.item label="æ¡è¿Žæ–°æ‰‹å…‰è‡¨" name="item8"/> + <combo_box.item label="公園與自然景觀" name="item9"/> <combo_box.item label="ä½å®…" name="item10"/> - <combo_box.item label="採購" name="item11"/> - <combo_box.item label="Rental" name="item13"/> - <combo_box.item label="Other" name="item12"/> + <combo_box.item label="購物" name="item11"/> + <combo_box.item label="出租" name="item13"/> + <combo_box.item label="å…¶ä»–" name="item12"/> </combo_box> <check_box label="é©åº¦æˆäººå…§å®¹" name="MatureCheck" tool_tip=" "/> <text name="Snapshot:"> 快照: </text> - <texture_picker name="snapshot_ctrl" tool_tip="點擊以挑é¸åœ–åƒ"/> + <texture_picker name="snapshot_ctrl" tool_tip="點按以挑é¸åœ–片"/> + <text name="allow_label5"> + 其他地段的化身å¯ä»¥çœ‹è¦‹æœ¬åœ°æ®µè£¡çš„化身,並與之交談 + </text> + <check_box label="察看化身" name="SeeAvatarsCheck" tool_tip="å…è¨±å…¶ä»–åœ°æ®µçš„åŒ–èº«çœ‹åˆ°æœ¬åœ°æ®µåŒ…æ‹¬ä½ åœ¨å…§çš„åŒ–èº«ï¼Œä¸¦å¯äº’相交談。"/> <text name="landing_point"> 登陸點:[LANDING] </text> - <button label="è¨å®š" label_selected="è¨å®š" name="Set" tool_tip="Sets the landing point where visitors arrive. Sets to your avatar's location inside this parcel."/> + <button label="è¨å®š" label_selected="è¨å®š" name="Set" tool_tip="è¨å®šè¨ªå®¢ç™»é™¸åœ°é»žã€‚ è¨å®šä½ 的化身在æ¤åœ°æ®µå…§çš„ä½ç½®ã€‚"/> <button label="清除" label_selected="清除" name="Clear" tool_tip="清除登陸點"/> <text name="Teleport Routing: "> 瞬間傳é€è·¯å¾‘: </text> - <combo_box name="landing type" tool_tip="Teleport Routing -- select how to handle teleports onto your land"> - <combo_box.item label="Blocked" name="Blocked"/> - <combo_box.item label="Landing Point" name="LandingPoint"/> - <combo_box.item label="Anywhere" name="Anywhere"/> + <combo_box name="landing type" tool_tip="瞬間傳é€ç¹žè·¯ -- è¨å®šå¦‚何處ç†å‰å¾€ä½ 土地的瞬間傳é€"> + <combo_box.item label="å°éŽ–çš„" name="Blocked"/> + <combo_box.item label="登陸點" name="LandingPoint"/> + <combo_box.item label="任何地點" name="Anywhere"/> </combo_box> </panel> - <panel label="MEDIA" name="land_media_panel"> + <panel label="媒體" name="land_media_panel"> <text name="with media:"> 類型: </text> - <combo_box name="media type" tool_tip="Specify if the URL is a movie, web page, or other media"/> + <combo_box name="media type" tool_tip="指明這 URL 是影片ã€ç¶²é 還是其他媒體類型"/> <text name="at URL:"> 首é : </text> @@ -394,27 +397,27 @@ Only large parcels can be listed in search. <text name="Description:"> æè¿°ï¼š </text> - <line_editor name="url_description" tool_tip="Text displayed next to play/load button"/> + <line_editor name="url_description" tool_tip="æ’æ”¾ / 載入按鈕æ—顯示的文å—"/> <text name="Media texture:"> å–代æè³ªï¼š </text> - <texture_picker name="media texture" tool_tip="點擊以挑é¸åœ–åƒ"/> + <texture_picker name="media texture" tool_tip="點按以挑é¸åœ–片"/> <text name="replace_texture_help"> - Objects using this texture will show the movie or web page after you click the play arrow. Select the thumbnail to choose a different texture. + ä½¿ç”¨æ¤æè³ªçš„ç‰©ä»¶ï¼Œå°‡åœ¨ä½ é»žæŒ‰ã€Œæ’æ”¾ã€ç®é å¾Œæ’æ”¾å½±ç‰‡æˆ–顯示網é 。 é¸å–縮圖å³å¯é¸æ“‡ä¸åŒçš„æè³ªã€‚ </text> - <check_box label="自動縮放" name="media_auto_scale" tool_tip="Checking this option will scale the content for this parcel automatically. It may be slightly slower and lower quality visually but no other texture scaling or alignment will be required."/> - <text name="media_size" tool_tip="Size to render Web media, leave 0 for default."> + <check_box label="自動縮放" name="media_auto_scale" tool_tip="勾鏿¤é¸é …將會在æ¤åœ°æ®µè‡ªå‹•變更內容的比例。 速度å¯èƒ½ç¨æ…¢ï¼Œè¦–覺效果å¯èƒ½ç•¥éœï¼Œä½†ä¸éœ€è¦èª¿æ•´å…¶ä»–æè³ªçš„æ¯”ä¾‹æˆ–åŠ ä»¥å°é½Šã€‚"/> + <text name="media_size" tool_tip="ç¶²ä¸Šåª’é«”çš„é¡¯ç¤ºå°ºå¯¸ï¼Œè¨ 0 將採用é è¨å€¼ã€‚"> 尺寸: </text> - <spinner name="media_size_width" tool_tip="Size to render Web media, leave 0 for default."/> - <spinner name="media_size_height" tool_tip="Size to render Web media, leave 0 for default."/> + <spinner name="media_size_width" tool_tip="ç¶²ä¸Šåª’é«”çš„é¡¯ç¤ºå°ºå¯¸ï¼Œè¨ 0 將採用é è¨å€¼ã€‚"/> + <spinner name="media_size_height" tool_tip="ç¶²ä¸Šåª’é«”çš„é¡¯ç¤ºå°ºå¯¸ï¼Œè¨ 0 將採用é è¨å€¼ã€‚"/> <text name="pixels"> åƒç´ </text> <text name="Options:"> é¸é …: </text> - <check_box label="Loop" name="media_loop" tool_tip="Play media in a loop. When the media has finished playing, it will restart from the beginning."/> + <check_box label="連續" name="media_loop" tool_tip="é€£çºŒæ’æ”¾åª’體。 åª’é«”æ’æ”¾çµæŸå¾Œï¼Œæœƒå¾žé ç¹¼çºŒæ’æ”¾ã€‚"/> </panel> <panel label="è²éŸ³" name="land_audio_panel"> <text name="MusicURL:"> @@ -423,45 +426,45 @@ Only large parcels can be listed in search. <text name="Sound:"> è²éŸ³ï¼š </text> - <check_box label="Restrict gesture and object sounds to this parcel" name="check sound local"/> + <check_box label="將姿勢和物件的è²éŸ³é™åˆ¶æ–¼æ¤åœ°æ®µ" name="check sound local"/> + <text name="Avatar Sounds:"> + 化身è²éŸ³ï¼š + </text> + <check_box label="任何人" name="all av sound check"/> + <check_box label="群組" name="group av sound check"/> <text name="Voice settings:"> - Voice: + 語音: </text> - <check_box label="Enable Voice" name="parcel_enable_voice_channel"/> - <check_box label="Enable Voice (established by the Estate)" name="parcel_enable_voice_channel_is_estate_disabled"/> - <check_box label="Restrict Voice to this parcel" name="parcel_enable_voice_channel_local"/> + <check_box label="啟用語音" name="parcel_enable_voice_channel"/> + <check_box label="啟用è²éŸ³ï¼ˆç”±é ˜åœ°æ‰€ç¢ºç«‹ï¼‰" name="parcel_enable_voice_channel_is_estate_disabled"/> + <check_box label="å°‡è²éŸ³é™åˆ¶æ–¼æ¤åœ°æ®µ" name="parcel_enable_voice_channel_local"/> </panel> - <panel label="ACCESS" name="land_access_panel"> + <panel label="出入許å¯" name="land_access_panel"> <panel.string 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 name="Limit access to this parcel to:"> - 出入æ¤åœ°æ®µ - </text> + <check_box label="å…許公開出入(若未勾é¸ï¼Œå°‡è¨ç«‹ç¦è¶Šç·šï¼‰" name="public_access"/> <text name="Only Allow"> - Restrict Access to Residents verified by: + 僅å…許符åˆä»¥ä¸‹æ¢ä»¶çš„居民進入: </text> - <check_box label="Payment Information on File [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Ban unidentified Residents."/> - <check_box label="å¹´é½¡é©—è‰ [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Ban Residents who have not verified their age. See the [SUPPORT_SITE] for more information."/> + <check_box label="å·²é 留付款資料 [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="å±…æ°‘å¿…é ˆæä¾›ä»˜æ¬¾è³‡æ–™æ‰èƒ½é€²å…¥é€™åœ°æ®µã€‚ åƒé–± [SUPPORT_SITE] ç²å–進一æ¥è³‡è¨Šã€‚"/> + <check_box label="年滿 18 æ² [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="å±…æ°‘å¿…é ˆå¹´æ»¿ 18 æ²æ‰èƒ½é€²å…¥é€™åœ°æ®µã€‚ åƒé–± [SUPPORT_SITE] ç²å–進一æ¥è³‡è¨Šã€‚"/> <check_box label="å…許出入的群組:[GROUP]" name="GroupCheck" tool_tip="è¨å®šç¾¤çµ„於一般é 籤。"/> <check_box label="出售通行權給:" name="PassCheck" tool_tip="å…許暫時出入這個地段"/> <combo_box name="pass_combo"> - <combo_box.item label="Anyone" name="Anyone"/> + <combo_box.item label="任何人" name="Anyone"/> <combo_box.item label="群組" name="Group"/> </combo_box> - <spinner label="Price in L$:" name="PriceSpin"/> - <spinner label="Hours of access:" name="HoursSpin"/> + <spinner label="åƒ¹æ ¼ï¼ˆL$):" name="PriceSpin"/> + <spinner label="出入時間:" name="HoursSpin"/> <panel name="Allowed_layout_panel"> - <text label="Always Allow" name="AllowedText"> - Allowed Residents + <text label="æ°¸é å…許" name="AllowedText"> + å…許的居民 </text> - <name_list name="AccessList" tool_tip="([LISTED] listed, [MAX] max)"/> + <name_list name="AccessList" tool_tip="(已列入 [LISTED],最多å¯åˆ— [MAX])"/> <button label="æ·»åŠ " name="add_allowed"/> <button label="移除" label_selected="移除" name="remove_allowed"/> </panel> @@ -469,7 +472,7 @@ Only large parcels can be listed in search. <text label="ç¦æ¢" name="BanCheck"> 被å°éŽ–çš„å±…æ°‘ </text> - <name_list name="BannedList" tool_tip="([LISTED] listed, [MAX] max)"/> + <name_list name="BannedList" tool_tip="(已列入 [LISTED],最多å¯åˆ— [MAX])"/> <button label="æ·»åŠ " name="add_banned"/> <button label="移除" label_selected="移除" name="remove_banned"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/floater_activeim.xml b/indra/newview/skins/default/xui/zh/floater_activeim.xml index 93017bf5b2..b148ca8eb4 100644 --- a/indra/newview/skins/default/xui/zh/floater_activeim.xml +++ b/indra/newview/skins/default/xui/zh/floater_activeim.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_activeim" title="ACTIVE IM"/> +<floater name="floater_activeim" title="進行ä¸çš„ IM"/> diff --git a/indra/newview/skins/default/xui/zh/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/zh/floater_animation_anim_preview.xml new file mode 100644 index 0000000000..76cb9079c4 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_animation_anim_preview.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Anim Preview" title="ANIMATION.ANIM"> + <text name="name_label"> + å稱: + </text> + <text name="description_label"> + æè¿°ï¼š + </text> + <button label="上傳(L$[AMOUNT])" name="ok_btn"/> + <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml new file mode 100644 index 0000000000..ffb0de8a68 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml @@ -0,0 +1,186 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Animation Preview"> + <floater.string name="failed_to_initialize"> + 動作åˆå§‹åŒ–失敗 + </floater.string> + <floater.string name="anim_too_long"> + 動作檔長度為 [LENGTH] 秒。 + +動作檔長度最多å¯ç‚º [MAX_LENGTH] 秒。 + </floater.string> + <floater.string name="failed_file_read"> + 無法讀å–動作檔。 + +[STATUS] + </floater.string> + <floater.string name="E_ST_OK"> + 確定 + </floater.string> + <floater.string name="E_ST_EOF"> + 檔案çµå°¾ä¸æ£å¸¸ã€‚ + </floater.string> + <floater.string name="E_ST_NO_CONSTRAINT"> + 無法讀å–ç´„æŸå®šç¾©ã€‚ + </floater.string> + <floater.string name="E_ST_NO_FILE"> + 無法開啟 BVH 檔案。 + </floater.string> + <floater.string name="E_ST_NO_HIER"> + HIERARCHY 檔é 無效。 + </floater.string> + <floater.string name="E_ST_NO_JOINT"> + 找ä¸åˆ° ROOT 或 JOINT。 + </floater.string> + <floater.string name="E_ST_NO_NAME"> + 無法å–å¾— JOINT å稱。 + </floater.string> + <floater.string name="E_ST_NO_OFFSET"> + 無法尋找ä½ç§»ã€‚ + </floater.string> + <floater.string name="E_ST_NO_CHANNELS"> + 找ä¸åˆ°é »é“。 + </floater.string> + <floater.string name="E_ST_NO_ROTATION"> + 無法å–得旋轉åºã€‚ + </floater.string> + <floater.string name="E_ST_NO_AXIS"> + 無法å–得旋轉軸。 + </floater.string> + <floater.string name="E_ST_NO_MOTION"> + 找ä¸åˆ°å‹•作。 + </floater.string> + <floater.string name="E_ST_NO_FRAMES"> + 無法å–得幀數。 + </floater.string> + <floater.string name="E_ST_NO_FRAME_TIME"> + 無法å–得幀時間。 + </floater.string> + <floater.string name="E_ST_NO_POS"> + 無法å–å¾—ä½ç½®å€¼ã€‚ + </floater.string> + <floater.string name="E_ST_NO_ROT"> + 無法å–得旋轉值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_FILE"> + 無法開啟平移檔案。 + </floater.string> + <floater.string name="E_ST_NO_XLT_HEADER"> + 無法讀å–平移檔é 。 + </floater.string> + <floater.string name="E_ST_NO_XLT_NAME"> + 無法讀å–平移å稱。 + </floater.string> + <floater.string name="E_ST_NO_XLT_IGNORE"> + 無法讀å–平移忽略值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_RELATIVE"> + 無法讀å–平移相å°å€¼ã€‚ + </floater.string> + <floater.string name="E_ST_NO_XLT_OUTNAME"> + 無法讀å–平移輸出å稱。 + </floater.string> + <floater.string name="E_ST_NO_XLT_MATRIX"> + 無法讀å–平移矩陣。 + </floater.string> + <floater.string name="E_ST_NO_XLT_MERGECHILD"> + 無法å–å¾— mergechild å稱。 + </floater.string> + <floater.string name="E_ST_NO_XLT_MERGEPARENT"> + 無法å–å¾— mergeparent å稱。 + </floater.string> + <floater.string name="E_ST_NO_XLT_PRIORITY"> + 無法å–得優先值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_LOOP"> + 無法å–得迴圈值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_EASEIN"> + 無法å–å¾— easeIn 值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_EASEOUT"> + 無法å–å¾— easeOut 值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_HAND"> + 無法å–å¾— hand morph 值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_EMOTE"> + 無法讀å–表情符號å稱。 + </floater.string> + <floater.string name="E_ST_BAD_ROOT"> + root joint åç¨±ä¸æ£ç¢ºï¼Œä½¿ç”¨ "hip"。 + </floater.string> + <text name="name_label"> + å稱: + </text> + <text name="description_label"> + æè¿°ï¼š + </text> + <spinner label="優先度" name="priority" tool_tip="其他動作的控制å¯è¢«æ¤å‹•作強行å–代"/> + <check_box label="連續" name="loop_check" tool_tip="讓æ¤å‹•ä½œä¸æ–·é‡è¦†æ¼”ç¹¹"/> + <spinner label="å…¥(%)" name="loop_in_point" tool_tip="è¨å®šå‹•作ä¸é‡è¦†æ¼”繹的起始點"/> + <spinner label="出(%)" name="loop_out_point" tool_tip="è¨å®šå‹•作ä¸é‡è¦†æ¼”ç¹¹çš„çµæŸé»ž"/> + <text name="hand_label"> + 手部姿勢 + </text> + <combo_box name="hand_pose_combo" tool_tip="控制動作演繹時雙手的姿勢"> + <combo_box.item label="張開" name="Spread"/> + <combo_box.item label="放鬆" name="Relaxed"/> + <combo_box.item label="雙手伸出指é " name="PointBoth"/> + <combo_box.item label="拳é " name="Fist"/> + <combo_box.item label="左邊放鬆" name="RelaxedLeft"/> + <combo_box.item label="左邊伸指" name="PointLeft"/> + <combo_box.item label="å·¦é‚Šæ¡æ‹³" name="FistLeft"/> + <combo_box.item label="å³é‚Šæ”¾é¬†" name="RelaxedRight"/> + <combo_box.item label="å³é‚Šä¼¸æŒ‡" name="PointRight"/> + <combo_box.item label="å³é‚Šæ¡æ‹³" name="FistRight"/> + <combo_box.item label="峿‰‹æ•¬ç¦®" name="SaluteRight"/> + <combo_box.item label="打å—" name="Typing"/> + <combo_box.item label="峿‰‹æ¯”出和平手勢" name="PeaceRight"/> + </combo_box> + <text name="emote_label"> + 表情 + </text> + <combo_box name="emote_combo" tool_tip="控制動作演繹時臉部的姿態"> + <item label="(無)" name="[None]" value=""/> + <item label="å¼µå£å¶å–Šè²Œ" name="Aaaaah" value="å¼µå£å¶å–Šè²Œ"/> + <item label="害怕" name="Afraid" value="害怕"/> + <item label="生氣" name="Angry" value="生氣"/> + <item label="燦爛笑容" name="BigSmile" value="燦爛笑容"/> + <item label="ç„¡èŠ" name="Bored" value="ç„¡èŠ"/> + <item label="哿³£" name="Cry" value="哿³£"/> + <item label="鄙視" name="Disdain" value="鄙視"/> + <item label="å°·å°¬" name="Embarrassed" value="å°·å°¬"/> + <item label="皺眉" name="Frown" value="皺眉"/> + <item label="親å»" name="Kiss" value="親å»"/> + <item label="笑" name="Laugh" value="笑"/> + <item label="嫌惡貌" name="Plllppt" value="嫌惡貌"/> + <item label="作å™" name="Repulsed" value="作å™"/> + <item label="傷心" name="Sad" value="傷心"/> + <item label="è³è³è‚©" name="Shrug" value="è³è³è‚©"/> + <item label="微笑" name="Smile" value="微笑"/> + <item label="驚喜" name="Surprise" value="驚喜"/> + <item label="眨眼" name="Wink" value="眨眼"/> + <item label="擔心" name="Worry" value="擔心"/> + </combo_box> + <text name="preview_label"> + é 覽… + </text> + <combo_box name="preview_base_anim" tool_tip="ç”¨é€™å€‹ä¾†æ¸¬è©¦ä½ çš„åŒ–èº«å¾žä¸€èˆ¬å‹•ä½œè½‰å…¥å‹•ä½œæ¼”ç¹¹æ™‚çš„æƒ…æ³ã€‚"> + <item label="站立" name="Standing" value="站立"/> + <item label="æ¥è¡Œä¸" name="Walking" value="æ¥è¡Œä¸"/> + <item label="åè‘—" name="Sitting" value="åè‘—"/> + <item label="飛行" name="Flying" value="飛行"/> + </combo_box> + <spinner label="淡入(秒)" name="ease_in_time" tool_tip="動作攙混æ¤å…¥çš„æ™‚間長度(秒)"/> + <spinner label="淡出(秒)" name="ease_out_time" tool_tip="動作攙混淡出的時間長度(秒)"/> + <button name="play_btn" tool_tip="æ’æ”¾ä½ 的動作"/> + <button name="pause_btn" tool_tip="æš«åœä½ 的動åš"/> + <button name="stop_btn" tool_tip="åœæ¢æ’放動作"/> + <text name="bad_animation_text"> + 無法讀å–動作檔。 + +æˆ‘å€‘å»ºè°æŽ¡ç”¨ç”± Poser 4 匯出的 BVH æª”æ¡ˆæ ¼å¼ã€‚ + </text> + <button label="上傳(L$[AMOUNT])" name="ok_btn"/> + <button label="å–æ¶ˆ" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_animation_preview.xml b/indra/newview/skins/default/xui/zh/floater_animation_preview.xml deleted file mode 100644 index c5e2eac446..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_animation_preview.xml +++ /dev/null @@ -1,186 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview"> - <floater.string name="failed_to_initialize"> - Failed to initialize motion - </floater.string> - <floater.string name="anim_too_long"> - Animation file is [LENGTH] seconds in length. - -Maximum animation length is [MAX_LENGTH] seconds. - </floater.string> - <floater.string name="failed_file_read"> - 無法讀å–動作檔。 - -[STATUS] - </floater.string> - <floater.string name="E_ST_OK"> - 確定 - </floater.string> - <floater.string name="E_ST_EOF"> - Premature end of file. - </floater.string> - <floater.string name="E_ST_NO_CONSTRAINT"> - Cannot read constraint definition. - </floater.string> - <floater.string name="E_ST_NO_FILE"> - 無法開啟 BVH 檔案。 - </floater.string> - <floater.string name="E_ST_NO_HIER"> - Invalid HIERARCHY header. - </floater.string> - <floater.string name="E_ST_NO_JOINT"> - Cannot find ROOT or JOINT. - </floater.string> - <floater.string name="E_ST_NO_NAME"> - Cannot get JOINT name. - </floater.string> - <floater.string name="E_ST_NO_OFFSET"> - 無法尋找ä½ç§»ã€‚ - </floater.string> - <floater.string name="E_ST_NO_CHANNELS"> - Cannot find CHANNELS. - </floater.string> - <floater.string name="E_ST_NO_ROTATION"> - Cannot get rotation order. - </floater.string> - <floater.string name="E_ST_NO_AXIS"> - Cannot get rotation axis. - </floater.string> - <floater.string name="E_ST_NO_MOTION"> - Cannot find MOTION. - </floater.string> - <floater.string name="E_ST_NO_FRAMES"> - Cannot get number of frames. - </floater.string> - <floater.string name="E_ST_NO_FRAME_TIME"> - Cannot get frame time. - </floater.string> - <floater.string name="E_ST_NO_POS"> - Cannot get position values. - </floater.string> - <floater.string name="E_ST_NO_ROT"> - Cannot get rotation values. - </floater.string> - <floater.string name="E_ST_NO_XLT_FILE"> - Cannot open translation file. - </floater.string> - <floater.string name="E_ST_NO_XLT_HEADER"> - Cannot read translation header. - </floater.string> - <floater.string name="E_ST_NO_XLT_NAME"> - Cannot read translation names. - </floater.string> - <floater.string name="E_ST_NO_XLT_IGNORE"> - Cannot read translation ignore value. - </floater.string> - <floater.string name="E_ST_NO_XLT_RELATIVE"> - Cannot read translation relative value. - </floater.string> - <floater.string name="E_ST_NO_XLT_OUTNAME"> - Cannot read translation outname value. - </floater.string> - <floater.string name="E_ST_NO_XLT_MATRIX"> - Cannot read translation matrix. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGECHILD"> - Cannot get mergechild name. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGEPARENT"> - Cannot get mergeparent name. - </floater.string> - <floater.string name="E_ST_NO_XLT_PRIORITY"> - Cannot get priority value. - </floater.string> - <floater.string name="E_ST_NO_XLT_LOOP"> - Cannot get loop value. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEIN"> - Cannot get easeIn values. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEOUT"> - Cannot get easeOut values. - </floater.string> - <floater.string name="E_ST_NO_XLT_HAND"> - Cannot get hand morph value. - </floater.string> - <floater.string name="E_ST_NO_XLT_EMOTE"> - Cannot read emote name. - </floater.string> - <floater.string name="E_ST_BAD_ROOT"> - Incorrect root joint name, use "hip". - </floater.string> - <text name="name_label"> - å稱: - </text> - <text name="description_label"> - æè¿°ï¼š - </text> - <spinner label="優先度" name="priority" tool_tip="Controls which other animations can be overridden by this animation"/> - <check_box label="Loop" name="loop_check" tool_tip="Makes this animation loop"/> - <spinner label="In(%)" name="loop_in_point" tool_tip="Sets point in animation that looping returns to"/> - <spinner label="Out(%)" name="loop_out_point" tool_tip="Sets point in animation that ends a loop"/> - <text name="hand_label"> - Hand Pose - </text> - <combo_box name="hand_pose_combo" tool_tip="Controls what hands do during animation"> - <combo_box.item label="Spread" name="Spread"/> - <combo_box.item label="Relaxed" name="Relaxed"/> - <combo_box.item label="Point Both" name="PointBoth"/> - <combo_box.item label="Fist" name="Fist"/> - <combo_box.item label="Relaxed Left" name="RelaxedLeft"/> - <combo_box.item label="Point Left" name="PointLeft"/> - <combo_box.item label="Fist Left" name="FistLeft"/> - <combo_box.item label="Relaxed Right" name="RelaxedRight"/> - <combo_box.item label="Point Right" name="PointRight"/> - <combo_box.item label="Fist Right" name="FistRight"/> - <combo_box.item label="Salute Right" name="SaluteRight"/> - <combo_box.item label="Typing" name="Typing"/> - <combo_box.item label="Peace Right" name="PeaceRight"/> - </combo_box> - <text name="emote_label"> - Expression - </text> - <combo_box name="emote_combo" tool_tip="Controls what face does during animation"> - <item label="(無)" name="[None]" value=""/> - <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> - <item label="Afraid" name="Afraid" value="Afraid"/> - <item label="Angry" name="Angry" value="Angry"/> - <item label="Big Smile" name="BigSmile" value="Big Smile"/> - <item label="Bored" name="Bored" value="Bored"/> - <item label="Cry" name="Cry" value="Cry"/> - <item label="Disdain" name="Disdain" value="Disdain"/> - <item label="Embarrassed" name="Embarrassed" value="Embarrassed"/> - <item label="Frown" name="Frown" value="Frown"/> - <item label="Kiss" name="Kiss" value="Kiss"/> - <item label="Laugh" name="Laugh" value="Laugh"/> - <item label="Plllppt" name="Plllppt" value="Plllppt"/> - <item label="Repulsed" name="Repulsed" value="Repulsed"/> - <item label="Sad" name="Sad" value="Sad"/> - <item label="Shrug" name="Shrug" value="Shrug"/> - <item label="Smile" name="Smile" value="Smile"/> - <item label="Surprise" name="Surprise" value="Surprise"/> - <item label="Wink" name="Wink" value="Wink"/> - <item label="Worry" name="Worry" value="Worry"/> - </combo_box> - <text name="preview_label"> - Preview while - </text> - <combo_box name="preview_base_anim" tool_tip="Use this to test your animation behavior while your avatar performs common actions."> - <item label="Standing" name="Standing" value="Standing"/> - <item label="Walking" name="Walking" value="Walking"/> - <item label="Sitting" name="Sitting" value="Sitting"/> - <item label="飛行" name="Flying" value="飛行"/> - </combo_box> - <spinner label="淡入(秒)" name="ease_in_time" tool_tip="Amount of time (in seconds) over which animations blends in"/> - <spinner label="淡出(秒)" name="ease_out_time" tool_tip="Amount of time (in seconds) over which animations blends out"/> - <button name="play_btn" tool_tip="æ’æ”¾ä½ 的動作"/> - <button name="pause_btn" tool_tip="æš«åœä½ 的動åš"/> - <button name="stop_btn" tool_tip="Stop animation playback"/> - <text name="bad_animation_text"> - Unable to read animation file. - -We recommend BVH files exported from Poser 4. - </text> - <button label="上傳(L$[AMOUNT])" name="ok_btn"/> - <button label="å–æ¶ˆ" name="cancel_btn"/> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_auction.xml b/indra/newview/skins/default/xui/zh/floater_auction.xml index b1862bc582..1b589a92cc 100644 --- a/indra/newview/skins/default/xui/zh/floater_auction.xml +++ b/indra/newview/skins/default/xui/zh/floater_auction.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_auction" title="START LINDEN LAND SALE"> +<floater name="floater_auction" title="é–‹å§‹ Linden 土地出售"> <floater.string name="already for sale"> - You cannot auction parcels which are already for sale. + 出售ä¸çš„地段無法進行æ‹è³£ã€‚ </floater.string> - <check_box initial_value="true" label="Include yellow selection fence" name="fence_check"/> - <button label="Snapshot" label_selected="Snapshot" name="snapshot_btn"/> - <button label="Sell to Anyone" label_selected="Sell to Anyone" name="sell_to_anyone_btn"/> + <check_box initial_value="true" label="包括黃色åœç·š" name="fence_check"/> + <button label="å¿«ç…§" label_selected="å¿«ç…§" name="snapshot_btn"/> + <button label="出售給任何人" label_selected="出售給任何人" name="sell_to_anyone_btn"/> <button label="清除è¨å®š" label_selected="清除è¨å®š" name="reset_parcel_btn"/> - <button label="Start Auction" label_selected="Start Auction" name="start_auction_btn"/> + <button label="é–‹å§‹æ‹è³£" label_selected="é–‹å§‹æ‹è³£" name="start_auction_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_autoreplace.xml b/indra/newview/skins/default/xui/zh/floater_autoreplace.xml new file mode 100644 index 0000000000..4ee07e6295 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="自動å–代è¨å®š"> + <check_box label="啟用自動å–代" name="autoreplace_enable" tool_tip="在輸入èŠå¤©å…§å®¹çš„åŒæ™‚,將輸入的關éµå—代æ›ç‚ºç›¸æ‡‰çš„å–代文å—。"/> + <button label="匯入清單…" name="autoreplace_import_list" tool_tip="從檔案載入先å‰åŒ¯å‡ºéŽçš„æ¸…單。"/> + <button label="匯出清單…" name="autoreplace_export_list" tool_tip="å°‡æ‰€é¸æ¸…單儲å˜åˆ°æª”案以便和他人分享。"/> + <button label="新的清單…" name="autoreplace_new_list" tool_tip="新建一個清單。"/> + <button label="刪除清單" name="autoreplace_delete_list" tool_tip="åˆªé™¤æ‰€é¸æ¸…單。"/> + <button name="autoreplace_list_up" tool_tip="æé«˜æ¤æ¸…單的優先次åºã€‚"/> + <button name="autoreplace_list_down" tool_tip="é™ä½Žæ¤æ¸…單的優先次åºã€‚"/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="é—œéµå—" name="keyword"/> + <scroll_list.columns label="å–代文å—" name="replacement"/> + </scroll_list> + <button label="æ·»åŠ ..." name="autoreplace_add_entry"/> + <button label="移除" name="autoreplace_delete_entry"/> + <button label="儲å˜é …ç›®" name="autoreplace_save_entry" tool_tip="å„²å˜æ¤é …目。"/> + <button label="儲å˜è®Šæ›´" name="autoreplace_save_changes" tool_tip="å„²å˜æ‰€æœ‰è®Šæ›´ã€‚"/> + <button label="å–æ¶ˆ" name="autoreplace_cancel" tool_tip="放棄所有變更。"/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </text> +--> diff --git a/indra/newview/skins/default/xui/zh/floater_avatar.xml b/indra/newview/skins/default/xui/zh/floater_avatar.xml new file mode 100644 index 0000000000..55b1a95a41 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_avatar.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Avatar" title="鏿“‡ä¸€å€‹åŒ–身"/> diff --git a/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml b/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml index 7e2d74c728..c19369c859 100644 --- a/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml +++ b/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="avatarpicker" title="挑é¸å±…æ°‘"> <floater.string name="not_found"> - '[TEXT]' not found + 查無「[TEXT]〠</floater.string> <floater.string name="no_one_near"> - No one near + 附近無人 </floater.string> <floater.string name="no_results"> - No results + æ²’æœ‰çµæžœ </floater.string> <floater.string name="searching"> æœå°‹ä¸... @@ -21,9 +21,9 @@ <tab_container name="ResidentChooserTabs"> <panel label="æœå°‹" name="SearchPanel"> <text name="InstructSearchResidentName"> - Type part of a person's name: + éµå…¥äººå的一部分: </text> - <button label="Go" label_selected="Go" name="Find"/> + <button label="å‰å¾€" label_selected="å‰å¾€" name="Find"/> <scroll_list name="SearchResults"> <columns label="å稱" name="name"/> <columns label="使用者å稱" name="username"/> diff --git a/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml b/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml index 36dae7c798..69309c96de 100644 --- a/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml @@ -1,19 +1,19 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="avatar_texture_debug" title="化身æè³ª"> <floater.string name="InvalidAvatar"> - INVALID AVATAR + 無效的化身 </floater.string> <scroll_container name="profile_scroll"> <panel name="scroll_content_panel"> <text name="label"> - Baked -Textures + 確定產出的 +æè³ª </text> <text name="composite_label"> - Composite -Textures + åˆæˆ +æè³ª </text> - <button label="Dump IDs to Console" label_selected="Dump" name="Dump"/> + <button label="å‚¾å° ID 到控制臺" label_selected="傾å°" name="Dump"/> <panel name="scroll_content_panel"> <texture_picker label="é é«®" name="hair-baked"/> <texture_picker label="é é«®" name="hair_grain"/> @@ -25,7 +25,7 @@ Textures <texture_picker label="眼ç›" name="eyes-baked"/> <texture_picker label="眼ç›" name="eyes_iris"/> <texture_picker label="眼ç›åŠé€æ˜Ž" name="eyes_alpha"/> - <texture_picker label="上åŠèº«åŠé€æ˜Ž" name="upper-baked"/> + <texture_picker label="上åŠèº«" name="upper-baked"/> <texture_picker label="上åŠèº«èº«é«”部ä½" name="upper_bodypaint"/> <texture_picker label="å…§è¡£" name="upper_undershirt"/> <texture_picker label="手套" name="upper_gloves"/> diff --git a/indra/newview/skins/default/xui/zh/floater_beacons.xml b/indra/newview/skins/default/xui/zh/floater_beacons.xml index 1613b23e75..83e10804d6 100644 --- a/indra/newview/skins/default/xui/zh/floater_beacons.xml +++ b/indra/newview/skins/default/xui/zh/floater_beacons.xml @@ -1,22 +1,22 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="beacons" title="BEACONS"> +<floater name="beacons" title="指標"> <panel name="beacons_panel"> <text name="label_show"> - Show : + 顯示: </text> - <check_box label="Beacons" name="beacons"/> - <check_box label="Highlights" name="highlights"/> - <text name="beacon_width_label" tool_tip="Beacon width"> - Width: + <check_box label="指標" name="beacons"/> + <check_box label="高亮顯示" name="highlights"/> + <text name="beacon_width_label" tool_tip="指標寬度"> + 寬: </text> <text name="label_objects"> - For these objects: + å°è±¡ç‰©ä»¶ï¼š </text> - <check_box label="Physical" name="physical"/> - <check_box label="Scripted" name="scripted"/> - <check_box label="Touch only" name="touch_only"/> - <check_box label="Sound sources" name="sounds"/> - <check_box label="Particle sources" name="particles"/> - <check_box label="Media sources" name="moapbeacon"/> + <check_box label="ç‰©ç†æ€§" name="physical"/> + <check_box label="有腳本" name="scripted"/> + <check_box label="僅å¯è§¸ç¢°" name="touch_only"/> + <check_box label="è²éŸ³ä¾†æº" name="sounds"/> + <check_box label="例å來æº" name="particles"/> + <check_box label="媒體來æº" name="moapbeacon"/> </panel> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_build_options.xml b/indra/newview/skins/default/xui/zh/floater_build_options.xml index b9d3b6b849..29f36b461c 100644 --- a/indra/newview/skins/default/xui/zh/floater_build_options.xml +++ b/indra/newview/skins/default/xui/zh/floater_build_options.xml @@ -1,9 +1,32 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="build options floater" title="æ ¼ç·šé¸é …"> - <spinner label="æ ¼ç·šå–®ä½ï¼ˆå…¬å°ºï¼‰" name="GridResolution"/> - <spinner label="Grid Extents (meters)" name="GridDrawSize"/> + <floater.string name="grid_screen_text"> + 螢幕 + </floater.string> + <floater.string name="grid_local_text"> + 本地 + </floater.string> + <floater.string name="grid_world_text"> + 世界 + </floater.string> + <floater.string name="grid_reference_text"> + åƒè€ƒ + </floater.string> + <floater.string name="grid_attachment_text"> + 附件 + </floater.string> + <text name="grid_mode_label" tool_tip="æ ¼ç·šä¸é€æ˜Žåº¦"> + æ¨¡å¼ + </text> + <combo_box name="combobox grid mode" tool_tip="鏿“‡ç‰©ä»¶å®šä½åƒè€ƒçš„æ ¼ç·šå°ºåº¦é¡žåž‹"> + <combo_box.item label="ä¸–ç•Œæ ¼ç·š" name="World"/> + <combo_box.item label="åœ°æ–¹æ ¼ç·š" name="Local"/> + <combo_box.item label="åƒè€ƒæ ¼ç·š" name="Reference"/> + </combo_box> + <spinner label="å–®ä½ï¼ˆå…¬å°ºï¼‰" name="GridResolution"/> + <spinner label="範åœï¼ˆå…¬å°ºï¼‰" name="GridDrawSize"/> <check_box label="貼齊至åå–®ä½" name="GridSubUnit"/> - <check_box label="View cross-sections" name="GridCrossSection"/> + <check_box label="檢視橫剖é¢" name="GridCrossSection"/> <text name="grid_opacity_label" tool_tip="æ ¼ç·šä¸é€æ˜Žåº¦"> ä¸é€æ˜Žåº¦ï¼š </text> diff --git a/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml b/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml index 660710fb7b..59751a3a46 100644 --- a/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml +++ b/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml @@ -33,13 +33,13 @@ <text name="AnyoneLabel"> 任何人: </text> - <check_box label="覆製" name="everyone_copy"/> + <check_box label="æšåº¨" name="everyone_copy"/> <text name="NextOwnerLabel"> - ä¸‹ä¸€å€‹æ“æœ‰è€…: + 下一個所有人: </text> <check_box label="修改" name="next_owner_modify"/> - <check_box label="覆製" name="next_owner_copy"/> - <check_box initial_value="true" label="轉移" name="next_owner_transfer" tool_tip="ä¸‹ä¸€å€‹æ“æœ‰è€…能é€å‡ºæˆ–轉售這個物件"/> + <check_box label="æšåº¨" name="next_owner_copy"/> + <check_box initial_value="true" label="轉移" name="next_owner_transfer" tool_tip="下一個所有人å¯è´ˆé€æˆ–轉售這個物件"/> <button label="確定" name="apply"/> <button label="å–æ¶ˆ" name="close"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_contents.xml b/indra/newview/skins/default/xui/zh/floater_buy_contents.xml index 44d3394a52..5e4153de66 100644 --- a/indra/newview/skins/default/xui/zh/floater_buy_contents.xml +++ b/indra/newview/skins/default/xui/zh/floater_buy_contents.xml @@ -1,19 +1,19 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_buy_contents" title="BUY CONTENTS"> +<floater name="floater_buy_contents" title="購買內容"> <floater.string name="no_copy_text"> - (no copy) + ï¼ˆç¦æ¢è¤‡è£½ï¼‰ </floater.string> <floater.string name="no_modify_text"> - (no modify) + ï¼ˆç¦æ¢ä¿®æ”¹ï¼‰ </floater.string> <floater.string name="no_transfer_text"> - (no transfer) + ï¼ˆç¦æ¢è½‰è®“) </floater.string> <text name="contains_text"> - [NAME] contains: + <nolink>[NAME]</nolink> å…§å«ï¼š </text> <text name="buy_text"> - Buy for L$[AMOUNT] from [NAME]? + 是å¦èб L$[AMOUNT] å‘ [NAME] 購買? </text> <check_box label="ç«‹å³ç©¿ä¸Šæœè£" name="wear_check"/> <button label="購買" label_selected="購買" name="buy_btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_currency.xml b/indra/newview/skins/default/xui/zh/floater_buy_currency.xml index 9f6591faf9..fcf2800728 100644 --- a/indra/newview/skins/default/xui/zh/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/zh/floater_buy_currency.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="buy currency" title="購買 L$"> <floater.string name="buy_currency"> - Buy L$ [LINDENS] for approx. [LOCALAMOUNT] + 購買 L$ [LINDENS],所需花費約為 [LOCALAMOUNT] </floater.string> <text name="info_need_more"> - ä½ éœ€è¦æ›´å¤š L$ + ä½ çš„ L$ ä¸è¶³ </text> <text name="contacting"> è¯æŽ¥åˆ° LindeX ä¸... @@ -31,10 +31,10 @@ 以æ¤åƒ¹æ ¼ </text> <text name="currency_est"> - approx. [LOCALAMOUNT] + ç´„åˆ [LOCALAMOUNT] </text> <text name="getting_data"> - Estimating... + ä¼°ç®—ä¸â€¦ </text> <text name="buy_action"> [ACTION] @@ -46,16 +46,16 @@ 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 付費方å¼] | [http://www.secondlife.com/my/account/currency.php 幣種] </text> <text name="exchange_rate_note"> - Re-enter amount to see the latest exchange rate. + 釿–°è¼¸å…¥é‡‘é¡å³å¯å¯Ÿçœ‹æœ€æ–°çš„匯率。 </text> <text name="purchase_warning_repurchase"> - Confirming this purchase only buys L$, not the object. + 確èªé€™æ¬¡è³¼è²·åªæ˜¯æ·»è³¼ L$,並éžè³¼è²·ç‰©ä»¶ã€‚ </text> <text name="purchase_warning_notenough"> - ä½ ä¸¦æœªè³¼è²·è¶³å¤ çš„æž—ç™»å¹£ï¼Œè«‹å…ˆæ·»åŠ ä¸€äº›æ•¸é‡ã€‚ + ä½ è³¼è²·çš„æž—ç™»å¹£ä¸è¶³ï¼Œ è«‹å¢žåŠ æ•¸é¡ã€‚ </text> <button label="ç«‹å³è³¼è²·" name="buy_btn"/> <button label="å–æ¶ˆ" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_land.xml b/indra/newview/skins/default/xui/zh/floater_buy_land.xml index 336d14747d..51bbd6a561 100644 --- a/indra/newview/skins/default/xui/zh/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/zh/floater_buy_land.xml @@ -1,29 +1,29 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="buy land" title="購買土地"> <floater.string name="can_resell"> - May be resold. + 得以å†å‡ºå”®ã€‚ </floater.string> <floater.string name="can_not_resell"> - May not be resold. + ä¸å¾—å†å‡ºå”®ã€‚ </floater.string> <floater.string name="can_change"> - May be joined or subdivided. + 得以åˆä½µæˆ–分割。 </floater.string> <floater.string name="can_not_change"> - May not be joined or subdivided. + ä¸å¾—åˆä½µæˆ–分割。 </floater.string> <floater.string name="cant_buy_for_group"> - You do not have permission to buy land for your active group. + ä½ æ²’æœ‰æ¬Šé™ç‚ºä½ ç•¶å‰çš„群組購買土地。 </floater.string> <floater.string name="no_land_selected"> ç„¡åœŸåœ°è¢«é¸æ“‡ã€‚ </floater.string> <floater.string name="multiple_parcels_selected"> - Multiple different parcels selected. -Try selecting a smaller area. + é¸å–了多個ä¸åŒåœ°æ®µã€‚ +請嘗試é¸å–較å°å€åŸŸã€‚ </floater.string> <floater.string name="no_permission"> - You do not have permission to buy land for your active group. + ä½ æ²’æœ‰æ¬Šé™ç‚ºä½ ç•¶å‰çš„群組購買土地。 </floater.string> <floater.string name="parcel_not_for_sale"> æ‰€é¸æ“‡çš„地段ä¸å‡ºå”®ã€‚. @@ -35,37 +35,37 @@ Try selecting a smaller area. ä½ å·²ç¶“æ“æœ‰é€™å€‹åœ°æ®µã€‚ </floater.string> <floater.string name="set_to_sell_to_other"> - The selected parcel is set to sell to another party. + 所é¸åœ°æ®µå·²è¨ç‚ºå¾…售給他人。 </floater.string> <floater.string name="no_public_land"> - The selected area has no public land. + 所é¸å€åŸŸå…§ç„¡å…¬å…±åœŸåœ°ã€‚ </floater.string> <floater.string name="not_owned_by_you"> - Land owned by another Resident is selected. -Try selecting a smaller area. + é¸å–了å¦ä¸€ä½å±…æ°‘æ‰€æ“æœ‰åœŸåœ°ã€‚ +請嘗試é¸å–較å°å€åŸŸã€‚ </floater.string> <floater.string name="processing"> - Processing your purchase... + æ£åœ¨è™•ç†ä½ 的購買… -(éŽç¨‹é€™å°‡æœƒèŠ±è²»ä¸€åˆ°å…©åˆ†é˜ï¼‰ +(這éŽç¨‹å°‡æœƒèŠ±è²»ä¸€åˆ°å…©åˆ†é˜ã€‚) </floater.string> <floater.string name="fetching_error"> - There has been an error while fetching land buying information. + æ“·å–è³¼åœ°è¨Šæ¯æ™‚發生錯誤。 </floater.string> <floater.string name="buying_will"> - Buying this land will: + 購買這塊土地後: </floater.string> <floater.string name="buying_for_group"> - Buying land for group will: + 為群組購買土地後: </floater.string> <floater.string name="cannot_buy_now"> - Cannot buy now: + ç¾åœ¨ç„¡æ³•購買: </floater.string> <floater.string name="not_for_sale"> ä¸å‡ºå”®ï¼š </floater.string> <floater.string name="none_needed"> - none needed + ä¸éœ€è¦ </floater.string> <floater.string name="must_upgrade"> ä½ çš„å¸³æˆ¶å¿…é ˆè¦å‡ç´šæ‰èƒ½æ“有土地。 @@ -77,52 +77,52 @@ Try selecting a smaller area. ä½ æŒæœ‰ [BUYER] m² 土地。 </floater.string> <floater.string name="pay_to_for_land"> - Pay L$ [AMOUNT] to [SELLER] for this land + 支付 L$ [AMOUNT] 給 [SELLER] 購買這土地 </floater.string> <floater.string name="buy_for_US"> - Buy L$ [AMOUNT] for approx. [LOCAL_AMOUNT], + 購買 L$ [AMOUNT],所需花費約為 [LOCAL_AMOUNT], </floater.string> <floater.string name="parcel_meters"> - 這個地段為 [AMOUNT] m² + 這個地段有 [AMOUNT] 平方公尺 </floater.string> <floater.string name="premium_land"> - This land is premium, and will charge as [AMOUNT] m². + 這土地屬於高價地段,將計為 [AMOUNT] 平方公尺。 </floater.string> <floater.string name="discounted_land"> - This land is discounted, and will charge as [AMOUNT] m². + 這土地有折扣,將計為 [AMOUNT] 平方公尺。 </floater.string> <floater.string name="meters_supports_object"> - [AMOUNT] m² -supports [AMOUNT2] objects + [AMOUNT] 平方公尺 +æ”¯æ´ [AMOUNT2] é …ç‰©ä»¶ </floater.string> <floater.string name="sold_with_objects"> - sold with objects + å«ç‰©ä»¶å‡ºå”® </floater.string> <floater.string name="sold_without_objects"> - objects not included + ä¸å«ç‰©ä»¶ </floater.string> <floater.string name="info_price_string"> - L$ [PRICE] -(L$ [PRICE_PER_SQM]/m²) + L$[PRICE] +(L$ [PRICE_PER_SQM]/平方公尺) [SOLD_WITH_OBJECTS] </floater.string> <floater.string name="insufficient_land_credits"> - The group [GROUP] will need sufficient contributed land use credits to cover this parcel before the purchase will complete. + 群組 [GROUP] éœ€å…ˆæœ‰è¶³å¤ çš„æåœ°ä½¿ç”¨é¡åº¦ä¾†æ”¯æ‡‰é€™å€‹åœ°æ®µï¼Œæ‰å¯å®Œæˆè³¼è²·ã€‚ </floater.string> <floater.string name="have_enough_lindens"> - You have L$ [AMOUNT], which is enough to buy this land. + ä½ æœ‰ L$ [AMOUNT],足以購買這土地。 </floater.string> <floater.string name="not_enough_lindens"> - You have only L$ [AMOUNT], and need L$ [AMOUNT2] more. + ä½ åªæœ‰ L$ [AMOUNT],尚缺 L$ [AMOUNT2]。 </floater.string> <floater.string name="balance_left"> - After the purchase, you will have L$ [AMOUNT] left. + è³¼è²·å¾Œï¼Œä½ å°‡å‰©é¤˜ L$ [AMOUNT]。 </floater.string> <floater.string name="balance_needed"> - You need to buy at least L$ [AMOUNT] to afford this land. + ä½ è‡³å°‘å¿…é ˆè³¼è²· L$ [AMOUNT] æ‰èƒ½æ·»è³¼é€™åœŸåœ°ã€‚ </floater.string> <floater.string name="no_parcel_selected"> - ï¼ˆç„¡åœ°æ®µè¢«é¸æ“‡ï¼‰ + ï¼ˆæœªé¸æ“‡åœ°æ®µï¼‰ </floater.string> <text name="region_name_label"> 地å€ï¼š @@ -143,27 +143,27 @@ supports [AMOUNT2] objects (未知) </text> <text name="estate_owner_label"> - é ˜åœ°æ“æœ‰è€…: + é ˜åœ°æ‰€æœ‰äººï¼š </text> <text name="estate_owner_text"> (未知) </text> <text name="resellable_changeable_label"> - Purchased land in this region: + 在本地å€å·²è³¼åœŸåœ°ï¼š </text> <text name="resellable_clause"> - May or may not be resold. + 是å¦å¯å†å”®å‡ºã€‚ </text> <text name="changeable_clause"> - May or may not be joined or subdivided. + 是å¦å¯åˆä½µæˆ–分割。 </text> <text name="covenant_text"> - You must agree to the Estate Covenant: + ä½ å¿…é ˆåŒæ„é ˜åœ°å¥‘ç´„ï¼š </text> <text_editor name="covenant_editor"> 載入ä¸... </text_editor> - <check_box label="I Agree to the Covenant Defined Above." name="agree_covenant"/> + <check_box label="æˆ‘åŒæ„以上所訂契約。" name="agree_covenant"/> <text name="info_parcel_label"> 地段: </text> @@ -174,60 +174,60 @@ supports [AMOUNT2] objects 尺寸: </text> <text name="info_size"> - 1024 m² + 1024 平方公尺 </text> <text name="info_price_label"> åƒ¹æ ¼ï¼š </text> <text name="info_price"> L$ 1500 -(L$ 1.1/m²) -sold with objects +(L$ 1.1/平方公尺) +å«ç‰©ä»¶å‡ºå”® </text> <text name="info_action"> - Buying this land will: + 購買這塊土地後: </text> <text name="error_message"> - Something ain't right. + ææ€•出å•題了。 </text> <button label="å‰å¾€ç¶²ç«™" name="error_web"/> <text name="account_action"> - Upgrade you to premium membership. + å°‡ä½ å‡ç´šç‚ºä»˜è²»ç”¨æˆ¶ </text> <text name="account_reason"> - Only premimum members may own land. + åªæœ‰ä»˜è²»ç”¨æˆ¶æ‰èƒ½æ“有土地。 </text> <combo_box name="account_level"> - <combo_box.item label="US$9.95/month, billed monthly" name="US$9.95/month,billedmonthly"/> - <combo_box.item label="US$7.50/month, billed quarterly" name="US$7.50/month,billedquarterly"/> - <combo_box.item label="US$6.00/month, billed annually" name="US$6.00/month,billedannually"/> + <combo_box.item label="æ¯æœˆ US$9.95,按月支付" name="US$9.95/month,billedmonthly"/> + <combo_box.item label="æ¯æœˆ US$7.50ï¼ŒæŒ‰å£æ”¯ä»˜" name="US$7.50/month,billedquarterly"/> + <combo_box.item label="æ¯æœˆ US$6.00,一年支付一次" name="US$6.00/month,billedannually"/> </combo_box> <text name="land_use_action"> - Increase your monthly land use fees to US$ 40/month. + å°‡ä½ çš„æ¯æœˆåœŸåœ°ä½¿ç”¨è²»å¢žåŠ ç‚ºæ¯æœˆ US$ 40。 </text> <text name="land_use_reason"> - You hold 1309 m² of land. -This parcel is 512 m² of land. + ä½ æŒæœ‰ 1309 平方公尺土地。 +這地段有 512 平方公尺的土地。 </text> <text name="purchase_action"> - Pay Joe Resident L$ 4000 for the land + 支付給居民 Joe L$ 4000 購買土地 </text> <text name="currency_reason"> - You have L$ 2,100. + ä½ æœ‰ L$ 2,100。 </text> <text name="currency_action"> - Buy additional L$ + 購買更多 L$ </text> <line_editor name="currency_amt"> 1000 </line_editor> <text name="currency_est"> - for approx. [LOCAL_AMOUNT] + 花費大約 [LOCAL_AMOUNT] </text> <text name="currency_balance"> - You have L$ 2,100. + ä½ æœ‰ L$ 2,100。 </text> - <check_box label="Remove [AMOUNT] m² of contribution from group." name="remove_contribution"/> - <button label="Purchase" name="buy_btn"/> + <check_box label="從群組移除 [AMOUNT] 平方公尺的æå‡ºåœ°ã€‚" name="remove_contribution"/> + <button label="購買" name="buy_btn"/> <button label="å–æ¶ˆ" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_object.xml b/indra/newview/skins/default/xui/zh/floater_buy_object.xml index 507e482766..ff4a1feedb 100644 --- a/indra/newview/skins/default/xui/zh/floater_buy_object.xml +++ b/indra/newview/skins/default/xui/zh/floater_buy_object.xml @@ -4,25 +4,25 @@ 購買 </floater.string> <floater.string name="title_buy_copy_text"> - Buy a copy of + 購買一個 </floater.string> <floater.string name="no_copy_text"> - (no copy) + ï¼ˆç¦æ¢è¤‡è£½ï¼‰ </floater.string> <floater.string name="no_modify_text"> - (no modify) + ï¼ˆç¦æ¢ä¿®æ”¹ï¼‰ </floater.string> <floater.string name="no_transfer_text"> - (no transfer) + ï¼ˆç¦æ¢è½‰è®“) </floater.string> <text name="contents_text"> - Contains: + å…§å«ï¼š </text> <text name="buy_text"> - Buy for L$[AMOUNT] from: + 購買,支付 L$[AMOUNT] 給: </text> <text name="buy_name_text"> - [NAME]? + [NAME]? </text> <button label="購買" label_selected="購買" name="buy_btn"/> <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_camera.xml b/indra/newview/skins/default/xui/zh/floater_camera.xml index f4db20684c..becb7b9546 100644 --- a/indra/newview/skins/default/xui/zh/floater_camera.xml +++ b/indra/newview/skins/default/xui/zh/floater_camera.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="camera_floater"> +<floater name="camera_floater" title="æ”影機控制"> <floater.string name="rotate_tooltip"> - Rotate Camera Around Focus + 繞著焦點轉動æ”影機 </floater.string> <floater.string name="zoom_tooltip"> - Zoom Camera Towards Focus + æ”影機移近焦點 </floater.string> <floater.string name="move_tooltip"> - Move Camera Up and Down, Left and Right + æ”影機上下左å³ç§»å‹• </floater.string> <floater.string name="camera_modes_title"> æ”å½±æ©Ÿæ¨¡å¼ @@ -52,14 +52,14 @@ </panel_camera_item> </panel> <panel name="zoom"> - <joystick_rotate name="cam_rotate_stick" tool_tip="Orbit camera around focus"/> - <slider_bar name="zoom_slider" tool_tip="Zoom camera toward focus"/> + <joystick_rotate name="cam_rotate_stick" tool_tip="æ”影機繞焦點旋轉"/> + <slider_bar name="zoom_slider" tool_tip="æ”影機移近焦點"/> <joystick_track name="cam_track_stick" tool_tip="移動æ”影機上下左å³"/> </panel> </panel> <panel name="buttons"> <button label="" name="presets_btn" tool_tip="é è¨è¦–è§’"/> - <button label="" name="pan_btn" tool_tip="Orbit Zoom Pan"/> + <button label="" name="pan_btn" tool_tip="環繞縮放平移"/> <button label="" name="avatarview_btn" tool_tip="æ”影機模å¼"/> </panel> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_chat_bar.xml b/indra/newview/skins/default/xui/zh/floater_chat_bar.xml new file mode 100644 index 0000000000..f1a69a7688 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_chat_bar.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="chat_bar" title="附近的èŠå¤©"> + <panel name="bottom_panel"> + <line_editor label="點按æ¤è™•é–‹å§‹èŠå¤©ã€‚" name="chat_box" tool_tip="按下 Enter éµä¾†èªªæˆ–按下 Ctrl+Enter 來喊å«"/> + <button name="show_nearby_chat" tool_tip="顯示 / éš±è— é™„è¿‘çš„èŠå¤©ç´€éŒ„"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_color_picker.xml b/indra/newview/skins/default/xui/zh/floater_color_picker.xml index a7ac78e419..fa7b795d4f 100644 --- a/indra/newview/skins/default/xui/zh/floater_color_picker.xml +++ b/indra/newview/skins/default/xui/zh/floater_color_picker.xml @@ -10,13 +10,13 @@ è—色: </text> <text name="h_val_text"> - Hue: + 色調: </text> <text name="s_val_text"> - Sat: + 飽和度: </text> <text name="l_val_text"> - Lum: + 亮度: </text> <check_box label="ç«‹å³å¥—用" name="apply_immediate"/> <button label="確定" label_selected="確定" name="select_btn"/> @@ -25,6 +25,6 @@ ç›®å‰é¡è‰²ï¼š </text> <text name="(Drag below to save.)"> - (Drag below to save) + (拖曳到下方å³å¯å„²å˜ï¼‰ </text> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml new file mode 100644 index 0000000000..4aafb31952 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<floater name="Delete Env Preset" title="刪除環境自訂é…ç½®"> + <string name="title_water"> + 刪除水的自訂é…ç½® + </string> + <string name="title_sky"> + 刪除天空自訂é…ç½® + </string> + <string name="title_day_cycle"> + 刪除日循環 + </string> + <string name="label_water"> + 自訂é…置: + </string> + <string name="label_sky"> + 自訂é…置: + </string> + <string name="label_day_cycle"> + 日循環: + </string> + <string name="msg_confirm_deletion"> + 確定è¦åˆªé™¤æ‰€é¸è‡ªè¨‚é…置? + </string> + <string name="msg_sky_is_referenced"> + 無法刪除日循環有所指涉的自訂é…置。 + </string> + <string name="combo_label"> + -鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®- + </string> + <text name="label"> + 自訂é…置: + </text> + <button label="刪除" name="delete"/> + <button label="å–æ¶ˆ" name="cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_destinations.xml b/indra/newview/skins/default/xui/zh/floater_destinations.xml new file mode 100644 index 0000000000..f50a6a631a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_destinations.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Destinations" title="目的地"/> diff --git a/indra/newview/skins/default/xui/zh/floater_display_name.xml b/indra/newview/skins/default/xui/zh/floater_display_name.xml index 01b5088794..aa71bba769 100644 --- a/indra/newview/skins/default/xui/zh/floater_display_name.xml +++ b/indra/newview/skins/default/xui/zh/floater_display_name.xml @@ -1,18 +1,18 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Display Name" title="變更顯示å稱"> <text name="info_text"> - The name you give your avatar is called your Display Name. You can change it once a week. + ä½ ç‚ºä½ çš„åŒ–èº«å–çš„åå—å«åšã€Œé¡¯ç¤ºå稱ã€ã€‚ 一星期å¯ä»¥ä¿®æ”¹ä¸€æ¬¡ã€‚ </text> <text name="lockout_text"> - You cannot change your Display Name until: [TIME]. + ä½ ä¸‹æ¬¡èƒ½å†æ›´æ”¹é¡¯ç¤ºå稱的時間為 [TIME]。 </text> <text name="set_name_label"> 新顯示å稱: </text> <text name="name_confirm_label"> - Type your new name again to confirm: + 冿¬¡è¼¸å…¥ä½ 的新å稱以便確èªï¼š </text> - <button label="儲å˜" name="save_btn" tool_tip="儲å˜ä½ 的新顯示å稱"/> - <button label="é‡è¨" name="reset_btn" tool_tip="Make Display Name the same as Username"/> + <button label="儲å˜" name="save_btn" tool_tip="儲å˜ä½ 的新的顯示å稱"/> + <button label="é‡è¨" name="reset_btn" tool_tip="將顯示åç¨±è¨æˆå’Œä½¿ç”¨è€…å稱相åŒ"/> <button label="å–æ¶ˆ" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/zh/floater_edit_day_cycle.xml new file mode 100644 index 0000000000..b84a4027ea --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_edit_day_cycle.xml @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Edit Day cycle" title="編輯日循環"> + <string name="title_new"> + 新建一個日循環 + </string> + <string name="title_edit"> + 編輯日循環 + </string> + <string name="hint_new"> + 為日循環定å,調整å„é …æŽ§åˆ¶ç¢ºå®šç´°ç¯€ï¼Œå†é»žæŒ‰ã€Œå„²å˜ã€ã€‚ + </string> + <string name="hint_edit"> + è‹¥è¦ç·¨è¼¯ä½ 的日循環,請調整下方å„é …æŽ§åˆ¶ï¼Œå†é»žæŒ‰ã€Œå„²å˜ã€ã€‚ + </string> + <string name="combo_label"> + -鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®- + </string> + <text name="label"> + 自訂é…ç½®å稱: + </text> + <text name="note"> + 注æ„:更改自訂é…置的å稱將會新建一個自訂é…ç½®ï¼Œä¸æœƒæ”¹è®ŠåŽŸæœ‰çš„è‡ªè¨‚é…置。 + </text> + <text name="hint_item1"> + - 點按一個é 籤,編輯特定的天空è¨å®šå’Œæ™‚間。 + </text> + <text name="hint_item2"> + - 點按並拖曳å„個é 籤,å³å¯è¨å®šéŽæ¸¡æ™‚間。 + </text> + <text name="hint_item3"> + - 使用 scrubber é è¦½ä½ çš„æ—¥å¾ªç’°ã€‚ + </text> + <panel name="day_cycle_slider_panel"> + <multi_slider initial_value="0" name="WLTimeSlider"/> + <multi_slider initial_value="0" name="WLDayCycleKeys"/> + <button label="新增éµ" label_selected="新增éµ" name="WLAddKey"/> + <button label="刪除éµ" label_selected="刪除éµ" name="WLDeleteKey"/> + <text name="WL12am"> + åˆå¤œ 12 點 + </text> + <text name="WL3am"> + 凌晨 3 點 + </text> + <text name="WL6am"> + ä¸Šåˆ 6 點 + </text> + <text name="WL9amHash"> + ä¸Šåˆ 9 點 + </text> + <text name="WL12pmHash"> + ä¸åˆ 12 點 + </text> + <text name="WL3pm"> + ä¸‹åˆ 3 點 + </text> + <text name="WL6pm"> + ä¸‹åˆ 6 點 + </text> + <text name="WL9pm"> + ä¸‹åˆ 9 點 + </text> + <text name="WL12am2"> + åˆå¤œ 12 點 + </text> + <text name="WL12amHash"> + | + </text> + <text name="WL3amHash"> + I + </text> + <text name="WL6amHash"> + | + </text> + <text name="WL9amHash2"> + I + </text> + <text name="WL12pmHash2"> + | + </text> + <text name="WL3pmHash"> + I + </text> + <text name="WL6pmHash"> + | + </text> + <text name="WL9pmHash"> + I + </text> + <text name="WL12amHash2"> + | + </text> + </panel> + <text name="WLCurKeyPresetText"> + 天空è¨å®šï¼š + </text> + <combo_box label="é è¨å€¼" name="WLSkyPresets"/> + <text name="WLCurKeyTimeText"> + 時間: + </text> + <time name="time" value="ä¸Šåˆ 6 點"/> + <check_box label="æ ¹æ“šé€™è¨å®šè®Šæ›´æˆ‘的日循環" name="make_default_cb"/> + <button label="儲å˜" name="save"/> + <button label="å–æ¶ˆ" name="cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/zh/floater_edit_sky_preset.xml new file mode 100644 index 0000000000..1ff832cdc4 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_edit_sky_preset.xml @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Edit Sky Preset" title="編輯天空自訂é…ç½®"> + <string name="title_new"> + 建立新的天空自訂é…ç½® + </string> + <string name="title_edit"> + 編輯天空自訂é…ç½® + </string> + <string name="hint_new"> + 為自訂é…置定å,調整å„é …æŽ§åˆ¶ç¢ºå®šé…置細節,完æˆå¾Œé»žæŒ‰ã€Œå„²å˜ã€ã€‚ + </string> + <string name="hint_edit"> + è‹¥è¦ç·¨è¼¯ä½ 的天空自訂é…置,請調整å„é …æŽ§åˆ¶ï¼Œå†é»žæŒ‰ã€Œå„²å˜ã€ã€‚ + </string> + <string name="combo_label"> + -鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®- + </string> + <text name="hint"> + è‹¥è¦ç·¨è¼¯ä½ 的自訂é…置,請調整å„é …æŽ§åˆ¶ï¼Œå†é»žæŒ‰ã€Œå„²å˜ã€ã€‚ + </text> + <text name="label"> + 自訂é…ç½®å稱: + </text> + <text name="note"> + 注æ„:更改自訂é…置的å稱將會新建一個自訂é…ç½®ï¼Œä¸æœƒæ”¹è®ŠåŽŸæœ‰çš„è‡ªè¨‚é…置。 + </text> + <tab_container name="WindLight Tabs"> + <panel label="大氣" name="Atmosphere"> + <text name="BHText"> + è—天水平線 + </text> + <text name="BDensText"> + 陰霾水平線 + </text> + <text name="BDensText2"> + è—天密度 + </text> + <text name="HDText"> + 陰霾密度 + </text> + <text name="DensMultText"> + 密度å€å¢ž + </text> + <text name="WLDistanceMultText"> + è·é›¢å€å¢ž + </text> + <text name="MaxAltText"> + 最大高度 + </text> + </panel> + <panel label="照明" name="Lighting"> + <text name="SLCText"> + æ—¥ï¼æœˆ é¡è‰² + </text> + <text name="WLAmbientText"> + 環境 + </text> + <text name="SunGlowText"> + å¤ªé™½å…‰è¼ + </text> + <slider label="èšç„¦" name="WLGlowB"/> + <slider label="尺寸" name="WLGlowR"/> + <text name="WLStarText"> + 星空亮度 + </text> + <text name="SceneGammaText"> + å ´æ™¯ Gamma 值 + </text> + <text name="TODText"> + æ—¥ï¼æœˆ ä½ç½® + </text> + <multi_slider initial_value="0" name="WLSunPos"/> + <text name="WL12amHash"> + | + </text> + <text name="WL6amHash"> + | + </text> + <text name="WL12pmHash2"> + | + </text> + <text name="WL6pmHash"> + | + </text> + <text name="WL12amHash2"> + | + </text> + <text name="WL12am"> + åˆå¤œ 12 點 + </text> + <text name="WL6am"> + ä¸Šåˆ 6 點 + </text> + <text name="WL12pmHash"> + ä¸åˆ 12 點 + </text> + <text name="WL6pm"> + ä¸‹åˆ 6 點 + </text> + <text name="WL12am2"> + åˆå¤œ 12 點 + </text> + <time name="WLDayTime" value="ä¸Šåˆ 6 點"/> + <text name="WLEastAngleText"> + æ±å‡è§’度 + </text> + </panel> + <panel label="雲彩" name="Clouds"> + <text name="WLCloudColorText"> + 雲彩é¡è‰² + </text> + <text name="WLCloudColorText2"> + 雲彩 XY 軸 / 密度 + </text> + <slider label="X" name="WLCloudX"/> + <slider label="Y" name="WLCloudY"/> + <slider label="D" name="WLCloudDensity"/> + <text name="WLCloudCoverageText"> + 雲彩覆蓋 + </text> + <text name="WLCloudScaleText"> + é›²å½©è¦æ¨¡ + </text> + <text name="WLCloudDetailText"> + 雲彩細節(XY 軸 / 密度) + </text> + <slider label="X" name="WLCloudDetailX"/> + <slider label="Y" name="WLCloudDetailY"/> + <slider label="D" name="WLCloudDetailDensity"/> + <text name="WLCloudScrollXText"> + 雲彩 X 滾軸 + </text> + <check_box label="鎖定" name="WLCloudLockX"/> + <text name="WLCloudScrollYText"> + 雲彩 Y 滾軸 + </text> + <check_box label="鎖定" name="WLCloudLockY"/> + </panel> + </tab_container> + <check_box label="æ ¹æ“šé€™è‡ªè¨‚é…置變更我的天空è¨å®š" name="make_default_cb"/> + <button label="儲å˜" name="save"/> + <button label="å–æ¶ˆ" name="cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/zh/floater_edit_water_preset.xml new file mode 100644 index 0000000000..7943866e72 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_edit_water_preset.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Edit Water Preset" title="編輯水的自訂é…ç½®"> + <string name="title_new"> + 新建水的自訂é…ç½® + </string> + <string name="title_edit"> + 編輯水的自訂é…ç½® + </string> + <string name="hint_new"> + 為自訂é…置定å,調整å„é …æŽ§åˆ¶ç¢ºå®šé…置細節,完æˆå¾Œé»žæŒ‰ã€Œå„²å˜ã€ã€‚ + </string> + <string name="hint_edit"> + è‹¥è¦ç·¨è¼¯æ°´çš„自訂é…置,請調整å„é …æŽ§åˆ¶ï¼Œå†é»žæŒ‰ã€Œå„²å˜ã€ã€‚ + </string> + <string name="combo_label"> + -鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®- + </string> + <text name="hint"> + è‹¥è¦ç·¨è¼¯ä½ 的自訂é…置,請調整å„é …æŽ§åˆ¶ï¼Œå†é»žæŒ‰ã€Œå„²å˜ã€ã€‚ + </text> + <text name="label"> + 自訂é…ç½®å稱: + </text> + <text name="note"> + 注æ„:更改自訂é…置的å稱將會新建一個自訂é…ç½®ï¼Œä¸æœƒæ”¹è®ŠåŽŸæœ‰çš„è‡ªè¨‚é…置。 + </text> + <panel name="panel_water_preset"> + <text name="water_color_label"> + 水霧é¡è‰² + </text> + <text name="water_fog_density_label"> + 霧密度指數 + </text> + <text name="underwater_fog_modifier_label"> + 水底霧修飾元 + </text> + <text name="BHText"> + å¤§æ³¢æµªæ–¹å‘ + </text> + <slider label="X" name="WaterWave1DirX"/> + <slider label="Y" name="WaterWave1DirY"/> + <text name="BDensText"> + åå°„åæ³¢æ¯”例 + </text> + <text name="HDText"> + è²æ¶…耳比例 + </text> + <text name="FresnelOffsetText"> + è²æ¶…耳åè· + </text> + <text name="BHText2"> + å°æ³¢æµªæ–¹å‘ + </text> + <slider label="X" name="WaterWave2DirX"/> + <slider label="Y" name="WaterWave2DirY"/> + <text name="DensMultText"> + 上折射比例 + </text> + <text name="WaterScaleBelowText"> + 下折射比例 + </text> + <text name="MaxAltText"> + æ¨¡ç³Šå€æ•¸ + </text> + <text name="BHText3"> + æ£å¸¸åœ°åœ– + </text> + </panel> + <check_box label="æ ¹æ“šé€™è‡ªè¨‚é…置變更我水的è¨å®š" name="make_default_cb"/> + <button label="儲å˜" name="save"/> + <button label="å–æ¶ˆ" name="cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_env_settings.xml b/indra/newview/skins/default/xui/zh/floater_env_settings.xml deleted file mode 100644 index 534ee7f0d0..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_env_settings.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Environment Editor Floater" title="ENVIRONMENT EDITOR"> - <floater.string name="timeStr"> - [hour12,datetime,utc]:[min,datetime,utc] [ampm,datetime,utc] - </floater.string> - <text name="EnvTimeText"> - Time of Day - </text> - <text name="EnvTimeText2"> - 12:00 PM - </text> - <text name="EnvCloudText"> - Cloud Cover - </text> - <text name="EnvWaterColorText"> - 水色 - </text> - <color_swatch name="EnvWaterColor" tool_tip="Click to open color picker"/> - <text name="EnvWaterFogText"> - 水霧 - </text> - <button label="Use Estate Time" name="EnvUseEstateTimeButton"/> - <button label="進階天空" name="EnvAdvancedSkyButton"/> - <button label="進階水文" name="EnvAdvancedWaterButton"/> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_environment_settings.xml b/indra/newview/skins/default/xui/zh/floater_environment_settings.xml new file mode 100644 index 0000000000..1c6f2f936d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_environment_settings.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Environment Editor Floater" title="環境è¨å®š"> + <text name="note"> + 使用以下的é¸é …è‡ªè¨‚ä½ Viewer 的環境è¨å®šã€‚ + </text> + <radio_group name="region_settings_radio_group"> + <radio_item label="使用地å€è¨å®š" name="use_region_settings"/> + <radio_item label="自訂我的環境" name="use_my_settings"/> + </radio_group> + <panel name="user_environment_settings"> + <text name="note"> + 注æ„ï¼šä½ çš„è‡ªè¨‚è¨å®šä¸æœƒè¢«å…¶ä»–使用者看見。 + </text> + <text name="water_settings_title"> + æ°´çš„è¨å®š + </text> + <combo_box name="water_settings_preset_combo"> + <combo_box.item label="-鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/> + </combo_box> + <text name="sky_dayc_settings_title"> + 天空 / 日循環 + </text> + <radio_group name="sky_dayc_settings_radio_group"> + <radio_item label="固定天空" name="my_sky_settings"/> + <radio_item label="日循環" name="my_dayc_settings"/> + </radio_group> + <combo_box name="sky_settings_preset_combo"> + <combo_box.item label="-鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/> + </combo_box> + <combo_box name="dayc_settings_preset_combo"> + <combo_box.item label="-鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/> + </combo_box> + </panel> + <button label="確定" name="ok_btn"/> + <button label="å–æ¶ˆ" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_event.xml b/indra/newview/skins/default/xui/zh/floater_event.xml index 349b5717f2..7175731fef 100644 --- a/indra/newview/skins/default/xui/zh/floater_event.xml +++ b/indra/newview/skins/default/xui/zh/floater_event.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater label="Event" name="Event" title="EVENT DETAILS"> +<floater label="活動" name="Event" title="活動細節"> <floater.string name="loading_text"> 載入ä¸... </floater.string> <floater.string name="done_text"> - Done + å®Œæˆ </floater.string> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_fast_timers.xml b/indra/newview/skins/default/xui/zh/floater_fast_timers.xml new file mode 100644 index 0000000000..871849305c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_fast_timers.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="fast_timers"> + <string name="pause"> + æš«åœ + </string> + <string name="run"> + è·‘æ¥ + </string> + <button label="æš«åœ" name="pause_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_gesture.xml b/indra/newview/skins/default/xui/zh/floater_gesture.xml index a809cf085c..e7b1ed1de3 100644 --- a/indra/newview/skins/default/xui/zh/floater_gesture.xml +++ b/indra/newview/skins/default/xui/zh/floater_gesture.xml @@ -7,17 +7,17 @@ ï¼ˆæ’æ”¾ä¸ï¼‰ </floater.string> <floater.string name="copy_name"> - Copy of [COPY_NAME] + [COPY_NAME] 複本 </floater.string> <scroll_list name="gesture_list"> <scroll_list.columns label="å稱" name="name"/> <scroll_list.columns label="èŠå¤©" name="trigger"/> - <scroll_list.columns label="Key" name="shortcut"/> + <scroll_list.columns label="éµ" name="shortcut"/> </scroll_list> <panel label="bottom_panel" name="bottom_panel"> <menu_button name="gear_btn" tool_tip="更多é¸é …"/> <button name="new_gesture_btn" tool_tip="製作新姿勢e"/> - <button name="activate_btn" tool_tip="Activate/Deactivate selected gesture"/> + <button name="activate_btn" tool_tip="啟動/åœæ¢æ‰€é¸å§¿å‹¢"/> <button name="del_btn" tool_tip="刪除這個姿勢"/> </panel> <button label="編輯" name="edit_btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_god_tools.xml b/indra/newview/skins/default/xui/zh/floater_god_tools.xml index 448113bf74..69a6eadc8c 100644 --- a/indra/newview/skins/default/xui/zh/floater_god_tools.xml +++ b/indra/newview/skins/default/xui/zh/floater_god_tools.xml @@ -8,42 +8,42 @@ <text name="Region Name:"> 地å€å稱: </text> - <check_box label="Prelude" name="check prelude" tool_tip="Set this to make the region a prelude"/> - <check_box label="固定太陽" name="check fixed sun" tool_tip="Fix the sun position (like in Region/Estate > Terrain"/> - <check_box label="Reset Home On Teleport" name="check reset home" tool_tip="When Resident teleports out, reset their home to the destination position."/> - <check_box label="Visible" name="check visible" tool_tip="Set this to make the region visible to non-gods"/> - <check_box label="傷害" name="check damage" tool_tip="Set this to enable damage in this region"/> - <check_box label="é˜»æ¢æµé‡è¿½è¹¤" name="block dwell" tool_tip="Set this to make the region not compute traffic"/> - <check_box label="阻æ¢è®Šå½¢" name="block terraform" tool_tip="Set this to disallow people terraforming their land"/> - <check_box label="沙盒" name="is sandbox" tool_tip="Toggle whether this is a sandbox region"/> - <button label="Bake Terrain" label_selected="Bake Terrain" name="Bake Terrain" tool_tip="儲å˜ç›®å‰çš„地形為é è¨"/> - <button label="Revert Terrain" label_selected="Revert Terrain" name="Revert Terrain" tool_tip="Replace the current terrain with default"/> - <button label="Swap Terrain" label_selected="Swap Terrain" name="Swap Terrain" tool_tip="Swap current terrain with default"/> + <check_box label="導引å€" name="check prelude" tool_tip="在æ¤è¨å®šï¼Œå°‡å€åŸŸè¨ç‚ºå°Žå¼•å€"/> + <check_box label="固定太陽" name="check fixed sun" tool_tip="固定太陽ä½ç½®ï¼ˆå¦‚åŒåœ°å€/é ˜åœ° > 地形)"/> + <check_box label="çž¬é–“å‚³é€æ™‚é‡è¨å®¶çš„ä½ç½®" name="check reset home" tool_tip="居民瞬間傳é€é›¢é–‹æ™‚,將他們的家é‡è¨ç‚ºçž¬é–“傳é€çš„目的地。"/> + <check_box label="å¯çœ‹åˆ°" name="check visible" tool_tip="在æ¤è¨å®šï¼Œå°‡å€åŸŸè¨ç‚ºå¯è®“éžç¥žè€…看到。"/> + <check_box label="傷害" name="check damage" tool_tip="在æ¤è¨å®šï¼Œä½¿æœ¬åœ°å€å…許傷害。"/> + <check_box label="é˜»æ¢æµé‡è¿½è¹¤" name="block dwell" tool_tip="在æ¤è¨å®šï¼Œä½¿æœ¬å€åŸŸä¸è¨ˆç®—æµé‡ã€‚"/> + <check_box label="阻æ¢åœŸåœ°è®Šå½¢" name="block terraform" tool_tip="è¨å®šç¦æ¢äººå€‘將其土地變形。"/> + <check_box label="沙盤" name="is sandbox" tool_tip="åˆ‡æ›æ˜¯å¦è¨ç‚ºæ²™ç›¤å€åŸŸã€‚"/> + <button label="確定地形" label_selected="確定地形" name="Bake Terrain" tool_tip="將目å‰çš„地形儲å˜ç‚ºé è¨å€¼"/> + <button label="回復原地形" label_selected="回復原地形" name="Revert Terrain" tool_tip="以é è¨å€¼å–代目å‰çš„地形"/> + <button label="交æ›åœ°å½¢" label_selected="交æ›åœ°å½¢" name="Swap Terrain" tool_tip="將目å‰çš„地形和é è¨å€¼äº¤æ›"/> <text name="estate id"> é ˜åœ° ID: </text> <text name="parent id"> - Parent ID: + æ¯é ˜åœ° ID: </text> - <line_editor name="parentestate" tool_tip="This is the parent estate for this region"/> + <line_editor name="parentestate" tool_tip="這是本å€åŸŸçš„æ¯é ˜åœ°"/> <text name="Grid Pos: "> ç¶²æ ¼ä½ç½®ï¼š </text> - <line_editor name="gridposx" tool_tip="This is the grid x position for this region"/> - <line_editor name="gridposy" tool_tip="This is the grid y position for this region"/> + <line_editor name="gridposx" tool_tip="這是本å€åŸŸçš„ç¶²æ ¼ X ä½ç½®"/> + <line_editor name="gridposy" tool_tip="這是本å€åŸŸçš„ç¶²æ ¼ Y ä½ç½®"/> <text name="Redirect to Grid: "> - Redirect to Grid: + 釿–°å°Žå‘è‡³ç¶²æ ¼ï¼š </text> <text name="billable factor text"> - Billable Factor: + 收費率: </text> <text name="land cost text"> - L$ per m²: + æ¯å¹³æ–¹å…¬å°º L$: </text> - <button label="釿–°æ•´ç†" label_selected="釿–°æ•´ç†" name="Refresh" tool_tip="Click here to refresh the above information"/> - <button label="套用" label_selected="套用" name="Apply" tool_tip="點擊æ¤è™•以接å—套用上述變更"/> - <button label="鏿“‡åœ°å€" label_selected="鏿“‡åœ°å€" name="Select Region" tool_tip="Select the whole region with the land tool"/> - <button label="ç«‹å³è‡ªå‹•儲å˜" label_selected="ç«‹å³è‡ªå‹•儲å˜" name="Autosave now" tool_tip="Save gzipped state to autosave directory"/> + <button label="釿–°æ•´ç†" label_selected="釿–°æ•´ç†" name="Refresh" tool_tip="點按這裡刷新上列資料"/> + <button label="套用" label_selected="套用" name="Apply" tool_tip="點按æ¤è™•以接å—套用上述變更"/> + <button label="鏿“‡åœ°å€" label_selected="鏿“‡åœ°å€" name="Select Region" tool_tip="以土地工具é¸å–整個å€åŸŸ"/> + <button label="ç«‹å³è‡ªå‹•儲å˜" label_selected="ç«‹å³è‡ªå‹•儲å˜" name="Autosave now" tool_tip="å„²å˜ gzip 壓縮狀態至自動儲å˜ç›®éŒ„"/> </panel> <panel label="物件" name="objects"> <panel.string name="no_target"> @@ -53,44 +53,44 @@ 地å€å稱: </text> <text name="region name"> - Welsh + å¨çˆ¾æ–¯ </text> <check_box label="關閉腳本" name="disable scripts" tool_tip="關閉這個地å€ç¾åœ¨çš„全部腳本"/> - <check_box label="Disable Collisions" name="disable collisions" tool_tip="Set this to disable non-agent collisions in this region"/> - <check_box label="Disable Physics" name="disable physics" tool_tip="Set this to disable all physics in this region"/> - <button label="套用" label_selected="套用" name="Apply" tool_tip="Click here to apply any changes from above"/> - <button label="Set Target" label_selected="Set Target" name="Set Target" tool_tip="Set the target avatar for object deletion"/> + <check_box label="ç¦æ¢ç¢°æ’ž" name="disable collisions" tool_tip="è¨ç½®é—œé–‰åœ°å€å…§é™¤äº†äººä»¥å¤–的碰撞"/> + <check_box label="關閉物ç†" name="disable physics" tool_tip="è¨ç½®é—œé–‰æœ¬å€åŸŸå…§æ‰€æœ‰ç‰©ç†"/> + <button label="套用" label_selected="套用" name="Apply" tool_tip="點按æ¤è™•以接å—套用上述變更"/> + <button label="è¨å®šç›®æ¨™" label_selected="è¨å®šç›®æ¨™" name="Set Target" tool_tip="將目標化身è¨ç‚ºå¾…刪除的物件"/> <text name="target_avatar_name"> (無目標) </text> - <button label="Delete Target's Scripted Objects On Others Land" label_selected="Delete Target's Scripted Objects On Others Land" name="Delete Target's Scripted Objects On Others Land" tool_tip="Delete all scripted objects owned by the target on land not owned by the target. (no copy) objects will be returned."/> - <button label="Delete Target's Scripted Objects On *Any* Land" label_selected="Delete Target's Scripted Objects On *Any* Land" name="Delete Target's Scripted Objects On *Any* Land" tool_tip="Delete all scripted objects owned by the target in this region. (no copy) objects will be returned."/> - <button label="Delete *ALL* Of Target's Objects" label_selected="Delete *ALL* Of Target's Objects" name="Delete *ALL* Of Target's Objects" tool_tip="Delete all objects owned by the target in this region. (no copy) objects will be returned."/> - <button label="Get Top Colliders" label_selected="Get Top Colliders" name="Get Top Colliders" tool_tip="Gets list of objects experiencing the most narrowphase callbacks"/> - <button label="Get Top Scripts" label_selected="Get Top Scripts" name="Get Top Scripts" tool_tip="Gets list of objects spending the most time running scripts"/> - <button label="Scripts digest" label_selected="Scripts digest" name="Scripts digest" tool_tip="Gets a list of all scripts and number of occurences of each"/> + <button label="刪除目標物在其他土地的帶腳本的物件" label_selected="刪除目標物在其他土地的帶腳本的物件" name="Delete Target's Scripted Objects On Others Land" tool_tip="åœ¨ä¸æ˜¯ç›®æ¨™ç‰©æ‰€æ“有的土地上,刪除屬於該目標物的所有帶腳本的物件。 ã€Œç¦æ¢è¤‡è£½ã€çš„物件將被é€å›žã€‚"/> + <button label="刪除目標物在任何土地的帶腳本的物件" label_selected="刪除目標物在任何土地的帶腳本的物件" name="Delete Target's Scripted Objects On *Any* Land" tool_tip="刪除本å€åŸŸå…§å±¬æ–¼ç›®æ¨™ç‰©çš„æ‰€æœ‰å¸¶è…³æœ¬çš„物件。 ã€Œç¦æ¢è¤‡è£½ã€çš„物件將被é€å›žã€‚"/> + <button label="刪除目標物所有的物件" label_selected="刪除目標物所有的物件" name="Delete *ALL* Of Target's Objects" tool_tip="刪除本å€åŸŸå…§å±¬æ–¼ç›®æ¨™ç‰©çš„æ‰€æœ‰ç‰©ä»¶ã€‚ ã€Œç¦æ¢è¤‡è£½ã€çš„物件將被é€å›žã€‚"/> + <button label="å–得最常碰撞的物件" label_selected="å–得最常碰撞的物件" name="Get Top Colliders" tool_tip="å–å¾—ç¶“æ·æœ€å¤šæ¬¡ã€Œçª„相ã€å›žèª¿çš„物件清單"/> + <button label="å–å¾—æŽ’åæœ€é«˜çš„腳本" label_selected="å–å¾—æŽ’åæœ€é«˜çš„腳本" name="Get Top Scripts" tool_tip="å–得花最多時間執行腳本的物件清單"/> + <button label="腳本集" label_selected="腳本集" name="Scripts digest" tool_tip="å–得所有腳本清單,並列出發生次數,é‡å°æ¯ä¸€"/> </panel> - <panel label="Request" name="request"> + <panel label="請求" name="request"> <text name="Destination:"> - Destination: + 目的地: </text> <combo_box name="destination"> - <combo_box.item label="Selection" name="item1"/> - <combo_box.item label="Agent Region" name="item2"/> + <combo_box.item label="鏿“‡" name="item1"/> + <combo_box.item label="用戶地å€" name="item2"/> </combo_box> <text name="Request:"> - Request: + 請求: </text> <combo_box name="request"> - <combo_box.item label="colliders <steps>" name="item1"/> - <combo_box.item label="scripts <count>,<optional pattern>" name="item2"/> - <combo_box.item label="objects <pattern>" name="item3"/> + <combo_box.item label="碰撞物 <æ¥é©Ÿ>" name="item1"/> + <combo_box.item label="腳本 <計數>,<éžå¿…è¦å½¢æ…‹>" name="item2"/> + <combo_box.item label="物件 <形態>" name="item3"/> <combo_box.item label="rez <asset_id>" name="item4"/> </combo_box> <text name="Parameter:"> - Parameter: + åƒæ•¸ï¼š </text> - <button label="Make Request" label_selected="Make Request" name="Make Request"/> + <button label="æå‡ºè«‹æ±‚" label_selected="æå‡ºè«‹æ±‚" name="Make Request"/> </panel> </tab_container> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml b/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml index 1465dcb256..9e3bb88ac0 100644 --- a/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml +++ b/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml @@ -1,14 +1,14 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Hardware Settings Floater" title="硬體è¨å®š"> <text name="Filtering:"> - Filtering: + éŽæ¿¾ï¼š </text> - <check_box label="Anisotropic Filtering (slower when enabled)" name="ani"/> - <text name="Antialiasing:"> - Antialiasing: + <check_box label="å„å‘ç•°æ€§éŽæ¿¾ï¼ˆè‹¥å•Ÿç”¨æœƒè®Šæ…¢ï¼‰" name="ani"/> + <text name="antialiasing label"> + 消除鋸齒: </text> - <combo_box label="Antialiasing" name="fsaa"> - <combo_box.item label="Disabled" name="FSAADisabled"/> + <combo_box label="消除鋸齒" name="fsaa"> + <combo_box.item label="å·²åœç”¨" name="FSAADisabled"/> <combo_box.item label="2x" name="2x"/> <combo_box.item label="4x" name="4x"/> <combo_box.item label="8x" name="8x"/> @@ -17,15 +17,19 @@ <text name="antialiasing restart"> ï¼ˆé ˆé‡æ–°å•Ÿå‹•ç€è¦½å™¨ï¼‰ </text> - <spinner label="Gamma:" name="gamma"/> + <spinner label="伽瑪值:" name="gamma"/> <text name="(brightness, lower is brighter)"> - (0 = default brightness, lower = brighter) + (0 = é è¨äº®åº¦ï¼›å€¼è¶Šå° = 亮度越高) </text> <text name="Enable VBO:"> - Enable VBO: + å•Ÿç”¨é ‚é»žç·©è¡ç‰©ä»¶(VBO): </text> - <check_box initial_value="true" label="Enable OpenGL Vertex Buffer Objects" name="vbo" tool_tip="Enabling this on modern hardware gives a performance gain. However, older hardware often has poor implementations of VBOs and you may get crashes when this is enabled."/> - <slider label="æè³ªè¨˜æ†¶é«”(MB):" name="GraphicsCardTextureMemory" tool_tip="Amount of memory to allocate for textures. Defaults to video card memory. Reducing this may improve performance but may also make textures blurry."/> - <spinner label="Fog Distance Ratio:" name="fog"/> + <check_box initial_value="true" label="啟用 OpenGL é ‚é»žç·©è¡ç‰©ä»¶(VBO)" name="vbo" tool_tip="åœ¨è¼ƒæ–°ç¡¬é«”ä¸Šå•Ÿç”¨ï¼Œå¯æå‡æ•ˆèƒ½ã€‚ 但是,較舊硬體的 VBO 實作ä¸ä½³ï¼Œè‹¥å•Ÿç”¨å¯èƒ½å°Žè‡´ç•¶æ©Ÿã€‚"/> + <text name="tc label"> + 啟用 S3TC: + </text> + <check_box initial_value="true" label="啟用æè³ªå£“ç¸®ï¼ˆé ˆé‡æ–°å•Ÿå‹•)" name="texture compression" tool_tip="在影片記憶體ä¸å£“縮æè³ªï¼Œè®“高解æžåº¦æè³ªå¯ä»¥è¼‰å…¥ï¼Œä½†è‰²å½©å“質ç¨å·®ã€‚"/> + <slider label="æè³ªè¨˜æ†¶é«”(MB):" name="GraphicsCardTextureMemory" tool_tip="é…置給æè³ªä½¿ç”¨çš„記憶體é‡ã€‚ é è¨ç‚ºé¡¯åƒå¡è¨˜æ†¶é«”。 é™ä½Žæ¤å€¼å¯ä»¥æå‡æ•ˆèƒ½ï¼Œä½†æè³ªä¹Ÿæœƒè®Šæ¨¡ç³Šã€‚"/> + <spinner label="霧è·é›¢æ¯”率:" name="fog"/> <button label="確定" label_selected="確定" name="OK"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_how_to.xml b/indra/newview/skins/default/xui/zh/floater_how_to.xml new file mode 100644 index 0000000000..e033327165 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_how_to.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_how_to" title="簡易教å¸"/> diff --git a/indra/newview/skins/default/xui/zh/floater_im_session.xml b/indra/newview/skins/default/xui/zh/floater_im_session.xml index e8db97560e..808a0b6720 100644 --- a/indra/newview/skins/default/xui/zh/floater_im_session.xml +++ b/indra/newview/skins/default/xui/zh/floater_im_session.xml @@ -2,7 +2,7 @@ <floater name="panel_im"> <layout_stack name="im_panels"> <layout_panel> - <line_editor label="To" name="chat_editor"/> + <line_editor label="至" name="chat_editor"/> </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_image_preview.xml b/indra/newview/skins/default/xui/zh/floater_image_preview.xml index 1260601f90..d2de37fa6a 100644 --- a/indra/newview/skins/default/xui/zh/floater_image_preview.xml +++ b/indra/newview/skins/default/xui/zh/floater_image_preview.xml @@ -26,7 +26,7 @@ 請嘗試儲å˜åœ–åƒç‚º 24 ä½å…ƒ Targa(.tgaï¼‰æ ¼å¼ã€‚ </text> - <check_box label="Use lossless compression" name="lossless_check"/> + <check_box label="使用零失真壓縮" name="lossless_check"/> <button label="å–æ¶ˆ" name="cancel_btn"/> <button label="上傳(L$[AMOUNT])" name="ok_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_import_collada.xml b/indra/newview/skins/default/xui/zh/floater_import_collada.xml new file mode 100644 index 0000000000..8f6b476ccf --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_import_collada.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Import Collada" title="åŒ¯å…¥å ´æ™¯"> + <text name="mesh count"> + ç¶²é¢ï¼š[COUNT] + </text> + <text name="texture count"> + æè³ªï¼š [COUNT] + </text> + <text name="status"> + 狀態:[STATUS] + </text> + <button label="å–æ¶ˆ" name="cancel"/> + <button label="確定" name="ok"/> + <string name="status_idle"> + é–’ç½®ä¸ + </string> + <string name="status_uploading"> + æ£åœ¨ä¸Šå‚³ [NAME] + </string> + <string name="status_creating"> + æ£åœ¨å»ºç«‹ [NAME] 物件 + </string> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_incoming_call.xml b/indra/newview/skins/default/xui/zh/floater_incoming_call.xml index a0f31fa11f..45a003d3c8 100644 --- a/indra/newview/skins/default/xui/zh/floater_incoming_call.xml +++ b/indra/newview/skins/default/xui/zh/floater_incoming_call.xml @@ -4,28 +4,28 @@ 5 </floater.string> <floater.string name="localchat"> - 附近的音èŠå¤© + 附近的語音èŠå¤© </floater.string> <floater.string name="anonymous"> 匿å </floater.string> <floater.string name="VoiceInviteP2P"> - 通話ä¸ã€‚ + 來電ä¸ã€‚ </floater.string> <floater.string name="VoiceInviteAdHoc"> - å·²åŠ è¨´å…¥æœƒè°äº¤è«‡ä¸çš„語音èŠå¤©ã€‚ + å·²åŠ å…¥å¤šæ–¹èªžéŸ³é€šè©±ã€‚ </floater.string> <floater.string name="VoiceInviteGroup"> å‰›åŠ å…¥ '[GROUP]' èªžéŸ³é »é“。 </floater.string> <floater.string name="VoiceInviteQuestionGroup"> - Would you like to leave [CURRENT_CHAT] and join the call with '[GROUP]'? + 是å¦é›¢é–‹ [CURRENT_CHAT] ä¸¦åŠ å…¥å’Œã€Œ[GROUP]ã€é€šè©±ï¼Ÿ </floater.string> <floater.string name="VoiceInviteQuestionDefault"> - Do you want to leave [CURRENT_CHAT] and join this voice chat? + 是å¦é›¢é–‹ [CURRENT_CHAT] ä¸¦åŠ å…¥é€™å€‹èªžéŸ³èŠå¤©ï¼Ÿ </floater.string> <text name="question"> - Do you want to leave [CURRENT_CHAT] and join this voice chat? + 是å¦é›¢é–‹ [CURRENT_CHAT] ä¸¦åŠ å…¥é€™å€‹èªžéŸ³èŠå¤©ï¼Ÿ </text> <button label="接å—" label_selected="接å—" name="Accept"/> <button label="拒絕" label_selected="拒絕" name="Reject"/> diff --git a/indra/newview/skins/default/xui/zh/floater_inspect.xml b/indra/newview/skins/default/xui/zh/floater_inspect.xml index ea3d9d0c3e..4e1f4b24fd 100644 --- a/indra/newview/skins/default/xui/zh/floater_inspect.xml +++ b/indra/newview/skins/default/xui/zh/floater_inspect.xml @@ -1,14 +1,14 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="inspect" title="INSPECT OBJECTS"> +<floater name="inspect" title="檢視物件"> <floater.string name="timeStamp"> [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] </floater.string> - <scroll_list name="object_list" tool_tip="Select an object from this list to highlight it in-world"> + <scroll_list name="object_list" tool_tip="從清單ä¸é¸å–一物件,在虛擬世界ä¸åŠ ä»¥é«˜äº®é¡¯ç¤ºã€‚"> <scroll_list.columns label="物件å稱" name="object_name"/> - <scroll_list.columns label="æ“æœ‰è€…å稱" name="owner_name"/> + <scroll_list.columns label="所有人å稱" name="owner_name"/> <scroll_list.columns label="å‰µé€ è€…å稱" name="creator_name"/> <scroll_list.columns label="å‰µé€ æ—¥æœŸ" name="creation_date"/> </scroll_list> - <button label="å¯Ÿçœ‹æ“æœ‰è€…檔案..." name="button owner" tool_tip="See profile of the highlighted object's owner"/> - <button label="å¯Ÿçœ‹å‰µé€ è€…æª”æ¡ˆ..." name="button creator" tool_tip="See profile of the highlighted object's original creator"/> + <button label="察看所有人檔案..." name="button owner" tool_tip="察看高亮顯示的物件的物主個人檔案"/> + <button label="å¯Ÿçœ‹å‰µé€ äººæª”æ¡ˆ..." name="button creator" tool_tip="察看高亮顯示的物件的原創人個人檔案"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_inventory.xml b/indra/newview/skins/default/xui/zh/floater_inventory.xml deleted file mode 100644 index da4619c964..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_inventory.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="我的收ç´å€"> - <panel label="æ”¶ç´å€é¢æ¿" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml index a41be7ef9a..6998df75f3 100644 --- a/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml +++ b/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml @@ -10,7 +10,7 @@ ä½ å¯ä»¥ï¼š </floater.string> <floater.string name="owner_can"> - æ“æœ‰è€…å¯ä»¥ï¼š + 所有人å¯ä»¥ï¼š </floater.string> <floater.string name="acquiredDate"> [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] @@ -26,11 +26,11 @@ </text> <button label="檔案..." name="BtnCreator"/> <text name="LabelOwnerTitle"> - æ“æœ‰è€…: + 所有人: </text> <button label="檔案..." name="BtnOwner"/> <text name="LabelAcquiredTitle"> - Acquired: + å–得於: </text> <text name="LabelAcquiredDate"> Wed May 24 12:50:46 2006 @@ -39,25 +39,25 @@ ä½ ï¼š </text> <check_box label="編輯" name="CheckOwnerModify"/> - <check_box label="覆製" name="CheckOwnerCopy"/> + <check_box label="æšåº¨" name="CheckOwnerCopy"/> <check_box label="轉售" name="CheckOwnerTransfer"/> <text name="AnyoneLabel"> 任何人: </text> - <check_box label="覆製" name="CheckEveryoneCopy"/> + <check_box label="æšåº¨" name="CheckEveryoneCopy"/> <text name="GroupLabel"> 群組: </text> <check_box label="分享" name="CheckShareWithGroup"/> <text name="NextOwnerLabel"> - ä¸‹ä¸€å€‹æ“æœ‰è€…: + 下一個所有人: </text> <check_box label="編輯" name="CheckNextOwnerModify"/> - <check_box label="覆製" name="CheckNextOwnerCopy"/> + <check_box label="æšåº¨" name="CheckNextOwnerCopy"/> <check_box label="轉售" name="CheckNextOwnerTransfer"/> <check_box label="出售" name="CheckPurchase"/> <combo_box name="combobox sale copy"> - <combo_box.item label="副本" name="Copy"/> + <combo_box.item label="æšåº¨" name="Copy"/> <combo_box.item label="原件" name="Original"/> </combo_box> <spinner label="åƒ¹æ ¼ï¼š" name="Edit Cost"/> diff --git a/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml index d698edf5e5..6d1d18b67c 100644 --- a/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml +++ b/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml @@ -5,16 +5,17 @@ <check_box label="æœè£" name="check_clothing"/> <check_box label="å§¿å‹¢" name="check_gesture"/> <check_box label="地標" name="check_landmark"/> + <check_box label="ç¶²é¢" name="check_mesh"/> <check_box label="記事å¡" name="check_notecard"/> - <check_box label="Objects" name="check_object"/> + <check_box label="物件" name="check_object"/> <check_box label="腳本" name="check_script"/> - <check_box label="Sounds" name="check_sound"/> + <check_box label="è²éŸ³" name="check_sound"/> <check_box label="æè³ª" name="check_texture"/> - <check_box label="Snapshots" name="check_snapshot"/> + <check_box label="å¿«ç…§" name="check_snapshot"/> <button label="全部" label_selected="全部" name="All"/> <button label="ç„¡" label_selected="ç„¡" name="None"/> - <check_box label="Always show folders" name="check_show_empty"/> - <check_box label="Since Logoff" name="check_since_logoff"/> + <check_box label="固定顯示資料夾" name="check_show_empty"/> + <check_box label="自上次登出" name="check_since_logoff"/> <text name="- OR -"> - 或 - </text> diff --git a/indra/newview/skins/default/xui/zh/floater_joystick.xml b/indra/newview/skins/default/xui/zh/floater_joystick.xml index 1721f7cd1e..e0b2cf5a1c 100644 --- a/indra/newview/skins/default/xui/zh/floater_joystick.xml +++ b/indra/newview/skins/default/xui/zh/floater_joystick.xml @@ -1,79 +1,79 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Joystick" title="JOYSTICK CONFIGURATION"> +<floater name="Joystick" title="æ–æ¡¿è¨ç½®"> <floater.string name="NoDevice"> æœªåµæ¸¬åˆ°è¨å‚™ </floater.string> - <check_box label="Enable Joystick:" name="enable_joystick"/> - <spinner label="X Axis Mapping" name="JoystickAxis1"/> - <spinner label="Y Axis Mapping" name="JoystickAxis2"/> - <spinner label="Z Axis Mapping" name="JoystickAxis0"/> - <spinner label="Pitch Mapping" name="JoystickAxis4"/> - <spinner label="Yaw Mapping" name="JoystickAxis5"/> - <spinner label="Roll Mapping" name="JoystickAxis3"/> - <spinner label="Zoom Mapping" name="JoystickAxis6"/> - <check_box label="Direct Zoom" name="ZoomDirect"/> - <check_box label="3D Cursor" name="Cursor3D"/> - <check_box label="Auto Level" name="AutoLeveling"/> + <check_box label="å•Ÿç”¨æ–æ¡¿ï¼š" name="enable_joystick"/> + <spinner label="X è»¸æ˜ å°„" name="JoystickAxis1"/> + <spinner label="Y è»¸æ˜ å°„" name="JoystickAxis2"/> + <spinner label="Z è»¸æ˜ å°„" name="JoystickAxis0"/> + <spinner label="ä¿¯ä»°æ˜ å°„" name="JoystickAxis4"/> + <spinner label="åæ“ºæ˜ å°„" name="JoystickAxis5"/> + <spinner label="ç¿»æ»¾æ˜ å°„" name="JoystickAxis3"/> + <spinner label="ç¸®æ”¾æ˜ å°„" name="JoystickAxis6"/> + <check_box label="直接縮放" name="ZoomDirect"/> + <check_box label="ä¸‰ç¶æ¸¸æ¨™" name="Cursor3D"/> + <check_box label="自動水平" name="AutoLeveling"/> <text name="Control Modes:"> - Control Modes: + 控制模å¼ï¼š </text> <check_box label="化身" name="JoystickAvatarEnabled"/> <check_box label="å»ºé€ " name="JoystickBuildEnabled"/> - <check_box label="Flycam" name="JoystickFlycamEnabled"/> - <stat_view label="Joystick Monitor" name="axis_view"> - <stat_bar label="Axis 0" name="axis0"/> - <stat_bar label="Axis 1" name="axis1"/> - <stat_bar label="Axis 2" name="axis2"/> - <stat_bar label="Axis 3" name="axis3"/> - <stat_bar label="Axis 4" name="axis4"/> - <stat_bar label="Axis 5" name="axis5"/> + <check_box label="移動æ”影機" name="JoystickFlycamEnabled"/> + <stat_view label="æ–æ¡¿ç›£æŽ§å™¨" name="axis_view"> + <stat_bar label="軸 0" name="axis0"/> + <stat_bar label="軸 1" name="axis1"/> + <stat_bar label="軸 2" name="axis2"/> + <stat_bar label="軸 3" name="axis3"/> + <stat_bar label="軸 4" name="axis4"/> + <stat_bar label="軸 5" name="axis5"/> </stat_view> <text name="XScale"> - X Scale + X 比例 </text> <text name="YScale"> - Y Scale + Y 比例 </text> <text name="ZScale"> - Z Scale + Z 比例 </text> <text name="PitchScale"> - Pitch Scale + 俯仰比例 </text> <text name="YawScale"> - Yaw Scale + åæ“ºæ¯”例 </text> <text name="RollScale"> - Roll Scale + 翻滾比例 </text> <text name="XDeadZone"> - X Dead Zone + X æ»å€ </text> <text name="YDeadZone"> - Y Dead Zone + Y æ»å€ </text> <text name="ZDeadZone"> - Z Dead Zone + Z æ»å€ </text> <text name="PitchDeadZone"> - Pitch Dead Zone + 俯仰æ»å€ </text> <text name="YawDeadZone"> - Yaw Dead Zone + åæ“ºæ»å€ </text> <text name="RollDeadZone"> - Roll Dead Zone + 翻滾æ»å€ </text> <text name="Feathering"> - Feathering + é‡é‡å應 </text> <text name="ZoomScale2"> - Zoom Scale + 縮放比例 </text> <text name="ZoomDeadZone"> - Zoom Dead Zone + 縮放æ»å€ </text> - <button label="SpaceNavigator Defaults" name="SpaceNavigatorDefaults"/> + <button label="SpaceNavigator é è¨å€¼" name="SpaceNavigatorDefaults"/> <button label="確定" label_selected="確定" name="ok_btn"/> <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_lagmeter.xml b/indra/newview/skins/default/xui/zh/floater_lagmeter.xml index 6e58e7332f..e9a082288a 100644 --- a/indra/newview/skins/default/xui/zh/floater_lagmeter.xml +++ b/indra/newview/skins/default/xui/zh/floater_lagmeter.xml @@ -7,7 +7,7 @@ 360 </floater.string> <floater.string name="min_title_msg"> - Lag + å»¶é² </floater.string> <floater.string name="min_width_px"> 90 @@ -22,28 +22,28 @@ 15 </floater.string> <floater.string name="client_frame_time_window_bg_msg"> - Normal, window in background + æ£å¸¸ï¼Œè¦–çª—ä½æ–¼èƒŒæ™¯ </floater.string> <floater.string name="client_frame_time_critical_msg"> - Client frame rate below [CLIENT_FRAME_RATE_CRITICAL] + 客戶端幀率低於 [CLIENT_FRAME_RATE_CRITICAL] </floater.string> <floater.string name="client_frame_time_warning_msg"> - Client frame rate between [CLIENT_FRAME_RATE_CRITICAL] and [CLIENT_FRAME_RATE_WARNING] + 客戶端幀率介於 [CLIENT_FRAME_RATE_CRITICAL] å’Œ [CLIENT_FRAME_RATE_WARNING] 之間 </floater.string> <floater.string name="client_frame_time_normal_msg"> æ£å¸¸ </floater.string> <floater.string name="client_draw_distance_cause_msg"> - Possible cause: Draw distance set too high + å¯èƒ½åŽŸå› ï¼šå¯è¦–è·é›¢è¨å¾—太é </floater.string> <floater.string name="client_texture_loading_cause_msg"> - Possible cause: Images loading + å¯èƒ½åŽŸå› ï¼šæ£åœ¨è¼‰å…¥åœ–åƒ </floater.string> <floater.string name="client_texture_memory_cause_msg"> - Possible cause: Too many images in memory + å¯èƒ½åŽŸå› ï¼šè¨˜æ†¶é«”è£¡åœ–åƒå¤ªå¤š </floater.string> <floater.string name="client_complex_objects_cause_msg"> - Possible cause: Too many complex objects in scene + å¯èƒ½åŽŸå› ï¼šå ´æ™¯å…§è¤‡é›œç‰©ä»¶å¤ªå¤š </floater.string> <floater.string name="network_text_msg"> 網路 @@ -55,10 +55,10 @@ 5 </floater.string> <floater.string name="network_packet_loss_critical_msg"> - Connection is dropping over [NETWORK_PACKET_LOSS_CRITICAL]% of packets + 這次連通丟失了至少 [NETWORK_PACKET_LOSS_CRITICAL]% çš„å°åŒ… </floater.string> <floater.string name="network_packet_loss_warning_msg"> - Connection is dropping [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% of packets + 這次連通丟失了 [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% çš„å°åŒ… </floater.string> <floater.string name="network_performance_normal_msg"> æ£å¸¸ @@ -70,16 +70,16 @@ 300 </floater.string> <floater.string name="network_ping_critical_msg"> - Connection ping time is over [NETWORK_PING_CRITICAL] ms + æŽ¢æ¸¬é€£é€šå›žæ‡‰æ™‚é–“è¶…éŽ [NETWORK_PING_CRITICAL] 毫秒 </floater.string> <floater.string name="network_ping_warning_msg"> - Connection ping time is [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms + 探測連通回應時間為 [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] 毫秒 </floater.string> <floater.string name="network_packet_loss_cause_msg"> - Possible bad connection or 'Bandwidth' pref too high. + å¯èƒ½é€£é€šä¸è‰¯ï¼Œæˆ–所è¨çš„åå¥½é€£é€šé »å¯¬éŽé«˜ã€‚ </floater.string> <floater.string name="network_ping_cause_msg"> - Possible bad connection or file-sharing app. + å¯èƒ½é€£é€šä¸è‰¯ï¼Œæˆ–使用檔案分享應用程å¼ã€‚ </floater.string> <floater.string name="server_text_msg"> 伺æœå™¨ diff --git a/indra/newview/skins/default/xui/zh/floater_land_holdings.xml b/indra/newview/skins/default/xui/zh/floater_land_holdings.xml index 1d172f63e1..aae2cfb466 100644 --- a/indra/newview/skins/default/xui/zh/floater_land_holdings.xml +++ b/indra/newview/skins/default/xui/zh/floater_land_holdings.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="land holdings floater" title="我的土地"> <floater.string name="area_string"> - [AREA] m² + [AREA] 平方公尺 </floater.string> <scroll_list name="parcel list"> <scroll_list.columns label="地段" name="name"/> @@ -12,28 +12,28 @@ <button label="瞬間傳é€" label_selected="瞬間傳é€" name="Teleport" tool_tip="瞬間傳é€åˆ°é€™åœŸåœ°çš„ä¸å¤®ã€‚"/> <button label="地圖" label_selected="地圖" name="Show on Map" tool_tip="將這塊土地顯示在世界地圖上。"/> <text name="contrib_label"> - Contributions to your groups: + å°ä½ 的群組的貢ç»ï¼š </text> <scroll_list name="grant list"> <scroll_list.columns label="群組" name="group"/> <scroll_list.columns label="å€åŸŸ" name="area"/> </scroll_list> <text name="allowed_label"> - Allowed land holdings at current payment plan: + ç›®å‰ä»˜è²»è¨ˆåŠƒæ‰€å…è¨±æ“æœ‰çš„土地: </text> <text name="allowed_text"> - [AREA] m² + [AREA] 平方公尺 </text> <text name="current_label"> - Current land holdings: + ç›®å‰æ“有的土地: </text> <text name="current_text"> - [AREA] m² + [AREA] 平方公尺 </text> <text name="available_label"> - Available for land purchases: + å¯è³¼åœŸåœ°ï¼š </text> <text name="available_text"> - [AREA] m² + [AREA] 平方公尺 </text> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml index fe61c312ed..f4a7ba5cca 100644 --- a/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml +++ b/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="script ed float" title="腳本: 新腳本"> <floater.string name="not_allowed"> - You can not view or edit this script, since it has been set as "no copy". You need full permissions to view or edit a script inside an object. + ä½ ç„¡æ³•å¯Ÿçœ‹æˆ–ç·¨è¼¯é€™è…³æœ¬ï¼Œå®ƒè¢«è¨ç‚ºã€Œç¦æ¢è¤‡è£½ã€ã€‚ ä½ éœ€è¦å®Œæ•´æ¬Šé™åŽ»å¯Ÿçœ‹æˆ–ç·¨è¼¯ç‰©ä»¶å…§çš„è…³æœ¬ã€‚ </floater.string> <floater.string name="script_running"> åŸ·è¡Œä¸ diff --git a/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml b/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml index e5c3c47827..b10a480b06 100644 --- a/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml +++ b/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="script ed float" title="LSL REFERENCE"> - <check_box label="Follow cursor" name="lock_check"/> - <combo_box label="Lock" name="history_combo"/> - <button label="Back" name="back_btn"/> - <button label="Forward" name="fwd_btn"/> +<floater name="script ed float" title="LSL åƒè€ƒ"> + <check_box label="跟隨游標" name="lock_check"/> + <combo_box label="鎖定" name="history_combo"/> + <button label="返回" name="back_btn"/> + <button label="å‘å‰" name="fwd_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_map.xml b/indra/newview/skins/default/xui/zh/floater_map.xml index b535ef0074..8a030b3b3f 100644 --- a/indra/newview/skins/default/xui/zh/floater_map.xml +++ b/indra/newview/skins/default/xui/zh/floater_map.xml @@ -1,36 +1,36 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Map" title=""> +<floater name="Map" title="è¿·ä½ åœ°åœ–"> <floater.string name="ToolTipMsg"> - [REGION](Double-click to open Map, shift-drag to pan) + [REGION](雙擊以開啟地圖,按下 shift 鵿‹–曳來平移) </floater.string> <floater.string name="AltToolTipMsg"> - [REGION](Double-click to teleport, shift-drag to pan) + [REGION](雙擊以瞬間傳é€ï¼ŒæŒ‰ä¸‹ shift 鵿‹–曳來平移) </floater.string> <floater.string name="mini_map_caption"> - MINIMAP + è¿·ä½ åœ°åœ– </floater.string> - <text label="N" name="floater_map_north"> - N + <text label="北" name="floater_map_north"> + 北 </text> <text label="E" name="floater_map_east"> E </text> - <text label="W" name="floater_map_west"> - W + <text label="西" name="floater_map_west"> + 西 </text> - <text label="S" name="floater_map_south"> - S + <text label="å—" name="floater_map_south"> + å— </text> - <text label="SE" name="floater_map_southeast"> - SE + <text label="æ±å—" name="floater_map_southeast"> + æ±å— </text> - <text label="NE" name="floater_map_northeast"> - NE + <text label="æ±åŒ—" name="floater_map_northeast"> + æ±åŒ— </text> - <text label="SW" name="floater_map_southwest"> - SW + <text label="西å—" name="floater_map_southwest"> + è¥¿å— </text> - <text label="NW" name="floater_map_northwest"> - NW + <text label="西北" name="floater_map_northwest"> + 西北 </text> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_media_browser.xml b/indra/newview/skins/default/xui/zh/floater_media_browser.xml index 6e75016fad..7f030924e1 100644 --- a/indra/newview/skins/default/xui/zh/floater_media_browser.xml +++ b/indra/newview/skins/default/xui/zh/floater_media_browser.xml @@ -8,13 +8,13 @@ </floater.string> <layout_stack name="stack1"> <layout_panel name="nav_controls"> - <button label="å‘後" name="back"/> + <button label="返回" name="back"/> <button label="å‘å‰" name="forward"/> - <button label="é‡è¼‰" name="reload"/> - <button label="Go" name="go"/> + <button label="釿–°è¼‰å…¥" name="reload"/> + <button label="å‰å¾€" name="go"/> </layout_panel> <layout_panel name="time_controls"> - <button label="rewind" name="rewind"/> + <button label="倒轉" name="rewind"/> <button label="åœæ¢" name="stop"/> <button label="å‘å‰" name="seek"/> </layout_panel> @@ -22,8 +22,8 @@ <button label="é€å‡ºç›®å‰é é¢åˆ°åœ°æ®µ" name="assign"/> </layout_panel> <layout_panel name="external_controls"> - <button label="在我的網é ç€è¦½å™¨ä¸é–‹å•Ÿ" name="open_browser"/> - <check_box label="總是在我的網é ç€è¦½å™¨ä¸é–‹å•Ÿ" name="open_always"/> + <button label="用我的ç€è¦½å™¨é–‹å•Ÿ" name="open_browser"/> + <check_box label="固定用我的ç€è¦½å™¨é–‹å•Ÿ" name="open_always"/> <button label="關閉" name="close"/> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/zh/floater_media_settings.xml b/indra/newview/skins/default/xui/zh/floater_media_settings.xml index f42c0af3d9..3984095a65 100644 --- a/indra/newview/skins/default/xui/zh/floater_media_settings.xml +++ b/indra/newview/skins/default/xui/zh/floater_media_settings.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="media_settings" title="MEDIA SETTINGS"> +<floater name="media_settings" title="媒體è¨å®š"> <button label="確定" label_selected="確定" name="OK"/> <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="Cancel"/> <button label="套用" label_selected="套用" name="Apply"/> diff --git a/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml b/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml index 93c1b58df6..350254e385 100644 --- a/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml +++ b/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="MemLeak" title="SIMULATE A MEMORY LEAK"> - <spinner label="Leaking Speed (bytes per frame):" name="leak_speed"/> - <spinner label="Max Leaked Memory (MB):" name="max_leak"/> +<floater name="MemLeak" title="模擬記憶體æ¼è€—"> + <spinner label="æ¼è€—速度(ä½å…ƒçµ„/幀):" name="leak_speed"/> + <spinner label="最大記憶體æ¼è€—(MB):" name="max_leak"/> <text name="total_leaked_label"> - Current leaked memory: [SIZE] KB + ç›®å‰å·²æ¼è€—記憶體:[SIZE] KB </text> <text name="note_label_1"> [NOTE1] @@ -11,8 +11,8 @@ <text name="note_label_2"> [NOTE2] </text> - <button label="Start" name="start_btn"/> + <button label="é–‹å§‹" name="start_btn"/> <button label="åœæ¢" name="stop_btn"/> - <button label="Release" name="release_btn"/> + <button label="釋放" name="release_btn"/> <button label="關閉" name="close_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml new file mode 100644 index 0000000000..6b6126c8e0 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_merchant_outbox" title="商家發件匣"> + <string name="OutboxFolderCount1"> + 1 個資料夾 + </string> + <string name="OutboxFolderCountN"> + [NUM] 個資料夾 + </string> + <string name="OutboxImporting"> + æ£åœ¨å‚³é€è³‡æ–™å¤¾â€¦ + </string> + <string name="OutboxInitializing"> + æ£åœ¨åˆå§‹åŒ–… + </string> + <panel label=""> + <panel> + <panel name="outbox_inventory_placeholder_panel"> + <text name="outbox_inventory_placeholder_title"> + 載入ä¸... + </text> + </panel> + </panel> + <panel> + <button label="é€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集" name="outbox_import_btn" tool_tip="推到我第二人生購物市集的店é¢"/> + </panel> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_model_preview.xml b/indra/newview/skins/default/xui/zh/floater_model_preview.xml new file mode 100644 index 0000000000..22b3d3b065 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_model_preview.xml @@ -0,0 +1,312 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Model Preview" title="上傳模型"> + <string name="status_idle"/> + <string name="status_parse_error"> + éŒ¯èª¤ï¼šå‰–æž dae 時出錯,詳見記錄檔。 + </string> + <string name="status_material_mismatch"> + éŒ¯èª¤ï¼šæ¨¡åž‹ææ–™ä¸¦éžåƒè€ƒæ¨¡åž‹çš„å集åˆã€‚ + </string> + <string name="status_reading_file"> + 載入ä¸... + </string> + <string name="status_generating_meshes"> + æ£åœ¨ç”Ÿæˆç¶²é¢â€¦ + </string> + <string name="status_vertex_number_overflow"> + éŒ¯èª¤ï¼šé ‚é»žæ•¸ç›®è¶…éŽ 65534,程åºå·²ä¸æ¢ï¼ + </string> + <string name="bad_element"> + 錯誤:無效的元件 + </string> + <string name="high"> + 高 + </string> + <string name="medium"> + ä¸ + </string> + <string name="low"> + 低 + </string> + <string name="lowest"> + 最低 + </string> + <string name="mesh_status_good"> + ç¢ºå®šç”¢ç”Ÿï¼ + </string> + <string name="mesh_status_na"> + ä¸é©ç”¨ + </string> + <string name="mesh_status_none"> + ç„¡ + </string> + <string name="mesh_status_submesh_mismatch"> + 細節層次裡,å¯ä½¿ç”¨æè³ªçš„臉部數目ä¸åŒã€‚ + </string> + <string name="mesh_status_mesh_mismatch"> + 細節層次裡,網é¢å¯¦ä¾‹çš„æ•¸ç›®ä¸åŒã€‚ + </string> + <string name="mesh_status_too_many_vertices"> + ç´°ç¯€å±¤æ¬¡è£¡ï¼Œé ‚é»žæ•¸ç›®å¤ªå¤šã€‚ + </string> + <string name="mesh_status_missing_lod"> + 缺ä¹éœ€è¦çš„細節層次。 + </string> + <string name="mesh_status_invalid_material_list"> + ç´°ç¯€å±¤æ¬¡ææ–™ä¸¦éžåƒè€ƒæ¨¡åž‹çš„å集åˆã€‚ + </string> + <string name="layer_all"> + 全部 + </string> + <string name="decomposing"> + 分æžä¸â€¦ + </string> + <string name="simplifying"> + 簡化ä¸â€¦ + </string> + <string name="tbd"> + (未定) + </string> + <panel name="left_panel"> + <panel name="model_name_representation_panel"> + <text name="name_label"> + 模型å稱: + </text> + <text name="model_category_label"> + 這模型代表… + </text> + <combo_box name="model_category_combo"> + <combo_item label="鏿“‡ä¸€é ……" name="Choose one"/> + <combo_item label="化身形狀" name="Avatar shape"/> + <combo_item label="化身附件" name="Avatar attachment"/> + <combo_item label="會移動的物件(車輛ã€å‹•物)" name="Moving object (vehicle, animal)"/> + <combo_item label="建製元件" name="Building Component"/> + <combo_item label="大型ã€ä¸æœƒç§»å‹•ç‰é¡žåž‹" name="Large, non moving etc"/> + <combo_item label="較å°åž‹ã€ä¸æœƒç§»å‹•ç‰é¡žåž‹" name="Smaller, non-moving etc"/> + <combo_item label="並éžå…¶ä¸ä»»ä½•一個" name="Not really any of these"/> + </combo_box> + </panel> + <tab_container name="import_tab"> + <panel label="細節層次" name="lod_panel" title="細節層次"> + <text initial_value="來æº" name="source" value="來æº"/> + <text initial_value="三角形" name="triangles" value="三角形"/> + <text initial_value="é ‚é»ž" name="vertices" value="é ‚é»ž"/> + <text initial_value="高" name="high_label" value="高"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="從檔案載入"/> + <item name="Generate" value="產生"/> + </combo_box> + <button label="ç€è¦½â€¦" name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="三角形上é™"/> + <item name="Error Threshold" value="錯誤門檻"/> + </combo_box> + <text initial_value="0" name="high_triangles" value="0"/> + <text initial_value="0" name="high_vertices" value="0"/> + <text initial_value="ä¸" name="medium_label" value="ä¸"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="從檔案載入"/> + <item name="Generate" value="產生"/> + <item name="Use LoD above" value="以上使用低階細節"/> + </combo_box> + <button label="ç€è¦½â€¦" name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="三角形上é™"/> + <item name="Error Threshold" value="錯誤門檻"/> + </combo_box> + <text initial_value="0" name="medium_triangles" value="0"/> + <text initial_value="0" name="medium_vertices" value="0"/> + <text initial_value="低" name="low_label" value="低"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="從檔案載入"/> + <item name="Generate" value="產生"/> + <item name="Use LoD above" value="以上使用低階細節"/> + </combo_box> + <button label="ç€è¦½â€¦" name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="三角形上é™"/> + <item name="Error Threshold" value="錯誤門檻"/> + </combo_box> + <text initial_value="0" name="low_triangles" value="0"/> + <text initial_value="0" name="low_vertices" value="0"/> + <text initial_value="最低" name="lowest_label" value="最低"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="從檔案載入"/> + <item name="Generate" value="產生"/> + <item name="Use LoD above" value="以上使用低階細節"/> + </combo_box> + <button label="ç€è¦½â€¦" name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="三角形上é™"/> + <item name="Error Threshold" value="錯誤門檻"/> + </combo_box> + <text initial_value="0" name="lowest_triangles" value="0"/> + <text initial_value="0" name="lowest_vertices" value="0"/> + <check_box label="產生法線" name="gen_normals"/> + <text initial_value="皺褶角度:" name="crease_label" value="皺褶角度:"/> + <spinner name="crease_angle" value="75"/> + </panel> + <panel label="物ç†" name="physics_panel"> + <panel name="physics geometry"> + <text name="first_step_name"> + æ¥é©Ÿ 1:細節層次 + </text> + <combo_box name="physics_lod_combo" tool_tip="物ç†å½¢ç‹€æ‰€æŽ¡ç”¨çš„細節層次"> + <combo_item name="choose_one"> + 鏿“‡ä¸€é …… + </combo_item> + <combo_item name="physics_high"> + 高 + </combo_item> + <combo_item name="physics_medium"> + ä¸ + </combo_item> + <combo_item name="physics_low"> + 低 + </combo_item> + <combo_item name="physics_lowest"> + 最低 + </combo_item> + <combo_item name="load_from_file"> + 來自檔案 + </combo_item> + </combo_box> + <button label="ç€è¦½â€¦" name="physics_browse"/> + </panel> + <panel name="physics analysis"> + <text name="method_label"> + æ¥é©Ÿ 2ï¼šåˆ†æž + </text> + <text name="analysis_method_label"> + 方法: + </text> + <text name="quality_label"> + å“質: + </text> + <text name="smooth_method_label"> + 平滑: + </text> + <check_box label="關閉洞å£" name="Close Holes (Slow)"/> + <button label="分æž" name="Decompose"/> + <button label="å–æ¶ˆ" name="decompose_cancel"/> + </panel> + <panel name="physics simplification"> + <text name="second_step_label"> + æ¥é©Ÿ 3:簡化 + </text> + <text name="simp_method_header"> + 方法: + </text> + <text name="pass_method_header"> + 階段數: + </text> + <text name="Detail Scale label"> + 細節比例: + </text> + <text name="Retain%_label"> + ä¿ç•™ï¼š + </text> + <combo_box name="Combine Quality" value="1"/> + <button label="簡化" name="Simplify"/> + <button label="å–æ¶ˆ" name="simplify_cancel"/> + </panel> + <panel name="physics info"> + <text name="results_text"> + çµæžœï¼š + </text> + <text name="physics_triangles"> + 三角形:[TRIANGLES], + </text> + <text name="physics_points"> + é ‚é»žï¼š[POINTS], + </text> + <text name="physics_hulls"> + 殼é¢ï¼š[HULLS] + </text> + </panel> + </panel> + <panel label="上傳é¸é …" name="modifiers_panel"> + <text name="scale_label"> + 比例(1 = 原比例): + </text> + <spinner name="import_scale" value="1.0"/> + <text name="dimensions_label"> + è¦æ ¼ï¼š + </text> + <text name="import_dimensions"> + [X] X [Y] X [Z] + </text> + <check_box label="åŒ…å«æè³ª" name="upload_textures"/> + <text name="include_label"> + 僅é™åŒ–身模型: + </text> + <check_box label="包å«è¡¨çš®é‡é‡" name="upload_skin"/> + <check_box label="åŒ…å«æŽ¥é»žä½ç½®" name="upload_joints"/> + <text name="pelvis_offset_label"> + Z åè·ï¼ˆå‡é«˜æˆ–é™ä½ŽåŒ–身): + </text> + <spinner name="pelvis_offset" value="0.0"/> + </panel> + </tab_container> + <panel name="weights_and_warning_panel"> + <button label="計算é‡é‡å’Œè²»ç”¨" name="calculate_btn" tool_tip="計算é‡é‡å’Œè²»ç”¨"/> + <button label="å–æ¶ˆ" name="cancel_btn"/> + <button label="上傳" name="ok_btn" tool_tip="上傳至模擬器"/> + <button label="清除è¨å®šä¸¦é‡è¨å½¢å¼" name="reset_btn"/> + <text name="upload_fee"> + 上傳費用:L$ [FEE] + </text> + <text name="prim_weight"> + åœŸåœ°è¡æ“Šé‡ï¼š[EQ] + </text> + <text name="download_weight"> + 下載:[ST] + </text> + <text name="physics_weight"> + 物ç†ï¼š[PH] + </text> + <text name="server_weight"> + 伺æœå™¨ï¼š[SIM] + </text> + <text name="warning_title"> + 附註: + </text> + <text name="warning_message"> + ä½ ç„¡æ¬Šä¸Šå‚³ç¶²é¢æ¨¡åž‹ã€‚ [[VURL] çžè§£å¦‚何]通éŽèªè‰ã€‚ + </text> + <text name="status"> + [STATUS] + </text> + </panel> + </panel> + <text name="lod_label"> + é 覽: + </text> + <panel name="right_panel"> + <combo_box name="preview_lod_combo" tool_tip="è¦åœ¨å‘ˆåƒé 覽ä¸å¯Ÿçœ‹çš„細節層次"> + <combo_item name="high"> + 高 + </combo_item> + <combo_item name="medium"> + ä¸ + </combo_item> + <combo_item name="low"> + 低 + </combo_item> + <combo_item name="lowest"> + 最低 + </combo_item> + </combo_box> + <text name="label_display"> + 顯示… + </text> + <check_box label="邊" name="show_edges"/> + <check_box label="物ç†" name="show_physics"/> + <check_box label="æè³ª" name="show_textures"/> + <check_box label="表皮é‡é‡" name="show_skin_weight"/> + <check_box label="接點" name="show_joint_positions"/> + <text name="physics_explode_label"> + é 覽伸展: + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_moveview.xml b/indra/newview/skins/default/xui/zh/floater_moveview.xml index e1155bdf34..0b267e8fae 100644 --- a/indra/newview/skins/default/xui/zh/floater_moveview.xml +++ b/indra/newview/skins/default/xui/zh/floater_moveview.xml @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="move_floater"> +<floater name="move_floater" title="行走 / è·‘æ¥ / 飛行"> <string name="walk_forward_tooltip"> - Walk Forward (press Up Arrow or W) + å‘å‰èµ°ï¼ˆæŒ‰ä¸‹å‘上ç®é 或 W éµï¼‰ </string> <string name="walk_back_tooltip"> - Walk Backwards (press Down Arrow or S) + 倒退行走(按下å‘下ç®é 或 S éµï¼‰ </string> <string name="walk_left_tooltip"> - Walk left (press Shift + Left Arrow or A) + å‘左走(按下 Shift åŠ å·¦æ–¹å‘鵿ˆ–按 A éµï¼‰ </string> <string name="walk_right_tooltip"> - Walk right (press Shift + Right Arrow or D) + å‘å³èµ°ï¼ˆæŒ‰ä¸‹ Shift åŠ å³æ–¹å‘鵿ˆ–按 D éµï¼‰ </string> <string name="run_forward_tooltip"> - Run Forward (press Up Arrow or W) + å‘å‰è·‘(按下å‘上ç®é 或 W éµï¼‰ </string> <string name="run_back_tooltip"> - Run Backwards (press Down Arrow or S) + 倒退跑æ¥ï¼ˆæŒ‰ä¸‹å‘下ç®é 或 S éµï¼‰ </string> <string name="run_left_tooltip"> - Run left (press Shift + Left Arrow or A) + å‘左跑(按下 Shift + 左方å‘鵿ˆ–按 A éµï¼‰ </string> <string name="run_right_tooltip"> - Run right (press Shift + Right Arrow or D) + å‘å³è·‘(按下 Shift + 峿–¹å‘鵿ˆ–按 D éµï¼‰ </string> <string name="fly_forward_tooltip"> å‘å‰é£›ï¼ˆæŒ‰ä¸‹å‘上ç®é 或 W éµï¼‰ @@ -65,7 +65,7 @@ <joystick_turn name="forward btn" tool_tip="å‘å‰èµ°ï¼ˆæŒ‰å‘上方å‘鵿ˆ–按 W éµï¼‰"/> <joystick_turn name="backward btn" tool_tip="å‘後退(按å‘下方å‘鵿ˆ–按 S éµï¼‰"/> <button name="move up btn" tool_tip="å‘上飛(按下 E éµï¼‰"/> - <button name="move down btn" tool_tip="å‘下飛(按下 C 建)"/> + <button name="move down btn" tool_tip="å‘下飛(按下 C éµï¼‰"/> </panel> <panel name="panel_modes"> <button label="" name="mode_walk_btn" tool_tip="行走模å¼"/> diff --git a/indra/newview/skins/default/xui/zh/floater_mute_object.xml b/indra/newview/skins/default/xui/zh/floater_mute_object.xml index 606e061395..64998d3e28 100644 --- a/indra/newview/skins/default/xui/zh/floater_mute_object.xml +++ b/indra/newview/skins/default/xui/zh/floater_mute_object.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="block by name" title="ä¾å稱å°éŽ–ç‰©ä»¶"> <text name="message"> - Block an object: + å°éŽ–ä¸€å€‹ç‰©ä»¶ï¼š </text> <line_editor name="object_name"> 物件å稱 </line_editor> <text name="note"> - * Only blocks object text, not sounds + * åªå°éŽ–ç‰©ä»¶æ–‡å—,ä¸å°éŽ–è²éŸ³ </text> <button label="確定" name="OK"/> <button label="å–æ¶ˆ" name="Cancel"/> diff --git a/indra/newview/skins/default/xui/zh/floater_my_appearance.xml b/indra/newview/skins/default/xui/zh/floater_my_appearance.xml new file mode 100644 index 0000000000..217ea5d1f9 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_my_appearance.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_my_appearance" title="外觀"> + <panel label="編輯外觀" name="main_panel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_my_inventory.xml b/indra/newview/skins/default/xui/zh/floater_my_inventory.xml new file mode 100644 index 0000000000..187597f4eb --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_my_inventory.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_my_inventory" title="æ”¶ç´å€"/> diff --git a/indra/newview/skins/default/xui/zh/floater_nearby_chat.xml b/indra/newview/skins/default/xui/zh/floater_nearby_chat.xml deleted file mode 100644 index 38a5dab523..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="附近的èŠå¤©"> - <check_box label="Translate chat" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_object_weights.xml b/indra/newview/skins/default/xui/zh/floater_object_weights.xml new file mode 100644 index 0000000000..d2875b24b4 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_object_weights.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="object_weights" title="進階"> + <floater.string name="nothing_selected" value="--"/> + <text name="selected_text" value="å·²é¸"/> + <text name="objects" value="--"/> + <text name="objects_label" value="物件"/> + <text name="prims" value="--"/> + <text name="prims_label" value="幾何元件"/> + <text name="weights_of_selected_text" value="所é¸ç‰©é‡é‡"/> + <text name="download" value="--"/> + <text name="download_label" value="下載"/> + <text name="physics" value="--"/> + <text name="physics_label" value="物ç†"/> + <text name="server" value="--"/> + <text name="server_label" value="伺æœå™¨"/> + <text name="display" value="--"/> + <text name="display_label" value="顯示"/> + <text name="land_impacts_text" value="åœŸåœ°è¡æ“Šé‡"/> + <text name="selected" value="--"/> + <text name="selected_label" value="鏿“‡"/> + <text name="rezzed_on_land" value="--"/> + <text name="rezzed_on_land_label" value="已產生到土地上"/> + <text name="remaining_capacity" value="--"/> + <text name="remaining_capacity_label" value="剩餘容ç´é‡"/> + <text name="total_capacity" value="--"/> + <text name="total_capacity_label" value="總容ç´é‡"/> + <text name="help_SLURL" value="[secondlife:///app/help/object_weights 這是什麼?]"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_openobject.xml b/indra/newview/skins/default/xui/zh/floater_openobject.xml index 61ac3cb1fc..ce6869487a 100644 --- a/indra/newview/skins/default/xui/zh/floater_openobject.xml +++ b/indra/newview/skins/default/xui/zh/floater_openobject.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="objectcontents" title="物件內容"> <text name="object_name"> - [DESC]: + [DESC]: </text> <button label="覆製到收ç´å€" label_selected="覆製到收ç´å€" name="copy_to_inventory_button"/> <button label="覆製且穿上" label_selected="覆製且穿上" name="copy_and_wear_button"/> diff --git a/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml index a557e1c2e3..9e786edcdd 100644 --- a/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml +++ b/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml @@ -3,9 +3,9 @@ <button label="儲å˜" label_selected="儲å˜" name="Save"/> <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="Cancel"/> <text name="Save item as:"> - å„²å˜æˆ‘æ£åœ¨ç©¿çš„ç‚ºæ–°è£æ‰®ï¼š + å„²å˜æˆ‘ç¾åœ¨çš„ç©¿è‘—ç‚ºæ–°è£æ‰®ï¼š </text> <line_editor name="name ed"> - [DESC] (新) + [DESC](新) </line_editor> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml b/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml index 63da47f4de..e57374f4d7 100644 --- a/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml +++ b/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="outgoing call" title="CALLING"> +<floater name="outgoing call" title="打電話"> <floater.string name="lifetime"> 5 </floater.string> @@ -10,31 +10,31 @@ 匿å </floater.string> <floater.string name="VoiceInviteP2P"> - 通話ä¸ã€‚ + 來電ä¸ã€‚ </floater.string> <floater.string name="VoiceInviteAdHoc"> - has joined a Voice Chat call with a conference chat. + å·²åŠ å…¥å¤šæ–¹èªžéŸ³é€šè©±ã€‚ </floater.string> <text name="connecting"> - Connecting to [CALLEE_NAME] + æ£åœ¨é€£é€š [CALLEE_NAME] </text> <text name="calling"> - Calling [CALLEE_NAME] + æ£åœ¨æ‰“給 [CALLEE_NAME] </text> <text name="noanswer"> - 無應ç”,請ç¨å€™å†è©¦ã€‚ + 無人接è½ã€‚ è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚ </text> <text name="nearby"> - You have been disconnected from [VOICE_CHANNEL_NAME]. [RECONNECT_NEARBY] + ä½ çš„ [VOICE_CHANNEL_NAME] é€šè©±å·²ç¶“ä¸æ–·ã€‚ [RECONNECT_NEARBY] </text> <text name="nearby_P2P_by_other"> - Your call has ended. [RECONNECT_NEARBY] + ä½ çš„é€šè©±å·²ç¶“çµæŸã€‚ [RECONNECT_NEARBY] </text> <text name="nearby_P2P_by_agent"> - You have ended the call. [RECONNECT_NEARBY] + ä½ å·²ç¶“çµæŸé€šè©±ã€‚ [RECONNECT_NEARBY] </text> <text name="leaving"> - Leaving [CURRENT_CHAT]. + 離開 [CURRENT_CHAT]。 </text> <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/zh/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..e6971d111f --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="尋徑角色"> + <floater.string name="messaging_get_inprogress"> + 尋徑角色查詢ä¸â€¦ + </floater.string> + <floater.string name="messaging_get_error"> + 查詢尋徑角色時出錯。 + </floater.string> + <floater.string name="messaging_complete_none_found"> + 沒有尋徑角色。 + </floater.string> + <floater.string name="messaging_complete_available"> + 從 [NUM_TOTAL] 個角色ä¸é¸å–了 [NUM_SELECTED] 個。 + </floater.string> + <floater.string name="messaging_not_enabled"> + 這地å€ä¸¦æœªå•Ÿç”¨å°‹å¾‘。 + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] 微秒 + </floater.string> + <floater.string name="character_owner_loading"> + [Loading] + </floater.string> + <floater.string name="character_owner_unknown"> + [Unknown] + </floater.string> + <floater.string name="character_owner_group"> + [group] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="å稱" name="name"/> + <scroll_list.columns label="æè¿°" name="description"/> + <scroll_list.columns label="所有人" name="owner"/> + <scroll_list.columns label="ä¸å¤®è™•ç†å™¨" name="cpu_time"/> + <scroll_list.columns label="高度" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + 角色: + </text> + <button label="刷新清單" name="refresh_objects_list"/> + <button label="å…¨é¸" name="select_all_objects"/> + <button label="全都ä¸é¸" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + 所é¸è§’色所採動作: + </text> + <check_box label="顯示指標" name="show_beacon"/> + <check_box label="顯示物ç†å›Š" name="show_physics_capsule"/> + <button label="å–å¾—" name="take_objects"/> + <button label="æ‹¿å–副本" name="take_copy_objects"/> + <button label="çž¬é–“å‚³é€æˆ‘到那裡" name="teleport_me_to_object" tool_tip="åªåœ¨é¸å–了一個角色時啟用。"/> + <button label="退回" name="return_objects"/> + <button label="刪除" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/zh/floater_pathfinding_console.xml new file mode 100644 index 0000000000..be009b54d8 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="尋徑察看 / 測試"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + 找ä¸åˆ°å°‹å¾‘函å¼åº«å¯¦ä½œã€‚ + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + 這地å€ä¸¦æœªå•Ÿç”¨å°‹å¾‘。 + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + ç‰å¾…地å€å®Œæˆè¼‰å…¥ã€‚ + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + æ£åœ¨æª¢æŸ¥å°Žèˆªç¶²é¢ç‹€æ…‹ã€‚ + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + æ£åœ¨ä¸‹è¼‰å°Žèˆªç¶²é¢ã€‚ + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + 伺æœå™¨ä¸Šçš„導航網é¢å·²è®Šæ›´ã€‚ æ£åœ¨ä¸‹è¼‰æœ€æ–°çš„導航網é¢ã€‚ + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + 最新的導航網é¢ä¸‹è¼‰å®Œæˆã€‚ + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + 無法完æˆå°Žèˆªç¶²é¢ä¸‹è¼‰ã€‚ + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + å°Žèˆªç¶²é¢æœ‰è®Šæ›´å¾…å˜ã€‚ + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + æ£åœ¨å»ºæ§‹å°Žèˆªç¶²é¢ã€‚ + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + æŸäº›å°Žèˆªç¶²é¢åœ°å€æœ‰è®Šæ›´å¾…å˜ã€‚ + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + æ£åœ¨å»ºæ§‹æŸäº›å°Žèˆªç¶²é¢åœ°å€ã€‚ + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + æŸäº›å°Žèˆªç¶²é¢åœ°å€æœ‰è®Šæ›´å¾…å˜ï¼Œå…¶ä»–çš„æ£åœ¨å»ºæ§‹ä¸ã€‚ + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + 導航網é¢å·²å…¨é¢æ›´æ–°ã€‚ + </floater.string> + <floater.string name="pathing_library_not_implemented"> + 找ä¸åˆ°å°‹å¾‘函å¼åº«å¯¦ä½œã€‚ + </floater.string> + <floater.string name="pathing_region_not_enabled"> + 這地å€ä¸¦æœªå•Ÿç”¨å°‹å¾‘。 + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + è«‹é¸æ“‡èµ·é»žå’Œçµ‚點。 + </floater.string> + <floater.string name="pathing_choose_start_point"> + è«‹é¸æ“‡èµ·é»žã€‚ + </floater.string> + <floater.string name="pathing_choose_end_point"> + è«‹é¸æ“‡çµ‚點。 + </floater.string> + <floater.string name="pathing_path_valid"> + 路徑以橘色顯示。 + </floater.string> + <floater.string name="pathing_path_invalid"> + 在所é¸çš„點之間找ä¸åˆ°è·¯å¾‘。 + </floater.string> + <floater.string name="pathing_error"> + 產生路徑時出錯。 + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="視角" name="view_panel"> + <text name="show_label"> + 顯示: + </text> + <check_box label="世界" name="show_world"/> + <check_box label="僅é™å¯ç§»å‹•çš„" name="show_world_movables_only"/> + <check_box label="導航網é¢" name="show_navmesh"/> + <text name="show_walkability_label"> + 顯示å¯è¡Œèµ°åœ°åœ–: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="ä¸é¡¯ç¤º" name="show_heatmap_mode_none"/> + <combo_box.item label="類型 A 角色" name="show_heatmap_mode_a"/> + <combo_box.item label="類型 B 角色" name="show_heatmap_mode_b"/> + <combo_box.item label="類型 C 角色" name="show_heatmap_mode_c"/> + <combo_box.item label="類型 D 角色" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="å¯è¡Œèµ°çš„" name="show_walkables"/> + <check_box label="實質體ç©" name="show_material_volumes"/> + <check_box label="éœæ…‹éšœç¤™" name="show_static_obstacles"/> + <check_box label="排除體ç©" name="show_exclusion_volumes"/> + <check_box label="æ°´å¹³é¢" name="show_water_plane"/> + <check_box label="å…· X å…‰é€è¦–力" name="show_xray"/> + </panel> + <panel label="測試路徑" name="test_panel"> + <text name="ctrl_click_label"> + æŒ‰ä½ Ctrl 並點按å³å¯é¸æ“‡èµ·é»žã€‚ + </text> + <text name="shift_click_label"> + æŒ‰ä½ Shift 並點按å³å¯é¸æ“‡çµ‚點。 + </text> + <text name="character_width_label"> + 角色寬度 + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + 公尺 + </text> + <text name="character_type_label"> + 角色類型 + </text> + <combo_box name="path_character_type"> + <combo_box.item label="ç„¡" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="清除路徑" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/zh/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..22e5d2e846 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="尋徑è¯çµé›†"> + <floater.string name="messaging_get_inprogress"> + 尋徑è¯çµé›†æŸ¥è©¢ä¸â€¦ + </floater.string> + <floater.string name="messaging_get_error"> + 查詢尋徑è¯çµé›†æ™‚出錯。 + </floater.string> + <floater.string name="messaging_set_inprogress"> + æ£åœ¨ä¿®æ”¹æ‰€é¸å°‹å¾‘è¯çµé›†â€¦ + </floater.string> + <floater.string name="messaging_set_error"> + 修改所é¸å°‹å¾‘è¯çµé›†æ™‚出錯。 + </floater.string> + <floater.string name="messaging_complete_none_found"> + 沒有尋徑è¯çµé›†ã€‚ + </floater.string> + <floater.string name="messaging_complete_available"> + 從 [NUM_TOTAL] 個è¯çµé›†ä¸é¸å–了 [NUM_SELECTED] 個。 + </floater.string> + <floater.string name="messaging_not_enabled"> + 這地å€ä¸¦æœªå•Ÿç”¨å°‹å¾‘。 + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terrain] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Loading] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Unknown] + </floater.string> + <floater.string name="linkset_owner_group"> + [group] + </floater.string> + <floater.string name="linkset_is_scripted"> + 是 + </floater.string> + <floater.string name="linkset_is_not_scripted"> + å¦ + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + 未知 + </floater.string> + <floater.string name="linkset_use_walkable"> + å¯è¡Œèµ°çš„ + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + éœæ…‹éšœç¤™ + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + å¯ç§»å‹•障礙 + </floater.string> + <floater.string name="linkset_use_material_volume"> + å¯¦è³ªé«”ç© + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + æŽ’é™¤é«”ç© + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + å¯ç§»å‹•幻影 + </floater.string> + <floater.string name="linkset_is_terrain"> + [unmodifiable] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [restricted] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [concave] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [restricted,concave] + </floater.string> + <floater.string name="linkset_choose_use"> + 鏿“‡è¯çµé›†çš„使用… + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="按è¯çµé›†çš„ä½¿ç”¨ä¾†éŽæ¿¾â€¦" name="filter_by_linkset_use_none"/> + <combo_box.item label="å¯è¡Œèµ°çš„" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="éœæ…‹éšœç¤™" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="å¯ç§»å‹•障礙" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="實質體ç©" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="排除體ç©" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="å¯ç§»å‹•幻影" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="套用" name="apply_filters"/> + <button label="清除" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="åç¨±ï¼ˆæ ¹å¹¾ä½•å…ƒä»¶ï¼‰" name="name"/> + <scroll_list.columns label="æè¿°ï¼ˆæ ¹å¹¾ä½•元件)" name="description"/> + <scroll_list.columns label="所有人" name="owner"/> + <scroll_list.columns label="有腳本" name="scripted"/> + <scroll_list.columns label="è¡æ“Š" name="land_impact"/> + <scroll_list.columns label="è·é›¢" name="dist_from_you"/> + <scroll_list.columns label="è¯çµé›†çš„使用" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + è¯çµé›†ï¼š + </text> + <button label="刷新清單" name="refresh_objects_list"/> + <button label="å…¨é¸" name="select_all_objects"/> + <button label="全都ä¸é¸" name="select_none_objects"/> + </panel> + <panel> + <check_box label="顯示指標" name="show_beacon"/> + <button label="å–å¾—" name="take_objects"/> + <button label="æ‹¿å–副本" name="take_copy_objects"/> + <button label="çž¬é–“å‚³é€æˆ‘到那裡" name="teleport_me_to_object"/> + <button label="退回" name="return_objects"/> + <button label="刪除" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + å¯è¡Œèµ°æ€§ï¼š + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="A 類型角色的å¯è¡Œèµ°æ€§ã€‚以類人類為範例角色類型。"/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="B 類型角色的å¯è¡Œèµ°æ€§ã€‚以ç¸é¡žç‚ºç¯„例角色類型。"/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="C 類型角色的å¯è¡Œèµ°æ€§ã€‚以機械類為範例角色類型。"/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="D 類型角色的å¯è¡Œèµ°æ€§ã€‚以其他種類為範例角色類型。"/> + <button label="套用變更" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (類人類) + </text> + <text name="suggested_use_b_label"> + (ç¸é¡žï¼‰ + </text> + <text name="suggested_use_c_label"> + (機械類) + </text> + <text name="suggested_use_d_label"> + (其他) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_pay.xml b/indra/newview/skins/default/xui/zh/floater_pay.xml index 0a823cd82e..69427605a4 100644 --- a/indra/newview/skins/default/xui/zh/floater_pay.xml +++ b/indra/newview/skins/default/xui/zh/floater_pay.xml @@ -7,14 +7,14 @@ 支付居民 </string> <text name="payee_name"> - Test Name That Is Extremely Long To Check Clipping + 測試一個長度éžå¸¸éžå¸¸éžå¸¸é•·çš„å稱,檢查是å¦è¢«åˆ‡æ–· </text> <button label="L$1" label_selected="L$1" name="fastpay 1"/> <button label="L$5" label_selected="L$5" name="fastpay 5"/> <button label="L$10" label_selected="L$10" name="fastpay 10"/> <button label="L$20" label_selected="L$20" name="fastpay 20"/> <text name="amount text"> - æˆ–ï¼Œé¸æ“‡ä¸€å€‹é‡‘é¡ï¼š + æˆ–é¸æ“‡ä¸€å€‹é‡‘é¡ï¼š </text> <button label="支付" label_selected="支付" name="pay btn"/> <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="cancel btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_pay_object.xml b/indra/newview/skins/default/xui/zh/floater_pay_object.xml index 39259524d7..7d20b44bc6 100644 --- a/indra/newview/skins/default/xui/zh/floater_pay_object.xml +++ b/indra/newview/skins/default/xui/zh/floater_pay_object.xml @@ -14,14 +14,14 @@ </text> <icon name="icon_object" tool_tip="物件"/> <text name="object_name_text"> - My awesome object with a really damn long name + 這是我å稱很長很長很長很長的一個很棒的物件 </text> <button label="L$1" label_selected="L$1" name="fastpay 1"/> <button label="L$5" label_selected="L$5" name="fastpay 5"/> <button label="L$10" label_selected="L$10" name="fastpay 10"/> <button label="L$20" label_selected="L$20" name="fastpay 20"/> <text name="amount text"> - æˆ–è€…ï¼Œé¸æ“‡ä¸€å€‹é‡‘é¡ï¼š + æˆ–é¸æ“‡ä¸€å€‹é‡‘é¡ï¼š </text> <button label="支付" label_selected="支付" name="pay btn"/> <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="cancel btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_people.xml b/indra/newview/skins/default/xui/zh/floater_people.xml new file mode 100644 index 0000000000..f629f2f184 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_people.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_people" title="人群"> + <panel_container name="main_panel"> + <panel label="群組檔案" name="panel_group_info_sidetray"/> + <panel label="被å°éŽ–çš„å±…æ°‘èˆ‡ç‰©ä»¶" name="panel_block_list_sidetray"/> + </panel_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml b/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml index 498848ee56..b38db59ff3 100644 --- a/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml +++ b/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml @@ -4,10 +4,10 @@ <check_box label="與群組分享" name="share_with_group"/> <check_box label="å…許任何人覆製" name="everyone_copy"/> <text name="NextOwnerLabel"> - ä¸‹ä¸€å€‹æ“æœ‰è€…å¯ä»¥ï¼š + 下一個所有人å¯ä»¥ï¼š </text> <check_box label="修改" name="next_owner_modify"/> - <check_box label="覆製" name="next_owner_copy"/> + <check_box label="æšåº¨" name="next_owner_copy"/> <check_box initial_value="true" label="轉售 / é€äºº" name="next_owner_transfer"/> </panel> <button label="確定" label_selected="確定" name="ok"/> diff --git a/indra/newview/skins/default/xui/zh/floater_picks.xml b/indra/newview/skins/default/xui/zh/floater_picks.xml new file mode 100644 index 0000000000..a8bfcd99e3 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_picks.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_picks" title="ç²¾é¸åœ°é»ž"/> diff --git a/indra/newview/skins/default/xui/zh/floater_places.xml b/indra/newview/skins/default/xui/zh/floater_places.xml new file mode 100644 index 0000000000..f6ef1e2141 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_places.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_places" title="地點"> + <panel label="地點" name="main_panel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_post_process.xml b/indra/newview/skins/default/xui/zh/floater_post_process.xml index 0972c6dfa6..2908f7c1d0 100644 --- a/indra/newview/skins/default/xui/zh/floater_post_process.xml +++ b/indra/newview/skins/default/xui/zh/floater_post_process.xml @@ -1,50 +1,50 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Post-Process Floater" title="POST-PROCESS SETTINGS"> +<floater name="Post-Process Floater" title="後處ç†è¨å®šï¼š"> <tab_container name="Post-Process Tabs"> - <panel label="Color Filter" name="wmiColorFilterPanel"> - <check_box label="Enable" name="wmiColorFilterToggle"/> + <panel label="é¡è‰²éŽæ¿¾" name="wmiColorFilterPanel"> + <check_box label="啟用" name="wmiColorFilterToggle"/> <text name="wmiColorFilterBrightnessText"> - Brightness + 亮度 </text> <text name="wmiColorFilterSaturationText"> - Saturation + 飽和度 </text> <text name="wmiColorFilterContrastText"> - Contrast + å°æ¯” </text> <text name="wmiColorFilterBaseText"> - Contrast Base Color + å°æ¯”基本色 </text> <slider label="R" name="wmiColorFilterBaseR"/> <slider label="G" name="wmiColorFilterBaseG"/> <slider label="B" name="wmiColorFilterBaseB"/> <slider label="I" name="wmiColorFilterBaseI"/> </panel> - <panel label="Night Vision" name="wmiNightVisionPanel"> - <check_box label="Enable" name="wmiNightVisionToggle"/> + <panel label="夜視" name="wmiNightVisionPanel"> + <check_box label="啟用" name="wmiNightVisionToggle"/> <text name="wmiNightVisionBrightMultText"> - Light Amplification Multiple + å…‰æ”¾å¤§å€æ•¸ </text> <text name="wmiNightVisionNoiseSizeText"> - Noise Size + å™ªéŸ³è¦æ¨¡ </text> <text name="wmiNightVisionNoiseStrengthText"> - Noise Strength + 噪音強度 </text> </panel> - <panel label="Bloom" name="wmiBloomPanel"> - <check_box label="Enable" name="wmiBloomToggle"/> + <panel label="開花" name="wmiBloomPanel"> + <check_box label="啟用" name="wmiBloomToggle"/> <text name="wmiBloomExtractText"> - Luminosity Extraction + 光度èƒå– </text> <text name="wmiBloomSizeText"> - Bloom Size + é–‹èŠ±å¤§å° </text> <text name="wmiBloomStrengthText"> - Bloom Strength + 開花強度 </text> </panel> - <panel label="Extras" name="Extras"> + <panel label="å…¶ä»–" name="Extras"> <button label="LoadEffect" label_selected="LoadEffect" name="PPLoadEffect"/> <button label="SaveEffect" label_selected="SaveEffect" name="PPSaveEffect"/> <line_editor label="效果å稱" name="PPEffectNameEditor"/> diff --git a/indra/newview/skins/default/xui/zh/floater_preferences.xml b/indra/newview/skins/default/xui/zh/floater_preferences.xml index 396a4893e0..b0a27e8c1f 100644 --- a/indra/newview/skins/default/xui/zh/floater_preferences.xml +++ b/indra/newview/skins/default/xui/zh/floater_preferences.xml @@ -3,11 +3,11 @@ <button label="確定" label_selected="確定" name="OK"/> <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="Cancel"/> <tab_container name="pref core"> - <panel label="一般" name="general"/> - <panel label="圖形" name="display"/> + <panel label="基本è¨å®š" name="general"/> + <panel label="顯åƒ" name="display"/> <panel label="è²éŸ³èˆ‡åª’é«”" name="audio"/> <panel label="èŠå¤©" name="chat"/> - <panel label="移動與視角" name="move"/> + <panel label="移動/視野" name="move"/> <panel label="通知" name="msgs"/> <panel label="é¡è‰²" name="colors"/> <panel label="éš±ç§" name="im"/> diff --git a/indra/newview/skins/default/xui/zh/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/zh/floater_preferences_proxy.xml new file mode 100644 index 0000000000..f91d5c5cdb --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_preferences_proxy.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Proxy Settings Floater" title="代ç†ä¼ºæœå™¨è¨å®š"> + <check_box initial_value="false" label="使用 HTTP 代ç†ä¼ºæœå™¨ç€è¦½ç¶²é " name="web_proxy_enabled"/> + <text name="http_proxy_label"> + HTTP 代ç†ä¼ºæœå™¨ï¼š + </text> + <line_editor name="web_proxy_editor" tool_tip="ä½ å¸Œæœ›ä½¿ç”¨çš„ HTTP 代ç†ä¼ºæœå™¨çš„ DNS å稱或 IP ä½å€ã€‚"/> + <spinner label="åŸ è™Ÿï¼š" name="web_proxy_port" tool_tip="ä½ å¸Œæœ›ä½¿ç”¨çš„ HTTP 代ç†ä¼ºæœå™¨çš„åŸ è™Ÿã€‚"/> + <check_box label="使用 SOCKS 5 代ç†ä¼ºæœå™¨è™•ç† UDP 資料æµ" name="socks_proxy_enabled"/> + <text name="socks5_proxy_label"> + SOCKS 5 代ç†ä¼ºæœå™¨ï¼š + </text> + <line_editor name="socks_proxy_editor" tool_tip="ä½ å¸Œæœ›ä½¿ç”¨çš„ SOCKS 5 代ç†ä¼ºæœå™¨çš„ DNS å稱或 IP ä½å€ã€‚"/> + <spinner label="åŸ è™Ÿï¼š" name="socks_proxy_port" tool_tip="ä½ å¸Œæœ›ä½¿ç”¨çš„ SOCKS 5 代ç†ä¼ºæœå™¨çš„åŸ è™Ÿã€‚"/> + <text name="socks_auth_label"> + SOCKS é‘’èªï¼š + </text> + <radio_group name="socks5_auth_type"> + <radio_item label="ç„¡é‘’èª" name="Socks5NoAuth" tool_tip="Socks5 代ç†ä¼ºæœå™¨ç„¡éœ€é‘’èªã€‚" value="ç„¡"/> + <radio_item label="使用者å稱 / 密碼" name="Socks5UserPass" tool_tip="Socks5 代ç†ä¼ºæœå™¨éœ€è¦é€éŽä½¿ç”¨è€…å稱 / 密碼鑒èªã€‚" value="UserPass"/> + </radio_group> + <text name="socks5_username_label"> + 使用者å稱: + </text> + <text name="socks5_password_label"> + 密碼: + </text> + <line_editor name="socks5_username" tool_tip="ä½ çš„ SOCKS 5 伺æœå™¨é‘’èªæ‰€ç”¨çš„使用者å稱"/> + <line_editor name="socks5_password" tool_tip="ä½ çš„ SOCKS 5 伺æœå™¨é‘’èªæ‰€ç”¨çš„密碼"/> + <text name="other_proxy_label"> + å…¶ä»– HTTP 資料æµä»£ç†ä¼ºæœå™¨ï¼š + </text> + <radio_group name="other_http_proxy_type"> + <radio_item label="ä¸ä½¿ç”¨ä»£ç†ä¼ºæœå™¨" name="OtherNoProxy" tool_tip="éžç¶²é çš„ HTTP 資料æµä¸æœƒè¢«å°Žå‘任何代ç†ä¼ºæœå™¨ã€‚" value="ç„¡"/> + <radio_item label="使用 HTTP 代ç†ä¼ºæœå™¨" name="OtherHTTPProxy" tool_tip="éžç¶²é çš„ HTTP 資料æµå°‡å°Žå‘所è¨çš„ç¶²é 代ç†ä¼ºæœå™¨ã€‚" value="ç¶²é "/> + <radio_item label="使用 SOCKS 5 代ç†ä¼ºæœå™¨" name="OtherSocksProxy" tool_tip="éžç¶²é çš„ HTTP 資料æµå°‡å°Žå‘所è¨çš„ Socks 5 代ç†ä¼ºæœå™¨ã€‚" value="網路套接"/> + </radio_group> + <button label="確定" label_selected="確定" name="OK"/> + <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="Cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_animation.xml b/indra/newview/skins/default/xui/zh/floater_preview_animation.xml index c435ddc0bd..b94d67b7ef 100644 --- a/indra/newview/skins/default/xui/zh/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/zh/floater_preview_animation.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="preview_anim"> <floater.string name="Title"> - 動作: [NAME] + 動作:[NAME] </floater.string> <text name="desc txt"> æè¿°ï¼š </text> - <button label="æ’æ”¾æ–¼è™›æ“¬ä¸–界" label_selected="åœæ¢" name="Anim play btn" tool_tip="Play this animation so that others can see it"/> - <button label="æ’æ”¾æ–¼æœ¬åœ°" label_selected="åœæ¢" name="Anim audition btn" tool_tip="Play this animation so that only you can see it"/> + <button label="åœ¨è™›æ“¬ä¸–ç•Œæ’æ”¾" label_selected="åœæ¢" name="Inworld" tool_tip="æ’æ”¾æ¤å‹•作讓他人看見"/> + <button label="åœ¨æœ¬åœ°æ’æ”¾" label_selected="åœæ¢" name="Locally" tool_tip="æ’æ”¾æ¤å‹•作,åªçµ¦è‡ªå·±çœ‹"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml b/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml index ad49370423..be75038a09 100644 --- a/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml +++ b/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="gesture_preview"> <floater.string name="step_anim"> - Animation to play: + è¦æ’放的動作: </floater.string> <floater.string name="step_sound"> - Sound to play: + è¦æ’放的è²éŸ³ï¼š </floater.string> <floater.string name="step_chat"> - Chat to say: + è¦èªªå‡ºçš„èŠå¤©æ–‡å—: </floater.string> <floater.string name="step_wait"> - Wait: + ç‰å¾…: </floater.string> <floater.string name="stop_txt"> åœæ¢ @@ -22,20 +22,20 @@ -- ç„¡ -- </floater.string> <floater.string name="Title"> - Gesture: [NAME] + 姿勢:[NAME] </floater.string> <text name="desc_label"> æè¿°ï¼š </text> <text name="trigger_label"> - Trigger: + 觸發: </text> - <text name="replace_text" tool_tip="Replace the trigger word(s) with these words. For example, trigger 'hello' replace with 'howdy' will turn the chat 'I wanted to say hello' into 'I wanted to say howdy' as well as playing the gesture!"> - Replace with: + <text name="replace_text" tool_tip="用這些å—眼å–代觸發å—眼。 例如,觸發 'hello' å–代為 'howdy' 後,將使得èŠå¤©æ–‡å—「我想說 helloã€è®Šæˆã€Œæˆ‘想說 howdyã€ï¼ŒåŒæ™‚é‚„æœƒæ’æ”¾è©²å§¿å‹¢ï¼"> + å–代æˆï¼š </text> - <line_editor name="replace_editor" tool_tip="Replace the trigger word(s) with these words. For example, trigger 'hello' replace with 'howdy' will turn the chat 'I wanted to say hello' into 'I wanted to say howdy' as well as playing the gesture"/> + <line_editor name="replace_editor" tool_tip="用這些å—眼å–代觸發å—眼。 例如,觸發 'hello' å–代為 'howdy' 後,將使得èŠå¤©æ–‡å—「我想說 helloã€è®Šæˆã€Œæˆ‘想說 howdyã€ï¼ŒåŒæ™‚é‚„æœƒæ’æ”¾è©²å§¿å‹¢ã€‚"/> <text name="key_label"> - Shortcut Key: + å¿«æ·éµï¼š </text> <combo_box label="ç„¡" name="modifier_combo"/> <combo_box label="ç„¡" name="key_combo"/> @@ -50,10 +50,10 @@ </scroll_list> <button label="æ·»åŠ >>" name="add_btn"/> <text name="steps_label"> - Steps: + æ¥é©Ÿï¼š </text> - <button label="Up" name="up_btn"/> - <button label="Down" name="down_btn"/> + <button label="上移éµ" name="up_btn"/> + <button label="下移éµ" name="down_btn"/> <button label="移除" name="delete_btn"/> <text name="options_text"> (é¸é …) @@ -63,11 +63,11 @@ <radio_item label="åœæ¢" name="stop"/> </radio_group> <check_box label="ç›´åˆ°å‹•ä½œçµæŸã€‚" name="wait_anim_check"/> - <check_box label="time in seconds:" name="wait_time_check"/> + <check_box label="時間(秒):" name="wait_time_check"/> <text name="help_label"> - All steps happen simultaneously, unless you add wait steps. + 所有æ¥é©Ÿéƒ½æœƒåŒæ™‚進行,除éžä½ åŠ å…¥ã€Œç‰å¾…ã€æ¥é©Ÿã€‚ </text> - <check_box label="Active" name="active_check" tool_tip="Active gestures can be triggered by chatting their trigger phrases or pressing their hot keys. Gestures usually become inactive when there is a key binding conflict."/> + <check_box label="å¯ç”¨" name="active_check" tool_tip="ä½ å¯ä»¥åœ¨èŠå¤©ä¸éµå…¥ã€Œè§¸ç™¼å—眼ã€ï¼Œæˆ–按æŸå§¿å‹¢çš„熱éµä¾†å•Ÿå‹•å¯ç”¨çš„姿勢。 熱éµçš„ç¶å®šè‹¥æœ‰è¡çªï¼Œé€šå¸¸æœƒä½¿å§¿å‹¢è®Šæˆä¸å¯ç”¨ã€‚"/> <button label="é 覽" name="preview_btn"/> <button label="儲å˜" name="save_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_sound.xml b/indra/newview/skins/default/xui/zh/floater_preview_sound.xml index 46844349de..d04428a36d 100644 --- a/indra/newview/skins/default/xui/zh/floater_preview_sound.xml +++ b/indra/newview/skins/default/xui/zh/floater_preview_sound.xml @@ -6,6 +6,6 @@ <text name="desc txt"> æè¿°ï¼š </text> - <button label="æ’æ”¾æ–¼è™›æ“¬ä¸–界" label_selected="æ’æ”¾æ–¼è™›æ“¬ä¸–界" name="Sound play btn" tool_tip="Play this sound so that others can hear it"/> - <button label="æ’æ”¾æ–¼æœ¬åœ°" label_selected="æ’æ”¾æ–¼æœ¬åœ°" name="Sound audition btn" tool_tip="Play this sound so that only you can hear it"/> + <button label="åœ¨è™›æ“¬ä¸–ç•Œæ’æ”¾" label_selected="åœ¨è™›æ“¬ä¸–ç•Œæ’æ”¾" name="Sound play btn" tool_tip="æ’æ”¾æ¤è²éŸ³è®“他人è½è¦‹"/> + <button label="åœ¨æœ¬åœ°æ’æ”¾" label_selected="åœ¨æœ¬åœ°æ’æ”¾" name="Sound audition btn" tool_tip="æ’æ”¾æ¤è²éŸ³ï¼Œåªè®“自己è½è¦‹"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml index 02e26cea24..c56b1c2987 100644 --- a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml @@ -10,31 +10,31 @@ æè¿°ï¼š </text> <text name="dimensions"> - [WIDTH]px x [HEIGHT]px + [WIDTH] åƒç´ X [HEIGHT] åƒç´ </text> <text name="aspect_ratio"> - Preview aspect ratio + é 覽長寬比 </text> - <combo_box name="combo_aspect_ratio" tool_tip="Preview at a fixed aspect ratio"> + <combo_box name="combo_aspect_ratio" tool_tip="以固定長寬比é 覽"> <combo_item name="Unconstrained"> - Unconstrained + ä¸å—é™ </combo_item> - <combo_item name="1:1" tool_tip="Group insignia or Real World profile"> + <combo_item name="1:1" tool_tip="ç¾¤çµ„å¾½ç« æˆ–ç¾å¯¦ä¸–ç•Œå°æª”案"> 1:1 </combo_item> <combo_item name="4:3" tool_tip="[SECOND_LIFE] 檔案"> 4:3 </combo_item> - <combo_item name="10:7" tool_tip="Classifieds and search listings, landmarks"> + <combo_item name="10:7" tool_tip="個人廣告和æœç´¢åˆŠç™»å»£å‘Šã€åœ°æ¨™"> 10:7 </combo_item> - <combo_item name="3:2" tool_tip="關於土地"> + <combo_item name="3:2" tool_tip="土地資料"> 3:2 </combo_item> <combo_item name="16:10"> 16:10 </combo_item> - <combo_item name="16:9" tool_tip="Profile picks"> + <combo_item name="16:9" tool_tip="個人檔案精é¸"> 16:9 </combo_item> <combo_item name="2:1"> @@ -42,6 +42,6 @@ </combo_item> </combo_box> <button label="確定" name="Keep"/> - <button label="Discard" name="Discard"/> - <button label="å¦å˜" name="save_tex_btn"/> + <button label="丟棄" name="Discard"/> + <button label="å¦å˜ç‚º" name="save_tex_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_price_for_listing.xml b/indra/newview/skins/default/xui/zh/floater_price_for_listing.xml new file mode 100644 index 0000000000..078b490655 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_price_for_listing.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="price_for_listing" title="刊登個人廣告"> + <text name="explanation_text"> + ä½ çš„å€‹äººå»£å‘Šå°‡å¾žåˆŠç™»æ—¥èµ·é€£çºŒåˆŠè¼‰ä¸€æ˜ŸæœŸã€‚ + +ä½ çš„å»£å‘Šåœ¨å€‹äººå»£å‘Šæ¬„å‡ºç¾çš„ä½ç½®ï¼Œå–æ±ºæ–¼ä½ æ±ºå®šä»˜è²»çš„å¤šå¯¡ã€‚ + +付費越多的個人廣告會出ç¾åœ¨æŽ¥è¿‘最上方ä½ç½®ï¼Œä¸¦é¡¯ç¤ºæ–¼æœå°‹çµæžœçš„å‰é¢ã€‚ + </text> + <text name="price_text"> + 刊登費: + </text> + <text name="price_symbol"> + L$ + </text> + <button label="確定" name="set_price_btn"/> + <button label="å–æ¶ˆ" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_publish_classified.xml b/indra/newview/skins/default/xui/zh/floater_publish_classified.xml index 5f0ffea182..b810af0145 100644 --- a/indra/newview/skins/default/xui/zh/floater_publish_classified.xml +++ b/indra/newview/skins/default/xui/zh/floater_publish_classified.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="publish_classified" title="Publishing Classified"> +<floater name="publish_classified" title="刊登個人廣告"> <text name="explanation_text"> - Your classified ad will run for one week from the date it is published. + ä½ çš„å€‹äººå»£å‘Šå°‡å¾žåˆŠç™»æ—¥èµ·é€£çºŒåˆŠè¼‰ä¸€æ˜ŸæœŸã€‚ -Remember, Classified fees are non-refundable. +請注æ„,個人廣告刊登費æ•ä¸é€€é‚„。 </text> - <spinner label="åƒ¹æ ¼ï¼š L$" name="price_for_listing" tool_tip="刊登費用。" value="50"/> + <spinner label="åƒ¹æ ¼ï¼š L$" name="price_for_listing" tool_tip="刊登費。" value="50"/> <button label="發布" name="publish_btn"/> <button label="å–æ¶ˆ" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_report_abuse.xml b/indra/newview/skins/default/xui/zh/floater_report_abuse.xml index 436f5cdcc5..8dbc216ab5 100644 --- a/indra/newview/skins/default/xui/zh/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/zh/floater_report_abuse.xml @@ -14,66 +14,66 @@ 地å€å稱 </text> <text name="pos_title"> - Position: + ä½ç½®ï¼š </text> <text name="pos_field"> {128.1, 128.1, 15.4} </text> <text name="select_object_label"> - Click the button, then the abusive object: + 點按按鈕,å†é»žæŒ‰é•紀的物件: </text> - <button name="pick_btn" tool_tip="Object Picker - Identify an object as the subject of this report"/> + <button name="pick_btn" tool_tip="物件é¸å–器 - æŒ‡æ˜Žæœ¬èˆ‰å ±çš„å°è±¡ç‰©ä»¶"/> <text name="object_name_label"> 物件: </text> <text name="owner_name_label"> - æ“æœ‰è€…: + 所有人: </text> - <combo_box name="category_combo" tool_tip="Category -- select the category that best describes this report"> + <combo_box name="category_combo" tool_tip="類別 -- 鏿“‡æœ€ç¬¦åˆæ¤æ¬¡èˆ‰å ±å…§å®¹çš„類別"> <combo_box.item label="鏿“‡é¡žåˆ¥" name="Select_category"/> - <combo_box.item label="Age > Age play" name="Age__Age_play"/> - <combo_box.item label="Age > Adult Resident on Teen Second Life" name="Age__Adult_resident_on_Teen_Second_Life"/> - <combo_box.item label="Age > Underage Resident outside of Teen Second Life" name="Age__Underage_resident_outside_of_Teen_Second_Life"/> - <combo_box.item label="Assault > Combat sandbox / unsafe area" name="Assault__Combat_sandbox___unsafe_area"/> - <combo_box.item label="Assault > Safe area" name="Assault__Safe_area"/> - <combo_box.item label="Assault > Weapons testing sandbox" name="Assault__Weapons_testing_sandbox"/> - <combo_box.item label="Commerce > Failure to deliver product or service" name="Commerce__Failure_to_deliver_product_or_service"/> - <combo_box.item label="Disclosure > Real world information" name="Disclosure__Real_world_information"/> - <combo_box.item label="Disclosure > Remotely monitoring chat" name="Disclosure__Remotely_monitoring chat"/> - <combo_box.item label="Disclosure > Second Life information/chat/IMs" name="Disclosure__Second_Life_information_chat_IMs"/> - <combo_box.item label="Disturbing the peace > Unfair use of region resources" name="Disturbing_the_peace__Unfair_use_of_region_resources"/> - <combo_box.item label="Disturbing the peace > Excessive scripted objects" name="Disturbing_the_peace__Excessive_scripted_objects"/> - <combo_box.item label="Disturbing the peace > Object littering" name="Disturbing_the_peace__Object_littering"/> - <combo_box.item label="Disturbing the peace > Repetitive spam" name="Disturbing_the_peace__Repetitive_spam"/> - <combo_box.item label="Disturbing the peace > Unwanted advert spam" name="Disturbing_the_peace__Unwanted_advert_spam"/> - <combo_box.item label="Fraud > L$" name="Fraud__L$"/> - <combo_box.item label="Fraud > Land" name="Fraud__Land"/> - <combo_box.item label="Fraud > Pyramid scheme or chain letter" name="Fraud__Pyramid_scheme_or_chain_letter"/> - <combo_box.item label="Fraud > US$" name="Fraud__US$"/> - <combo_box.item label="Harassment > Advert farms / visual spam" name="Harassment__Advert_farms___visual_spam"/> - <combo_box.item label="Harassment > Defaming individuals or groups" name="Harassment__Defaming_individuals_or_groups"/> - <combo_box.item label="Harassment > Impeding movement" name="Harassment__Impeding_movement"/> - <combo_box.item label="Harassment > Sexual harassment" name="Harassment__Sexual_harassment"/> - <combo_box.item label="Harassment > Solicting/inciting others to violate ToS" name="Harassment__Solicting_inciting_others_to_violate_ToS"/> - <combo_box.item label="Harassment > Verbal abuse" name="Harassment__Verbal_abuse"/> - <combo_box.item label="Indecency > Broadly offensive content or conduct" name="Indecency__Broadly_offensive_content_or_conduct"/> - <combo_box.item label="Indecency > Inappropriate avatar name" name="Indecency__Inappropriate_avatar_name"/> - <combo_box.item label="Indecency > Inappropriate content or conduct in a PG region" name="Indecency__Mature_content_in_PG_region"/> - <combo_box.item label="Indecency > Inappropriate content or conduct in a Moderate region" name="Indecency__Inappropriate_content_in_Mature_region"/> - <combo_box.item label="Intellectual property infringement > Content Removal" name="Intellectual_property_infringement_Content_Removal"/> - <combo_box.item label="Intellectual property infringement > CopyBot or Permissions Exploit" name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit"/> - <combo_box.item label="Intolerance" name="Intolerance"/> - <combo_box.item label="Land > Abuse of sandbox resources" name="Land__Abuse_of_sandbox_resources"/> - <combo_box.item label="Land > Encroachment > Objects/textures" name="Land__Encroachment__Objects_textures"/> - <combo_box.item label="Land > Encroachment > Particles" name="Land__Encroachment__Particles"/> - <combo_box.item label="Land > Encroachment > Trees/plants" name="Land__Encroachment__Trees_plants"/> - <combo_box.item label="Wagering/gambling" name="Wagering_gambling"/> + <combo_box.item label="年齡 > 年齡 play" name="Age__Age_play"/> + <combo_box.item label="年齡 > æˆäººå±…民出ç¾åœ¨é’少年專用第二人生" name="Age__Adult_resident_on_Teen_Second_Life"/> + <combo_box.item label="年齡 > 未æˆå¹´å±…民出ç¾åœ¨é’å°‘å¹´å°ˆç”¨ç¬¬äºŒäººç”Ÿä»¥å¤–å ´æ‰€" name="Age__Underage_resident_outside_of_Teen_Second_Life"/> + <combo_box.item label="攻擊 > 戰鬥沙盤 / ä¸å®‰å…¨å€åŸŸ" name="Assault__Combat_sandbox___unsafe_area"/> + <combo_box.item label="攻擊 > 安全å€åŸŸ" name="Assault__Safe_area"/> + <combo_box.item label="攻擊 > 測試æ¦å™¨çš„æ²™ç›¤" name="Assault__Weapons_testing_sandbox"/> + <combo_box.item label="å•†æ¥ > 未é€äº¤ç”¢å“或履行æœå‹™" name="Commerce__Failure_to_deliver_product_or_service"/> + <combo_box.item label="æéœ² > 真實世界資訊" name="Disclosure__Real_world_information"/> + <combo_box.item label="æéœ² > é 端監控èŠå¤©å…§å®¹" name="Disclosure__Remotely_monitoring chat"/> + <combo_box.item label="æéœ² > 第二人生資訊 / èŠå¤©å…§å®¹ / 峿™‚訊æ¯" name="Disclosure__Second_Life_information_chat_IMs"/> + <combo_box.item label="擾亂 > ä¸å…¬å¹³ä½¿ç”¨åœ°å€è³‡æº" name="Disturbing_the_peace__Unfair_use_of_region_resources"/> + <combo_box.item label="擾亂 > éŽåº¦ä½¿ç”¨å¸¶è…³æœ¬çš„物件" name="Disturbing_the_peace__Excessive_scripted_objects"/> + <combo_box.item label="擾亂 > ä»»æ„æ£„置物件" name="Disturbing_the_peace__Object_littering"/> + <combo_box.item label="擾亂 > 一å†ç™¼å‡ºåžƒåœ¾è¨Šæ¯" name="Disturbing_the_peace__Repetitive_spam"/> + <combo_box.item label="擾亂 > ä¸å—æ¡è¿Žçš„垃圾廣告" name="Disturbing_the_peace__Unwanted_advert_spam"/> + <combo_box.item label="è©æ¬º > L$" name="Fraud__L$"/> + <combo_box.item label="è©æ¬º > 土地" name="Fraud__Land"/> + <combo_box.item label="è©æ¬º > å±¤å£“å¼æŽ¨éŠ·æˆ–é€£ç’°ä¿¡" name="Fraud__Pyramid_scheme_or_chain_letter"/> + <combo_box.item label="è©æ¬º > 美金" name="Fraud__US$"/> + <combo_box.item label="騷擾 > å»£å‘Šè¾²å ´ / 視覺轟炸" name="Harassment__Advert_farms___visual_spam"/> + <combo_box.item label="騷擾 > 詆è個人或群組" name="Harassment__Defaming_individuals_or_groups"/> + <combo_box.item label="騷擾 > 阻撓移動" name="Harassment__Impeding_movement"/> + <combo_box.item label="騷擾 > 性騷擾" name="Harassment__Sexual_harassment"/> + <combo_box.item label="騷擾 > é¼“å¹ / 教唆他人é•åæœå‹™æ¢æ¬¾" name="Harassment__Solicting_inciting_others_to_violate_ToS"/> + <combo_box.item label="騷擾 > 言語暴力" name="Harassment__Verbal_abuse"/> + <combo_box.item label="ä¸é›… > 令大多人ä¸å¿«çš„內容或行為" name="Indecency__Broadly_offensive_content_or_conduct"/> + <combo_box.item label="ä¸é›… > 冒犯人的化身å稱" name="Indecency__Inappropriate_avatar_name"/> + <combo_box.item label="ä¸é›… > 在一般普級地å€å‡ºç¾å†’犯人的內容或行為" name="Indecency__Mature_content_in_PG_region"/> + <combo_box.item label="ä¸é›… > 在é©åº¦æˆäººåœ°å€å‡ºç¾å†’犯人的內容或行為" name="Indecency__Inappropriate_content_in_Mature_region"/> + <combo_box.item label="侵犯智產權 > 移除內容" name="Intellectual_property_infringement_Content_Removal"/> + <combo_box.item label="侵犯智產權 > 複製機器程å¼ç¢¼ CopyBot 或濫用權é™" name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit"/> + <combo_box.item label="ä¸å®¹ç•°å·±" name="Intolerance"/> + <combo_box.item label="土地 > ä¸ç•¶ä½¿ç”¨æ²™ç›¤è³‡æº" name="Land__Abuse_of_sandbox_resources"/> + <combo_box.item label="土地 > 侵佔 > 物件 / æè³ª" name="Land__Encroachment__Objects_textures"/> + <combo_box.item label="土地 > 侵佔 > ç²’å" name="Land__Encroachment__Particles"/> + <combo_box.item label="土地 > 侵佔 > 樹種 / æ¤ç‰©" name="Land__Encroachment__Trees_plants"/> + <combo_box.item label="下注 / è³åš" name="Wagering_gambling"/> <combo_box.item label="å…¶ä»–" name="Other"/> </combo_box> <text name="abuser_name_title"> 濫用者å稱: </text> - <button label="鏿“‡" name="select_abuser" tool_tip="Select the name of the abuser from a list"/> + <button label="鏿“‡" name="select_abuser" tool_tip="從清單ä¸é¸æ“‡é•紀者姓å"/> <text name="abuser_name_title2"> 濫用ä½ç½®ï¼š </text> @@ -84,11 +84,11 @@ 細節: </text> <text name="bug_aviso"> - Please be as specific as possible + 請盡å¯èƒ½æä¾›å…·é«”細節 </text> <text name="incomplete_title"> - * Incomplete reports won't be investigated + * ä¸å®Œæ•´çš„èˆ‰å ±å…§å®¹æ¦‚ä¸å—ç†èª¿æŸ¥ </text> - <button label="èˆ‰å ±æ¿«ç”¨" label_selected="èˆ‰å ±æ¿«ç”¨" name="send_btn"/> + <button label="é•è¦èˆ‰å ±" label_selected="é•è¦èˆ‰å ±" name="send_btn"/> <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_script_preview.xml b/indra/newview/skins/default/xui/zh/floater_script_preview.xml index c3d05402c0..a6c6c76181 100644 --- a/indra/newview/skins/default/xui/zh/floater_script_preview.xml +++ b/indra/newview/skins/default/xui/zh/floater_script_preview.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="preview lsl text" title="SCRIPT: ROTATION SCRIPT"> +<floater name="preview lsl text" title="腳本:旋轉腳本"> <floater.string name="Title"> 腳本:[NAME] </floater.string> diff --git a/indra/newview/skins/default/xui/zh/floater_script_queue.xml b/indra/newview/skins/default/xui/zh/floater_script_queue.xml index ff02946d86..7c253aa74c 100644 --- a/indra/newview/skins/default/xui/zh/floater_script_queue.xml +++ b/indra/newview/skins/default/xui/zh/floater_script_queue.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="queue" title="RESET PROGRESS"> +<floater name="queue" title="é‡è¨é€²åº¦"> <floater.string name="Starting"> - Starting [START] of [COUNT] items. + æ£åœ¨å•Ÿå‹• [START] é …ï¼Œå…± [COUNT] é …ã€‚ </floater.string> <floater.string name="Done"> - Done. + 完æˆã€‚ </floater.string> <floater.string name="Resetting"> é‡è¨ä¸ diff --git a/indra/newview/skins/default/xui/zh/floater_script_search.xml b/indra/newview/skins/default/xui/zh/floater_script_search.xml index 400ef4be81..11c23d933f 100644 --- a/indra/newview/skins/default/xui/zh/floater_script_search.xml +++ b/indra/newview/skins/default/xui/zh/floater_script_search.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="script search" title="腳本æœå°‹"> - <check_box label="Case Insensitive" name="case_text"/> + <check_box label="大å°å¯«è¦–為相åŒ" name="case_text"/> <button label="æœå°‹" label_selected="æœå°‹" name="search_btn"/> <button label="å–代" label_selected="å–代" name="replace_btn"/> <button label="全部å–代" label_selected="全部å–代" name="replace_all_btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_search.xml b/indra/newview/skins/default/xui/zh/floater_search.xml index bb693b7a70..3e85a529ae 100644 --- a/indra/newview/skins/default/xui/zh/floater_search.xml +++ b/indra/newview/skins/default/xui/zh/floater_search.xml @@ -1,15 +1,15 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_search" title="尋找"> +<floater name="floater_search" title=""> <floater.string name="loading_text"> 載入ä¸... </floater.string> <floater.string name="done_text"> - Done + å®Œæˆ </floater.string> <layout_stack name="stack1"> <layout_panel name="browser_layout"> <text name="refresh_search"> - Redo search to reflect current God level + 以目å‰å…·å‚™çš„ç¥žéšŽç´šå†æœå°‹ä¸€æ¬¡ </text> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/zh/floater_select_key.xml b/indra/newview/skins/default/xui/zh/floater_select_key.xml index c1661635f1..231eb48b04 100644 --- a/indra/newview/skins/default/xui/zh/floater_select_key.xml +++ b/indra/newview/skins/default/xui/zh/floater_select_key.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="modal container"> <text name="Save item as:"> - Press a key to set your Speak button trigger. + 按任一éµè¨å®šã€Œèªªè©±ã€æŒ‰éˆ•的觸發。 </text> <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_sell_land.xml b/indra/newview/skins/default/xui/zh/floater_sell_land.xml index 19580c99a1..9030f7eb63 100644 --- a/indra/newview/skins/default/xui/zh/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/zh/floater_sell_land.xml @@ -12,16 +12,16 @@ 尺寸: </text> <text name="info_size"> - [AREA] m² + [AREA] 平方公尺 </text> <text name="info_action"> - To sell this parcel: + 出售地段: </text> <text name="price_label"> - 1. Set a price: + 1. è¨‚å®šåƒ¹æ ¼ï¼š </text> <text name="price_text"> - Choose an appropriate price. + 鏿“‡é©åˆçš„åƒ¹æ ¼ã€‚ </text> <text name="price_ld"> L$ @@ -30,13 +30,13 @@ 0 </line_editor> <text name="price_per_m"> - (L$[PER_METER] per m²) + (æ¯å¹³æ–¹å…¬å°º L$[PER_METER]) </text> <text name="sell_to_label"> - 2. Sell the land to: + 2. 出售土地給: </text> <text name="sell_to_text"> - Choose whether to sell to anyone or a particular buyer. + 鏿“‡è¦è³£çµ¦ä»»ä½•人或賣給特定買主。 </text> <combo_box name="sell_to"> <combo_box.item label="- 鏿“‡ä¸€å€‹ -" name="--selectone--"/> @@ -45,20 +45,20 @@ </combo_box> <button label="鏿“‡" name="sell_to_select_agent"/> <text name="sell_objects_label"> - 3. Sell the objects with the land? + 3. 物件連åŒåœŸåœ°ä¸€èµ·å”®å‡ºï¼Ÿ </text> <text name="sell_objects_text"> - Land owner's transferable objects on parcel will change ownership. + 地段上地主的å¯è½‰è®“物件將éŽç¹¼æ‰€æœ‰æ¬Šã€‚ </text> <radio_group name="sell_objects"> - <radio_item label="No, keep ownership of objects" name="no"/> - <radio_item label="Yes, sell objects with land" name="yes"/> + <radio_item label="ä¸ï¼Œæˆ‘è¦ä¿ç•™ç‰©ä»¶æ‰€æœ‰æ¬Š" name="no"/> + <radio_item label="好,物件連åŒåœŸåœ°ä¸€èµ·å”®å‡º" name="yes"/> </radio_group> <button label="顯示物件" name="show_objects"/> <text name="nag_message_label"> - REMEMBER: All sales are final. + 請記ä½ï¼šå”®å¾Œä¸€æ¦‚ä¸é€€ã€‚ </text> - <button label="Set Land For Sale" name="sell_btn"/> + <button label="è¨å®šåœŸåœ°å¾…å”®" name="sell_btn"/> <button label="å–æ¶ˆ" name="cancel_btn"/> </panel> </scroll_container> diff --git a/indra/newview/skins/default/xui/zh/floater_snapshot.xml b/indra/newview/skins/default/xui/zh/floater_snapshot.xml index 9edc19969f..e86e20829f 100644 --- a/indra/newview/skins/default/xui/zh/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/zh/floater_snapshot.xml @@ -1,74 +1,65 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Snapshot" title="SNAPSHOT PREVIEW"> +<floater name="Snapshot" title="å¿«ç…§é 覽"> <floater.string name="unknown"> 未知 </floater.string> - <radio_group label="Snapshot type" name="snapshot_type_radio"> - <radio_item label="Email" name="postcard"/> - <radio_item label="我的收ç´å€ï¼ˆL$[AMOUNT])" name="texture"/> - <radio_item label="Save to my computer" 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] KB </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"> - Format - </text> - <combo_box label="Resolution" 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="Resolution" name="texture_size_combo"> - <combo_box.item label="ç›®å‰è¦–窗" name="CurrentWindow"/> - <combo_box.item label="Small (128x128)" name="Small(128x128)"/> - <combo_box.item label="Medium (256x256)" name="Medium(256x256)"/> - <combo_box.item label="Large (512x512)" name="Large(512x512)"/> - <combo_box.item label="自訂" name="Custom"/> - </combo_box> - <combo_box label="Resolution" 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="Custom" 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="Width" name="snapshot_width"/> - <spinner label="Height" name="snapshot_height"/> - <check_box label="Constrain proportions" name="keep_aspect_check"/> - <slider label="圖åƒå“質" name="image_quality_slider"/> - <text name="layer_type_label"> - Capture: - </text> - <combo_box label="圖層" name="layer_types"> - <combo_box.item label="Colors" name="Colors"/> - <combo_box.item label="Depth" name="Depth"/> - </combo_box> - <check_box label="Interface" name="ui_check"/> - <check_box label="HUDs" name="hud_check"/> - <check_box label="Keep open after saving" name="keep_open_check"/> - <check_box label="å‡çµæ¡†æž¶ï¼ˆå…¨èž¢å¹•)" name="freeze_frame_check"/> - <check_box label="Auto-refresh" 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/zh/floater_sound_devices.xml b/indra/newview/skins/default/xui/zh/floater_sound_devices.xml new file mode 100644 index 0000000000..0374c74f8f --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_sound_devices.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_sound_devices" title="è²éŸ³è£ç½®"> + <text name="voice_label"> + 語音èŠå¤© + </text> + <check_box label="已啟用" name="enable_voice"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_spellcheck.xml b/indra/newview/skins/default/xui/zh/floater_spellcheck.xml new file mode 100644 index 0000000000..f5a6665844 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="æ‹¼å—æª¢æŸ¥è¨å®š"> + <check_box label="å•Ÿç”¨æ‹¼å—æª¢æŸ¥" name="spellcheck_enable"/> + <text name="spellcheck_main"> + 主è¦å—典: + </text> + <text label="記錄:" name="spellcheck_additional"> + é™„åŠ å—典: + </text> + <text name="spellcheck_available"> + å¯ç”¨çš„ + </text> + <text name="spellcheck_active"> + å¯ç”¨ + </text> + <button label="移除" name="spellcheck_remove_btn"/> + <button label="匯入…" name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/zh/floater_spellcheck_import.xml new file mode 100644 index 0000000000..6094a3bbce --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="匯入å—å…¸"> + <button label="ç€è¦½" label_selected="ç€è¦½" name="dictionary_path_browse"/> + <button label="匯入" name="ok_btn"/> + <button label="å–æ¶ˆ" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_stats.xml b/indra/newview/skins/default/xui/zh/floater_stats.xml index 582572d0e2..4af5684ec1 100644 --- a/indra/newview/skins/default/xui/zh/floater_stats.xml +++ b/indra/newview/skins/default/xui/zh/floater_stats.xml @@ -3,67 +3,84 @@ <scroll_container name="statistics_scroll"> <container_view name="statistics_view"> <stat_view label="基本" name="basic"> - <stat_bar label="FPS" name="fps"/> + <stat_bar label="æ¯ç§’幀數" name="fps"/> <stat_bar label="é »å¯¬" name="bandwidth"/> <stat_bar label="å°åŒ…æå¤±" name="packet_loss"/> - <stat_bar label="Ping Sim" name="ping"/> + <stat_bar label="æŽ¢è©¢æ¨¡æ“¬å™¨æœ‰ç„¡åæ‡‰" name="ping"/> </stat_view> <stat_view label="進階" name="advanced"> - <stat_view label="Render" name="render"> - <stat_bar label="KTris Drawn" name="ktrisframe"/> - <stat_bar label="KTris Drawn" name="ktrissec"/> + <stat_view label="呈åƒ" name="render"> + <stat_bar label="繪出的 KTris(æ¯å¹€ï¼‰" name="ktrisframe"/> + <stat_bar label="繪出的 KTris(æ¯ç§’)" name="ktrissec"/> <stat_bar label="物件總計" name="objs"/> <stat_bar label="新物件" name="newobjs"/> + <stat_bar label="物件快å–讀å–率" name="object_cache_hits"/> </stat_view> <stat_view label="æè³ª" name="texture"> + <stat_bar label="å¿«å–讀å–率" name="texture_cache_hits"/> + <stat_bar label="å¿«å–讀å–å»¶é²" name="texture_cache_read_latency"/> <stat_bar label="計數" name="numimagesstat"/> - <stat_bar label="Raw Count" name="numrawimagesstat"/> - <stat_bar label="GL Mem" name="gltexmemstat"/> - <stat_bar label="Formatted Mem" name="formattedmemstat"/> - <stat_bar label="Raw Mem" name="rawmemstat"/> - <stat_bar label="Bound Mem" name="glboundmemstat"/> + <stat_bar label="原始計數" name="numrawimagesstat"/> + <stat_bar label="GL 記憶" name="gltexmemstat"/> + <stat_bar label="æ ¼å¼åŒ–記憶" name="formattedmemstat"/> + <stat_bar label="原始記憶" name="rawmemstat"/> + <stat_bar label="界é™è¨˜æ†¶" name="glboundmemstat"/> </stat_view> <stat_view label="網路" name="network"> - <stat_bar label="Packets In" name="packetsinstat"/> - <stat_bar label="Packets Out" name="packetsoutstat"/> + <stat_bar label="進入å°åŒ…" name="packetsinstat"/> + <stat_bar label="出去å°åŒ…" name="packetsoutstat"/> <stat_bar label="物件" name="objectkbitstat"/> <stat_bar label="æè³ª" name="texturekbitstat"/> <stat_bar label="資產" name="assetkbitstat"/> - <stat_bar label="Layers" name="layerskbitstat"/> - <stat_bar label="Actual In" name="actualinkbitstat"/> - <stat_bar label="Actual Out" name="actualoutkbitstat"/> - <stat_bar label="VFS Pending Ops" name="vfspendingoperations"/> + <stat_bar label="層次" name="layerskbitstat"/> + <stat_bar label="實入" name="actualinkbitstat"/> + <stat_bar label="實出" name="actualoutkbitstat"/> + <stat_bar label="VFS 待行作æ¥" name="vfspendingoperations"/> </stat_view> </stat_view> <stat_view label="模擬器" name="sim"> - <stat_bar label="Time Dilation" name="simtimedilation"/> - <stat_bar label="Sim FPS" name="simfps"/> - <stat_bar label="Physics FPS" name="simphysicsfps"/> - <stat_view label="Physics Details" name="physicsdetail"> - <stat_bar label="Pinned Objects" name="physicspinnedtasks"/> - <stat_bar label="Low LOD Objects" name="physicslodtasks"/> + <stat_bar label="時間膨脹" name="simtimedilation"/> + <stat_bar label="模擬器æ¯ç§’幀數" name="simfps"/> + <stat_bar label="物ç†å¼•擎æ¯ç§’幀數" name="simphysicsfps"/> + <stat_view label="物ç†ç´°ç¯€" name="physicsdetail"> + <stat_bar label="固ä½ç‰©ä»¶" name="physicspinnedtasks"/> + <stat_bar label="低細節層次物件" name="physicslodtasks"/> <stat_bar label="記憶體é…ç½®" name="physicsmemoryallocated"/> </stat_view> - <stat_bar label="Agent Updates/Sec" name="simagentups"/> - <stat_bar label="Main Agents" name="simmainagents"/> - <stat_bar label="Child Agents" name="simchildagents"/> + <stat_bar label="用戶更新 / ç§’" name="simagentups"/> + <stat_bar label="主è¦ç”¨æˆ¶" name="simmainagents"/> + <stat_bar label="兒童用戶" name="simchildagents"/> <stat_bar label="物件" name="simobjects"/> - <stat_bar label="Active Objects" name="simactiveobjects"/> - <stat_bar label="Active Scripts" name="simactivescripts"/> + <stat_bar label="使用ä¸ç‰©ä»¶" name="simactiveobjects"/> + <stat_bar label="使用ä¸è…³æœ¬" name="simactivescripts"/> + <stat_bar label="腳本執行" name="simpctscriptsrun"/> <stat_bar label="腳本事件" name="simscripteps"/> + <stat_view label="尋徑" name="simpathfinding"> + <stat_bar label="人工智慧æ¥é©Ÿæ™‚é–“" name="simsimaistepmsec"/> + <stat_bar label="已略éŽè¼ªå»“æ¥é©Ÿ" name="simsimskippedsilhouettesteps"/> + <stat_bar label="角色已更新" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_bar label="進入å°åŒ…" name="siminpps"/> <stat_bar label="出去å°åŒ…" name="simoutpps"/> <stat_bar label="擱置下載" name="simpendingdownloads"/> <stat_bar label="擱置上傳" name="simpendinguploads"/> - <stat_bar label="Total Unacked Bytes" name="simtotalunackedbytes"/> - <stat_view label="Time (ms)" name="simperf"> - <stat_bar label="Total Frame Time" name="simframemsec"/> - <stat_bar label="Net Time" name="simnetmsec"/> - <stat_bar label="Physics Time" name="simsimphysicsmsec"/> - <stat_bar label="Simulation Time" name="simsimothermsec"/> - <stat_bar label="Agent Time" name="simagentmsec"/> - <stat_bar label="Images Time" name="simimagesmsec"/> + <stat_bar label="未承èªçš„總ä½å…ƒçµ„數" name="simtotalunackedbytes"/> + <stat_view label="時間(毫秒)" name="simperf"> + <stat_bar label="總禎時間" name="simframemsec"/> + <stat_bar label="淨時間" name="simnetmsec"/> + <stat_bar label="ç‰©ç†æ™‚é–“" name="simsimphysicsmsec"/> + <stat_bar label="模擬時間" name="simsimothermsec"/> + <stat_bar label="用戶時間" name="simagentmsec"/> + <stat_bar label="åœ–åƒæ™‚é–“" name="simimagesmsec"/> <stat_bar label="腳本時間" name="simscriptmsec"/> + <stat_bar label="閒置時間" name="simsparemsec"/> + <stat_view label="時間細節(毫秒)" name="timedetails"> + <stat_bar label="ç‰©ç†æ¥é©Ÿ" name="simsimphysicsstepmsec"/> + <stat_bar label="更新物ç†å½¢ç‹€" name="simsimphysicsshapeupdatemsec"/> + <stat_bar label="物ç†ï¼ˆå…¶ä»–)" name="simsimphysicsothermsec"/> + <stat_bar label="ç¡çœ 時間" name="simsleepmsec"/> + <stat_bar label="Pump IO" name="simpumpiomsec"/> + </stat_view> </stat_view> </stat_view> </container_view> diff --git a/indra/newview/skins/default/xui/zh/floater_sys_well.xml b/indra/newview/skins/default/xui/zh/floater_sys_well.xml index fd27e944ac..ca0b7f146d 100644 --- a/indra/newview/skins/default/xui/zh/floater_sys_well.xml +++ b/indra/newview/skins/default/xui/zh/floater_sys_well.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="sys_well_window" title="通知"> <string name="title_im_well_window"> - CONVERSATIONS + 交談 </string> <string name="title_notification_well_window"> 通知 diff --git a/indra/newview/skins/default/xui/zh/floater_telehub.xml b/indra/newview/skins/default/xui/zh/floater_telehub.xml index b4c9f3ab29..ee21a78e90 100644 --- a/indra/newview/skins/default/xui/zh/floater_telehub.xml +++ b/indra/newview/skins/default/xui/zh/floater_telehub.xml @@ -1,29 +1,29 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <!-- Explicit left edge to avoid overlapping build tools --> -<floater name="telehub" title="TELEHUB"> +<floater name="telehub" title="瞬間傳é€ä¸å¿ƒ"> <text name="status_text_connected"> - Telehub connected to object [OBJECT] + 瞬間傳é€ä¸å¿ƒå·²é€£é€šç‰©ä»¶ [OBJECT] </text> <text name="status_text_not_connected"> - No telehub connected. + 無連通的瞬間傳é€ä¸å¿ƒã€‚ </text> <text name="help_text_connected"> - To remove, click Disconnect. + é»žæŒ‰ã€Œä¸æ–·ã€å³å¯ç§»é™¤ã€‚ </text> <text name="help_text_not_connected"> - Select object and click Connect Telehub. + 鏿“‡ç‰©ä»¶ï¼Œä¸¦é»žæŒ‰ã€Œé€£é€šçž¬é–“傳é€ä¸å¿ƒã€ã€‚ </text> - <button label="Connect Telehub" name="connect_btn"/> - <button label="Disconnect" name="disconnect_btn"/> + <button label="連通瞬間傳é€ä¸å¿ƒ" name="connect_btn"/> + <button label="䏿–·" name="disconnect_btn"/> <text name="spawn_points_text"> - Spawn Points (positions, not objects): + 產生點(ä½ç½®è€Œéžç‰©ä»¶ï¼‰ï¼š </text> - <button label="Add Spawn" name="add_spawn_point_btn"/> - <button label="Remove Spawn" name="remove_spawn_point_btn"/> + <button label="新增產生" name="add_spawn_point_btn"/> + <button label="移除產生" name="remove_spawn_point_btn"/> <text name="spawn_point_help"> - Select object and click "Add Spawn" to specify position. -You can then move or delete the object. -Positions are relative to the telehub center. -Select an item in list to highlight it inworld. + 鏿“‡ç‰©ä»¶ï¼Œä¸¦é»žæŒ‰ã€Œæ–°å¢žç”¢ç”Ÿã€ä¾†æŒ‡å®šä½ç½®ã€‚ +ä½ å¯ä»¥æŽ¥è‘—移動或刪除該物件。 +ä½ç½®æ˜¯èˆ‡çž¬é–“傳é€ä¸å¿ƒç›¸å°ã€‚ +從清單ä¸é¸å–ä¸€é …ï¼Œåœ¨è™›æ“¬ä¸–ç•Œä¸ä»¥é«˜äº®é¡¯ç¤ºã€‚ </text> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/zh/floater_test_layout_stacks.xml new file mode 100644 index 0000000000..68fcf3f7f7 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_test_layout_stacks.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="LAYOUTSTACK 測試"/> diff --git a/indra/newview/skins/default/xui/zh/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/zh/floater_test_text_vertical_aligment.xml new file mode 100644 index 0000000000..83b6df6fe5 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_test_text_vertical_aligment.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="測試浮動視窗"/> diff --git a/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml index 01586ac153..e909a67e2c 100644 --- a/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml @@ -1,23 +1,35 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="texture picker" title="PICK: TEXTURE"> +<floater name="texture picker" title="ç²¾é¸ï¼šæè³ª"> <floater.string name="choose_picture"> - 點擊以挑é¸åœ–åƒ + 點按以挑é¸åœ–片 </floater.string> <floater.string name="pick title"> - Pick: + ç²¾é¸åœ°é»žï¼š </floater.string> <text name="Multiple"> - Multiple textures + å¤šé‡æè³ª </text> + <radio_group name="mode_selection"> + <radio_item label="æ”¶ç´å€" name="inventory" value="0"/> + <radio_item label="本地" name="local" value="1"/> + </radio_group> <text name="unknown"> 尺寸:[DIMENSIONS] </text> <button label="é è¨" label_selected="é è¨" name="Default"/> + <button label="空白" label_selected="空白" name="Blank"/> <button label="ç„¡" label_selected="ç„¡" name="None"/> - <button label="Blank" label_selected="Blank" name="Blank"/> - <check_box initial_value="true" label="ç«‹å³å¥—用" name="apply_immediate_check"/> + <check_box initial_value="true" label="實時é 覽" name="apply_immediate_check"/> + <text name="preview_disabled" value="å·²åœç”¨é 覽"/> <filter_editor label="æè³ªéŽæ¿¾å™¨" name="inventory search editor"/> <check_box initial_value="false" label="顯示資料夾" name="show_folders_check"/> + <button label="æ·»åŠ " label_selected="æ·»åŠ " name="l_add_btn"/> + <button label="移除" label_selected="移除" name="l_rem_btn"/> + <button label="上傳" label_selected="上傳" name="l_upl_btn"/> + <scroll_list name="l_name_list"> + <column label="å稱" name="unit_name"/> + <column label="ID" name="unit_id_HIDDEN"/> + </scroll_list> <button label="確定" label_selected="確定" name="Select"/> <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/zh/floater_texture_fetch_debugger.xml new file mode 100644 index 0000000000..0dcac17a75 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_texture_fetch_debugger.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="TexFetchDebugger" title="æè³ªæ“·å–除錯器"> + <text name="total_num_fetched_label"> + 1. å·²æ“·å–æè³ªç¸½æ•¸ï¼š[NUM] + </text> + <text name="total_num_fetching_requests_label"> + 2. 總擷å–請求數:[NUM] + </text> + <text name="total_num_cache_hits_label"> + 3. å¿«å–ç¸½è®€å–æ•¸ï¼š[NUM] + </text> + <text name="total_num_visible_tex_label"> + 4. å¯è¦‹æè³ªç¸½æ•¸ï¼š[NUM] + </text> + <text name="total_num_visible_tex_fetch_req_label"> + 5. å¯è¦‹æè³ªæ“·å–總請求數:[NUM] + </text> + <text name="total_fetched_data_label"> + 6. 總擷å–資料é‡ï¼š[SIZE1] KB,解碼資料é‡ï¼š[SIZE2] KB,[PIXEL] 百è¬åƒç´ + </text> + <text name="total_fetched_vis_data_label"> + 7. å¯è¦‹è³‡æ–™ç¸½é‡ï¼š[SIZE1] KB,解碼資料é‡ï¼š[SIZE2] KB + </text> + <text name="total_fetched_rendered_data_label"> + 8. 總呈åƒè³‡æ–™é‡ï¼š[SIZE1] KB,解碼資料é‡ï¼š[SIZE2] KB,[PIXEL] 百è¬åƒç´ + </text> + <text name="total_time_cache_read_label"> + 9. å¿«å–讀å–總時間:[TIME] ç§’ + </text> + <text name="total_time_cache_write_label"> + 10. å¿«å–寫入總時間:[TIME] ç§’ + </text> + <text name="total_time_decode_label"> + 11. 解碼總時間:[TIME] ç§’ + </text> + <text name="total_time_gl_label"> + 12. 建立 gl æè³ªç¸½æ™‚間:[TIME] ç§’ + </text> + <text name="total_time_http_label"> + 13. HTTP æ“·å–總時間:[TIME] ç§’ + </text> + <text name="total_time_fetch_label"> + 14. 所有擷å–動作總時間:[TIME] ç§’ + </text> + <text name="total_time_refetch_vis_cache_label"> + 15. 自快å–釿–°æ“·å–å¯è¦‹æè³ªï¼Œæ™‚間:[TIME] 秒,擷å–é‡ï¼š[SIZE] KB,[PIXEL] 百è¬åƒç´ + </text> + <text name="total_time_refetch_all_cache_label"> + 16. 從快å–釿–°æ“·å–所有æè³ªï¼Œæ™‚間:[TIME] 秒,擷å–é‡ï¼š[SIZE] KB,[PIXEL] 百è¬åƒç´ + </text> + <text name="total_time_refetch_vis_http_label"> + 17. 自 HTTP 釿–°æ“·å–å¯è¦‹æè³ªï¼Œæ™‚間:[TIME] 秒,擷å–é‡ï¼š[SIZE] KB,[PIXEL] 百è¬åƒç´ + </text> + <text name="total_time_refetch_all_http_label"> + 18. 自 HTTP 釿–°æ“·å–所有æè³ªï¼Œæ™‚間:[TIME] 秒,擷å–é‡ï¼š[SIZE] KB,[PIXEL] 百è¬åƒç´ + </text> + <spinner label="19. æè³ª/åƒç´ 比率:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20. æè³ªä¾†æºï¼š + </text> + <radio_group name="texture_source"> + <radio_item label="å¿«å– + HTTP" name="0"/> + <radio_item label="åƒ…é™ HTTP" name="1"/> + </radio_group> + <button label="é–‹å§‹" name="start_btn"/> + <button label="é‡è¨" name="clear_btn"/> + <button label="關閉" name="close_btn"/> + <button label="å¿«å–讀å–" name="cacheread_btn"/> + <button label="å¿«å–寫入" name="cachewrite_btn"/> + <button label="HTTP" name="http_btn"/> + <button label="解碼" name="decode_btn"/> + <button label="GL æè³ª" name="gl_btn"/> + <button label="å¿«å–é‡å–å¯è¦‹æè³ª" name="refetchviscache_btn"/> + <button label="釿–°æ“·å–所有快å–" name="refetchallcache_btn"/> + <button label="HTTP é‡å–å¯è¦‹æè³ª" name="refetchvishttp_btn"/> + <button label="釿–°æ“·å–所有 HTTP" name="refetchallhttp_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_tools.xml b/indra/newview/skins/default/xui/zh/floater_tools.xml index 2db98eb3d7..33c9ebeaf0 100644 --- a/indra/newview/skins/default/xui/zh/floater_tools.xml +++ b/indra/newview/skins/default/xui/zh/floater_tools.xml @@ -1,43 +1,49 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="toolbox floater" short_title="å»ºé€ å·¥å…·"> + <floater.string name="grid_screen_text"> + 螢幕 + </floater.string> + <floater.string name="grid_local_text"> + 本地 + </floater.string> + <floater.string name="grid_world_text"> + 世界 + </floater.string> + <floater.string name="grid_reference_text"> + åƒè€ƒ + </floater.string> + <floater.string name="grid_attachment_text"> + 附件 + </floater.string> <floater.string name="status_rotate"> - Drag colored bands to rotate object + 拖曳色æ¢å¯ä»¥æ—‹è½‰ç‰©ä»¶ </floater.string> <floater.string name="status_scale"> - Click and drag to stretch selected side + 按ä½ä¸¦æ‹–曳,å¯ä»¥æ‹‰ä¼¸æ‰€é¸çš„ä¸€é¢ </floater.string> <floater.string name="status_move"> - Drag to move, shift-drag to copy + 拖曳就會移動,按下 Shift 冿‹–曳則å¯è¤‡è£½ </floater.string> <floater.string name="status_modifyland"> - Click and hold to modify land + 按ä½ä¸æ”¾é–‹ï¼Œå¯ä»¥ä¿®æ”¹åœŸåœ° </floater.string> <floater.string name="status_camera"> - Click and drag to move camera + 按ä½ä¸¦æ‹–曳,å¯ä»¥ç§»å‹•æ”影機 </floater.string> <floater.string name="status_grab"> - Drag to move, Ctrl to lift, Ctrl+Shift to rotate + 拖曳就å¯ç§»å‹•,按下 Ctrl å¯ä»¥æ‹¿èµ·ï¼ŒæŒ‰ä¸‹ Ctrl+Shift å¯ä»¥æ—‹è½‰ </floater.string> <floater.string name="status_place"> - Click inworld to build + 在虛擬世界裡點按一下,å¯ä»¥å»ºè£½ç‰©ä»¶ </floater.string> <floater.string name="status_selectland"> - Click and drag to select land + 按ä½ä¸¦æ‹–曳,å¯ä»¥é¸å–土地 </floater.string> - <floater.string name="grid_screen_text"> - Screen + <floater.string name="status_selectcount"> + é¸å–了 [OBJ_COUNT] å€‹ç‰©ä»¶ï¼ŒåœŸåœ°è¡æ“Šé‡ [LAND_IMPACT] </floater.string> - <floater.string name="grid_local_text"> - Local - </floater.string> - <floater.string name="grid_world_text"> - World - </floater.string> - <floater.string name="grid_reference_text"> - Reference - </floater.string> - <floater.string name="grid_attachment_text"> - Attachment + <floater.string name="status_remaining_capacity"> + 剩餘容ç´é‡ [LAND_CAPACITY]。 </floater.string> <button name="button focus" tool_tip="èšç„¦"/> <button name="button move" tool_tip="移動"/> @@ -45,7 +51,7 @@ <button name="button create" tool_tip="å‰µé€ "/> <button name="button land" tool_tip="土地"/> <text name="text status"> - Drag to move, shift-drag to copy + 拖曳就會移動,按下 Shift 冿‹–曳則å¯è¤‡è£½ </text> <radio_group name="focus_radio_group"> <radio_item label="縮放" name="radio zoom"/> @@ -56,7 +62,7 @@ <radio_group name="move_radio_group"> <radio_item label="移動" name="radio move"/> <radio_item label="舉起(Ctrl)" name="radio lift"/> - <radio_item label="Spin (Ctrl+Shift)" name="radio spin"/> + <radio_item label="旋轉(Ctrl+Shift)" name="radio spin"/> </radio_group> <radio_group name="edit_radio_group"> <radio_item label="移動" name="radio position"/> @@ -67,39 +73,36 @@ <check_box label="編輯è¯çµéƒ¨åˆ†" name="checkbox edit linked parts"/> <button label="è¯çµ" name="link_btn"/> <button label="å–æ¶ˆè¯çµ" name="unlink_btn"/> - <text name="RenderingCost" tool_tip="Shows the rendering cost calculated for this object"> - þ: [COUNT] - </text> <text label="åŒæ™‚伸展兩å´" name="checkbox uniform label"> åŒæ™‚ä¼¸å±•å…©å´ </text> <check_box initial_value="true" label="伸展æè³ª" name="checkbox stretch textures"/> - <check_box initial_value="true" label="è²¼é½Šæ ¼ç·š" name="checkbox snap to grid"/> + <check_box initial_value="true" label="Snap" name="checkbox snap to grid"/> <combo_box name="combobox grid mode" tool_tip="鏿“‡ç‰©ä»¶å®šä½åƒè€ƒçš„æ ¼ç·šå°ºåº¦é¡žåž‹"> - <combo_box.item label="ä¸–ç•Œæ ¼ç·š" name="World"/> - <combo_box.item label="åœ°æ–¹æ ¼ç·š" name="Local"/> - <combo_box.item label="åƒè€ƒæ ¼ç·š" name="Reference"/> + <combo_box.item label="世界" name="World"/> + <combo_box.item label="本地" name="Local"/> + <combo_box.item label="åƒè€ƒ" name="Reference"/> </combo_box> - <button name="Options..." tool_tip="å¯Ÿçœ‹æ›´å¤šæ ¼ç·šé¸é …"/> - <button name="ToolCube" tool_tip="Cube"/> - <button name="ToolPrism" tool_tip="Prism"/> - <button name="ToolPyramid" tool_tip="Pyramid"/> - <button name="ToolTetrahedron" tool_tip="Tetrahedron"/> - <button name="ToolCylinder" tool_tip="Cylinder"/> - <button name="ToolHemiCylinder" tool_tip="Hemicylinder"/> - <button name="ToolCone" tool_tip="Cone"/> - <button name="ToolHemiCone" tool_tip="Hemicone"/> - <button name="ToolSphere" tool_tip="Sphere"/> - <button name="ToolHemiSphere" tool_tip="Hemisphere"/> - <button name="ToolTorus" tool_tip="Torus"/> - <button name="ToolTube" tool_tip="Tube"/> - <button name="ToolRing" tool_tip="Ring"/> - <button name="ToolTree" tool_tip="Tree"/> - <button name="ToolGrass" tool_tip="Grass"/> + <button label="" name="Options..." tool_tip="å¯Ÿçœ‹æ›´å¤šæ ¼ç·šé¸é …"/> + <button name="ToolCube" tool_tip="立方體"/> + <button name="ToolPrism" tool_tip="稜é¡é«”"/> + <button name="ToolPyramid" tool_tip="金å—å¡”"/> + <button name="ToolTetrahedron" tool_tip="æ£å››é¢é«”"/> + <button name="ToolCylinder" tool_tip="圓柱體"/> + <button name="ToolHemiCylinder" tool_tip="åŠåœ“柱體"/> + <button name="ToolCone" tool_tip="圓éŒ"/> + <button name="ToolHemiCone" tool_tip="åŠåœ“éŒ"/> + <button name="ToolSphere" tool_tip="çƒé«”"/> + <button name="ToolHemiSphere" tool_tip="åŠçƒé«”"/> + <button name="ToolTorus" tool_tip="ç’°é¢"/> + <button name="ToolTube" tool_tip="圓管"/> + <button name="ToolRing" tool_tip="圓環"/> + <button name="ToolTree" tool_tip="樹木"/> + <button name="ToolGrass" tool_tip="è‰åœ°"/> <check_box label="ä¿æŒå·²é¸æ“‡çš„工具" name="checkbox sticky"/> - <check_box label="è¦†è£½é¸æ“‡" name="checkbox copy selection"/> - <check_box initial_value="true" label="Center Copy" name="checkbox copy centers"/> - <check_box label="Rotate Copy" name="checkbox copy rotates"/> + <check_box label="è¤‡è£½é¸æ“‡" name="checkbox copy selection"/> + <check_box initial_value="true" label="複製物置ä¸" name="checkbox copy centers"/> + <check_box label="旋轉複製物" name="checkbox copy rotates"/> <radio_group name="land_radio_group"> <radio_item label="鏿“‡åœŸåœ°" name="radio select land"/> <radio_item label="攤平" name="radio flatten"/> @@ -121,11 +124,11 @@ </text> <slider_bar initial_value="0.00" name="slider force"/> <button label="套用" label_selected="套用" name="button apply to selection" tool_tip="ä¿®æ”¹æ‰€é¸æ“‡çš„土地"/> - <text name="obj_count"> - 物件: [COUNT] + <text name="selection_empty"> + 未åšä»»ä½•鏿“‡ã€‚ </text> - <text name="prim_count"> - 幾何元件: [COUNT] + <text name="remaining_capacity"> + [CAPACITY_STRING] [secondlife:///app/openfloater/object_weights 詳情] </text> <tab_container name="Object Info Tabs"> <panel label="一般" name="General"> @@ -147,6 +150,12 @@ <panel.string name="text modify info 4"> ä½ ä¸èƒ½ä¿®æ”¹é€™äº›ç‰©ä»¶ </panel.string> + <panel.string name="text modify info 5"> + 無法跨地å€ä¿®æ”¹é€™å€‹ç‰©ä»¶ + </panel.string> + <panel.string name="text modify info 6"> + 無法跨地å€ä¿®æ”¹é€™äº›ç‰©ä»¶ + </panel.string> <panel.string name="text modify warning"> ä½ å¿…é ˆé¸å–整個物件以è¨å®šæ¬Šé™ </panel.string> @@ -154,16 +163,16 @@ åƒ¹æ ¼ï¼š L$ </panel.string> <panel.string name="Cost Total"> - 總價: L$ + 總價:L$ </panel.string> <panel.string name="Cost Per Unit"> - 單價æ¯å€‹ï¼š L$ + 單價:L$ </panel.string> <panel.string name="Cost Mixed"> - Mixed Price + æ··åˆåƒ¹æ ¼ </panel.string> <panel.string name="Sale Mixed"> - Mixed Sale + æ··åˆéŠ·å”® </panel.string> <text name="Name:"> å稱: @@ -175,49 +184,49 @@ å‰µé€ è€…ï¼š </text> <text name="Owner:"> - æ“æœ‰è€…: + 所有人: </text> <text name="Group:"> 群組: </text> <name_box initial_value="載入ä¸..." name="Group Name Proxy"/> - <button name="button set group" tool_tip="鏿“‡ä¸€å€‹ç¾¤çµ„以分享這物件權é™"/> - <check_box label="分享" name="checkbox share with group" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."/> - <button label="讓渡" label_selected="讓渡" name="button deed" tool_tip="Deeding gives this item away with next owner permissions. Group shared objects can be deeded by a group officer."/> + <button name="button set group" tool_tip="鏿“‡ä¸€å€‹ç¾¤çµ„以分享這物件的權é™"/> + <check_box label="分享" name="checkbox share with group" tool_tip="å…許æ¤ç¾¤çµ„所有æˆå“¡å…±äº«ä½ 修改æ¤ç‰©ä»¶çš„æ¬Šé™ã€‚ ä½ å¿…é ˆè®“æ¸¡æ‰èƒ½å•Ÿå‹•角色é™åˆ¶ã€‚"/> + <button label="讓渡" label_selected="讓渡" name="button deed" tool_tip="ã€Œè®“æ¸¡ã€æœƒæŠŠé€™ç‰©ä»¶è´ˆé€å‡ºåŽ»ä¸¦è³¦äºˆã€Œä¸‹ä¸€å€‹æ‰€æœ‰äººã€æ¬Šé™ã€‚ 群組所分享的物件å¯ç”±ç¾¤çµ„è·å“¡åŠ ä»¥è®“æ¸¡ã€‚"/> <text name="label click action"> - 點擊以: + 點按以: </text> <combo_box name="clickaction"> <combo_box.item label="觸碰(é è¨ï¼‰" name="Touch/grab(default)"/> <combo_box.item label="å在物件上" name="Sitonobject"/> <combo_box.item label="購買物件" name="Buyobject"/> <combo_box.item label="支付物件" name="Payobject"/> - <combo_box.item label="開啟" name="Open"/> + <combo_box.item label="打開" name="Open"/> <combo_box.item label="縮放" name="Zoom"/> </combo_box> - <check_box label="出售:" name="checkbox for sale"/> + <check_box label="出售ä¸ï¼š" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> - <combo_box.item label="副本" name="Copy"/> + <combo_box.item label="æšåº¨" name="Copy"/> <combo_box.item label="內容" name="Contents"/> <combo_box.item label="原件" name="Original"/> </combo_box> - <spinner label="åƒ¹æ ¼ï¼š L$" name="Edit Cost"/> - <check_box label="顯示在æœå°‹ä¸" name="search_check" tool_tip="讓其他人å¯ä»¥åœ¨æœå°‹çµæžœä¸çœ‹åˆ°é€™ç‰©ä»¶"/> + <check_box label="顯示在æœå°‹ä¸" name="search_check" tool_tip="讓其他人å¯ä»¥åœ¨æœå°‹çµæžœä¸å¯Ÿçœ‹åˆ°æ¤ç‰©ä»¶"/> <panel name="perms_build"> <text name="perm_modify"> - ä½ å¯ä»¥ä¿®æ”¹é€™å€‹ç‰©ä»¶ + ä½ èƒ½ä¿®æ”¹é€™å€‹ç‰©ä»¶ </text> <text name="Anyone can:"> 任何人: </text> <check_box label="移動" name="checkbox allow everyone move"/> - <check_box label="覆製" name="checkbox allow everyone copy"/> + <check_box label="æšåº¨" name="checkbox allow everyone copy"/> <text name="Next owner can:"> - ä¸‹ä¸€å€‹æ“æœ‰è€…: + 下一個所有人: </text> <check_box label="修改" name="checkbox next owner can modify"/> - <check_box label="覆製" name="checkbox next owner can copy"/> - <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="ä¸‹ä¸€å€‹æ“æœ‰è€…å¯ä»¥é€äººæˆ–轉售這個物件"/> + <check_box label="æšåº¨" name="checkbox next owner can copy"/> + <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="下一個所有人å¯è´ˆé€æˆ–轉售這個物件"/> <text name="B:"> B: </text> @@ -237,9 +246,14 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + 尋徑屬性: + </text> + </panel> </panel> <panel label="物件" name="Object"> - <check_box label="鎖定" name="checkbox locked" tool_tip="é é˜²ç‰©ä»¶è¢«ç§»å‹•æˆ–åˆªé™¤ï¼Œæœ€å¸¸ä½¿ç”¨çš„ç‹€æ³æ˜¯åœ¨å»ºé€ éŽç¨‹ä¸é¿å…被æ„外的編輯。"/> + <check_box label="已鎖ä½" name="checkbox locked" tool_tip="é¿å…物件被移動或刪除。 這在建製éŽç¨‹ä¸éžå¸¸æœ‰ç”¨ï¼Œå¯é¿å…æ„外的編輯更動。"/> <check_box label="ç‰©ç†æ€§" name="Physical Checkbox Ctrl" tool_tip="å…許物件被推撞與å—é‡åŠ›å½±éŸ¿"/> <check_box label="暫時性" name="Temporary Checkbox Ctrl" tool_tip="ä½¿ç‰©ä»¶åœ¨å»ºé€ å¾Œçš„ä¸€åˆ†é˜è‡ªå‹•刪除"/> <check_box label="幻影性" name="Phantom Checkbox Ctrl" tool_tip="ä½¿ç‰©ä»¶ä¸æœƒèˆ‡å…¶ä»–物件或化身產生碰撞"/> @@ -262,26 +276,17 @@ <spinner label="Y" name="Rot Y"/> <spinner label="Z" name="Rot Z"/> <combo_box name="comboBaseType"> - <combo_box.item label="Box" name="Box"/> - <combo_box.item label="Cylinder" name="Cylinder"/> - <combo_box.item label="Prism" name="Prism"/> - <combo_box.item label="Sphere" name="Sphere"/> - <combo_box.item label="Torus" name="Torus"/> - <combo_box.item label="Tube" name="Tube"/> - <combo_box.item label="Ring" name="Ring"/> - <combo_box.item label="Sculpted" name="Sculpted"/> - </combo_box> - <combo_box name="material"> - <combo_box.item label="石é " name="Stone"/> - <combo_box.item label="金屬" name="Metal"/> - <combo_box.item label="玻璃" name="Glass"/> - <combo_box.item label="木é " name="Wood"/> - <combo_box.item label="肌肉" name="Flesh"/> - <combo_box.item label="å¡‘è† " name="Plastic"/> - <combo_box.item label="æ©¡è† " name="Rubber"/> + <combo_box.item label="ç®±å" name="Box"/> + <combo_box.item label="圓柱體" name="Cylinder"/> + <combo_box.item label="稜é¡é«”" name="Prism"/> + <combo_box.item label="çƒé«”" name="Sphere"/> + <combo_box.item label="ç’°é¢" name="Torus"/> + <combo_box.item label="圓管" name="Tube"/> + <combo_box.item label="圓環" name="Ring"/> + <combo_box.item label="雕刻的" name="Sculpted"/> </combo_box> <text name="text cut"> - Path Cut (begin/end) + 路徑切斷(開始 / çµæŸï¼‰ </text> <spinner label="B" name="cut begin"/> <spinner label="E" name="cut end"/> @@ -289,24 +294,24 @@ ä¸ç©º </text> <text name="text skew"> - Skew + åæ–œ </text> <text name="Hollow Shape"> ä¸ç©ºå½¢ç‹€ </text> <combo_box name="hole"> <combo_box.item label="é è¨" name="Default"/> - <combo_box.item label="Circle" name="Circle"/> - <combo_box.item label="Square" name="Square"/> - <combo_box.item label="Triangle" name="Triangle"/> + <combo_box.item label="圓圈" name="Circle"/> + <combo_box.item label="方形" name="Square"/> + <combo_box.item label="三角形" name="Triangle"/> </combo_box> <text name="text twist"> - Twist (begin/end) + æ‰æ›²ï¼ˆé–‹å§‹ / çµæŸï¼‰ </text> <spinner label="B" name="Twist Begin"/> <spinner label="E" name="Twist End"/> <text name="scale_taper"> - Taper + éŒåŒ– </text> <text name="scale_hole"> 洞尺寸 @@ -314,54 +319,62 @@ <spinner label="X" name="Taper Scale X"/> <spinner label="Y" name="Taper Scale Y"/> <text name="text topshear"> - Top Shear + é ‚éƒ¨æ–œè®Š </text> <spinner label="X" name="Shear X"/> <spinner label="Y" name="Shear Y"/> <text name="advanced_cut"> - Profile Cut (begin/end) + å´é¢åˆ‡æ–·ï¼ˆé–‹å§‹ / çµæŸï¼‰ </text> <text name="advanced_dimple"> - Dimple (begin/end) + 凹陷(開始 / çµæŸï¼‰ </text> <text name="advanced_slice"> - Slice (begin/end) + Slice(開始 / çµæŸï¼‰ </text> <spinner label="B" name="Path Limit Begin"/> <spinner label="E" name="Path Limit End"/> <text name="text taper2"> - Taper + éŒåŒ– </text> <spinner label="X" name="Taper X"/> <spinner label="Y" name="Taper Y"/> <text name="text radius delta"> - Radius + åŠå¾‘ </text> <text name="text revolutions"> - Revolutions + 旋轉 </text> - <texture_picker label="Sculpt Texture" name="sculpt texture control" tool_tip="點擊以挑é¸åœ–åƒ"/> - <check_box label="Mirror" name="sculpt mirror control" tool_tip="Flips sculpted prim along the X axis"/> - <check_box label="Inside-out" name="sculpt invert control" tool_tip="Inverts the sculpted prims normals, making it appear inside-out"/> + <texture_picker label="雕刻æè³ª" name="sculpt texture control" tool_tip="點按以挑é¸åœ–片"/> + <check_box label="é¡åƒ" name="sculpt mirror control" tool_tip="沿X軸翻轉雕刻幾何元件"/> + <check_box label="內外倒翻" name="sculpt invert control" tool_tip="將雕刻幾何元件的æ£å¸¸å€¼é¡›å€’,使其看來有如內外倒翻"/> <text name="label sculpt type"> - Stitching type + 縫åˆé¡žåž‹ </text> <combo_box name="sculpt type control"> - <combo_box.item label="(無)" name="None"/> - <combo_box.item label="Sphere" name="Sphere"/> - <combo_box.item label="Torus" name="Torus"/> - <combo_box.item label="Plane" name="Plane"/> - <combo_box.item label="Cylinder" name="Cylinder"/> + <combo_box.item label="çƒé«”" name="Sphere"/> + <combo_box.item label="ç’°é¢" name="Torus"/> + <combo_box.item label="å¹³é¢" name="Plane"/> + <combo_box.item label="圓柱體" name="Cylinder"/> </combo_box> </panel> <panel label="特性" name="Features"> + <panel.string name="None"> + ç„¡ + </panel.string> + <panel.string name="Prim"> + 幾何元件 + </panel.string> + <panel.string name="Convex Hull"> + 凸包 + </panel.string> <text name="select_single"> åªèƒ½é¸æ“‡ä¸€å€‹å¹¾ä½•元件去編輯細節。 </text> <text name="edit_object"> 編輯物件特性: </text> - <check_box label="彈性路徑" name="Flexible1D Checkbox Ctrl" tool_tip="Allows object to flex about the Z axis (Client-side only)"/> + <check_box label="彈性路徑" name="Flexible1D Checkbox Ctrl" tool_tip="å…許物件繞 Z 軸伸展(僅é™å®¢æˆ¶ç«¯ï¼‰"/> <spinner label="柔軟" name="FlexNumSections"/> <spinner label="é‡åŠ›" name="FlexGravity"/> <spinner label="拖曳" name="FlexFriction"/> @@ -371,14 +384,31 @@ <spinner label="強制 Y 軸" name="FlexForceY"/> <spinner label="強制 Z 軸" name="FlexForceZ"/> <check_box label="å…‰æº" name="Light Checkbox Ctrl" tool_tip="導致物件發光"/> - <color_swatch name="colorswatch" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/> - <texture_picker label="" name="light texture control" tool_tip="Click to choose a projection image (only has effect with deferred rendering enabled)"/> + <color_swatch name="colorswatch" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/> + <texture_picker label="" name="light texture control" tool_tip="é»žé¸æŠ•å½±åœ–åƒï¼ˆåªåœ¨å•Ÿç”¨å»¶é²å‘ˆåƒæ™‚生效)"/> <spinner label="強度" name="Light Intensity"/> - <spinner label="FOV" name="Light FOV"/> + <spinner label="視角" name="Light FOV"/> <spinner label="åŠå¾‘" name="Light Radius"/> - <spinner label="Focus" name="Light Focus"/> + <spinner label="焦點" name="Light Focus"/> <spinner label="衰減" name="Light Falloff"/> - <spinner label="Ambiance" name="Light Ambiance"/> + <spinner label="環境" name="Light Ambiance"/> + <text name="label physicsshapetype"> + 物ç†å½¢ç‹€é¡žåž‹ï¼š + </text> + <combo_box name="Physics Shape Type Combo Ctrl" tool_tip="鏿“‡ç‰©ç†å½¢ç‹€é¡žåž‹"/> + <combo_box name="material"> + <combo_box.item label="石é " name="Stone"/> + <combo_box.item label="金屬" name="Metal"/> + <combo_box.item label="玻璃" name="Glass"/> + <combo_box.item label="木é " name="Wood"/> + <combo_box.item label="肌肉" name="Flesh"/> + <combo_box.item label="å¡‘è† " name="Plastic"/> + <combo_box.item label="æ©¡è† " name="Rubber"/> + </combo_box> + <spinner label="é‡åŠ›" name="Physics Gravity"/> + <spinner label="摩擦" name="Physics Friction"/> + <spinner label="密度(100 公斤 / 立方公尺)" name="Physics Density"/> + <spinner label="æ¢å¾©" name="Physics Restitution"/> </panel> <panel label="æè³ª" name="Texture"> <panel.string name="string repeats per meter"> @@ -387,8 +417,8 @@ <panel.string name="string repeats per face"> æ¯ä¸€é¢é‡è¦†æ¬¡æ•¸ </panel.string> - <texture_picker label="æè³ª" name="texture control" tool_tip="點擊以挑é¸åœ–åƒ"/> - <color_swatch label="é¡è‰²" name="colorswatch" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/> + <texture_picker label="æè³ª" name="texture control" tool_tip="點按以挑é¸åœ–片"/> + <color_swatch label="é¡è‰²" name="colorswatch" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/> <text name="color trans"> 逿˜Žåº¦ % </text> @@ -417,25 +447,25 @@ </text> <combo_box name="combobox bumpiness"> <combo_box.item label="ç„¡" name="None"/> - <combo_box.item label="Brightness" name="Brightness"/> - <combo_box.item label="Darkness" name="Darkness"/> - <combo_box.item label="woodgrain" name="woodgrain"/> - <combo_box.item label="bark" name="bark"/> - <combo_box.item label="bricks" name="bricks"/> - <combo_box.item label="checker" name="checker"/> - <combo_box.item label="concrete" name="concrete"/> - <combo_box.item label="crustytile" name="crustytile"/> - <combo_box.item label="cutstone" name="cutstone"/> - <combo_box.item label="discs" name="discs"/> - <combo_box.item label="gravel" name="gravel"/> - <combo_box.item label="petridish" name="petridish"/> - <combo_box.item label="siding" name="siding"/> - <combo_box.item label="stonetile" name="stonetile"/> - <combo_box.item label="stucco" name="stucco"/> - <combo_box.item label="suction" name="suction"/> - <combo_box.item label="weave" name="weave"/> + <combo_box.item label="亮度" name="Brightness"/> + <combo_box.item label="暗度" name="Darkness"/> + <combo_box.item label="木紋" name="woodgrain"/> + <combo_box.item label="樹皮" name="bark"/> + <combo_box.item label="磚" name="bricks"/> + <combo_box.item label="æ ¼å" name="checker"/> + <combo_box.item label="æ··å‡åœŸ" name="concrete"/> + <combo_box.item label="粗花磚" name="crustytile"/> + <combo_box.item label="石磚" name="cutstone"/> + <combo_box.item label="圓盤" name="discs"/> + <combo_box.item label="碎石" name="gravel"/> + <combo_box.item label="培養皿" name="petridish"/> + <combo_box.item label="å´é‚Šç‰‡" name="siding"/> + <combo_box.item label="çŸ³ç£šæ ¼" name="stonetile"/> + <combo_box.item label="彩色沙岩" name="stucco"/> + <combo_box.item label="å¸é™„" name="suction"/> + <combo_box.item label="編織" name="weave"/> </combo_box> - <check_box initial_value="false" label="å°é½Šå¹³é¢" name="checkbox planar align" tool_tip="ä»¥æœ€å¾Œæ‰€é¸æ“‡çš„é¢ç‚ºåŸºæº–,å°é½Šå…¨éƒ¨æ‰€é¸æ“‡çš„é¢ä¸Šçš„æè³ªã€‚é€™å¿…é ˆä½¿ç”¨å¹³é¢æè³ªæ˜ å°„æ–¹å¼ã€‚"/> + <check_box initial_value="false" label="å°é½Šå¹³é¢" name="checkbox planar align" tool_tip="ä»¥æœ€å¾Œæ‰€é¸æ“‡çš„é¢ç‚ºåŸºæº–,å°é½Šå…¨éƒ¨æ‰€é¸æ“‡çš„é¢ä¸Šçš„æè³ªã€‚ é€™å¿…é ˆä½¿ç”¨å¹³é¢æè³ªæ˜ å°„æ–¹å¼ã€‚"/> <text name="rpt"> é‡è¦†æ¬¡æ•¸ / é¢ </text> @@ -476,15 +506,8 @@ <text name="label_area"> é¢ç©ï¼š [AREA] m² </text> - <button label="關於土地" label_selected="關於土地" name="button about land"/> - <check_box label="é¡¯ç¤ºæ“æœ‰è€…" name="checkbox show owners" tool_tip="Colorize the parcels according to the type of owner: - -ç¶ è‰² = ä½ çš„åœŸåœ° -æ°´è— = ä½ ç¾¤çµ„çš„åœŸåœ° -紅色 = 其他人所有 -黃色 = 出售 -紫色 = æ‹è³£ -ç°è‰² = 公有地"/> + <button label="土地資料" label_selected="土地資料" name="button about land"/> + <check_box label="顯示所有人" name="checkbox show owners" tool_tip="æ ¹æ“šæ‰€æœ‰äººå°‡åœ°æ®µåˆ†é¡žä¸Šè‰²ï¼š ç¶ è‰² = ä½ çš„åœŸåœ° æ°´è— = ä½ ç¾¤çµ„çš„åœŸåœ° 紅色 = 其他人所有 黃色 = 出售 紫色 = æ‹è³£ ç°è‰² = 公有地"/> <text name="label_parcel_modify"> 修改地段 </text> diff --git a/indra/newview/skins/default/xui/zh/floater_top_objects.xml b/indra/newview/skins/default/xui/zh/floater_top_objects.xml index 0e7e0c5b1a..6f50be0855 100644 --- a/indra/newview/skins/default/xui/zh/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/zh/floater_top_objects.xml @@ -1,28 +1,25 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="top_objects" title="Top Objects"> +<floater name="top_objects" title="排行最高的物件"> <floater.string name="top_scripts_title"> - Top Scripts + 排行最高的腳本 </floater.string> <floater.string name="top_scripts_text"> - [COUNT] scripts taking a total of [TIME] ms + [COUNT] 個腳本共需時 [TIME] 毫秒 </floater.string> <floater.string name="scripts_score_label"> - Time - </floater.string> - <floater.string name="scripts_mono_time_label"> - Mono Time + 時間 </floater.string> <floater.string name="top_colliders_title"> - Top Colliders + æœ€å¸¸ç¢°æ’žç‰©é … </floater.string> <floater.string name="top_colliders_text"> - Top [COUNT] objects experiencing many potential collisions + 排行最高的 [COUNT] 個物件å¯èƒ½ç™¼ç”Ÿå¤šæ¬¡ç¢°æ’ž </floater.string> <floater.string name="colliders_score_label"> ç©åˆ† </floater.string> <floater.string name="none_descriptor"> - 未發ç¾ã€‚ + æŸ¥ç„¡çµæžœã€‚ </floater.string> <text name="title_text"> 載入ä¸... @@ -30,11 +27,12 @@ <scroll_list name="objects_list"> <scroll_list.columns label="ç©åˆ†" name="score"/> <scroll_list.columns label="å稱" name="name"/> - <scroll_list.columns label="æ“æœ‰è€…" name="owner"/> + <scroll_list.columns label="所有人" name="owner"/> <scroll_list.columns label="ä½ç½®" name="location"/> - <scroll_list.columns label="Time" name="time"/> - <scroll_list.columns label="Mono Time" name="mono_time"/> - <scroll_list.columns label="URLs" name="URLs"/> + <scroll_list.columns label="地段" name="parcel"/> + <scroll_list.columns label="時間" name="time"/> + <scroll_list.columns label="URL" name="URLs"/> + <scroll_list.columns label="記憶體 (KB)" name="memory"/> </scroll_list> <text name="id_text"> 物件 ID: @@ -45,11 +43,15 @@ </text> <button label="éŽæ¿¾å™¨" name="filter_object_btn"/> <text name="owner_name_text"> - æ“æœ‰è€…: + 所有人: </text> <button label="éŽæ¿¾å™¨" name="filter_owner_btn"/> + <text name="parcel_name_text"> + 地段: + </text> + <button label="éŽæ¿¾å™¨" name="filter_parcel_btn"/> <button label="é€€å›žæ‰€é¸æ“‡çš„" name="return_selected_btn"/> <button label="全部退回" name="return_all_btn"/> - <button label="é—œé–‰æ‰€é¸æ“‡çš„" name="disable_selected_btn"/> - <button label="全部關閉" name="disable_all_btn"/> + <button label="åœç”¨æ‰€é¸çš„" name="disable_selected_btn"/> + <button label="全部åœç”¨" name="disable_all_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_tos.xml b/indra/newview/skins/default/xui/zh/floater_tos.xml index 5f9e16afe1..3da9445a55 100644 --- a/indra/newview/skins/default/xui/zh/floater_tos.xml +++ b/indra/newview/skins/default/xui/zh/floater_tos.xml @@ -4,12 +4,12 @@ http://secondlife.com/app/tos/ </floater.string> <floater.string name="loading_url"> - data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E Loading %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E + data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E æ£åœ¨è¼‰å…¥ %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E </floater.string> <button label="繼續" label_selected="繼續" name="Continue"/> <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="Cancel"/> <check_box label="æˆ‘åŒæ„æŽ¥å—æœå‹™æ¢æ¬¾åŠéš±ç§æ”¿ç–" name="agree_chk"/> <text name="tos_heading"> - 請謹慎閱讀以下的æœå‹™æ¢æ¬¾åŠéš±ç§æ”¿ç–。è¦ç¹¼çºŒç™»å…¥åˆ° [SECOND_LIFE]ï¼Œä½ å¿…é ˆæŽ¥å—這些å”è°ã€‚ + 請仔細閱讀以下æœå‹™æ¢æ¬¾åŠéš±ç§æ”¿ç–。 繼續登入 [SECOND_LIFE] å‰ï¼Œä½ å¿…é ˆåŒæ„æ¢æ¬¾ã€‚ </text> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_toybox.xml b/indra/newview/skins/default/xui/zh/floater_toybox.xml new file mode 100644 index 0000000000..fc6b6ea611 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_toybox.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<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/zh/floater_translation_settings.xml b/indra/newview/skins/default/xui/zh/floater_translation_settings.xml new file mode 100644 index 0000000000..fe84872557 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/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 ç¿»è¯å™¨" name="bing"/> + <radio_item initial_value="google" label="Google ç¿»è¯" 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="確定" name="ok_btn"/> + <button label="å–æ¶ˆ" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_voice_controls.xml b/indra/newview/skins/default/xui/zh/floater_voice_controls.xml index 24b7efea4f..a3a7679957 100644 --- a/indra/newview/skins/default/xui/zh/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/zh/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] 進行群組通話 </string> <string name="title_adhoc"> - 會è°é€šè©± + 多方通話 </string> <string name="title_peer_2_peer"> - 與 [NAME] 進行通話 + å’Œ [NAME] 通話 </string> <string name="no_one_near"> 附近沒有一人開啟語音 @@ -22,7 +22,7 @@ <layout_panel name="leave_call_panel"> <layout_stack name="voice_effect_and_leave_call_stack"> <layout_panel name="leave_call_btn_panel"> - <button label="çµæŸé€šè©±" name="leave_call_btn"/> + <button label="離開通話" name="leave_call_btn"/> </layout_panel> </layout_stack> </layout_panel> diff --git a/indra/newview/skins/default/xui/zh/floater_voice_effect.xml b/indra/newview/skins/default/xui/zh/floater_voice_effect.xml index 36efe20b65..81e0204262 100644 --- a/indra/newview/skins/default/xui/zh/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/zh/floater_voice_effect.xml @@ -1,29 +1,158 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater label="地點" name="voice_effects" title="語音變è²"> <string name="no_voice_effect"> - (No Voice Morph) + ï¼ˆç„¡è®Šè²æ•ˆæžœï¼‰ </string> <string name="active_voice_effect"> - (Active) + (使用ä¸ï¼‰ </string> <string name="unsubscribed_voice_effect"> - (Unsubscribed) + ï¼ˆå·²åœæ¢è¨‚用) </string> <string name="new_voice_effect"> - (New!) + (新的ï¼ï¼‰ + </string> + <string name="effect_Arena"> + ç«¶æŠ€å ´ + </string> + <string name="effect_Beast"> + é‡Žç¸ + </string> + <string name="effect_Buff"> + Buff + </string> + <string name="effect_Buzz"> + Buzz + </string> + <string name="effect_Camille"> + å¡èœœå…’ + </string> + <string name="effect_Creepy"> + 怪異 + </string> + <string name="effect_CreepyBot"> + 怪異機器人 + </string> + <string name="effect_Cyber"> + ç§‘å¹» + </string> + <string name="effect_DeepBot"> + 深沉機器人 + </string> + <string name="effect_Demon"> + é”鬼 + </string> + <string name="effect_Female Elf"> + 女性 - å°ç²¾éˆ + </string> + <string name="effect_Flirty"> + 調情 + </string> + <string name="effect_Foxy"> + 香豔 + </string> + <string name="effect_Halloween 2010 Bonus"> + 2010è¬è–ç¯€åŠ è´ˆ + </string> + <string name="effect_Helium"> + 氦氣 + </string> + <string name="effect_Husky"> + 沙啞 + </string> + <string name="effect_Husky Whisper"> + 沙啞耳語 + </string> + <string name="effect_Intercom"> + å°è¬›æ©Ÿ + </string> + <string name="effect_Julia"> + 茱莉亞 + </string> + <string name="effect_Lo Lilt"> + 輕微抑æšé “挫 + </string> + <string name="effect_Macho"> + 陽剛 + </string> + <string name="effect_Micro"> + Micro + </string> + <string name="effect_Mini"> + è¿·ä½ + </string> + <string name="effect_Model"> + 模型 + </string> + <string name="effect_Nano"> + Nano + </string> + <string name="effect_Nightmare"> + 惡夢 + </string> + <string name="effect_PopBot"> + PopBot + </string> + <string name="effect_Rachel"> + 瑞秋 + </string> + <string name="effect_Radio"> + 收音機 + </string> + <string name="effect_Robot"> + 機器人 + </string> + <string name="effect_Roxanne"> + è˜¿å§ + </string> + <string name="effect_Rumble"> + ä½Žæ²‰éš†éš†è² + </string> + <string name="effect_Sabrina"> + 薩賓娜 + </string> + <string name="effect_Samantha"> + å§æ›¼èŽŽ + </string> + <string name="effect_Sexy"> + 性感 + </string> + <string name="effect_Shorty"> + 矮個兒 + </string> + <string name="effect_Smaller"> + è¼ƒå° + </string> + <string name="effect_Sneaky"> + 鬼祟 + </string> + <string name="effect_Stallion"> + 種馬 + </string> + <string name="effect_Sultry"> + å‹¾é‚ + </string> + <string name="effect_Thunder"> + é›·è² + </string> + <string name="effect_Vixen"> + 潑婦 + </string> + <string name="effect_WhinyBot"> + å“鬧機器人 </string> <text name="preview_text"> - To Preview + é 覽 </text> <text name="status_text"> - Record a sample, then click on a voice to hear how it will sound. + 錄下一段樣本,å†é»žæŒ‰è²éŸ³æª¢æŸ¥çµæžœã€‚ </text> - <button label="Record" name="record_btn" tool_tip="Record a sample of your voice."/> + <button label="錄音" name="record_btn" tool_tip="éŒ„ä¸‹ä¸€æ®µä½ çš„è²éŸ³ã€‚"/> <button label="åœæ¢" name="record_stop_btn"/> <text name="voice_morphing_link"> - [[URL] Subscribe Now] + [[URL] ç¾åœ¨è¨‚用] </text> - <scroll_list name="voice_effect_list" tool_tip="Record a sample of your voice, then click an effect to preview."> + <scroll_list name="voice_effect_list" tool_tip="éŒ„ä¸‹ä¸€æ®µä½ çš„è²éŸ³ï¼Œå†é»žé¸ä¸€å€‹æ•ˆæžœè©¦è½ã€‚"> <scroll_list.columns label="語音å稱" name="name"/> <scroll_list.columns label="éŽæœŸ" name="expires"/> </scroll_list> diff --git a/indra/newview/skins/default/xui/zh/floater_water.xml b/indra/newview/skins/default/xui/zh/floater_water.xml deleted file mode 100644 index 5fb57272af..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_water.xml +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Water Floater" title="進階水文編輯器"> - <floater.string name="WLDefaultWaterNames"> - Default:Glassy:Pond:Murky:Second Plague:SNAKE!!!:Valdez - </floater.string> - <text name="KeyFramePresetsText"> - Water Presets: - </text> - <button label="新增" label_selected="新增" name="WaterNewPreset"/> - <button label="儲å˜" label_selected="儲å˜" name="WaterSavePreset"/> - <button label="刪除" label_selected="刪除" name="WaterDeletePreset"/> - <tab_container name="Water Tabs"> - <panel label="è¨å®š" name="Settings"> - <text name="BHText"> - Water Fog Color - </text> - <color_swatch name="WaterFogColor" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/> - <text name="WaterFogDensText"> - Fog Density Exponent - </text> - <text name="WaterUnderWaterFogModText"> - Underwater Fog Modifier - </text> - <text name="BDensText"> - Reflection Wavelet Scale - </text> - <slider label="1" name="WaterNormalScaleX"/> - <slider label="2" name="WaterNormalScaleY"/> - <slider label="3" name="WaterNormalScaleZ"/> - <text name="HDText"> - Fresnel Scale - </text> - <text name="FresnelOffsetText"> - Fresnel Offset - </text> - <text name="DensMultText"> - Refract Scale Above - </text> - <text name="WaterScaleBelowText"> - Refract Scale Below - </text> - <text name="MaxAltText"> - Blur Multiplier - </text> - </panel> - <panel label="圖åƒ" name="Waves"> - <text name="BHText"> - Big Wave Direction - </text> - <text name="WaterWave1DirXText"> - X - </text> - <text name="WaterWave1DirYText"> - Y - </text> - <text name="BHText2"> - Little Wave Direction - </text> - <text name="WaterWave2DirXText"> - X - </text> - <text name="WaterWave2DirYText"> - Y - </text> - <text name="BHText3"> - æ£å¸¸åœ°åœ– - </text> - </panel> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_windlight_options.xml b/indra/newview/skins/default/xui/zh/floater_windlight_options.xml deleted file mode 100644 index 383e35d50d..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_windlight_options.xml +++ /dev/null @@ -1,167 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="WindLight floater" title="進階天空編輯器"> - <floater.string name="WLDefaultSkyNames"> - A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor's Delight:Sheer Sensuality - </floater.string> - <text name="KeyFramePresetsText"> - 天空é è¨å€¼ï¼š - </text> - <button label="新增" label_selected="新增" name="WLNewPreset"/> - <button label="儲å˜" label_selected="儲å˜" name="WLSavePreset"/> - <button label="刪除" label_selected="刪除" name="WLDeletePreset"/> - <button label="日循環編輯器" label_selected="日循環編輯器" name="WLDayCycleMenuButton"/> - <tab_container name="WindLight Tabs"> - <panel label="大氣" name="Atmosphere"> - <text name="BHText"> - è—天水平線 - </text> - <text name="BHText2"> - R - </text> - <text name="BHText3"> - G - </text> - <text name="BHText4"> - B - </text> - <text name="BHText5"> - I - </text> - <text name="BDensText"> - 陰霾水平線 - </text> - <text name="BDensText2"> - è—天密度 - </text> - <text name="BHText6"> - R - </text> - <text name="BHText7"> - G - </text> - <text name="BHText8"> - B - </text> - <text name="BHText9"> - I - </text> - <text name="HDText"> - 陰霾密度 - </text> - <text name="DensMultText"> - 密度å€å¢ž - </text> - <text name="WLDistanceMultText"> - è·é›¢å€å¢ž - </text> - <text name="MaxAltText"> - 最大高度 - </text> - </panel> - <panel label="照明" name="Lighting"> - <text name="SLCText"> - æ—¥ï¼æœˆ é¡è‰² - </text> - <text name="BHText"> - R - </text> - <text name="BHText2"> - G - </text> - <text name="BHText3"> - B - </text> - <text name="BHText4"> - I - </text> - <text name="TODText"> - æ—¥ï¼æœˆ ä½ç½® - </text> - <text name="WLAmbientText"> - 環境 - </text> - <text name="BHText5"> - R - </text> - <text name="BHText6"> - G - </text> - <text name="BHText7"> - B - </text> - <text name="BHText8"> - I - </text> - <text name="WLEastAngleText"> - æ±å‡è§’度 - </text> - <text name="SunGlowText"> - å¤ªé™½å…‰è¼ - </text> - <slider label="焦點" name="WLGlowB"/> - <slider label="尺寸" name="WLGlowR"/> - <text name="SceneGammaText"> - å ´æ™¯ Gamma 值 - </text> - <text name="WLStarText"> - 星空é‡åº¦ - </text> - </panel> - <panel label="雲彩" name="Clouds"> - <text name="WLCloudColorText"> - 雲彩é¡è‰² - </text> - <text name="BHText"> - R - </text> - <text name="BHText2"> - G - </text> - <text name="BHText3"> - B - </text> - <text name="BHText4"> - I - </text> - <text name="WLCloudColorText2"> - 雲彩 XY 軸 / 密度 - </text> - <text name="BHText5"> - X - </text> - <text name="BHText6"> - Y - </text> - <text name="BHText7"> - D - </text> - <text name="WLCloudCoverageText"> - 雲彩覆蓋 - </text> - <text name="WLCloudScaleText"> - é›²å½©è¦æ¨¡ - </text> - <text name="WLCloudDetailText"> - 雲彩細節(XY 軸 / 密度) - </text> - <text name="BHText8"> - X - </text> - <text name="BHText9"> - Y - </text> - <text name="BHText10"> - D - </text> - <text name="WLCloudScrollXText"> - 雲彩 X 滾軸 - </text> - <check_box label="鎖定" name="WLCloudLockX"/> - <text name="WLCloudScrollYText"> - 雲彩 Y 滾軸 - </text> - <check_box label="鎖定" name="WLCloudLockY"/> - <check_box label="æç¹ªå‚³çµ±é›²å½©" name="DrawClassicClouds"/> - </panel> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_window_size.xml b/indra/newview/skins/default/xui/zh/floater_window_size.xml index 54b72afccc..3942f72d76 100644 --- a/indra/newview/skins/default/xui/zh/floater_window_size.xml +++ b/indra/newview/skins/default/xui/zh/floater_window_size.xml @@ -7,10 +7,17 @@ è¨å®šè¦–窗尺寸大å°ï¼š </text> <combo_box name="window_size_combo" tool_tip="寬度 x 高度"> - <combo_box.item label="1000 x 700 (é è¨ï¼‰" name="item0"/> - <combo_box.item label="1024 x 768" name="item1"/> - <combo_box.item label="1280 x 720 (720p)" name="item2"/> - <combo_box.item label="1920 x 1080 (1080p)" name="item3"/> + <combo_box.item label="1000 x 700 (é è¨ï¼‰" name="item1"/> + <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/> + <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/> + <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/> + <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/> + <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/> + <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/> + <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/> + <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/> + <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/> + <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/> </combo_box> <button label="è¨å®š" name="set_btn"/> <button label="å–æ¶ˆ" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_world_map.xml b/indra/newview/skins/default/xui/zh/floater_world_map.xml index 6ac6fb76b7..4cd05ebaa0 100644 --- a/indra/newview/skins/default/xui/zh/floater_world_map.xml +++ b/indra/newview/skins/default/xui/zh/floater_world_map.xml @@ -8,7 +8,7 @@ <panel name="layout_panel_2"> <button name="Show My Location" tool_tip="以我的化身所在ä½ç½®å±…ä¸åœ°åœ–"/> <text name="me_label"> - 自己 + 我自己 </text> <text name="person_label"> 人 @@ -23,14 +23,14 @@ 土地æ‹è³£ </text> <text name="by_owner_label"> - 便“有者 + 便‰€æœ‰äºº </text> - <button name="Go Home" tool_tip="瞬間傳é€åˆ°æˆ‘的家ä½ç½®"/> + <button name="Go Home" tool_tip="瞬間返回我的家"/> <text name="Home_label"> - å®¶ + 我的家 </text> <text name="events_label"> - 事件: + 活動: </text> <text name="pg_label"> 一般普級 @@ -57,17 +57,17 @@ </combo_box> <search_editor label="地å€ä¾å稱" name="location" tool_tip="輸入一個地å€çš„å稱"/> <button label="尋找" name="DoSearch" tool_tip="æœå°‹åœ°å€"/> - <button name="Clear" tool_tip="Clear tracking lines and reset map"/> + <button name="Clear" tool_tip="清楚追蹤線並é‡è¨åœ°åœ–"/> <text name="events_label"> ä½ç½®ï¼š </text> <button label="瞬間傳é€" name="Teleport" tool_tip="瞬間傳é€åˆ°æ‰€é¸çš„ä½ç½®"/> - <button label="覆製 SLurl" name="copy_slurl" tool_tip="Copies current location as SLurl to be used on the web."/> - <button label="Show Selection" name="Show Destination" tool_tip="Center map on selected location"/> + <button label="覆製 SLurl" name="copy_slurl" tool_tip="將目å‰ä½ç½®è¤‡è£½ç‚ºå¯åœ¨ç¶²è·¯ä¸Šä½¿ç”¨çš„ SLurl。"/> + <button label="é¡¯ç¤ºé¸æ“‡" name="Show Destination" tool_tip="將所é¸ä½ç½®ç§»åˆ°åœ°åœ–ä¸å¤®"/> </panel> <panel name="layout_panel_5"> <text name="zoom_label"> - Zoom + 縮放 </text> </panel> </floater> diff --git a/indra/newview/skins/default/xui/zh/inspect_avatar.xml b/indra/newview/skins/default/xui/zh/inspect_avatar.xml index 02e81983a6..ef10e5d2d0 100644 --- a/indra/newview/skins/default/xui/zh/inspect_avatar.xml +++ b/indra/newview/skins/default/xui/zh/inspect_avatar.xml @@ -10,16 +10,16 @@ <string name="Details"> [SL_PROFILE] </string> - <text name="user_subtitle" value="11 Months, 3 days old"/> + <text name="user_subtitle" value="年齡 11 å€‹æœˆåˆ 3 天"/> <text name="user_details"> - This is my second life description and I really think it is great. But for some reason my description is super extra long because I like to talk a whole lot + 這是我的「第二人生ã€è³‡è¨Šã€‚é€™åœ°æ–¹å¤ªæ£’äº†ï¼ åªä¸éŽï¼Œå¯æ˜¯å˜›â€¦â€¦æˆ‘的訊æ¯ç›¸ç•¶ç›¸ç•¶çš„å†—é•·ï¼Œå› ç‚ºâ€¦â€¦æˆ‘æ»¿æ„›ä¸ƒå˜´å…«èˆŒçš„å•¦ã€‚ </text> - <slider name="volume_slider" tool_tip="Voice volume" value="0.5"/> + <slider name="volume_slider" tool_tip="音é‡" value="0.5"/> <button label="åŠ ç‚ºæœ‹å‹" name="add_friend_btn"/> <button label="IM" name="im_btn"/> <button label="檔案" name="view_profile_btn"/> <panel name="moderator_panel"> - <button label="Disable Voice" name="disable_voice"/> - <button label="Enable Voice" name="enable_voice"/> + <button label="åœç”¨èªžéŸ³" name="disable_voice"/> + <button label="啟用語音" name="enable_voice"/> </panel> </floater> diff --git a/indra/newview/skins/default/xui/zh/inspect_group.xml b/indra/newview/skins/default/xui/zh/inspect_group.xml index ac331be203..ca5ccc3349 100644 --- a/indra/newview/skins/default/xui/zh/inspect_group.xml +++ b/indra/newview/skins/default/xui/zh/inspect_group.xml @@ -17,14 +17,14 @@ ä½ æ˜¯æˆå“¡ </string> <text name="group_subtitle"> - 123 members + 123 使ˆå“¡ </text> <text name="group_details"> - A group of folks charged with creating a room with a moose. -Fear the moose! Fear it! And the mongoose too! + 這一群人責在建立有麋鹿的房間。 +éº‹é¹¿è¬æ²ï¼è²“é¼¬è¬æ²ï¼ </text> <text name="group_cost"> - L$123 to join + åŠ å…¥è²»ç”¨ L$123 </text> <button label="åŠ å…¥" name="join_btn"/> <button label="退出" name="leave_btn"/> diff --git a/indra/newview/skins/default/xui/zh/inspect_object.xml b/indra/newview/skins/default/xui/zh/inspect_object.xml index 58091b3aef..377b8b7c78 100644 --- a/indra/newview/skins/default/xui/zh/inspect_object.xml +++ b/indra/newview/skins/default/xui/zh/inspect_object.xml @@ -5,40 +5,40 @@ --> <floater name="inspect_object"> <string name="Creator"> - By [CREATOR] + 創作人 [CREATOR] </string> <string name="CreatorAndOwner"> - By [CREATOR] -Owner [OWNER] + 創作人 [CREATOR] +所有人 [OWNER] </string> <string name="Price"> L$[AMOUNT] </string> <string name="PriceFree"> - Free! + å…è²»ï¼ </string> <string name="Touch"> - Touch + 觸碰 </string> <string name="Sit"> - Sit + å下 </string> <text name="object_creator"> - by secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about -owner secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about + 創作人 secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about +所有人 secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about </text> <text name="price_text"> L$30,000 </text> - <icon name="secure_browsing" tool_tip="Secure Browsing"/> + <icon name="secure_browsing" tool_tip="安全ç€è¦½"/> <text name="object_media_url"> http://www.superdupertest.com </text> <button label="購買" name="buy_btn"/> <button label="支付" name="pay_btn"/> <button label="å–得副本" name="take_free_copy_btn"/> - <button label="Touch" name="touch_btn"/> - <button label="Sit" name="sit_btn"/> - <button label="Open" name="open_btn"/> - <button label="More" name="more_info_btn"/> + <button label="觸碰" name="touch_btn"/> + <button label="å下" name="sit_btn"/> + <button label="打開" name="open_btn"/> + <button label="更多" name="more_info_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/inspect_remote_object.xml b/indra/newview/skins/default/xui/zh/inspect_remote_object.xml index bed19d6d78..b8418fc8a1 100644 --- a/indra/newview/skins/default/xui/zh/inspect_remote_object.xml +++ b/indra/newview/skins/default/xui/zh/inspect_remote_object.xml @@ -5,10 +5,10 @@ --> <floater name="inspect_remote_object"> <text name="object_name"> - Test Object Name That Is Really Long OMG so long I can't believe how long the name of this object is, I mean really. + 測試很長很長ã€é•·åˆ°ä¸å¯æ€è°çš„ã€è½è½é•·çš„ã€é•·å¾—ä¸å¾—了的ã€å¾ˆé•·å¾ˆé•·å¾ˆé•·ã€é•·åˆ°æˆ‘快發瘋ã€é•·ä¹‹åˆé•·çš„物件å稱。 </text> <text name="object_owner_label"> - æ“æœ‰è€…: + 所有人: </text> <text name="object_owner"> Longavatarname Johnsonlongstonnammer diff --git a/indra/newview/skins/default/xui/zh/menu_attachment_self.xml b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml index 1911a1aeff..c14a98c64b 100644 --- a/indra/newview/skins/default/xui/zh/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Attachment Pie"> - <menu_item_call label="Touch" name="Attachment Object Touch"/> + <menu_item_call label="觸碰" name="Attachment Object Touch"/> <menu_item_call label="編輯" name="Edit..."/> <menu_item_call label="å¸ä¸‹" name="Detach"/> <menu_item_call label="å下" name="Sit Down Here"/> @@ -10,7 +10,7 @@ <menu_item_call label="編輯我的體形" name="Edit My Shape"/> <menu_item_call label="我的朋å‹" name="Friends..."/> <menu_item_call label="我的群組" name="Groups..."/> - <menu_item_call label="我的檔案" name="Profile..."/> + <menu_item_call label="我的個人檔案" name="Profile..."/> <menu_item_call label="æè³ªé™¤éŒ¯" name="Debug..."/> <menu_item_call label="丟棄" name="Drop"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_other.xml b/indra/newview/skins/default/xui/zh/menu_avatar_other.xml index 260571eb54..1d02464748 100644 --- a/indra/newview/skins/default/xui/zh/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/zh/menu_avatar_other.xml @@ -6,11 +6,11 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="通話" name="Call"/> <menu_item_call label="é‚€è«‹åŠ å…¥ç¾¤çµ„" name="Invite..."/> - <menu_item_call label="Block" name="Avatar Mute"/> + <menu_item_call label="å°éŽ–" name="Avatar Mute"/> <menu_item_call label="å›žå ±" name="abuse"/> <menu_item_call label="å‡çµ" name="Freeze..."/> <menu_item_call label="踢出" name="Eject..."/> <menu_item_call label="æè³ªé™¤éŒ¯" name="Debug..."/> - <menu_item_call label="Zoom In" name="Zoom In"/> + <menu_item_call label="放大" name="Zoom In"/> <menu_item_call label="支付" name="Pay..."/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_self.xml b/indra/newview/skins/default/xui/zh/menu_avatar_self.xml index d516e3ab58..32757bbff6 100644 --- a/indra/newview/skins/default/xui/zh/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/zh/menu_avatar_self.xml @@ -14,19 +14,19 @@ <menu_item_call label="å…§è¡£" name="Self Undershirt"/> <menu_item_call label="內褲" name="Self Underpants"/> <menu_item_call label="刺é’" name="Self Tattoo"/> - <menu_item_call label="Physics" name="Self Physics"/> + <menu_item_call label="身體物ç†" name="Self Physics"/> <menu_item_call label="åŠé€æ˜Ž" name="Self Alpha"/> <menu_item_call label="全部衣æœ" name="All Clothes"/> </context_menu> - <context_menu label="HUD" name="Object Detach HUD"/> + <context_menu label="æ“¡é 顯示" name="Object Detach HUD"/> <context_menu label="å¸ä¸‹" name="Object Detach"/> <menu_item_call label="全部å¸ä¸‹" name="Detach All"/> </context_menu> <menu_item_call label="我的外觀" name="Chenge Outfit"/> - <menu_item_call label="ç·¨è¼¯æˆ‘è£æ‰®" name="Edit Outfit"/> + <menu_item_call label="ç·¨è¼¯æˆ‘çš„è£æ‰®" name="Edit Outfit"/> <menu_item_call label="編輯我的體形" name="Edit My Shape"/> <menu_item_call label="我的朋å‹" name="Friends..."/> <menu_item_call label="我的群組" name="Groups..."/> - <menu_item_call label="我的檔案" name="Profile..."/> + <menu_item_call label="我的個人檔案" name="Profile..."/> <menu_item_call label="æè³ªé™¤éŒ¯" name="Debug..."/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_bottomtray.xml b/indra/newview/skins/default/xui/zh/menu_bottomtray.xml deleted file mode 100644 index a00aa7cd35..0000000000 --- a/indra/newview/skins/default/xui/zh/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="講話按鈕" name="EnableVoiceChat"/> - <menu_item_check label="姿勢按鈕" name="ShowGestureButton"/> - <menu_item_check label="移動按鈕" name="ShowMoveButton"/> - <menu_item_check label="視角按鈕" name="ShowCameraButton"/> - <menu_item_check label="快照按鈕" name="ShowSnapshotButton"/> - <menu_item_check label="å»ºé€ æŒ‰éˆ•" name="ShowBuildButton"/> - <menu_item_check label="æœå°‹æŒ‰éˆ•" name="ShowSearchButton"/> - <menu_item_check label="地圖按鈕" name="ShowWorldMapButton"/> - <menu_item_check label="è¿·ä½ åœ°åœ–æŒ‰éˆ•" name="ShowMiniMapButton"/> - <menu_item_call label="剪下" name="NearbyChatBar_Cut"/> - <menu_item_call label="覆製" name="NearbyChatBar_Copy"/> - <menu_item_call label="貼上" name="NearbyChatBar_Paste"/> - <menu_item_call label="刪除" name="NearbyChatBar_Delete"/> - <menu_item_call label="å…¨é¸" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_edit.xml b/indra/newview/skins/default/xui/zh/menu_edit.xml index d6eb87a6b0..bda640e5f3 100644 --- a/indra/newview/skins/default/xui/zh/menu_edit.xml +++ b/indra/newview/skins/default/xui/zh/menu_edit.xml @@ -3,7 +3,7 @@ <menu_item_call label="復原" name="Undo"/> <menu_item_call label="é‡åš" name="Redo"/> <menu_item_call label="剪下" name="Cut"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="æšåº¨" name="Copy"/> <menu_item_call label="貼上" name="Paste"/> <menu_item_call label="刪除" name="Delete"/> <menu_item_call label="覆製貼上" name="Duplicate"/> diff --git a/indra/newview/skins/default/xui/zh/menu_favorites.xml b/indra/newview/skins/default/xui/zh/menu_favorites.xml index c60bebd3dc..a01412ce1c 100644 --- a/indra/newview/skins/default/xui/zh/menu_favorites.xml +++ b/indra/newview/skins/default/xui/zh/menu_favorites.xml @@ -4,7 +4,7 @@ <menu_item_call label="察看 / 編輯 地標" name="Landmark Open"/> <menu_item_call label="覆製 SLurl" name="Copy slurl"/> <menu_item_call label="顯示在地圖上" name="Show On Map"/> - <menu_item_call label="覆製" name="Landmark Copy"/> + <menu_item_call label="æšåº¨" name="Landmark Copy"/> <menu_item_call label="貼上" name="Landmark Paste"/> <menu_item_call label="刪除" name="Delete"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml b/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml index a331c47a6e..5a38197e4c 100644 --- a/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml +++ b/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <toggleable_menu name="menu_gesture_gear"> <menu_item_call label="ç”±æˆ‘çš„æœ€æ„›ä¸ æ·»åŠ /移除" name="activate"/> - <menu_item_call label="覆製" name="copy_gesture"/> + <menu_item_call label="æšåº¨" name="copy_gesture"/> <menu_item_call label="貼上" name="paste"/> <menu_item_call label="覆製 UUID" name="copy_uuid"/> <menu_item_call label="儲å˜åˆ°ç›®å‰è£æ‰®" name="save_to_outfit"/> diff --git a/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml b/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml index dbb8ececaa..3f6820cb32 100644 --- a/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml +++ b/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu name="hide_navbar_menu"> - <menu_item_check label="顯示導覽列" name="ShowNavbarNavigationPanel"/> + <menu_item_check label="顯示導覽列和我的最愛" name="ShowNavbarNavigationPanel"/> <menu_item_check label="顯示最愛列" name="ShowNavbarFavoritesPanel"/> <menu_item_check label="é¡¯ç¤ºè¿·ä½ ä½ç½®åˆ—" name="ShowMiniLocationPanel"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_im_well_button.xml b/indra/newview/skins/default/xui/zh/menu_im_well_button.xml deleted file mode 100644 index 4b9b4b2758..0000000000 --- a/indra/newview/skins/default/xui/zh/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<context_menu name="IM Well Button Context Menu"> - <menu_item_call label="全部關閉" name="Close All"/> -</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml index 7385764e4c..f4e886ff67 100644 --- a/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml +++ b/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml @@ -6,16 +6,16 @@ <menu_item_call label="通話" name="call"/> <menu_item_call label="瞬間傳é€" name="teleport"/> <menu_item_call label="é‚€è«‹åŠ å…¥ç¾¤çµ„" name="invite_to_group"/> - <menu_item_call label="Block" name="block"/> - <menu_item_call label="Unblock" name="unblock"/> + <menu_item_call label="å°éŽ–" name="block"/> + <menu_item_call label="解除å°éŽ–" name="unblock"/> <menu_item_call label="å›žå ±" name="report"/> <menu_item_call label="å‡çµ" name="freeze"/> <menu_item_call label="踢出" name="eject"/> <menu_item_call label="踢出" name="kick"/> - <menu_item_call label="CSR" name="csr"/> + <menu_item_call label="客æœ" name="csr"/> <menu_item_call label="æè³ªé™¤éŒ¯" name="debug"/> <menu_item_call label="在地圖上尋找" name="find_on_map"/> - <menu_item_call label="Zoom In" name="zoom_in"/> + <menu_item_call label="放大" name="zoom_in"/> <menu_item_call label="支付" name="pay"/> <menu_item_call label="分享" name="share"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml index 94ab82b8a9..abff0f64ac 100644 --- a/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml @@ -2,17 +2,18 @@ <toggleable_menu name="Gear Menu"> <menu_item_call label="觸碰" name="touch"/> <menu_item_call label="å下" name="sit"/> - <menu_item_call label="Pay" name="pay"/> + <menu_item_call label="支付" name="pay"/> <menu_item_call label="購買" name="buy"/> <menu_item_call label="å–å¾—" name="take"/> <menu_item_call label="å–得副本" name="take_copy"/> - <menu_item_call label="開啟" name="open"/> + <menu_item_call label="打開" name="open"/> <menu_item_call label="編輯" name="edit"/> <menu_item_call label="穿上" name="wear"/> <menu_item_call label="æ·»åŠ " name="add"/> <menu_item_call label="å›žå ±" name="report"/> - <menu_item_call label="Block" name="block"/> - <menu_item_call label="Zoom In" name="zoom_in"/> + <menu_item_call label="å°éŽ–" name="block"/> + <menu_item_call label="解除å°éŽ–" name="unblock"/> + <menu_item_call label="放大" name="zoom_in"/> <menu_item_call label="移除" name="remove"/> <menu_item_call label="更多資訊" name="more_info"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml index 1c75705743..c48ee0c9be 100644 --- a/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml +++ b/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml @@ -17,7 +17,7 @@ <menu_item_call label="åŠé€æ˜Ž" name="Self Alpha"/> <menu_item_call label="全部衣æœ" name="All Clothes"/> </context_menu> - <context_menu label="HUD" name="Object Detach HUD"/> + <context_menu label="æ“¡é 顯示" name="Object Detach HUD"/> <context_menu label="å¸ä¸‹" name="Object Detach"/> <menu_item_call label="全部å¸ä¸‹" name="Detach All"/> </context_menu> @@ -26,6 +26,6 @@ <menu_item_call label="編輯我的體形" name="Edit My Shape"/> <menu_item_call label="我的朋å‹" name="Friends..."/> <menu_item_call label="我的群組" name="Groups..."/> - <menu_item_call label="我的檔案" name="Profile..."/> + <menu_item_call label="我的個人檔案" name="Profile..."/> <menu_item_call label="æè³ªé™¤éŒ¯" name="Debug..."/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inventory.xml b/indra/newview/skins/default/xui/zh/menu_inventory.xml index 87d769af0d..7f745ffaa7 100644 --- a/indra/newview/skins/default/xui/zh/menu_inventory.xml +++ b/indra/newview/skins/default/xui/zh/menu_inventory.xml @@ -2,13 +2,13 @@ <menu name="Popup"> <menu_item_call label="分享" name="Share"/> <menu_item_call label="購買" name="Task Buy"/> - <menu_item_call label="開啟" name="Task Open"/> + <menu_item_call label="打開" name="Task Open"/> <menu_item_call label="æ’æ”¾" name="Task Play"/> <menu_item_call label="屬性" name="Task Properties"/> <menu_item_call label="æ›´å" name="Task Rename"/> <menu_item_call label="刪除" name="Task Remove"/> <menu_item_call label="清空垃圾ç’" name="Empty Trash"/> - <menu_item_call label="清空 Lost And Found" name="Empty Lost And Found"/> + <menu_item_call label="清空所有失物" name="Empty Lost And Found"/> <menu_item_call label="新資料夾" name="New Folder"/> <menu_item_call label="新腳本" name="New Script"/> <menu_item_call label="新記事å¡" name="New Note"/> @@ -18,7 +18,7 @@ <menu_item_call label="新褲å" name="New Pants"/> <menu_item_call label="æ–°éž‹å" name="New Shoes"/> <menu_item_call label="新襪å" name="New Socks"/> - <menu_item_call label="新夾克" name="New Jacket"/> + <menu_item_call label="新外套" name="New Jacket"/> <menu_item_call label="新裙å" name="New Skirt"/> <menu_item_call label="新手套" name="New Gloves"/> <menu_item_call label="æ–°å…§è¡£" name="New Undershirt"/> @@ -46,42 +46,46 @@ <menu_item_call label="å…§è¡£" name="Undershirt"/> </menu> <menu_item_call label="瞬間傳é€" name="Landmark Open"/> - <menu_item_call label="開啟" name="Animation Open"/> - <menu_item_call label="開啟" name="Sound Open"/> + <menu_item_call label="打開" name="Animation Open"/> + <menu_item_call label="打開" name="Sound Open"/> <menu_item_call label="å–代目å‰çš„è£æ‰®" name="Replace Outfit"/> <menu_item_call label="æ·»åŠ åˆ°ç›®å‰è£æ‰®" name="Add To Outfit"/> <menu_item_call label="由目å‰çš„è£æ‰®ç§»é™¤" name="Remove From Outfit"/> <menu_item_call label="尋找原件" name="Find Original"/> <menu_item_call label="清空物å“" name="Purge Item"/> - <menu_item_call label="æ¢å¾©ç‰©å“" name="Restore Item"/> - <menu_item_call label="開啟" name="Open"/> + <menu_item_call label="還原物å“" name="Restore Item"/> + <menu_item_call label="打開" name="Open"/> <menu_item_call label="開啟原件" name="Open Original"/> <menu_item_call label="屬性" name="Properties"/> <menu_item_call label="æ›´å" name="Rename"/> <menu_item_call label="覆製資產 UUID" name="Copy Asset UUID"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="剪下" name="Cut"/> + <menu_item_call label="æšåº¨" name="Copy"/> <menu_item_call label="貼上" name="Paste"/> - <menu_item_call label="Paste As Link" name="Paste As Link"/> + <menu_item_call label="ä»¥é€£çµæ ¼å¼è²¼ä¸Š" name="Paste As Link"/> <menu_item_call label="刪除" name="Remove Link"/> <menu_item_call label="刪除" name="Delete"/> <menu_item_call label="刪除系統資料夾" name="Delete System Folder"/> - <menu_item_call label="Start Conference Chat" name="Conference Chat Folder"/> + <menu_item_call label="發起多方通話" name="Conference Chat Folder"/> <menu_item_call label="æ’æ”¾" name="Sound Play"/> + <menu_item_call label="覆製 SLurl" name="url_copy"/> <menu_item_call label="æ·»åŠ åœ°æ¨™" name="About Landmark"/> - <menu_item_call label="æ’æ”¾æ–¼è™›æ“¬ä¸–界" name="Animation Play"/> - <menu_item_call label="æ’æ”¾æ–¼æœ¬åœ°" name="Animation Audition"/> + <menu_item_call label="åœ¨è™›æ“¬ä¸–ç•Œæ’æ”¾" name="Animation Play"/> + <menu_item_call label="åœ¨æœ¬åœ°æ’æ”¾" name="Animation Audition"/> <menu_item_call label="é€å‡ºå³æ™‚訊æ¯" name="Send Instant Message"/> - <menu_item_call label="發給瞬間傳é€è«‹æ±‚..." name="Offer Teleport..."/> - <menu_item_call label="開始會è°äº¤è«‡" name="Conference Chat"/> - <menu_item_call label="Activate" name="Activate"/> - <menu_item_call label="Deactivate" name="Deactivate"/> - <menu_item_call label="å¦å˜" name="Save As"/> - <menu_item_call label="Detach From Yourself" name="Detach From Yourself"/> - <menu_item_call label="Wear" name="Wearable And Object Wear"/> - <menu label="Attach To" name="Attach To"/> - <menu label="Attach To HUD" name="Attach To HUD"/> + <menu_item_call label="發出瞬間傳é€é‚€è«‹..." name="Offer Teleport..."/> + <menu_item_call label="發起多方通話" name="Conference Chat"/> + <menu_item_call label="啟動" name="Activate"/> + <menu_item_call label="åœç”¨" name="Deactivate"/> + <menu_item_call label="å¦å˜ç‚º" name="Save As"/> + <menu_item_call label="å¾žä½ èº«ä¸Šç§»é™¤" name="Detach From Yourself"/> + <menu_item_call label="穿上" name="Wearable And Object Wear"/> + <menu label="附著到..." name="Attach To"/> + <menu label="附著到擡é 顯示" name="Attach To HUD"/> <menu_item_call label="編輯" name="Wearable Edit"/> <menu_item_call label="æ·»åŠ " name="Wearable Add"/> <menu_item_call label="脫下" name="Take Off"/> + <menu_item_call label="複製到商家發件匣" name="Merchant Copy"/> + <menu_item_call label="é€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集" name="Marketplace Send"/> <menu_item_call label="-- ç„¡é¸é … --" name="--no options--"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inventory_add.xml b/indra/newview/skins/default/xui/zh/menu_inventory_add.xml index a0fc060e27..30bf5a7e75 100644 --- a/indra/newview/skins/default/xui/zh/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/zh/menu_inventory_add.xml @@ -4,7 +4,9 @@ <menu_item_call label="圖åƒï¼ˆL$[COST])..." name="Upload Image"/> <menu_item_call label="è²éŸ³ï¼ˆL$[COST])..." name="Upload Sound"/> <menu_item_call label="動作(L$[COST])..." name="Upload Animation"/> - <menu_item_call label="大批(L$[COST] æ¯æª”案)..." name="Bulk Upload"/> + <menu_item_call label="模型…" name="Upload Model"/> + <menu_item_call label="模型精éˆâ€¦" name="Upload Model Wizard"/> + <menu_item_call label="批é‡ï¼ˆæ¯æª”案 L$[COST] )..." name="Bulk Upload"/> <menu_item_call label="è¨å®šé è¨ä¸Šå‚³æ¬Šé™" name="perm prefs"/> </menu> <menu_item_call label="新資料夾" name="New Folder"/> @@ -16,7 +18,7 @@ <menu_item_call label="新褲å" name="New Pants"/> <menu_item_call label="æ–°éž‹å" name="New Shoes"/> <menu_item_call label="新襪å" name="New Socks"/> - <menu_item_call label="新夾克" name="New Jacket"/> + <menu_item_call label="新外套" name="New Jacket"/> <menu_item_call label="新裙å" name="New Skirt"/> <menu_item_call label="新手套" name="New Gloves"/> <menu_item_call label="æ–°å…§è¡£" name="New Undershirt"/> diff --git a/indra/newview/skins/default/xui/zh/menu_land.xml b/indra/newview/skins/default/xui/zh/menu_land.xml index 84941d138c..a87ab77dd0 100644 --- a/indra/newview/skins/default/xui/zh/menu_land.xml +++ b/indra/newview/skins/default/xui/zh/menu_land.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Land Pie"> - <menu_item_call label="關於土地" name="Place Information..."/> - <menu_item_call label="å在æ¤è™•" name="Sit Here"/> + <menu_item_call label="土地資料" name="Place Information..."/> + <menu_item_call label="å在這裡" name="Sit Here"/> <menu_item_call label="購買這塊土地" name="Land Buy"/> <menu_item_call label="購買通行權" name="Land Buy Pass"/> <menu_item_call label="å»ºé€ " name="Create"/> diff --git a/indra/newview/skins/default/xui/zh/menu_login.xml b/indra/newview/skins/default/xui/zh/menu_login.xml index d6bf34c66e..c327b132a1 100644 --- a/indra/newview/skins/default/xui/zh/menu_login.xml +++ b/indra/newview/skins/default/xui/zh/menu_login.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu_bar name="Login Menu"> - <menu label="自己" name="File"> - <menu_item_call label="å好è¨å®š" name="Preferences..."/> - <menu_item_call label="çµæŸé€€å‡º [APP_NAME]" name="Quit"/> + <menu label="我自己" name="File"> + <menu_item_call label="å好è¨å®šâ€¦" name="Preferences..."/> + <menu_item_call label="退出 [APP_NAME]" name="Quit"/> </menu> <menu label="幫助" name="Help"> <menu_item_call label="[SECOND_LIFE] 幫助" name="Second Life Help"/> @@ -14,11 +14,11 @@ <menu_item_call label="UI / é¡è‰² è¨å®š" name="UI/Color Settings"/> <menu_item_call label="XUI é 覽工具" name="UI Preview Tool"/> <menu label="UI 測試" name="UI Tests"/> - <menu_item_call label="è¨å®šè¦–窗尺寸大å°..." name="Set Window Size..."/> + <menu_item_call label="è¨å®šè¦–窗大å°..." name="Set Window Size..."/> <menu_item_call label="顯示 TOS" name="TOS"/> <menu_item_call label="顯示嚴é‡è¨Šæ¯" name="Critical"/> - <menu_item_call label="媒體ç€è¦½å™¨æ¸¬è©¦" name="Web Browser Test"/> - <menu_item_call label="ç¶²é 內容浮動視窗測試" name="Web Content Floater Test"/> + <menu_item_call label="ç¶²é 內容浮動視窗除錯測試" name="Web Content Floater Debug Test"/> + <menu label="è¨å®šè¨˜éŒ„細節" name="Set Logging Level"/> <menu_item_check label="é¡¯ç¤ºç¶²æ ¼æŒ‘é¸å™¨" name="Show Grid Picker"/> <menu_item_call label="顯示通知控制å°" name="Show Notifications Console"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml b/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml index 2ec95aa4f9..d222d7f658 100644 --- a/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml +++ b/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="media ctrl context menu"> <menu_item_call label="剪下" name="Cut"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="æšåº¨" name="Copy"/> <menu_item_call label="貼上" name="Paste"/> + <menu_item_call label="開啟網é 嵿Ÿ¥å™¨" name="open_webinspector"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_mini_map.xml b/indra/newview/skins/default/xui/zh/menu_mini_map.xml index 24bc6355c7..7fd629471a 100644 --- a/indra/newview/skins/default/xui/zh/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/zh/menu_mini_map.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu name="Popup"> - <menu_item_call label="Zoom Close" name="Zoom Close"/> - <menu_item_call label="Zoom Medium" name="Zoom Medium"/> - <menu_item_call label="Zoom Far" name="Zoom Far"/> - <menu_item_call label="Zoom Default" name="Zoom Default"/> + <menu_item_call label="放大é è¿‘" name="Zoom Close"/> + <menu_item_call label="é è¿‘é©è·" name="Zoom Medium"/> + <menu_item_call label="縮å°é 離" name="Zoom Far"/> + <menu_item_call label="縮放æ¢å¾©é è¨" name="Zoom Default"/> <menu_item_check label="旋轉地圖" name="Rotate Map"/> <menu_item_check label="自動居ä¸" name="Auto Center"/> <menu_item_call label="åœæ¢è¿½è¹¤" name="Stop Tracking"/> diff --git a/indra/newview/skins/default/xui/zh/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/zh/menu_model_import_gear_default.xml new file mode 100644 index 0000000000..5f82685632 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_model_import_gear_default.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="model_menu_gear_default"> + <menu_item_check label="顯示å´é‚Š" name="show_edges"/> + <menu_item_check label="顯示物ç†" name="show_physics"/> + <menu_item_check label="顯示æè³ª" name="show_textures"/> + <menu_item_check label="顯示表皮é‡é‡" name="show_skin_weight"/> + <menu_item_check label="顯示接點ä½ç½®" name="show_joint_positions"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_navbar.xml b/indra/newview/skins/default/xui/zh/menu_navbar.xml index 69df4929f2..d8356e6277 100644 --- a/indra/newview/skins/default/xui/zh/menu_navbar.xml +++ b/indra/newview/skins/default/xui/zh/menu_navbar.xml @@ -4,7 +4,7 @@ <menu_item_check label="顯示地段屬性" name="Show Parcel Properties"/> <menu_item_call label="地標" name="Landmark"/> <menu_item_call label="剪下" name="Cut"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="æšåº¨" name="Copy"/> <menu_item_call label="貼上" name="Paste"/> <menu_item_call label="刪除" name="Delete"/> <menu_item_call label="å…¨é¸" name="Select All"/> diff --git a/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml b/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml index cad462eebb..ce5f5b6e17 100644 --- a/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml +++ b/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu name="NearBy Chat Menu"> <menu_item_call label="顯示附近的人..." name="nearby_people"/> - <menu_item_check label="Show Blocked Text" name="muted_text"/> - <menu_item_check label="Show Buddy Icons" name="show_buddy_icons"/> - <menu_item_check label="Show Names" name="show_names"/> - <menu_item_check label="Show Icons and Names" name="show_icons_and_names"/> + <menu_item_check label="顯示被å°éŽ–æ–‡å—" name="muted_text"/> + <menu_item_check label="顯示密å‹åœ–示" name="show_buddy_icons"/> + <menu_item_check label="顯示åå—" name="show_names"/> + <menu_item_check label="顯示圖示和åå—" name="show_icons_and_names"/> <menu_item_call label="å—型尺寸" name="font_size"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_object.xml b/indra/newview/skins/default/xui/zh/menu_object.xml index ed41a4f0bf..4282c1e131 100644 --- a/indra/newview/skins/default/xui/zh/menu_object.xml +++ b/indra/newview/skins/default/xui/zh/menu_object.xml @@ -3,19 +3,21 @@ <menu_item_call label="觸碰" name="Object Touch"/> <menu_item_call label="編輯" name="Edit..."/> <menu_item_call label="å»ºé€ " name="Build"/> - <menu_item_call label="開啟" name="Open"/> - <menu_item_call label="å下" name="Object Sit"/> + <menu_item_call label="在è¯çµé›†è£¡é¡¯ç¤º" name="show_in_linksets"/> + <menu_item_call label="在角色ä¸é¡¯ç¤º" name="show_in_characters"/> + <menu_item_call label="打開" name="Open"/> + <menu_item_call label="å在這裡" name="Object Sit"/> <menu_item_call label="èµ·ç«‹" name="Object Stand Up"/> <menu_item_call label="物件檔案" name="Object Inspect"/> - <menu_item_call label="Zoom In" name="Zoom In"/> + <menu_item_call label="放大" name="Zoom In"/> <context_menu label="穿上" name="Put On"> <menu_item_call label="穿上" name="Wear"/> <menu_item_call label="æ·»åŠ " name="Add"/> - <context_menu label="Attach" name="Object Attach"/> - <context_menu label="Attach HUD" name="Object Attach HUD"/> + <context_menu label="附著" name="Object Attach"/> + <context_menu label="é™„åŠ æ“¡é 顯示" name="Object Attach HUD"/> </context_menu> <context_menu label="管ç†" name="Remove"> - <menu_item_call label="èˆ‰å ±æ¿«ç”¨" name="Report Abuse..."/> + <menu_item_call label="é•è¦èˆ‰å ±" name="Report Abuse..."/> <menu_item_call label="å°éŽ–" name="Object Mute"/> <menu_item_call label="退回" name="Return..."/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_object_icon.xml b/indra/newview/skins/default/xui/zh/menu_object_icon.xml index d27e75b830..f4f93b0bdc 100644 --- a/indra/newview/skins/default/xui/zh/menu_object_icon.xml +++ b/indra/newview/skins/default/xui/zh/menu_object_icon.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu name="Object Icon Menu"> <menu_item_call label="物件檔案..." name="Object Profile"/> - <menu_item_call label="Block..." name="Block"/> + <menu_item_call label="å°éŽ–â€¦" name="Block"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml b/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml index 90704fee65..e85b4b7182 100644 --- a/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml @@ -8,7 +8,7 @@ <menu_item_call label="新褲å" name="New Pants"/> <menu_item_call label="æ–°éž‹å" name="New Shoes"/> <menu_item_call label="新襪å" name="New Socks"/> - <menu_item_call label="新夾克" name="New Jacket"/> + <menu_item_call label="新外套" name="New Jacket"/> <menu_item_call label="新裙å" name="New Skirt"/> <menu_item_call label="新手套" name="New Gloves"/> <menu_item_call label="æ–°å…§è¡£" name="New Undershirt"/> diff --git a/indra/newview/skins/default/xui/zh/menu_participant_list.xml b/indra/newview/skins/default/xui/zh/menu_participant_list.xml index 81ae6e4e85..2456e9fee9 100644 --- a/indra/newview/skins/default/xui/zh/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/zh/menu_participant_list.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Participant List Context Menu"> <menu_item_check label="ä¾å稱排åº" name="SortByName"/> - <menu_item_check label="Sort by Recent Speakers" name="SortByRecentSpeakers"/> + <menu_item_check label="便œ€è¿‘說話者排åº" name="SortByRecentSpeakers"/> <menu_item_call label="察看檔案" name="View Profile"/> <menu_item_call label="åŠ ç‚ºæœ‹å‹" name="Add Friend"/> <menu_item_call label="IM" name="IM"/> @@ -9,13 +9,13 @@ <menu_item_call label="分享" name="Share"/> <menu_item_call label="支付" name="Pay"/> <menu_item_check label="察看人群圖示" name="View Icons"/> - <menu_item_check label="Block Voice" name="Block/Unblock"/> - <menu_item_check label="Block Text" name="MuteText"/> - <context_menu label="Moderator Options" name="Moderator Options"> - <menu_item_check label="Allow text chat" name="AllowTextChat"/> - <menu_item_call label="Mute this participant" name="ModerateVoiceMuteSelected"/> - <menu_item_call label="Unmute this participant" name="ModerateVoiceUnMuteSelected"/> - <menu_item_call label="Mute everyone" name="ModerateVoiceMute"/> - <menu_item_call label="Unmute everyone" name="ModerateVoiceUnmute"/> + <menu_item_check label="ç¦æ¢èªžéŸ³" name="Block/Unblock"/> + <menu_item_check label="ç¦æ¢æ–‡å—" name="MuteText"/> + <context_menu label="主æŒäººé¸é …" name="Moderator Options"> + <menu_item_check label="å…許文å—èŠå¤©" name="AllowTextChat"/> + <menu_item_call label="å°‡æ¤äººæ¶ˆéŸ³" name="ModerateVoiceMuteSelected"/> + <menu_item_call label="å–æ¶ˆå°æ¤äººçš„æ¶ˆéŸ³" name="ModerateVoiceUnMuteSelected"/> + <menu_item_call label="所有人消音" name="ModerateVoiceMute"/> + <menu_item_call label="å–æ¶ˆæ‰€æœ‰äººçš„æ¶ˆéŸ³" name="ModerateVoiceUnmute"/> </context_menu> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_groups.xml b/indra/newview/skins/default/xui/zh/menu_people_groups.xml index 1d78c1de0a..5768c554c9 100644 --- a/indra/newview/skins/default/xui/zh/menu_people_groups.xml +++ b/indra/newview/skins/default/xui/zh/menu_people_groups.xml @@ -3,6 +3,6 @@ <menu_item_call label="察看資訊" name="View Info"/> <menu_item_call label="èŠå¤©" name="Chat"/> <menu_item_call label="通話" name="Call"/> - <menu_item_call label="Activate" name="Activate"/> - <menu_item_call label="Leave" name="Leave"/> + <menu_item_call label="啟動" name="Activate"/> + <menu_item_call label="退出" name="Leave"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_nearby.xml b/indra/newview/skins/default/xui/zh/menu_people_nearby.xml index 9faa35001c..38d5f3d324 100644 --- a/indra/newview/skins/default/xui/zh/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/zh/menu_people_nearby.xml @@ -2,12 +2,12 @@ <context_menu name="Avatar Context Menu"> <menu_item_call label="察看檔案" name="View Profile"/> <menu_item_call label="åŠ ç‚ºæœ‹å‹" name="Add Friend"/> - <menu_item_call label="Remove Friend" name="Remove Friend"/> + <menu_item_call label="移除朋å‹" name="Remove Friend"/> <menu_item_call label="IM" name="IM"/> <menu_item_call label="通話" name="Call"/> <menu_item_call label="地圖" name="Map"/> <menu_item_call label="分享" name="Share"/> <menu_item_call label="支付" name="Pay"/> - <menu_item_check label="Block/Unblock" name="Block/Unblock"/> + <menu_item_check label="å°éŽ–/ä¸å†å°éŽ–" name="Block/Unblock"/> <menu_item_call label="發給瞬間傳é€è«‹æ±‚" name="teleport"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml index a7f5c74b82..6cb0ac3c89 100644 --- a/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml +++ b/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml @@ -4,5 +4,6 @@ <menu_item_check label="ä¾å稱排åº" name="sort_name"/> <menu_item_check label="ä¾è·é›¢æŽ’åº" name="sort_distance"/> <menu_item_check label="察看人群圖示" name="view_icons"/> - <menu_item_call label="顯示笨å°éŽ–çš„å±…æ°‘èˆ‡ç‰©ä»¶" name="show_blocked_list"/> + <menu_item_check label="察看地圖" name="view_map"/> + <menu_item_call label="顯示被å°éŽ–çš„å±…æ°‘èˆ‡ç‰©ä»¶" name="show_blocked_list"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_picks_plus.xml b/indra/newview/skins/default/xui/zh/menu_picks_plus.xml index e962bd90d5..80922a757d 100644 --- a/indra/newview/skins/default/xui/zh/menu_picks_plus.xml +++ b/indra/newview/skins/default/xui/zh/menu_picks_plus.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <toggleable_menu name="picks_plus_menu"> <menu_item_call label="æ–°ç²¾é¸åœ°é»ž" name="create_pick"/> - <menu_item_call label="New Classified" name="create_classified"/> + <menu_item_call label="新個人廣告" name="create_classified"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml index 7f4144d14d..27f0c7ebdb 100644 --- a/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml +++ b/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml @@ -4,7 +4,7 @@ <menu_item_call label="æ·»åŠ è³‡æ–™å¤¾" name="add_folder"/> <menu_item_call label="還原物å“" name="restore_item"/> <menu_item_call label="剪下" name="cut"/> - <menu_item_call label="覆製" name="copy_folder"/> + <menu_item_call label="æšåº¨" name="copy_folder"/> <menu_item_call label="貼上" name="paste"/> <menu_item_call label="æ›´å" name="rename"/> <menu_item_call label="刪除" name="delete"/> diff --git a/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml b/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml index ca637ae54d..f77e7090c4 100644 --- a/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml +++ b/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml @@ -3,10 +3,10 @@ <menu_item_call label="地圖" name="show_on_map"/> <menu_item_call label="支付" name="pay"/> <menu_item_call label="分享" name="share"/> - <menu_item_call label="Block" name="block"/> - <menu_item_call label="Unblock" name="unblock"/> + <menu_item_call label="å°éŽ–" name="block"/> + <menu_item_call label="解除å°éŽ–" name="unblock"/> <menu_item_call label="踢出" name="kick"/> <menu_item_call label="å‡çµ" name="freeze"/> <menu_item_call label="è§£å‡" name="unfreeze"/> - <menu_item_call label="CSR" name="csr"/> + <menu_item_call label="客æœ" name="csr"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_save_outfit.xml b/indra/newview/skins/default/xui/zh/menu_save_outfit.xml index 7884df5b01..53ee6ee977 100644 --- a/indra/newview/skins/default/xui/zh/menu_save_outfit.xml +++ b/indra/newview/skins/default/xui/zh/menu_save_outfit.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <toggleable_menu name="save_outfit_menu"> <menu_item_call label="儲å˜" name="save_outfit"/> - <menu_item_call label="å¦å˜" name="save_as_new_outfit"/> + <menu_item_call label="å¦å˜ç‚º" name="save_as_new_outfit"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml index f9107a96ed..90e8098348 100644 --- a/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml +++ b/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Teleport History Item Context Menu"> - <menu_item_call label="開啟" name="TabOpen"/> + <menu_item_call label="打開" name="TabOpen"/> <menu_item_call label="關閉" name="TabClose"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_text_editor.xml b/indra/newview/skins/default/xui/zh/menu_text_editor.xml index c25f5128c3..febc0b8b67 100644 --- a/indra/newview/skins/default/xui/zh/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/zh/menu_text_editor.xml @@ -1,7 +1,14 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(未知)" name="Suggestion 1"/> + <menu_item_call label="(未知)" name="Suggestion 2"/> + <menu_item_call label="(未知)" name="Suggestion 3"/> + <menu_item_call label="(未知)" name="Suggestion 4"/> + <menu_item_call label="(未知)" name="Suggestion 5"/> + <menu_item_call label="新增到å—å…¸" name="Add to Dictionary"/> + <menu_item_call label="新增到忽略清單" name="Add to Ignore"/> <menu_item_call label="剪下" name="Cut"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="æšåº¨" name="Copy"/> <menu_item_call label="貼上" name="Paste"/> <menu_item_call label="刪除" name="Delete"/> <menu_item_call label="å…¨é¸" name="Select All"/> diff --git a/indra/newview/skins/default/xui/zh/menu_toolbars.xml b/indra/newview/skins/default/xui/zh/menu_toolbars.xml new file mode 100644 index 0000000000..d318992dd5 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_toolbars.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Toolbars Popup"> + <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/zh/menu_topinfobar.xml b/indra/newview/skins/default/xui/zh/menu_topinfobar.xml index debaafaa10..b07e9890ff 100644 --- a/indra/newview/skins/default/xui/zh/menu_topinfobar.xml +++ b/indra/newview/skins/default/xui/zh/menu_topinfobar.xml @@ -3,5 +3,5 @@ <menu_item_check label="顯示座標" name="Show Coordinates"/> <menu_item_check label="顯示地段屬性" name="Show Parcel Properties"/> <menu_item_call label="地標" name="Landmark"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="æšåº¨" name="Copy"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_http.xml b/indra/newview/skins/default/xui/zh/menu_url_http.xml index cf953576f3..861cbfb975 100644 --- a/indra/newview/skins/default/xui/zh/menu_url_http.xml +++ b/indra/newview/skins/default/xui/zh/menu_url_http.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Url Popup"> <menu_item_call label="開啟網é " name="url_open"/> - <menu_item_call label="Open in Internal Browser" name="url_open_internal"/> - <menu_item_call label="Open in External Browser" name="url_open_external"/> - <menu_item_call label="Copy URL to clipboard" name="url_copy"/> + <menu_item_call label="用內部ç€è¦½å™¨é–‹å•Ÿ" name="url_open_internal"/> + <menu_item_call label="用外部ç€è¦½å™¨é–‹å•Ÿ" name="url_open_external"/> + <menu_item_call label="覆製 URL 到剪貼簿" name="url_copy"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_slapp.xml b/indra/newview/skins/default/xui/zh/menu_url_slapp.xml index afc15ce13c..6ce9a10d3e 100644 --- a/indra/newview/skins/default/xui/zh/menu_url_slapp.xml +++ b/indra/newview/skins/default/xui/zh/menu_url_slapp.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Url Popup"> - <menu_item_call label="Run This Command" name="run_slapp"/> + <menu_item_call label="執行這個指令" name="run_slapp"/> <menu_item_call label="覆製 SLurl 到剪貼簿" name="url_copy"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml index f7be781cac..ac0e9e7e35 100644 --- a/indra/newview/skins/default/xui/zh/menu_viewer.xml +++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml @@ -1,68 +1,92 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu_bar name="Main Menu"> - <menu label="自己" name="Me"> - <menu_item_call label="å好è¨å®š" name="Preferences"/> - <menu_item_call label="我的塗鴉牆" name="Manage My Account"/> - <menu_item_call label="購買 L$" name="Buy and Sell L$"/> - <menu_item_call label="我的個人檔案" name="Profile"/> - <menu_item_call label="我的外觀" name="ChangeOutfit"/> - <menu_item_check label="我的庫å˜" name="Inventory"/> - <menu_item_check label="我的庫å˜" name="ShowSidetrayInventory"/> - <menu_item_check label="我的姿勢" name="Gestures"/> - <menu_item_check label="我的è²éŸ³" name="ShowVoice"/> - <menu label="移動" name="Movement"> + <menu label="我自己" name="Me"> + <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_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"/> - <menu_item_check label="總是奔跑" name="Always Run"/> + <menu_item_check label="以跑代æ¥" name="Always Run"/> <menu_item_call label="åœæ¢æˆ‘身上的動作" name="Stop Animating My Avatar"/> + <menu_item_call label="行走 / è·‘æ¥ / 飛行…" name="Walk / run / fly"/> </menu> - <menu label="我的狀態" name="Status"> + <menu label="狀態" name="Status"> <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_item_call label="購買 L$…" name="Buy and Sell L$"/> + <menu_item_call label="商家發件匣…" name="MerchantOutbox"/> + <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="Hide UI"/> + <menu_item_check label="顯示 HUD 附件" name="Show HUD Attachments"/> + <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_call label="å°éŽ–æ¸…å–®" name="Block List"/> </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="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="Teleport Home"/> + <menu_item_call label="把這裡è¨ç‚ºæˆ‘的家" name="Set Home to Here"/> + <menu_item_call label="å¿«ç…§" name="Take Snapshot"/> + <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"/> + <menu_item_check label="地產邊界" name="Property Lines"/> <menu_item_check label="地主" name="Land Owners"/> <menu_item_check label="座標" name="Coordinates"/> <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 label="太陽" name="Sun"> <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="Revert to Region Default"/> - <menu_item_call label="環境編輯器" name="Environment Editor"/> + <menu_item_call label="使用地å€è¨å®š" name="Use Region Settings"/> + </menu> + <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"/> + <menu_item_call label="刪除自訂é…置…" name="delete_water_preset"/> + </menu> + <menu label="天空自訂é…ç½®" name="Sky Presets"> + <menu_item_call label="新的自訂é…置…" name="new_sky_preset"/> + <menu_item_call label="編輯自訂é…置…" name="edit_sky_preset"/> + <menu_item_call label="刪除自訂é…置…" name="delete_sky_preset"/> + </menu> + <menu label="日的自訂é…ç½®" name="Day Presets"> + <menu_item_call label="新的自訂é…置…" name="new_day_preset"/> + <menu_item_call label="編輯自訂é…置…" name="edit_day_preset"/> + <menu_item_call label="刪除自訂é…置…" name="delete_day_preset"/> + </menu> </menu> </menu> <menu label="å»ºé€ " name="BuildTools"> @@ -100,110 +124,104 @@ <menu_item_call label="è¨å®šè…³æœ¬ç‚ºåŸ·è¡Œä¸" name="Set Scripts to Running"/> <menu_item_call label="è¨å®šè…³æœ¬ç‚ºéžåŸ·è¡Œä¸" name="Set Scripts to Not Running"/> </menu> + <menu label="尋徑" name="Pathfinding"> + <menu_item_call label="è¯çµé›†â€¦" name="pathfinding_linksets_menu_item"/> + <menu_item_call label="角色…" name="pathfinding_characters_menu_item"/> + <menu_item_call label="察看 / 測試…" name="pathfinding_console_menu_item"/> + </menu> <menu label="é¸é …" name="Options"> <menu_item_check label="顯示進階權é™" name="DebugPermissions"/> <menu_item_check label="åªé¸å–我的物件" name="Select Only My Objects"/> <menu_item_check label="åªé¸å–å¯ç§»å‹•的物件" name="Select Only Movable Objects"/> - <menu_item_check label="Select By Surrounding" name="Select By Surrounding"/> - <menu_item_check label="Show Selection Outlines" name="Show Selection Outlines"/> - <menu_item_check label="Show Hidden Selection" name="Show Hidden Selection"/> - <menu_item_check label="Show Light Radius for Selection" name="Show Light Radius for Selection"/> - <menu_item_check label="Show Selection Beam" name="Show Selection Beam"/> + <menu_item_check label="環繞é¸å–" name="Select By Surrounding"/> + <menu_item_check label="顯示é¸å–輪廓線" name="Show Selection Outlines"/> + <menu_item_check label="顯示隱è—çš„é¸å–" name="Show Hidden Selection"/> + <menu_item_check label="é¡¯ç¤ºé¸æ“‡çš„ Light åŠå¾‘" name="Show Light Radius for Selection"/> + <menu_item_check label="é¡¯ç¤ºé¸æ“‡å°Žå¼•ç·š" name="Show Selection Beam"/> <menu_item_check label="è²¼é½Šæ ¼ç·š" name="Snap to Grid"/> <menu_item_call label="貼齊物件 XY è»¸åˆ°æ ¼ç·š" name="Snap Object XY to Grid"/> - <menu_item_call label="Use Selection for Grid" name="Use Selection for Grid"/> + <menu_item_call label="ä»¥æ‰€é¸æ“‡ä½œç‚ºæ ¼ç·š" name="Use Selection for Grid"/> <menu_item_call label="æ ¼ç·šé¸é …" name="Grid Options"/> </menu> <menu label="上傳" name="Upload"> <menu_item_call label="圖åƒï¼ˆL$[COST])..." name="Upload Image"/> <menu_item_call label="è²éŸ³ï¼ˆL$[COST])..." name="Upload Sound"/> <menu_item_call label="動作(L$[COST])..." name="Upload Animation"/> - <menu_item_call label="大é‡ä¸Šå‚³ï¼ˆæ¯æª”案 L$[COST] )..." name="Bulk Upload"/> + <menu_item_call label="模型…" name="Upload Model"/> + <menu_item_call label="批é‡ï¼ˆæ¯æª”案 L$[COST] )..." name="Bulk Upload"/> <menu_item_call label="è¨å®šé è¨ä¸Šå‚³æ¬Šé™" name="perm prefs"/> </menu> <menu_item_call label="復原" name="Undo"/> <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_check label="啟用æç¤º" name="Enable Hints"/> - <menu_item_call label="èˆ‰å ±æ¿«ç”¨" name="Report Abuse"/> + <menu_item_call label="é•è¦èˆ‰å ±" name="Report Abuse"/> <menu_item_call label="å›žå ±è‡èŸ²" name="Report Bug"/> <menu_item_call label="關於 [APP_NAME]" name="About Second Life"/> </menu> <menu label="進階" name="Advanced"> - <menu_item_call label="Rebake Textures" name="Rebake Texture"/> - <menu_item_call label="è¨å®šä½¿ç”¨è€…界é¢å¤§å°è‡³é è¨å€¼" name="Set UI Size to Default"/> - <menu_item_call label="è¨å®šè¦–窗尺寸大å°..." name="Set Window Size..."/> + <menu_item_call label="釿–°ç”¢å‡ºæè³ª" name="Rebake Texture"/> + <menu_item_call label="以é è¨å€¼è¨å®šä½¿ç”¨è€…界é¢å¤§å°" name="Set UI Size to Default"/> + <menu_item_call label="è¨å®šè¦–窗大å°..." name="Set Window Size..."/> <menu_item_check label="é™åˆ¶é¸æ“‡è·é›¢" name="Limit Select Distance"/> - <menu_item_check label="Disable Camera Constraints" name="Disable Camera Distance"/> + <menu_item_check label="å–æ¶ˆé¡é é™åˆ¶" name="Disable Camera Distance"/> <menu_item_check label="高解æžåº¦å¿«ç…§" name="HighResSnapshot"/> <menu_item_check label="éœéŸ³æ‹æ”快照到硬碟" name="QuietSnapshotsToDisk"/> - <menu_item_check label="壓縮快照å˜åˆ°ç¡¬ç¢Ÿ" name="CompressSnapshotsToDisk"/> <menu label="效能工具" name="Performance Tools"> - <menu_item_call label="Lag Meter" name="Lag Meter"/> + <menu_item_call label="Lag 測é‡å™¨" name="Lag Meter"/> <menu_item_check label="統計列" name="Statistics Bar"/> - <menu_item_check label="Show Avatar Rendering Cost" name="Avatar Rendering Cost"/> + <menu_item_check label="顯示化身的繪製é‡é‡" name="Avatar Rendering Cost"/> </menu> <menu label="高亮顯示與å¯è¦‹åº¦" name="Highlighting and Visibility"> - <menu_item_check label="Cheesy Beacon" name="Cheesy Beacon"/> + <menu_item_check label="Cheesy 指標" name="Cheesy Beacon"/> <menu_item_check label="éš±è—ç²’åæ•ˆæžœ" name="Hide Particles"/> <menu_item_check label="éš±è—æ‰€é¸æ“‡çš„" name="Hide Selected"/> <menu_item_check label="é«˜äº®é¡¯ç¤ºé€æ˜Žç‰©ä»¶" name="Highlight Transparent"/> - <menu_item_check label="顯示 HUD 附件" name="Show HUD Attachments"/> <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> - <menu label="Rendering Features" name="Rendering Features"> - <menu_item_check label="UI" name="UI"/> - <menu_item_check label="Selected" name="Selected"/> - <menu_item_check label="Highlighted" name="Highlighted"/> - <menu_item_check label="Dynamic Textures" name="Dynamic Textures"/> + <menu label="呈åƒé¡žåž‹" name="Rendering Types"> + <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="呈åƒåŠŸèƒ½" name="Rendering Features"> + <menu_item_check label="使用者界é¢" name="ToggleUI"/> + <menu_item_check label="鏿“‡" name="Selected"/> + <menu_item_check label="高亮顯示" name="Highlighted"/> + <menu_item_check label="å‹•æ…‹æè³ª" name="Dynamic Textures"/> <menu_item_check label="è…³æ¥é™°å½±" name="Foot Shadows"/> <menu_item_check label="霧氣" name="Fog"/> - <menu_item_check label="Test FRInfo" name="Test FRInfo"/> + <menu_item_check label="測試 FRInfo" name="Test FRInfo"/> <menu_item_check label="彈性物件" name="Flexible Objects"/> </menu> <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"/> <menu_item_call label="æ‹æ”快照到硬碟" name="Snapshot to Disk"/> <menu_item_call label="第一人稱視角" name="Mouselook"/> - <menu_item_check label="Joystick Flycam" name="Joystick Flycam"/> + <menu_item_check label="æ–æ¡¿ç§»å‹•æ”影機" 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"/> + <menu_item_call label="放大" name="Zoom In"/> + <menu_item_call label="縮放æ¢å¾©é è¨" name="Zoom Default"/> + <menu_item_call label="縮å°" name="Zoom Out"/> </menu> <menu_item_call label="顯示除錯è¨å®š" name="Debug Settings"/> <menu_item_check label="顯示開發é¸å–®" name="Debug Mode"/> @@ -213,25 +231,27 @@ <menu_item_check label="æè³ªæŽ§åˆ¶å°" name="Texture Console"/> <menu_item_check label="除錯控制å°" name="Debug Console"/> <menu_item_call label="通知控制å°" name="Notifications"/> - <menu_item_check label="æè³ªå°ºå¯¸æŽ§åˆ¶å°" name="Texture Size"/> - <menu_item_check label="æè³ªåˆ†é¡žæŽ§åˆ¶å°" name="Texture Category"/> <menu_item_check label="快速碼錶" name="Fast Timers"/> <menu_item_check label="記憶體" name="Memory"/> + <menu_item_check label="å ´æ™¯çµ±è¨ˆè³‡æ–™" name="Scene Statistics"/> + <menu_item_call label="æè³ªæ“·å–除錯控制å°" name="Texture Fetch Debug Console"/> <menu_item_call label="地å€è³‡è¨Šå‚³è‡³é™¤éŒ¯æŽ§åˆ¶å°" name="Region Info to Debug Console"/> <menu_item_call label="群組資訊至除錯控制å°" name="Group Info to Debug Console"/> - <menu_item_call label="Capabilities Info to Debug Console" name="Capabilities Info to Debug Console"/> + <menu_item_call label="性能資訊傳至除錯控制å°" name="Capabilities Info to Debug Console"/> <menu_item_check label="æ”影機" name="Camera"/> <menu_item_check label="風力" name="Wind"/> - <menu_item_check label="FOV" name="FOV"/> - <menu_item_check label="Badge" name="Badge"/> + <menu_item_check label="視角" name="FOV"/> + <menu_item_check label="å‹›ç« " name="Badge"/> </menu> <menu label="顯示資訊" name="Display Info"> <menu_item_check label="顯示時間" name="Show Time"/> - <menu_item_check label="Show Render Info" name="Show Render Info"/> + <menu_item_check label="顯示上傳費用" name="Show Upload Cost"/> + <menu_item_check label="顯示呈åƒè³‡è¨Š" name="Show Render Info"/> <menu_item_check label="顯示æè³ªè³‡è¨Š" name="Show Texture Info"/> - <menu_item_check label="Show Matrices" name="Show Matrices"/> - <menu_item_check label="Show Color Under Cursor" name="Show Color Under Cursor"/> + <menu_item_check label="顯示矩陣" name="Show Matrices"/> + <menu_item_check label="游標下顯示é¡è‰²" name="Show Color Under Cursor"/> <menu_item_check label="顯示記憶體" name="Show Memory"/> + <menu_item_check label="顯示ç§å€è¨˜æ†¶é«”資訊" name="Show Private Mem Info"/> <menu_item_check label="顯示更新到物件" name="Show Updates"/> </menu> <menu label="強制錯誤" name="Force Errors"> @@ -244,60 +264,71 @@ <menu_item_call label="強制ç€è¦½å™¨æ–·ç·š" name="Force Disconnect Viewer"/> <menu_item_call label="模擬記憶體ä¸è¶³" name="Memory Leaking Simulation"/> </menu> - <menu label="Render Tests" name="Render Tests"> + <menu label="å‘ˆåƒæ¸¬è©¦" name="Render Tests"> <menu_item_check label="æ”影機ä½ç§»" name="Camera Offset"/> - <menu_item_check label="Randomize Framerate" name="Randomize Framerate"/> - <menu_item_check label="Periodic Slow Frame" name="Periodic Slow Frame"/> - <menu_item_check label="Frame Test" name="Frame Test"/> - </menu> - <menu label="Render Metadata" name="Render Metadata"> - <menu_item_check label="Bounding Boxes" name="Bounding Boxes"/> - <menu_item_check label="Octree" name="Octree"/> - <menu_item_check label="Shadow Frusta" name="Shadow Frusta"/> - <menu_item_check label="Occlusion" name="Occlusion"/> - <menu_item_check label="Render Batches" name="Render Batches"/> - <menu_item_check label="Update Type" name="Update Type"/> - <menu_item_check label="Texture Anim" name="Texture Anim"/> - <menu_item_check label="Texture Priority" name="Texture Priority"/> - <menu_item_check label="Texture Area" name="Texture Area"/> - <menu_item_check label="Face Area" name="Face Area"/> - <menu_item_check label="Lights" name="Lights"/> - <menu_item_check label="Collision Skeleton" name="Collision Skeleton"/> - <menu_item_check label="Raycast" name="Raycast"/> - </menu> - <menu label="Rendering" name="Rendering"> - <menu_item_check label="Axes" name="Axes"/> - <menu_item_check label="Tangent Basis" name="Tangent Basis"/> - <menu_item_call label="Selected Texture Info Basis" name="Selected Texture Info Basis"/> - <menu_item_check label="Wireframe" name="Wireframe"/> - <menu_item_check label="Object-Object Occlusion" name="Object-Object Occlusion"/> - <menu_item_check label="Framebuffer Objects" name="Framebuffer Objects"/> - <menu_item_check label="Lighting and Shadows" name="Lighting and Shadows"/> - <menu_item_check label="Shadows from Sun/Moon/Projectors" name="Shadows from Sun/Moon/Projectors"/> - <menu_item_check label="SSAO and Shadow Smoothing" name="SSAO and Shadow Smoothing"/> - <menu_item_check label="Global Illumination (experimental)" name="Global Illumination"/> + <menu_item_check label="隨機變動幀率" name="Randomize Framerate"/> + <menu_item_check label="å®šæœŸå‡ºç¾æ…¢å¹€çއ" name="Periodic Slow Frame"/> + <menu_item_check label="ç•«é¢æ¸¬è©¦" name="Frame Test"/> + </menu> + <menu label="呈åƒçš„元資料" name="Render Metadata"> + <menu_item_check label="外框箱" name="Bounding Boxes"/> + <menu_item_check label="法線" name="Normals"/> + <menu_item_check label="八剿¨¹" name="Octree"/> + <menu_item_check label="陰影平截é é«”" name="Shadow Frusta"/> + <menu_item_check label="物ç†å½¢ç‹€" name="Physics Shapes"/> + <menu_item_check label="é®è”½" name="Occlusion"/> + <menu_item_check label="å‘ˆåƒæ‰¹æ¬¡" name="Render Batches"/> + <menu_item_check label="更新類型" name="Update Type"/> + <menu_item_check label="æè³ªå‹•ç•«" name="Texture Anim"/> + <menu_item_check label="æè³ªå„ªå…ˆåº" name="Texture Priority"/> + <menu_item_check label="æè³ªå€åŸŸ" name="Texture Area"/> + <menu_item_check label="臉å€åŸŸ" name="Face Area"/> + <menu_item_check label="細節層次資訊" name="LOD Info"/> + <menu_item_check label="建製佇列" name="Build Queue"/> + <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="attachment bytes"/> + <menu_item_check label="雕刻" name="Sculpt"/> + <menu label="æè³ªå¯†åº¦" name="Texture Density"> + <menu_item_check label="ç„¡" name="None"/> + <menu_item_check label="ç›®å‰" name="Current"/> + <menu_item_check label="ç†æƒ³" name="Desired"/> + <menu_item_check label="完全" name="Full"/> + </menu> + </menu> + <menu label="呈åƒ" name="Rendering"> + <menu_item_check label="軸" name="Axes"/> + <menu_item_check label="切線基礎" name="Tangent Basis"/> + <menu_item_call label="å·²é¸å–æè³ªè³‡è¨ŠåŸºç¤Ž" name="Selected Texture Info Basis"/> + <menu_item_check label="線框" name="Wireframe"/> + <menu_item_check label="物件導å‘çš„é®è”½" name="Object-Object Occlusion"/> + <menu_item_check label="光線和陰影" name="Lighting and Shadows"/> + <menu_item_check label="來自日/月/投影物的陰影" name="Shadows from Sun/Moon/Projectors"/> + <menu_item_check label="å±å¹•空間環境光é®è”½å’Œé™°å½±å¹³æ»‘技術" name="SSAO and Shadow Smoothing"/> <menu_item_check label="GL 除錯" name="Debug GL"/> <menu_item_check label="管線除錯" name="Debug Pipeline"/> <menu_item_check label="自動åŠé€æ˜Žé®ç½©ï¼ˆéžå»¶ï¼‰" name="Automatic Alpha Masks (deferred)"/> <menu_item_check label="自動åŠé€æ˜Žé®ç½©ï¼ˆéžéžå»¶ï¼‰" name="Automatic Alpha Masks (non-deferred)"/> - <menu_item_check label="Animation Textures" name="Animation Textures"/> + <menu_item_check label="動作æè³ª" name="Animation Textures"/> <menu_item_check label="關閉æè³ª" name="Disable Textures"/> - <menu_item_check label="Full Res Textures" name="Rull Res Textures"/> - <menu_item_check label="Audit Textures" name="Audit Textures"/> - <menu_item_check label="Texture Atlas (experimental)" name="Texture Atlas"/> - <menu_item_check label="Render Attached Lights" name="Render Attached Lights"/> - <menu_item_check label="Render Attached Particles" name="Render Attached Particles"/> - <menu_item_check label="Hover Glow Objects" name="Hover Glow Objects"/> + <menu_item_check label="全解æžåº¦æè³ª" name="Rull Res Textures"/> + <menu_item_check label="æè³ªåœ–集(實驗性質)" name="Texture Atlas"/> + <menu_item_check label="使附著燈光呈åƒ" name="Render Attached Lights"/> + <menu_item_check label="ä½¿é™„è‘—ä¾‹åæ•ˆæžœå‘ˆåƒ" name="Render Attached Particles"/> + <menu_item_check label="åœæ‡¸ç™¼å…‰ç‰©ä»¶" name="Hover Glow Objects"/> </menu> <menu label="網路" name="Network"> - <menu_item_check label="Pause Agent" name="AgentPause"/> - <menu_item_call label="Enable Message Log" name="Enable Message Log"/> - <menu_item_call label="Disable Message Log" name="Disable Message Log"/> - <menu_item_check label="Velocity Interpolate Objects" name="Velocity Interpolate Objects"/> - <menu_item_check label="Ping Interpolate Object Positions" name="Ping Interpolate Object Positions"/> - <menu_item_call label="Drop a Packet" name="Drop a Packet"/> - </menu> - <menu_item_call label="Dump Scripted Camera" name="Dump Scripted Camera"/> + <menu_item_check label="æš«åœç”¨æˆ¶" name="AgentPause"/> + <menu_item_call label="啟用訊æ¯è¨˜éŒ„" name="Enable Message Log"/> + <menu_item_call label="åœç”¨è¨Šæ¯è¨˜éŒ„" name="Disable Message Log"/> + <menu_item_check label="速度內æ’物件" name="Velocity Interpolate Objects"/> + <menu_item_check label="探詢內æ’物件ä½ç½®" name="Ping Interpolate Object Positions"/> + <menu_item_call label="丟出一個å°åŒ…" name="Drop a Packet"/> + </menu> + <menu_item_call label="傾å°è…³æœ¬æŽ§åˆ¶çš„æ”å½±æ©Ÿ" name="Dump Scripted Camera"/> <menu_item_call label="ç¢°æ’žã€æŽ¨æ“ èˆ‡æ‰“æ“Š" name="Bumps, Pushes &amp; Hits"/> <menu label="錄製器" name="Recorder"> <menu_item_call label="é–‹å§‹æ’æ”¾" name="Start Playback"/> @@ -306,30 +337,29 @@ <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> - <menu label="UI" name="UI"> - <menu_item_call label="測試媒體ç€è¦½å™¨" name="Web Browser Test"/> + <menu label="使用者界é¢" name="UI"> + <menu_item_call label="媒體ç€è¦½å™¨æ¸¬è©¦" name="Web Browser Test"/> <menu_item_call label="ç¶²é 內容ç€è¦½å™¨" name="Web Content Browser"/> - <menu_item_call label="Dump SelectMgr" name="Dump SelectMgr"/> + <menu_item_call label="å‚¾å° SelectMgr" name="Dump SelectMgr"/> <menu_item_call label="傾尿”¶ç´å€" name="Dump Inventory"/> <menu_item_call label="傾å°ç¢¼éŒ¶" name="Dump Timers"/> - <menu_item_call label="Dump Focus Holder" name="Dump Focus Holder"/> - <menu_item_call label="Print Selected Object Info" name="Print Selected Object Info"/> - <menu_item_call label="Print Agent Info" name="Print Agent Info"/> + <menu_item_call label="傾å°ç„¦é»žå®¹å™¨" name="Dump Focus Holder"/> + <menu_item_call label="åˆ—å°æ‰€é¸ç‰©ä»¶è³‡è¨Š" name="Print Selected Object Info"/> + <menu_item_call label="列å°ç”¨æˆ¶è³‡è¨Š" name="Print Agent Info"/> <menu_item_call label="計憶體狀態" name="Memory Stats"/> - <menu_item_check label="Region Debug Console" name="Region Debug Console"/> - <menu_item_check label="Debug SelectMgr" name="Debug SelectMgr"/> - <menu_item_check label="Debug Clicks" name="Debug Clicks"/> + <menu_item_check label="地å€é™¤éŒ¯æŽ§åˆ¶å°" name="Region Debug Console"/> + <menu_item_check label="除錯 SelectMgr" name="Debug SelectMgr"/> + <menu_item_check label="除錯點按動作" name="Debug Clicks"/> <menu_item_check label="視角除錯" name="Debug Views"/> - <menu_item_check label="Debug Name Tooltips" name="Debug Name Tooltips"/> + <menu_item_check label="除錯åç¨±è¨Šæ¯æç¤º" name="Debug Name Tooltips"/> <menu_item_check label="æ»‘é¼ äº‹ä»¶é™¤éŒ¯" name="Debug Mouse Events"/> <menu_item_check label="按éµé™¤éŒ¯" name="Debug Keys"/> - <menu_item_check label="Debug WindowProc" name="Debug WindowProc"/> + <menu_item_check label="除錯 WindowProc" name="Debug WindowProc"/> </menu> <menu label="XUI" name="XUI"> <menu_item_call label="釿–°è¼‰å…¥é¡è‰²è¨å®š" name="Reload Color Settings"/> @@ -339,19 +369,18 @@ <menu_item_call label="æ²–æ´—å稱快å–資料" name="Flush Names Caches"/> </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 label="抓å–已產出æè³ª" name="Grab Baked Texture"> + <menu_item_call label="虹膜" name="Grab Iris"/> + <menu_item_call label="é 部" name="Grab Head"/> + <menu_item_call label="上åŠèº«" name="Grab Upper Body"/> + <menu_item_call label="下åŠèº«" 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"/> - <menu_item_call label="Toggle Character Geometry" name="Toggle Character Geometry"/> + <menu label="å—元測試" name="Character Tests"> + <menu_item_call label="å°‡å¤–è§€è½‰æˆ XML" name="Appearance To XML"/> + <menu_item_call label="切æ›å—元幾何特性" name="Toggle Character Geometry"/> <menu_item_call label="男性測試" name="Test Male"/> <menu_item_call label="女性測試" name="Test Female"/> - <menu_item_call label="PG 切æ›" name="Toggle PG"/> <menu_item_check label="å…è¨±é¸æ“‡åŒ–身" name="Allow Select Avatar"/> </menu> <menu_item_call label="å¼·åˆ¶åƒæ•¸ç‚ºé è¨å€¼" name="Force Params to Default"/> @@ -359,47 +388,56 @@ <menu_item_check label="慢動作" name="Slow Motion Animations"/> <menu_item_check label="顯示注視在" name="Show Look At"/> <menu_item_check label="顯示指å‘在" name="Show Point At"/> - <menu_item_check label="Debug Joint Updates" name="Debug Joint Updates"/> - <menu_item_check label="Disable LOD" name="Disable LOD"/> - <menu_item_check label="Debug Character Vis" name="Debug Character Vis"/> - <menu_item_check label="Show Collision Skeleton" name="Show Collision Skeleton"/> - <menu_item_check label="Display Agent Target" name="Display Agent Target"/> + <menu_item_check label="除錯旋軸的更新" name="Debug Joint Updates"/> + <menu_item_check label="åœç”¨ç´°ç¯€å±¤æ¬¡" name="Disable LOD"/> + <menu_item_check label="除錯å—å…ƒå¯è¦‹æ€§" name="Debug Character Vis"/> + <menu_item_check label="顯示碰撞骨架" name="Show Collision Skeleton"/> + <menu_item_check label="顯示用戶目標" name="Display Agent Target"/> --> - <menu_item_call label="Dump Attachments" name="Dump Attachments"/> - <menu_item_call label="Debug Avatar Textures" name="Debug Avatar Textures"/> - <menu_item_call label="Dump Local Textures" name="Dump Local Textures"/> + <menu_item_call label="傾å°é™„ä»¶" name="Dump Attachments"/> + <menu_item_call label="除錯化身æè³ª" name="Debug Avatar Textures"/> + <menu_item_call label="傾尿œ¬åœ°æè³ª" name="Dump Local Textures"/> </menu> <menu_item_check label="HTTP æè³ª" name="HTTP Textures"/> - <menu_item_call label="Compress Images" name="Compress Images"/> - <menu_item_check label="Output Debug Minidump" name="Output Debug Minidump"/> - <menu_item_check label="Console Window on next Run" name="Console Window"/> - <menu_item_call label="Request Admin Status" name="Request Admin Options"/> - <menu_item_call label="Leave Admin Status" name="Leave Admin Options"/> - <menu_item_check label="Show Admin Menu" name="View Admin Options"/> + <menu_item_check label="HTTP æ”¶ç´å€" name="HTTP Inventory"/> + <menu_item_call label="壓縮圖åƒ" name="Compress Images"/> + <menu_item_call label="啟用記憶體洩æ¼è¦–è¦ºåµæ¸¬å™¨" name="Enable Visual Leak Detector"/> + <menu_item_check label="輸出除錯å°åž‹å‚¾å°" name="Output Debug Minidump"/> + <menu_item_check label="下次執行時顯示控制å°è¦–窗" name="Console Window"/> + <menu label="è¨å®šè¨˜éŒ„細節" name="Set Logging Level"> + <menu_item_check label="除錯" name="Debug"/> + <menu_item_check label="資訊" name="Info"/> + <menu_item_check label="è¦å‘Š" name="Warning"/> + <menu_item_check label="錯誤" name="Error"/> + <menu_item_check label="ç„¡" name="None"/> + </menu> + <menu_item_call label="è¦æ±‚管ç†å“¡ç‹€æ…‹" name="Request Admin Options"/> + <menu_item_call label="離開管ç†å“¡ç‹€æ…‹" name="Leave Admin Options"/> + <menu_item_check label="顯示管ç†å“¡é¸å–®" name="View Admin Options"/> </menu> - <menu label="Admin" name="Admin"> - <menu label="Object"> - <menu_item_call label="å–得副本" name="Take Copy"/> - <menu_item_call label="å¼·åˆ¶æ“æœ‰è€…為我" name="Force Owner To Me"/> - <menu_item_call label="Force Owner Permissive" name="Force Owner Permissive"/> + <menu label="管ç†å“¡" name="Admin"> + <menu label="物件" name="AdminObject"> + <menu_item_call label="å–得副本" name="Admin Take Copy"/> + <menu_item_call label="將所有人強è¨ç‚ºæˆ‘自己" name="Force Owner To Me"/> + <menu_item_call label="å¼·è¨ç‚ºã€Œå‡†è¨±æ‰€æœ‰äººã€" name="Force Owner Permissive"/> <menu_item_call label="刪除" name="Delete"/> - <menu_item_call label="Lock" name="Lock"/> - <menu_item_call label="Get Assets IDs" name="Get Assets IDs"/> + <menu_item_call label="鎖定" name="Lock"/> + <menu_item_call label="å–得資產 ID" name="Get Assets IDs"/> </menu> <menu label="地段" name="Parcel"> - <menu_item_call label="å¼·åˆ¶æ“æœ‰è€…為我" name="Owner To Me"/> - <menu_item_call label="Set to Linden Content" name="Set to Linden Content"/> - <menu_item_call label="Claim Public Land" name="Claim Public Land"/> + <menu_item_call label="將所有人強è¨ç‚ºæˆ‘自己" name="Owner To Me"/> + <menu_item_call label="è¨ç‚º Linden 內容" name="Set to Linden Content"/> + <menu_item_call label="æ”¶å–公共地" name="Claim Public Land"/> </menu> <menu label="地å€" name="Region"> - <menu_item_call label="Dump Temp Asset Data" name="Dump Temp Asset Data"/> - <menu_item_call label="Save Region State" name="Save Region State"/> + <menu_item_call label="傾尿š«ç”¨è³‡ç”¢è³‡æ–™" name="Dump Temp Asset Data"/> + <menu_item_call label="儲å˜å€åŸŸç‹€æ…‹" name="Save Region State"/> </menu> - <menu_item_call label="God Tools" name="God Tools"/> + <menu_item_call label="神之工具" name="God Tools"/> </menu> - <menu label="Admin" name="Deprecated"> - <menu label="Attach Object" name="Attach Object"/> - <menu label="Detach Object" name="Detach Object"/> + <menu label="管ç†å“¡" name="Deprecated"> + <menu label="附著物件" name="Attach Object"/> + <menu label="å¸åŽ»ç‰©ä»¶" name="Detach Object"/> <menu label="脫下æœè£" name="Take Off Clothing"> <menu_item_call label="襯衫" name="Shirt"/> <menu_item_call label="褲å" name="Pants"/> @@ -415,15 +453,15 @@ <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_item_call label="腳本門戶" name="Scripting Portal"/> <menu label="è‡èŸ²å›žå ±" name="Bug Reporting"> - <menu_item_call label="Public Issue Tracker" name="Public Issue Tracker"/> - <menu_item_call label="Public Issue Tracker Help" name="Publc Issue Tracker Help"/> + <menu_item_call label="大眾å•é¡Œåæ‡‰è¿½è¹¤è™•" name="Public Issue Tracker"/> + <menu_item_call label="大眾å•é¡Œåæ‡‰è¿½è¹¤è™•幫助" name="Publc Issue Tracker Help"/> <menu_item_call label="è‡èŸ²å›žå ± 101" name="Bug Reporing 101"/> - <menu_item_call label="Security Issues" name="Security Issues"/> - <menu_item_call label="QA Wiki" name="QA Wiki"/> + <menu_item_call label="安全å•題" name="Security Issues"/> + <menu_item_call label="å“管ç¶åŸº" name="QA Wiki"/> </menu> </menu> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml index 2eea314dd8..576f7f3b73 100644 --- a/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Outfit Wearable Context Menu"> <menu_item_call label="å–代" name="wear_replace"/> - <menu_item_call label="Wear" name="wear_wear"/> + <menu_item_call label="穿上" name="wear_wear"/> <menu_item_call label="æ·»åŠ " name="wear_add"/> - <menu_item_call label="Take Off / Detach" name="take_off_or_detach"/> + <menu_item_call label="è„«ä¸‹è£æ‰® / å¸é™¤é™„ä»¶" name="take_off_or_detach"/> <menu_item_call label="å¸ä¸‹" name="detach"/> - <context_menu label="Attach to" name="wearable_attach_to"/> - <context_menu label="Attach to HUD" name="wearable_attach_to_hud"/> + <context_menu label="附著到..." name="wearable_attach_to"/> + <context_menu label="附著到擡é 顯示" name="wearable_attach_to_hud"/> <menu_item_call label="脫下" name="take_off"/> <menu_item_call label="編輯" name="edit"/> <menu_item_call label="ç‰©å“æª”案" name="object_profile"/> diff --git a/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml b/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml index d9f4acb27b..6184f956d1 100644 --- a/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml +++ b/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml @@ -2,4 +2,5 @@ <toggleable_menu name="Gear Wearing"> <menu_item_call label="ç·¨è¼¯è£æ‰®" name="edit"/> <menu_item_call label="脫下" name="takeoff"/> + <menu_item_call label="è¤‡è£½è£æ‰®æ¸…單到剪貼簿" name="copy"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/mime_types.xml b/indra/newview/skins/default/xui/zh/mime_types.xml index 8ac1bf6920..70af2d2f19 100644 --- a/indra/newview/skins/default/xui/zh/mime_types.xml +++ b/indra/newview/skins/default/xui/zh/mime_types.xml @@ -5,7 +5,7 @@ ç¶²é 內容 </label> <tooltip name="web_tooltip"> - 這ä½ç½®æœ‰ç¶²é 內容 + 這個ä½ç½®æœ‰ç¶²é 內容 </tooltip> <playtip name="web_playtip"> 顯示網é 內容 @@ -41,7 +41,7 @@ æœ‰ä¸€å€‹éŸ³é »åœ¨æ¤ä½ç½® </tooltip> <playtip name="audio_playtip"> - æ’æ”¾é€™å€‹ç¡¾çš„éŸ³é » + æ’æ”¾é€™å€‹ä½ç½®çš„éŸ³é » </playtip> </widgetset> <scheme name="rtsp"> @@ -66,7 +66,7 @@ </mimetype> <mimetype name="video/*"> <label name="video2_label"> - è¦–é » + 影片 </label> </mimetype> <mimetype name="image/*"> @@ -111,7 +111,7 @@ </mimetype> <mimetype name="application/xhtml+xml"> <label name="application/xhtml+xml_label"> - é¸é …(XHTML) + ç¶²é (XHTML) </label> </mimetype> <mimetype name="application/x-director"> @@ -171,7 +171,7 @@ </mimetype> <mimetype name="text/html"> <label name="text/html_label"> - é¸é … + ç¶²é </label> </mimetype> <mimetype name="text/plain"> diff --git a/indra/newview/skins/default/xui/zh/mime_types_linux.xml b/indra/newview/skins/default/xui/zh/mime_types_linux.xml index 90f17b841c..70af2d2f19 100644 --- a/indra/newview/skins/default/xui/zh/mime_types_linux.xml +++ b/indra/newview/skins/default/xui/zh/mime_types_linux.xml @@ -5,7 +5,7 @@ ç¶²é 內容 </label> <tooltip name="web_tooltip"> - This location has Web content + 這個ä½ç½®æœ‰ç¶²é 內容 </tooltip> <playtip name="web_playtip"> 顯示網é 內容 @@ -27,7 +27,7 @@ åœ–åƒ </label> <tooltip name="image_tooltip"> - There is an image at this location + 有一個圖åƒåœ¨æ¤ä½ç½® </tooltip> <playtip name="image_playtip"> 察看這個ä½ç½®çš„åœ–åƒ @@ -106,12 +106,12 @@ </mimetype> <mimetype name="application/smil"> <label name="application/smil_label"> - Synchronized Multimedia Integration Language (SMIL) + åŒæ¥å¤šåª’體整åˆèªžè¨€ï¼ˆSMIL) </label> </mimetype> <mimetype name="application/xhtml+xml"> <label name="application/xhtml+xml_label"> - é¸é …(XHTML) + ç¶²é (XHTML) </label> </mimetype> <mimetype name="application/x-director"> @@ -171,7 +171,7 @@ </mimetype> <mimetype name="text/html"> <label name="text/html_label"> - é¸é … + ç¶²é </label> </mimetype> <mimetype name="text/plain"> diff --git a/indra/newview/skins/default/xui/zh/mime_types_mac.xml b/indra/newview/skins/default/xui/zh/mime_types_mac.xml index b8105c145c..70af2d2f19 100644 --- a/indra/newview/skins/default/xui/zh/mime_types_mac.xml +++ b/indra/newview/skins/default/xui/zh/mime_types_mac.xml @@ -30,7 +30,7 @@ 有一個圖åƒåœ¨æ¤ä½ç½® </tooltip> <playtip name="image_playtip"> - 察看在æ¤ä½ç½®çš„åœ–åƒ + 察看這個ä½ç½®çš„åœ–åƒ </playtip> </widgetset> <widgetset name="audio"> @@ -41,7 +41,7 @@ æœ‰ä¸€å€‹éŸ³é »åœ¨æ¤ä½ç½® </tooltip> <playtip name="audio_playtip"> - æ’æ”¾åœ¨æ¤ä½ç½®çš„éŸ³é » + æ’æ”¾é€™å€‹ä½ç½®çš„éŸ³é » </playtip> </widgetset> <scheme name="rtsp"> @@ -66,7 +66,7 @@ </mimetype> <mimetype name="video/*"> <label name="video2_label"> - è¦–é » + 影片 </label> </mimetype> <mimetype name="image/*"> @@ -76,7 +76,7 @@ </mimetype> <mimetype name="video/vnd.secondlife.qt.legacy"> <label name="vnd.secondlife.qt.legacy_label"> - è¦–é » (QuickTime) + è¦–é »ï¼ˆQuickTime) </label> </mimetype> <mimetype name="application/javascript"> @@ -86,7 +86,7 @@ </mimetype> <mimetype name="application/ogg"> <label name="application/ogg_label"> - OGG éŸ³é »/è¦–é » + Ogg éŸ³é »/è¦–é » </label> </mimetype> <mimetype name="application/pdf"> @@ -121,7 +121,7 @@ </mimetype> <mimetype name="audio/mid"> <label name="audio/mid_label"> - éŸ³é » (MIDI) + éŸ³é »ï¼ˆMIDI) </label> </mimetype> <mimetype name="audio/mpeg"> diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml index 2d309a2af0..9fecf2c104 100644 --- a/indra/newview/skins/default/xui/zh/notifications.xml +++ b/indra/newview/skins/default/xui/zh/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -45,19 +51,19 @@ </form> </template> <notification label="未知的通知訊æ¯" name="MissingAlert"> - Your version of [APP_NAME] does not know how to display the notification it just received. Please verify that you have the latest Viewer installed. + ä½ çš„ [APP_NAME] 版本無法顯示它剛剛收到的通知。 è«‹ç¢ºå®šä½ å®‰è£äº†æœ€æ–°ç‰ˆæœ¬çš„ Viewer。 -Error details: The notification called '[_NAME]' was not found in notifications.xml. +錯誤詳情:在 notifications.xml 裡找ä¸åˆ°å為「[_NAME]ã€çš„通知。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="FloaterNotFound"> - Floater error: Could not find the following controls: + 浮動視窗錯誤:找ä¸åˆ°ä»¥ä¸‹çš„æŽ§åˆ¶ï¼š [CONTROLS] <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="TutorialNotFound"> - No tutorial is currently available. + ç›®å‰å°šç„¡æ•™å¸å…§å®¹ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="GenericAlert"> @@ -68,67 +74,101 @@ Error details: The notification called '[_NAME]' was not found in noti <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="是"/> </notification> <notification name="BadInstallation"> - An error occurred while updating [APP_NAME]. Please [http://get.secondlife.com download the latest version] of the Viewer. + [APP_NAME] 更新時出錯。 è«‹ [http://get.secondlife.com 下載] 最新版本的 Viewer。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="LoginFailedNoNetwork"> - 無法連接到[SECOND_LIFE_GRID]. - '[DIAGNOSTIC]' -è«‹ç¢ºå®šä½ çš„ç¶²éš›ç¶²è·¯æ˜¯æ£å¸¸é‹ä½œçš„。 + 無法連接到 [SECOND_LIFE_GRID]。 + ([DIAGNOSTIC]) +è«‹ç¢ºå®šä½ çš„ç¶²è·¯é€£ç·šæ²’æœ‰å•題。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="MessageTemplateNotFound"> - Message Template [PATH] not found. + 找ä¸åˆ°è¨Šæ¯æ¨¡æ¿ [PATH]。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="WearableSave"> 除å˜è®Šæ›´åˆ°ç›®å‰çš„è¡£æœ/身體部ä½ï¼Ÿ <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="ä¸è¦å„²å˜" yestext="儲å˜"/> </notification> + <notification name="ConfirmNoCopyToOutbox"> + ä½ ç„¡æ¬Šå°‡è‡³å°‘ä¸€ä»¶ç‰©é …è¤‡è£½åˆ°ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚é›†çš„ç™¼ä»¶åŒ£ã€‚ ä½ å¯ä»¥ç§»å‹•é€™äº›ç‰©é …ï¼Œæˆ–ä¿ç•™ä¸å‹•。 + <usetemplate name="okcancelbuttons" notext="ä¿ç•™ä¸ç§»å‹•ç‰©é …" yestext="ç§»å‹•ç‰©é …"/> + </notification> + <notification name="OutboxFolderCreated"> + å·²ç¶“ç‚ºä½ æ‰€è½‰ç§»åˆ°å•†å®¶ç™¼ä»¶åŒ£é ‚å±¤çš„æ¯ä¸€å€‹ç‰©é …,å„自建立了一個新資料夾。 + <usetemplate ignoretext="商家發件匣裡æˆåŠŸå»ºç«‹äº†ä¸€å€‹æ–°è³‡æ–™å¤¾" name="okignore" yestext="確定"/> + </notification> + <notification name="OutboxImportComplete"> + æˆåŠŸ + +所有資料夾已æˆåŠŸé€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集。 + <usetemplate ignoretext="所有資料夾已é€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集" name="okignore" yestext="確定"/> + </notification> + <notification name="OutboxImportHadErrors"> + 一部分的資料夾無法轉移 + +將一部分資料夾é€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集時出錯。 這些資料夾ä»åœ¨ä½ 的商家發件匣。 + +詳情請åƒé–±[[MARKETPLACE_IMPORTS_URL]錯誤記錄]。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="OutboxImportFailed"> + 轉移失敗 + +未將任何資料夾é€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集,系統或網路出錯。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚ + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="OutboxInitFailed"> + 第二人生購物市集åˆå§‹åŒ–失敗 + +第二人生購物市集åˆå§‹åŒ–失敗,系統或網路出錯。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚ + <usetemplate name="okbutton" yestext="確定"/> + </notification> <notification name="CompileQueueSaveText"> - There was a problem uploading the text for a script due to the following reason: [REASON]. Please try again later. + ä¸Šå‚³è…³æœ¬æ–‡å—æ™‚出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="CompileQueueSaveBytecode"> - There was a problem uploading the compiled script due to the following reason: [REASON]. Please try again later. + 上傳已編è¯è…³æœ¬æ™‚出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="WriteAnimationFail"> - There was a problem writing animation data. Please try again later. + 寫入動作資料時出錯。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="UploadAuctionSnapshotFail"> - There was a problem uploading the auction snapshot due to the following reason: [REASON] + 上傳æ‹è³£å¿«ç…§æ™‚出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON] </notification> <notification name="UnableToViewContentsMoreThanOne"> - Unable to view the contents of more than one item at a time. -Please select only one object and try again. + 無法一次ç€è¦½å¤šå€‹é …目的內容。 +è«‹åªé¸æ“‡ä¸€å€‹ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="SaveClothingBodyChanges"> 儲å˜å…¨éƒ¨æœè£æˆ–身體部ä½çš„變更? <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="ä¸è¦å„²å˜" yestext="全部儲å˜"/> </notification> <notification name="FriendsAndGroupsOnly"> - Non-friends won't know that you've choosen to ignore their calls and instant messages. + 䏿˜¯æœ‹å‹çš„äººä¸æœƒçŸ¥é“ä½ é¸æ“‡å¿½ç•¥ä»–å€‘çš„é€šè©±è¦æ±‚å’Œå³æ™‚訊æ¯ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="FavoritesOnLogin"> - Note: When you turn on this option, anyone who uses this computer can see your list of favorite locations. + 注æ„ï¼šä½ ä¸€æ—¦åŒæ„這é¸é …,任何使用這部電腦的人都å¯çœ‹åˆ°ä½ 有哪些「最愛ã€åœ°é»žã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="GrantModifyRights"> - Granting modify rights to another Resident allows them to change, delete or take ANY objects you may have in-world. Be VERY careful when handing out this permission. -Do you want to grant modify rights for [NAME]? - <usetemplate name="okcancelbuttons" notext="No" yestext="是"/> + 賦予å¦ä¸€å±…æ°‘ã€Œä¿®æ”¹ã€æ¬Šï¼Œå°‡å…許他更改ã€åˆªé™¤æˆ–æ‹¿å–ä½ åœ¨è™›æ“¬ä¸–ç•Œè£¡æ“æœ‰çš„任何物件。 è³¦äºˆé€™é …æ¬Šé™æ™‚,敬請慎é‡è€ƒæ…®ã€‚ +ä½ ä»è¦è³¦äºˆ [NAME] 修改權嗎? + <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> </notification> <notification name="GrantModifyRightsMultiple"> - Granting modify rights to another Resident allows them to change ANY objects you may have in-world. Be VERY careful when handing out this permission. -Do you want to grant modify rights for the selected Residents? + 賦予å¦ä¸€å±…æ°‘ã€Œä¿®æ”¹ã€æ¬Šï¼Œå°‡å…è¨±ä»–æ›´æ”¹ä½ åœ¨è™›æ“¬ä¸–ç•Œè£¡æ“æœ‰çš„任何物件。 è³¦äºˆé€™é …æ¬Šé™æ™‚,敬請慎é‡è€ƒæ…®ã€‚ +ä½ ä»è¦å°‡ä¿®æ”¹æ¬Šè³¦äºˆæ‰€é¸å±…æ°‘å—Ž? <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> </notification> <notification name="RevokeModifyRights"> - Do you want to revoke modify rights for [NAME]? + ä½ è¦æ’¤éŠ· [NAME] 的修改權嗎? <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> </notification> <notification name="RevokeModifyRightsMultiple"> - Do you want to revoke modify rights for the selected Residents? + ä½ è¦æ’¤éŠ·æ‰€é¸å±…民的修改權嗎? <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> </notification> <notification name="UnableToCreateGroup"> @@ -146,33 +186,33 @@ Do you want to grant modify rights for the selected Residents? <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="AddGroupOwnerWarning"> - You are about to add group members to the role of [ROLE_NAME]. -Members cannot be removed from that role. -The members must resign from the role themselves. -Are you sure you want to continue? - <usetemplate ignoretext="åœ¨æˆ‘æ·»åŠ ä¸€å€‹æ–°çš„ç¾¤çµ„æ“æœ‰è€…å‰ç¢ºèª" name="okcancelignore" notext="å¦" yestext="是"/> + ä½ å³å°‡è³¦äºˆç¾¤çµ„æˆå“¡ [ROLE_NAME] 的角色。 +æˆå“¡ä¸€æ—¦ç²å¾—æ¤è§’è‰²ï¼Œä½ å°±ä¸èƒ½è‡ªè¡Œæ’¤éŠ·ã€‚ +æˆå“¡å¿…é ˆè‡ªè¡Œé›¢è·æ‰èƒ½æ’¤éŠ·é€™è§’è‰²ã€‚ +ä½ ç¢ºå®šä½ è¦ç¹¼çºŒï¼Ÿ + <usetemplate ignoretext="åœ¨æˆ‘æ·»åŠ ä¸€å€‹æ–°çš„ç¾¤çµ„æ‰€æœ‰äººå‰å†æ¬¡ç¢ºèª" name="okcancelignore" notext="å¦" yestext="是"/> </notification> <notification name="AssignDangerousActionWarning"> - You are about to add the Ability '[ACTION_NAME]' to the Role '[ROLE_NAME]'. + ä½ å³å°‡æŠŠã€Œ[ACTION_NAME]ã€èƒ½åŠ›å¢žåŠ çµ¦ã€Œ[ROLE_NAME]ã€è§’色。 - *WARNING* - Any Member in a Role with this Ability can assign themselves -- and any other member -- to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability. + *è¦å‘Š* + 任何屬於帶有這能力的角色的æˆå“¡ï¼Œéƒ½å¯ä»¥è³¦äºˆè‡ªå·±æˆ–ä»»ä½•äººæ–°çš„è§’è‰²ï¼Œå› æ¤å¾—到比ç¾åœ¨æ›´å¤šçš„æ¬ŠåŠ›ï¼Œæœ€çµ‚å¯èƒ½æ“有近似「所有人ã€çš„æ¬ŠåŠ›ã€‚ è³¦äºˆé€™é …èƒ½åŠ›ä¹‹å‰ï¼Œæ•¬è«‹æ…Žé‡è€ƒæ…®ã€‚ -Add this Ability to '[ROLE_NAME]'? +ä½ ä»è¦æ–°å¢žé€™é …能力給「[ROLE_NAME]ã€ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> </notification> <notification name="AssignDangerousAbilityWarning"> - You are about to add the Ability '[ACTION_NAME]' to the Role '[ROLE_NAME]'. + ä½ å³å°‡æŠŠã€Œ[ACTION_NAME]ã€èƒ½åŠ›å¢žåŠ çµ¦ã€Œ[ROLE_NAME]ã€è§’色。 - *WARNING* - Any Member in a Role with this Ability can assign themselves -- and any other member -- all Abilities, elevating themselves to near-Owner power. + *è¦å‘Š* + 任何屬於帶有這能力的角色的æˆå“¡ï¼Œéƒ½å¯ä»¥å°‡æ‰€æœ‰èƒ½åŠ›è³¦äºˆè‡ªå·±æˆ–ä»»ä½•äººï¼Œæå‡ç‚ºè¿‘ä¼¼ã€Œæ‰€æœ‰äººã€æ¬ŠåŠ›çš„å±¤ç´šã€‚ -Add this Ability to '[ROLE_NAME]'? +ä½ ä»è¦æ–°å¢žé€™é …能力給「[ROLE_NAME]ã€ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> </notification> <notification name="AttachmentDrop"> - You are about to drop your attachment. - Are you sure you want to continue? + ä½ å³å°‡å¸é™¤ä½ 的附件。 + ä½ ç¢ºå®šä½ è¦ç¹¼çºŒï¼Ÿ <usetemplate ignoretext="在丟下附件å‰ç¢ºèª" name="okcancelignore" notext="å¦" yestext="是"/> </notification> <notification name="JoinGroupCanAfford"> @@ -181,178 +221,184 @@ Add this Ability to '[ROLE_NAME]'? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="åŠ å…¥"/> </notification> <notification name="JoinGroupNoCost"> - You are joining group [NAME]. -Do you wish to proceed? + ä½ å³å°‡åŠ å…¥ [NAME] 群組。 +ä½ ç¢ºå®šè¦ç¹¼çºŒå—Žï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="åŠ å…¥"/> </notification> <notification name="JoinGroupCannotAfford"> - Joining this group costs L$[COST]. -You do not have enough L$ to join this group. + åŠ å…¥æ¤ç¾¤çµ„é ˆèŠ±è²» L$[COST]。 +ä½ çš„ L$ ä¸å¤ åŠ å…¥é€™ç¾¤çµ„ã€‚ </notification> <notification name="CreateGroupCost"> - Creating this group will cost L$100. -Groups need more than one member, or they are deleted forever. -Please invite members within 48 hours. + 創立這個群組費用為 L$100。 +ç¾¤çµ„éœ€æœ‰è‡³å°‘å…©ä½æˆå“¡ï¼Œå¦å‰‡å°‡æ°¸ä¹…被刪除。 +請在 48 å°æ™‚內邀請æˆå“¡åŠ å…¥ã€‚ <usetemplate canceltext="å–æ¶ˆ" name="okcancelbuttons" notext="å–æ¶ˆ" yestext="花費 L$100 建立群組"/> </notification> <notification name="LandBuyPass"> - For L$[COST] you can enter this land ('[PARCEL_NAME]') for [TIME] hours. Buy a pass? + 花費 L$[COST],å¯é€²å…¥ã€Œ[PARCEL_NAME]ã€åœŸåœ°ï¼Œåœç•™ [TIME] å°æ™‚。 購買通行權? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="SalePriceRestriction"> - Sale price must be set to more than L$0 if selling to anyone. -Please select an individual to sell to if selling for L$0. + è‹¥æ˜¯å‡ºå”®çµ¦ä»»ä½•äººï¼Œå”®åƒ¹å¿…é ˆè¶…éŽ L$0。 +如果售價定為 L$0,請é¸å®šä¸€ä½å‡ºå”®å°è±¡ã€‚ </notification> <notification name="ConfirmLandSaleChange"> - The selected [LAND_SIZE] m² land is being set for sale. -Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NAME]. + 所é¸çš„ [LAND_SIZE] 平方公尺土地å³å°‡æº–備出售。 +售價將為 L$[SALE_PRICE]ï¼Œä¸¦å°‡ç¶“ä½ æŽˆæ¬Šå‡ºå”®çµ¦ [NAME]。 <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmLandSaleToAnyoneChange"> - ATTENTION: Clicking 'sell to anyone' makes your land available to the entire [SECOND_LIFE] community, even those not in this region. + 請注æ„:若點按「出售給任何人ã€ï¼Œä½ 的土地將å…許整個 [SECOND_LIFE] 社群å‰ä¾†è³¼è²·ï¼ŒåŒ…括æ¤åœ°å€å¤–的人。 -The selected [LAND_SIZE] m² land is being set for sale. -Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NAME]. +所é¸çš„ [LAND_SIZE] 平方公尺土地å³å°‡æº–備出售。 +售價將為 L$[SALE_PRICE]ï¼Œä¸¦å°‡ç¶“ä½ æŽˆæ¬Šå‡ºå”®çµ¦ [NAME]。 <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ReturnObjectsDeededToGroup"> - Are you sure you want to return all objects shared with the group '[NAME]' on this parcel of land back to their previous owner's inventory? + ä½ ç¢ºå®šè¦å°‡å’Œæœ¬åœŸåœ°åœ°æ®µçš„「[NAME]ã€ç¾¤çµ„分享的所有物件é€è¿”到原所有人的收ç´å€ï¼Ÿ -*WARNING* This will delete the non-transferable objects deeded to the group! +è¦å‘Šï¼šé€™å‹•作將會刪除原先讓渡給這群組的所有ä¸å¯è½‰è®“ç‰©ä»¶ï¼ -Objects: [N] +物件:[N] <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ReturnObjectsOwnedByUser"> - Are you sure you want to return all objects owned by the Resident '[NAME]' on this parcel of land back to their inventory? + ä½ ç¢ºå®šè¦å°‡æœ¬åœ°æ®µè£¡ã€Œ[NAME]ã€å±…æ°‘æ‰€æ“æœ‰çš„æ‰€æœ‰ç‰©ä»¶é€è¿”å…¶æ”¶ç´å€ï¼Ÿ -Objects: [N] +物件:[N] <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ReturnObjectsOwnedBySelf"> - Are you sure you want to return all objects owned by you on this parcel of land back to your inventory? + ä½ ç¢ºå®šè¦å°‡æœ¬åœ°æ®µè£¡ä½ æ‰€æ“æœ‰çš„æ‰€æœ‰ç‰©ä»¶é€è¿”ä½ çš„æ”¶ç´å€ï¼Ÿ -Objects: [N] +物件:[N] <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ReturnObjectsNotOwnedBySelf"> - Are you sure you want to return all objects NOT owned by you on this parcel of land back to their owner's inventory? -Transferable objects deeded to a group will be returned to their previous owners. + ä½ ç¢ºå®šè¦å°‡æœ¬åœ°æ®µè£¡ä¸å±¬æ–¼ä½ 的所有物件é€è¿”其所有人的收ç´å€ï¼Ÿ +å…ˆå‰è®“渡給群組的å¯è½‰è®“物件將é€è¿”給原物主。 -*WARNING* This will delete the non-transferable objects deeded to the group! +è¦å‘Šï¼šé€™å‹•作將會刪除原先讓渡給這群組的所有ä¸å¯è½‰è®“ç‰©ä»¶ï¼ -Objects: [N] +物件:[N] <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ReturnObjectsNotOwnedByUser"> - Are you sure you want to return all objects NOT owned by [NAME] on this parcel of land back to their owner's inventory? -Transferable objects deeded to a group will be returned to their previous owners. + ä½ ç¢ºå®šè¦å°‡æœ¬åœ°æ®µè£¡ä¸å±¬æ–¼ [NAME] 的所有物件é€è¿”其所有人的收ç´å€ï¼Ÿ +å…ˆå‰è®“渡給群組的å¯è½‰è®“物件將é€è¿”給原物主。 -*WARNING* This will delete the non-transferable objects deeded to the group! +è¦å‘Šï¼šé€™å‹•作將會刪除原先讓渡給這群組的所有ä¸å¯è½‰è®“ç‰©ä»¶ï¼ -Objects: [N] +物件:[N] <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ReturnAllTopObjects"> - Are you sure you want to return all listed objects back to their owner's inventory? + ä½ ç¢ºå®šè¦å°‡æ‰€åˆ—的所有物件é€è¿”其所有人的收ç´å€ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="DisableAllTopObjects"> - Are you sure you want to disable all objects in this region? + ä½ ç¢ºå®šè¦åœç”¨æœ¬åœ°å€è£¡æ‰€æœ‰ç‰©ä»¶ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ReturnObjectsNotOwnedByGroup"> - Return the objects on this parcel of land that are NOT shared with the group [NAME] back to their owners? + 將本地段裡未和 [NAME] 群組分享的物件é€è¿”給物主? -Objects: [N] +物件:[N] <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="UnableToDisableOutsideScripts"> - Can not disable scripts. -This entire region is damage enabled. -Scripts must be allowed to run for weapons to work. + 無法åœç”¨è…³æœ¬ã€‚ +這整個地å€å…許傷害。 +è…³æœ¬å¿…é ˆç²å‡†åŸ·è¡Œï¼Œæ¦å™¨æ‰æœ‰æ•ˆã€‚ </notification> <notification name="MultipleFacesSelected"> - Multiple faces are currently selected. -If you continue this action, separate instances of media will be set on multiple faces of the object. -To place the media on only one face, choose Select Face and click on the desired face of that object then click Add. - <usetemplate ignoretext="Media will be set on multiple selected faces" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> + ç›®å‰é¸æ“‡äº†å¤šå€‹è‡‰éƒ¨ã€‚ +å¦‚æžœä½ ç¹¼çºŒï¼Œç‰©ä»¶çš„å¤šå€‹è‡‰éƒ¨å°‡æœ‰å„自的媒體啟動。 +若想åªåœ¨ä¸€å€‹è‡‰éƒ¨æ”¾ç½®åª’é«”ï¼Œè«‹ã€Œé¸æ“‡è‡‰éƒ¨ã€ï¼Œé»žæŒ‰ç‰©ä»¶ä¸Šä½ 所è¦çš„è‡‰éƒ¨ï¼Œå†æŒ‰ã€Œæ–°å¢žã€ã€‚ + <usetemplate ignoretext="所é¸çš„多個臉部都將啟用å„自的媒體。" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="MustBeInParcel"> - You must be standing inside the land parcel to set its Landing Point. + ä½ å¿…é ˆç«™åœ¨åœ°æ®µä¸Šæ‰èƒ½è¨å®šå…¶ç™»é™¸é»žã€‚ </notification> <notification name="PromptRecipientEmail"> - Please enter a valid email address for the recipient(s). + 請輸入居民的有效的電郵地å€ã€‚ </notification> <notification name="PromptSelfEmail"> - Please enter your email address. + è«‹è¼¸å…¥ä½ çš„é›»éƒµåœ°å€ã€‚ </notification> <notification name="PromptMissingSubjMsg"> - Email snapshot with the default subject or message? + 用é è¨çš„電郵主旨或內文é€å‡ºå¿«ç…§ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ErrorProcessingSnapshot"> - Error processing snapshot data + 處ç†å¿«ç…§è³‡æ–™æ™‚出錯 </notification> <notification name="ErrorEncodingSnapshot"> - Error encoding snapshot. + 為快照編碼時出錯。 </notification> <notification name="ErrorUploadingPostcard"> - There was a problem sending a snapshot due to the following reason: [REASON] + 發é€å¿«ç…§æ™‚出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON] </notification> <notification name="ErrorUploadingReportScreenshot"> - There was a problem uploading a report screenshot due to the following reason: [REASON] + ä¸Šå‚³èˆ‰å ±ç”¨å¿«ç…§æ™‚å‡ºå•é¡Œï¼ŒåŽŸå› ï¼š[REASON] </notification> <notification name="MustAgreeToLogIn"> - You must agree to the Terms of Service to continue logging into [SECOND_LIFE]. + ä½ å¿…é ˆåŒæ„æœå‹™æ¢æ¬¾æ‰å¯ç¹¼çºŒç™»å…¥ [SECOND_LIFE]。 </notification> <notification name="CouldNotPutOnOutfit"> - Could not put on outfit. -The outfit folder contains no clothing, body parts, or attachments. + ç„¡æ³•ç©¿ä¸Šè£æ‰®ã€‚ +è£æ‰®è³‡æ–™å¤¾è£¡æ²’有任何衣物ã€èº«é«”éƒ¨ä½æˆ–附件。 </notification> <notification name="CannotWearTrash"> - You can not wear clothes or body parts that are in the trash + ä½ ä¸èƒ½ç©¿æˆ´åžƒåœ¾æ¡¶è£¡çš„衣物或身體部ä½ã€‚ </notification> <notification name="MaxAttachmentsOnOutfit"> - Could not attach object. -Exceeds the attachments limit of [MAX_ATTACHMENTS] objects. Please detach another object first. + ç„¡æ³•é™„åŠ ç‰©ä»¶ã€‚ +è¶…éŽ [MAX_ATTACHMENTS] é …ç‰©ä»¶çš„é™„åŠ ä¸Šé™ã€‚ è«‹å…ˆå¸é™¤ä¸€å€‹ç‰©ä»¶ã€‚ </notification> <notification name="CannotWearInfoNotComplete"> - You can not wear that item because it has not yet loaded. Please try again in a minute. + 無法穿戴該物件,它尚未完æˆè¼‰å…¥ã€‚ è«‹ç¨å€™å†è©¦ã€‚ </notification> <notification name="MustHaveAccountToLogIn"> - Oops! Something was left blank. -You need to enter the Username name of your avatar. + ç³Ÿç³•ï¼ ç™¼ç¾æœ‰å…§å®¹ç•™ç™½ã€‚ +ä½ å¿…é ˆç‚ºåŒ–èº«è¼¸å…¥ä¸€å€‹ä½¿ç”¨è€…å稱。 -You need an account to enter [SECOND_LIFE]. Would you like to create one now? +進入 [SECOND_LIFE] 需è¦ä¸€å€‹å¸³è™Ÿã€‚ ä½ ç¾åœ¨è¦ä¸è¦æ–°å»ºä¸€å€‹ï¼Ÿ <url name="url"> - http://join.secondlife.com/ + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="å†è©¦ä¸€æ¬¡" yestext="å‰µé€ æ–°å¸³æˆ¶"/> </notification> <notification name="InvalidCredentialFormat"> - You need to enter either the Username or both the First and Last name of your avatar into the Username field, then login again. + ä½ å¿…é ˆåœ¨ã€Œä½¿ç”¨è€…åç¨±ã€æ¬„ä½è£¡è¼¸å…¥ä½¿ç”¨è€…å稱,或輸入化身的å和姓,然後å†ç™»å…¥ã€‚ + </notification> + <notification name="InvalidGrid"> + '[GRID]' 䏿˜¯æœ‰æ•ˆçš„ç¶²æ ¼è¾¨è˜å…ƒã€‚ + </notification> + <notification name="InvalidLocationSLURL"> + ä½ çš„é–‹å§‹ä½ç½®æ‰€æŒ‡å®šçš„ç¶²æ ¼ç„¡æ•ˆã€‚ </notification> <notification name="DeleteClassified"> - Delete classified '[NAME]'? -There is no reimbursement for fees paid. + 刪除個人廣告「[NAME]ã€ï¼Ÿ +已付費用æ•ä¸é€€å›žã€‚ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="DeleteMedia"> - You have selected to delete the media associated with this face. -Are you sure you want to continue? + ä½ é¸æ“‡åˆªé™¤ç½®æ–¼é€™è‡‰éƒ¨çš„媒體。 +ä½ ç¢ºå®šä½ è¦ç¹¼çºŒï¼Ÿ <usetemplate ignoretext="在我由一個部件ä¸åˆªé™¤åª’é«”å‰ç¢ºèª" name="okcancelignore" notext="å¦" yestext="是"/> </notification> <notification name="ClassifiedSave"> - Save changes to classified [NAME]? + 儲å˜å€‹äººå»£å‘Šã€Œ[NAME]ã€çš„變更? <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="ä¸è¦å„²å˜" yestext="儲å˜"/> </notification> <notification name="ClassifiedInsufficientFunds"> - Insufficient funds to create classified. + 金é¡ä¸è¶³ï¼Œç„¡æ³•刊登個人廣告。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="DeleteAvatarPick"> - Delete pick <nolink>[PICK]</nolink>? + 刪除精é¸ä½ç½®<nolink>[PICK]</nolink>? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="DeleteOutfits"> @@ -367,7 +413,7 @@ Are you sure you want to continue? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="SelectProposalToView"> - Please select a proposal to view. + è«‹é¸æ“‡ä¸€å€‹è¦å¯Ÿçœ‹çš„æè°ã€‚ </notification> <notification name="SelectHistoryItemToView"> è«‹é¸æ“‡ä¸€å€‹æ·å²ç´€éŒ„物å“去察看。 @@ -380,13 +426,13 @@ Are you sure you want to continue? 注æ„:這將會清除快å–資料。 </notification> <notification name="ChangeConnectionPort"> - Port settings take effect after you restart [APP_NAME]. + 釿–°å•Ÿå‹• [APP_NAME] å¾Œå°‡å•Ÿç”¨æ–°çš„åŸ è¨å®šã€‚ </notification> <notification name="ChangeSkin"> - The new skin will appear after you restart [APP_NAME]. + 釿–°å•Ÿå‹• [APP_NAME] å¾Œå°‡é¡¯ç¾æ–°çš„皮膚。 </notification> <notification name="ChangeLanguage"> - Changing language will take effect after you restart [APP_NAME]. + 釿–°å•Ÿå‹• [APP_NAME] å¾Œå°‡æ›æˆæ–°çš„語言。 </notification> <notification name="GoToAuctionPage"> å‰å¾€ [SECOND_LIFE] ç¶²é 去察看æ‹è³£ç´°ç¯€æˆ–下標? @@ -396,92 +442,101 @@ Are you sure you want to continue? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="SaveChanges"> - Save Changes? + 儲å˜è®Šæ›´ï¼Ÿ <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="ä¸è¦å„²å˜" yestext="儲å˜"/> </notification> <notification name="GestureSaveFailedTooManySteps"> - Gesture save failed. -This gesture has too many steps. -Try removing some steps, then save again. + 姿勢儲å˜å¤±æ•—。 +這個姿勢æ¥é©Ÿå¤ªå¤šã€‚ +請去除一些æ¥é©Ÿå†å„²å˜ã€‚ </notification> <notification name="GestureSaveFailedTryAgain"> - Gesture save failed. Please try again in a minute. + 姿勢儲å˜å¤±æ•—。 è«‹ç¨å€™å†è©¦ã€‚ </notification> <notification name="GestureSaveFailedObjectNotFound"> - Could not save gesture because the object or the associated object inventory could not be found. -The object may be out of range or may have been deleted. + 無法儲å˜å§¿å‹¢ï¼Œæ‰¾ä¸åˆ°è©²ç‰©ä»¶æˆ–所屬物件收ç´å€ã€‚ +該物件å¯èƒ½è¶…å‡ºç¯„åœæˆ–已被刪除。 </notification> <notification name="GestureSaveFailedReason"> - There was a problem saving a gesture due to the following reason: [REASON]. Please try resaving the gesture later. + 儲å˜å§¿å‹¢æ™‚出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]。 è«‹ç¨å¾Œå†å˜—試儲å˜å§¿å‹¢ã€‚ </notification> <notification name="SaveNotecardFailObjectNotFound"> - Could not save notecard because the object or the associated object inventory could not be found. -The object may be out of range or may have been deleted. + 無法儲å˜è¨˜äº‹å¡ï¼Œæ‰¾ä¸åˆ°è©²ç‰©ä»¶æˆ–所屬物件收ç´å€ã€‚ +該物件å¯èƒ½è¶…å‡ºç¯„åœæˆ–已被刪除。 </notification> <notification name="SaveNotecardFailReason"> - There was a problem saving a notecard due to the following reason: [REASON]. Please try re-saving the notecard later. + 儲å˜è¨˜äº‹å¡æ™‚出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]。 è«‹ç¨å¾Œå†å˜—試儲å˜è¨˜äº‹å¡ã€‚ </notification> <notification name="ScriptCannotUndo"> - Could not undo all changes in your version of the script. -Would you like to load the server's last saved version? -(**Warning** This operation cannot be undone.) + ç„¡æ³•å–æ¶ˆä½ 這個版本腳本的變更。 +是å¦å¾žä¼ºæœå™¨è¼‰å…¥ä¸Šæ¬¡æˆåŠŸå„²å˜çš„版本? +(*è¦å‘Š* 這動作無法還原。) <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="SaveScriptFailReason"> - There was a problem saving a script due to the following reason: [REASON]. Please try re-saving the script later. + 儲å˜è…³æœ¬æ™‚出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]。 è«‹ç¨å¾Œå†å˜—試儲å˜è…³æœ¬ã€‚ </notification> <notification name="SaveScriptFailObjectNotFound"> - Could not save the script because the object it is in could not be found. -The object may be out of range or may have been deleted. + 無法儲å˜è…³æœ¬ï¼Œæ‰¾ä¸åˆ°å®ƒæ‰€å±¬çš„物件。 +該物件å¯èƒ½è¶…å‡ºç¯„åœæˆ–已被刪除。 </notification> <notification name="SaveBytecodeFailReason"> - There was a problem saving a compiled script due to the following reason: [REASON]. Please try re-saving the script later. + 儲å˜ç·¨è¯è…³æœ¬æ™‚出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]。 è«‹ç¨å¾Œå†å˜—試儲å˜è…³æœ¬ã€‚ </notification> <notification name="StartRegionEmpty"> - Oops, Your Start Region is not defined. -Please type the Region name in Start Location box or choose My Last Location or My Home as your Start Location. + ä½ çš„èµ·å§‹åœ°å€å°šæœªå®šç¾©ã€‚ +請在「開始ä½ç½®ã€æ¡†è£¡è¼¸å…¥å€åŸŸåï¼Œæˆ–é¸æ“‡ã€Œæˆ‘上一次ä½ç½®ã€æˆ–「我的家ã€ä½œç‚ºé–‹å§‹ä½ç½®ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="CouldNotStartStopScript"> - Could not start or stop the script because the object it is on could not be found. -The object may be out of range or may have been deleted. + ç„¡æ³•å•Ÿå‹•æˆ–åœæ¢è…³æœ¬ï¼Œæ‰¾ä¸åˆ°å®ƒæ‰€å±¬çš„物件。 +該物件å¯èƒ½è¶…å‡ºç¯„åœæˆ–已被刪除。 </notification> <notification name="CannotDownloadFile"> - Unable to download file + 無法下載檔案 </notification> <notification name="CannotWriteFile"> - Unable to write file [[FILE]] + 無法寫入檔案 [[FILE]] </notification> <notification name="UnsupportedHardware"> - Just so you know, your computer does not meet [APP_NAME]'s minimum system requirements. You may experience poor performance. Unfortunately, the [SUPPORT_SITE] can't provide technical support for unsupported system configurations. + è¦å‘ŠçŸ¥ä½ ï¼Œä½ çš„é›»è…¦æœªé” [APP_NAME] 的最低系統需求。 ä½ å¯èƒ½æœƒç™¼ç¾é›»è…¦æ€§èƒ½ä¸ä½³ã€‚ å¾ˆéºæ†¾ï¼Œ[SUPPORT_SITE] 無法é‡å°ä¸æ”¯æ´çš„系統è¨ç½®æä¾›æŠ€è¡“支æ´ã€‚ -Visit [_URL] for more information? +è¦é€ 訪 [_URL] ç²å–進一æ¥è³‡è¨Šï¼Ÿ <url name="url"> http://www.secondlife.com/corporate/sysreqs.php </url> <usetemplate ignoretext="æˆ‘çš„é›»è…¦ç¡¬é«”ä¸¦ä¸æ”¯æ´" name="okcancelignore" notext="å¦" yestext="是"/> </notification> + <notification name="IntelOldDriver"> + ä½ çš„é¡¯ç¤ºå¡å¾ˆå¯èƒ½æœ‰æ–°ç‰ˆçš„驅動程å¼ã€‚ æ›´æ–°é¡¯ç¤ºé©…å‹•ç¨‹å¼æœƒå¤§å¹…改善性能。 + + å‰å¾€ [_URL] å¯Ÿçœ‹æ˜¯å¦æœ‰æ–°ç‰ˆé©…動程å¼ï¼Ÿ + <url name="url"> + http://www.intel.com/p/en_US/support/detect/graphics + </url> + <usetemplate ignoretext="我的顯示驅動程å¼å¤ªè€èˆŠ" name="okcancelignore" notext="å¦" yestext="是"/> + </notification> <notification name="UnknownGPU"> - Your system contains a graphics card that [APP_NAME] doesn't recognize. -This is often the case with new hardware that hasn't been tested yet with [APP_NAME]. It will probably be ok, but you may need to adjust your graphics settings. -(Me > Preferences > Graphics). + ä½ çš„ç³»çµ±å«æœ‰ä¸€å€‹ [APP_NAME] 無法辨èªçš„顯åƒå¡ã€‚ +åŽŸå› å¾ˆå¯èƒ½æ˜¯ [APP_NAME] 尚未é‡å°æ–°ç¡¬é«”å®Œæˆæ¸¬è©¦ã€‚ é€™å¤§æ¦‚ä¸æœƒå‡ºå•é¡Œï¼Œä½†ä½ å¯èƒ½éœ€è¦èª¿æ•´é¡¯åƒè¨å®šã€‚ +(我自己 > å好è¨å®š > 顯åƒï¼‰ <form name="form"> <ignore name="ignore" text="我的顯示å¡ç„¡æ³•辨è˜"/> </form> </notification> <notification name="DisplaySettingsNoShaders"> - [APP_NAME] crashed while initializing graphics drivers. -Graphics Quality will be set to Low to avoid some common driver errors. This will disable some graphics features. -We recommend updating your graphics card drivers. -Graphics Quality can be raised in Preferences > Graphics. + [APP_NAME] åˆå§‹åŒ–顯åƒé©…å‹•ç¨‹å¼æ™‚當掉了。 +顯åƒåº¦å°‡è¨ç‚ºä½ŽéšŽï¼Œä»¥é˜²ç™¼ç”Ÿå¸¸è¦‹çš„é©…å‹•ç¨‹å¼æˆ–錯誤。 這將åœç”¨ä¸€äº›é¡¯åƒåŠŸèƒ½ã€‚ +我們建è°ä½ 更新顯åƒé©…動程å¼ã€‚ +請到「å好è¨å®š > 顯åƒã€æé«˜é¡¯åƒåº¦ã€‚ </notification> <notification name="RegionNoTerraforming"> 這個 [REGION] 地å€ä¸¦ä¸å…許變更地形。 </notification> <notification name="CannotCopyWarning"> - You do not have permission to copy the following items: + ä½ æ²’æœ‰æ¬Šé™è¤‡è£½ä»¥ä¸‹é …目: [ITEMS] -and will lose it from your inventory if you give it away. Do you really want to offer these items? +å¦‚æžœä½ å°‡å®ƒé€äººï¼Œå®ƒå°‡ç„¡æ³•續留在收ç´å€ã€‚ ä½ ç¢ºå®šè¦é€å‡ºé€™äº›æ±è¥¿å—Žï¼Ÿ <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> </notification> <notification name="CannotGiveItem"> @@ -491,18 +546,18 @@ and will lose it from your inventory if you give it away. Do you really want to äº¤æ˜“å·²å–æ¶ˆã€‚ </notification> <notification name="TooManyItems"> - Cannot give more than 42 items in a single inventory transfer. + æ¯ä¸€æ¬¡çš„æ”¶ç´å€è½‰ç§»å‹•作ä¸èƒ½è¶…éŽ 42 é …ç‰©ä»¶ã€‚ </notification> <notification name="NoItems"> - You do not have permission to transfer the selected items. + ä½ æ²’æœ‰æ¬Šé™è½‰ç§»æ‰€é¸é …目。 </notification> <notification name="CannotCopyCountItems"> - You do not have permission to copy [COUNT] of the selected items. You will lose these items from your inventory. -Do you really want to give these items? + ä½ æ²’æœ‰æ¬Šé™è¤‡è£½æ‰€é¸ç‰©ä»¶ç•¶ä¸çš„ [COUNT] é …ã€‚ ä½ çš„æ”¶ç´å€å°‡ç„¡æ³•續留這些物件。 +ä½ ç¢ºå®šè¦é€å‡ºé€™äº›æ±è¥¿å—Žï¼Ÿ <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> </notification> <notification name="CannotGiveCategory"> - You do not have permission to transfer the selected folder. + ä½ æ²’æœ‰æ¬Šé™è½‰ç§»æ‰€é¸è³‡æ–™å¤¾ã€‚ </notification> <notification name="FreezeAvatar"> å‡çµé€™ä½åŒ–身? @@ -533,75 +588,78 @@ Do you really want to give these items? å–得錯誤:太多物件被é¸å–。 </notification> <notification name="AcquireErrorObjectSpan"> - ACQUIRE ERROR: Objects span more than one region. -Please move all objects to be acquired onto the same region. + å–得錯誤:物件跨越多個地å€ã€‚ +請將所欲å–得的物件移到åŒä¸€å€åŸŸã€‚ </notification> <notification name="PromptGoToCurrencyPage"> [EXTRA] -Go to [_URL] for information on purchasing L$? +å‰å¾€ [_URL] 得知如何購買 L$? <url name="url"> http://secondlife.com/app/currency/ </url> <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="UnableToLinkObjects"> - Unable to link these [COUNT] objects. -You can link a maximum of [MAX] objects. + 無法è¯çµé€™ [COUNT] 個物件。 +ä½ æœ€å¤šå¯ä»¥è¯çµ [MAX] 個物件。 </notification> <notification name="CannotLinkIncompleteSet"> - You can only link complete sets of objects, and must select more than one object. + å¯ä»¥è¯çµçš„å¿…éœ€æ˜¯ä¸€å¥—ç‰©ä»¶ï¼Œè«‹é¸æ“‡è‡³å°‘兩個物件。 </notification> <notification name="CannotLinkModify"> - Unable to link because you don't have modify permission on all the objects. + 無法è¯çµï¼›ä½ å°æŸäº›ç‰©ä»¶æ²’有修改權。 -Please make sure none are locked, and that you own all of them. +請確定沒有物件被鎖ä½ï¼Œä¸¦ç¢ºå®šä½ æ“æœ‰æ‰€æœ‰ç‰©ä»¶ã€‚ + </notification> + <notification name="CannotLinkPermanent"> + 物件無法跨越地å€ç•Œé™é€²è¡Œè¯çµã€‚ </notification> <notification name="CannotLinkDifferentOwners"> - Unable to link because not all of the objects have the same owner. + 無法è¯çµï¼›æœ‰äº›ç‰©ä»¶çš„æ‰€æœ‰äººä¸åŒã€‚ -Please make sure you own all of the selected objects. +è«‹ç¢ºå®šä½ æ˜¯æ‰€é¸æ‰€æœ‰ç‰©ä»¶çš„æ‰€æœ‰äººã€‚ </notification> <notification name="NoFileExtension"> - No file extension for the file: '[FILE]' + 檔案沒有副檔å:'[FILE]' -Please make sure the file has a correct file extension. +請確定檔案具備æ£ç¢ºçš„副檔å。 </notification> <notification name="InvalidFileExtension"> - Invalid file extension [EXTENSION] -Expected [VALIDS] + 無效的副檔å:[EXTENSION] +應該是 [VALIDS] <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="CannotUploadSoundFile"> - Couldn't open uploaded sound file for reading: + 無法開啟並讀å–上傳的è²éŸ³æª”: [FILE] </notification> <notification name="SoundFileNotRIFF"> - File does not appear to be a RIFF WAVE file: + æª”æ¡ˆä¼¼ä¹Žä¸æ˜¯ RIFF WAVE 檔: [FILE] </notification> <notification name="SoundFileNotPCM"> - File does not appear to be a PCM WAVE audio file: + æª”æ¡ˆä¼¼ä¹Žä¸æ˜¯ PCM WAVE éŸ³é »æª”ï¼š [FILE] </notification> <notification name="SoundFileInvalidChannelCount"> - File has invalid number of channels (must be mono or stereo): + æª”æ¡ˆçš„é »é“æ•¸ç„¡æ•ˆï¼ˆå¿…需為單è²é“或立體è²ï¼‰ [FILE] </notification> <notification name="SoundFileInvalidSampleRate"> - File does not appear to be a supported sample rate (must be 44.1k): + æª”æ¡ˆä¼¼ä¹Žå¸¶æœ‰ä¸æ”¯æ´çš„æŽ¡æ¨£çŽ‡ï¼ˆéœ€ç‚º 44.1 k): [FILE] </notification> <notification name="SoundFileInvalidWordSize"> - File does not appear to be a supported word size (must be 8 or 16 bit): + æª”æ¡ˆä¼¼ä¹Žå¸¶æœ‰ä¸æ”¯æ´çš„å—組(需為 8 或 16 ä½å…ƒï¼‰ï¼š [FILE] </notification> <notification name="SoundFileInvalidHeader"> - Could not find 'data' chunk in WAV header: + 找ä¸åˆ° WAV 檔é 的「dataã€å€å¡Šï¼š [FILE] </notification> <notification name="SoundFileInvalidChunkSize"> - Wrong chunk size in WAV file: + WAV 檔å€å¡Šå¤§å°éŒ¯èª¤ï¼š [FILE] </notification> <notification name="SoundFileInvalidTooLong"> @@ -609,41 +667,41 @@ Expected [VALIDS] [FILE] </notification> <notification name="ProblemWithFile"> - Problem with file [FILE]: + 檔案 [FILE] 有å•題: [ERROR] </notification> <notification name="CannotOpenTemporarySoundFile"> - Couldn't open temporary compressed sound file for writing: [FILE] + ç„¡æ³•é–‹å•Ÿä¸¦å¯«å…¥æš«æ™‚å£“ç¸®éŸ³é »æª”ï¼š[FILE] </notification> <notification name="UnknownVorbisEncodeFailure"> - Unknown Vorbis encode failure on: [FILE] + ç™¼ç”Ÿä¸æ˜Žçš„ Vorbis 編碼錯誤:[FILE] </notification> <notification name="CannotEncodeFile"> - Unable to encode file: [FILE] + 無法將檔案編碼:[FILE] </notification> <notification name="CorruptedProtectedDataStore"> - We can't fill in your username and password. This may happen when you change network setup + æˆ‘å€‘ç„¡æ³•å¡«å…¥ä½ çš„ä½¿ç”¨è€…å稱和密碼。 這å¯èƒ½å› ç‚ºä½ è®Šæ›´äº†ç¶²è·¯è¨å®šã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="CorruptResourceFile"> - Corrupt resource file: [FILE] + 毀æçš„è³‡æºæª”:[FILE] </notification> <notification name="UnknownResourceFileVersion"> - Unknown Linden resource file version in file: [FILE] + 檔案ä¸ç™¼ç¾ä¸æ˜Žçš„ Linden è³‡æºæª”版本:[FILE] </notification> <notification name="UnableToCreateOutputFile"> - Unable to create output file: [FILE] + 無法建立輸出檔:[FILE] </notification> <notification name="DoNotSupportBulkAnimationUpload"> - [APP_NAME] does not currently support bulk upload of animation files. + [APP_NAME] ç›®å‰å°šä¸æ”¯æ´ BVH æ ¼å¼çš„動作檔批é‡ä¸Šå‚³ã€‚ </notification> <notification name="CannotUploadReason"> - Unable to upload [FILE] due to the following reason: [REASON] -Please try again later. + 無法上傳 [FILE]ï¼ŒåŽŸå› ï¼š[REASON] +è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="LandmarkCreated"> - ä½ å·²ç¶“æ·»åŠ "[LANDMARK_NAME]" åˆ°ä½ çš„ [FOLDER_NAME] 資料夾。 + ä½ å·²æ–°å¢žã€Œ[LANDMARK_NAME]ã€åˆ°ä½ çš„ [FOLDER_NAME] 資料夾。 </notification> <notification name="LandmarkAlreadyExists"> ä½ å·²ç¶“æœ‰é€™å€‹ä½ç½®çš„地標。 @@ -653,132 +711,132 @@ Please try again later. ä½ ä¸èƒ½å‰µé€ åœ°æ¨™ï¼Œå› ç‚ºåœ°ä¸»ä¸¦ä¸å…è¨±ä½ é€™æ¨£åšã€‚ </notification> <notification name="CannotRecompileSelectObjectsNoScripts"> - Not able to perform 'recompilation'. -Select an object with a script. + ç„¡æ³•é€²è¡Œé‡æ–°ç·¨è¯ã€‚ +è«‹é¸æ“‡å¸¶æœ‰è…³æœ¬çš„物件。 </notification> <notification name="CannotRecompileSelectObjectsNoPermission"> - Not able to perform 'recompilation'. + ç„¡æ³•é€²è¡Œé‡æ–°ç·¨è¯ã€‚ -Select objects with scripts that you have permission to modify. +鏿“‡å¸¶æœ‰ä½ å¯ä¿®æ”¹çš„腳本的物件。 </notification> <notification name="CannotResetSelectObjectsNoScripts"> - Not able to perform 'reset'. + ç„¡æ³•é‡æ–°å•Ÿå‹•。 -Select objects with scripts. +鏿“‡å¸¶æœ‰è…³æœ¬çš„物件。 </notification> <notification name="CannotResetSelectObjectsNoPermission"> - Not able to perform 'reset'. + ç„¡æ³•é‡æ–°å•Ÿå‹•。 -Select objects with scripts that you have permission to modify. +鏿“‡å¸¶æœ‰ä½ å¯ä¿®æ”¹çš„腳本的物件。 </notification> <notification name="CannotOpenScriptObjectNoMod"> - Unable to open script in object without modify permissions. + ç„¡æ³•é–‹å•Ÿç‰©ä»¶è£¡çš„è…³æœ¬ï¼Œå› ç‚ºä½ æ²’æœ‰ä¿®æ”¹æ¬Šã€‚ </notification> <notification name="CannotSetRunningSelectObjectsNoScripts"> - Not able to set any scripts to 'running'. + 無法將任何腳本è¨å®šç‚ºã€ŒåŸ·è¡Œä¸ã€ã€‚ -Select objects with scripts. +鏿“‡å¸¶æœ‰è…³æœ¬çš„物件。 </notification> <notification name="CannotSetRunningNotSelectObjectsNoScripts"> - Unable to set any scripts to 'not running'. + 無法將任何腳本è¨å®šç‚ºã€Œä¸åŸ·è¡Œã€ã€‚ -Select objects with scripts. +鏿“‡å¸¶æœ‰è…³æœ¬çš„物件。 </notification> <notification name="NoFrontmostFloater"> - No frontmost floater to save. + 沒有最å‰ç½®çš„æµ®å‹•視窗å¯å„²å˜ã€‚ </notification> <notification name="SeachFilteredOnShortWords"> - Your search query was modified and the words that were too short were removed. + ä½ çš„æœå°‹å—串已被修改,太çŸçš„å—已被移除。 -Searched for: [FINALQUERY] +æœå°‹ï¼š[FINALQUERY] </notification> <notification name="SeachFilteredOnShortWordsEmpty"> - Your search terms were too short so no search was performed. + ä½ çš„æœå°‹å—串太çŸï¼Œæ‰€ä»¥æ²’有啟動æœç´¢ã€‚ </notification> <notification name="CouldNotTeleportReason"> 瞬間傳é€å¤±æ•—。 [REASON] </notification> <notification name="invalid_tport"> - Problem encountered processing your teleport request. You may need to log back in before you can teleport. -If you continue to get this message, please check the [SUPPORT_SITE]. + 處ç†ä½ 瞬間傳é€è¦æ±‚時發生å•題。 如果想è¦çž¬é–“傳é€ï¼Œä½ å¯èƒ½éœ€è¦é‡æ–°ç™»å…¥ã€‚ +å¦‚æžœä½ æŒçºŒå¾—到æ¤è¨Šæ¯ï¼Œè«‹æŸ¥é–± [SUPPORT_SITE]。 </notification> <notification name="invalid_region_handoff"> - Problem encountered processing your region crossing. You may need to log back in before you can cross regions. -If you continue to get this message, please check the [SUPPORT_SITE]. + 處ç†ä½ 跨越地å€å‹•作時發生å•題。 如果想è¦è·¨è¶Šåœ°å€ï¼Œä½ å¯èƒ½éœ€è¦é‡æ–°ç™»å…¥ã€‚ +å¦‚æžœä½ æŒçºŒå¾—到æ¤è¨Šæ¯ï¼Œè«‹æŸ¥é–± [SUPPORT_SITE]。 </notification> <notification name="blocked_tport"> - Sorry, teleport is currently blocked. Try again in a moment. If you still cannot teleport, please log out and log back in to resolve the problem. + 抱æ‰ï¼Œç›®å‰ç¦æ¢çž¬é–“傳é€ã€‚ è«‹ç¨å¾Œå†è©¦ã€‚ å¦‚æžœä½ ä»ç„¡æ³•進行瞬間傳é€ï¼Œè«‹ç™»å‡ºå¾Œé‡æ–°å…¥ä¾†è§£æ±ºæ¤ä¸€å•題。 </notification> <notification name="nolandmark_tport"> - Sorry, but system was unable to locate landmark destination. + 抱æ‰ï¼Œä¸éŽç³»çµ±ç„¡æ³•找到地標所在目的地。 </notification> <notification name="timeout_tport"> - Sorry, but system was unable to complete the teleport connection. Try again in a moment. + 抱æ‰ï¼Œä¸éŽç³»çµ±ç„¡æ³•完æˆçž¬é–“傳é€çš„è¯æŽ¥ã€‚ è«‹ç¨å¾Œå†è©¦ã€‚ </notification> <notification name="noaccess_tport"> - Sorry, you do not have access to that teleport destination. + 抱æ‰ï¼Œä½ 並沒有權é™é€²å…¥è¦çž¬é–“傳é€çš„目的地。 </notification> <notification name="missing_attach_tport"> - Your attachments have not arrived yet. Try waiting for a few more seconds or log out and back in again before attempting to teleport. + ä½ çš„é™„ä»¶å°šæœªæŠµé”。 è«‹ç¨å€™ä¸€æœƒå…’ï¼Œæˆ–è«‹ç™»å‡ºå¾Œé‡æ–°ç™»å…¥ï¼Œå†å˜—試瞬間傳é€ã€‚ </notification> <notification name="too_many_uploads_tport"> - The asset queue in this region is currently clogged so your teleport request will not be able to succeed in a timely manner. Please try again in a few minutes or go to a less busy area. + 該地å€çš„資產查詢目å‰å¤ªéŽæ“å¡žï¼Œå› æ¤ä½ 的瞬間傳é€å‹•作å¯èƒ½ç„¡æ³•峿™‚發生。 è«‹ç¨å€™å†è©¦ï¼Œæˆ–è«‹å‰å¾€è¼ƒä¸æ“塞的地å€ã€‚ </notification> <notification name="expired_tport"> - Sorry, but the system was unable to complete your teleport request in a timely fashion. Please try again in a few minutes. + 抱æ‰ï¼Œç³»çµ±ç„¡æ³•峿™‚完æˆç‚ºä½ 瞬間傳é€ã€‚ è«‹ç¨å¾…幾分é˜å†è©¦ã€‚ </notification> <notification name="expired_region_handoff"> - Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes. + 抱æ‰ï¼Œç³»çµ±ç„¡æ³•峿™‚è®“ä½ è·¨è¶Šåœ°å€ã€‚ è«‹ç¨å¾…幾分é˜å†è©¦ã€‚ </notification> <notification name="no_host"> - Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes. + 找ä¸åˆ°çž¬é–“傳é€çš„目的地。 目的地å¯èƒ½æš«æ™‚ä¸å¯ç”¨ï¼Œæˆ–å·²ä¸å˜åœ¨ã€‚ è«‹ç¨å¾…幾分é˜å†è©¦ã€‚ </notification> <notification name="no_inventory_host"> æ”¶ç´å€åŠŸèƒ½ç›®å‰ç„¡æ³•使用。 </notification> <notification name="CannotSetLandOwnerNothingSelected"> - 無法è¨å®šåœŸåœ°æ“有者: -無地段被é¸å–。 + 無法è¨å®šåœŸåœ°æ‰€æœ‰äººï¼š +æœªé¸æ“‡åœ°æ®µã€‚ </notification> <notification name="CannotSetLandOwnerMultipleRegions"> - Unable to force land ownership because selection spans multiple regions. Please select a smaller area and try again. + 無法強è¨åœŸåœ°æ‰€æœ‰æ¬Šï¼›æ‰€é¸éƒ¨åˆ†è·¨è¶Šå¤šå€‹å€åŸŸã€‚ 請縮å°é¸æ“‡ç¯„åœï¼Œå†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="ForceOwnerAuctionWarning"> - This parcel is up for auction. Forcing ownership will cancel the auction and potentially make some Residents unhappy if bidding has begun. -Force ownership? + 這地段æ£åœ¨æ‹è³£ä¸ã€‚ å¼·è¨æ‰€æœ‰æ¬Šå°‡å–消æ‹è³£ï¼Œé€™æå°‡é€ æˆæŸäº›å·²å‡ºåƒ¹çš„å±…æ°‘ä¸é«˜èˆˆã€‚ +è¦å¼·è¨æ‰€æœ‰æ¬Šå—Žï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="CannotContentifyNothingSelected"> - Unable to contentify: -No parcel selected. + 無法進行「內容化ã€ï¼š +æœªé¸æ“‡åœ°æ®µã€‚ </notification> <notification name="CannotContentifyNoRegion"> - Unable to contentify: -No region selected. + 無法進行「內容化ã€ï¼š +æœªé¸æ“‡å€åŸŸã€‚ </notification> <notification name="CannotReleaseLandNothingSelected"> 無法放棄土地: -ç„¡åœ°æ®µè¢«é¸æ“‡ã€‚ +æœªé¸æ“‡åœ°æ®µã€‚ </notification> <notification name="CannotReleaseLandNoRegion"> 無法放棄土地: -無法尋找地å€ã€‚ +找ä¸åˆ°åœ°å€ã€‚ </notification> <notification name="CannotBuyLandNothingSelected"> 無法購買土地: -ç„¡åœ°æ®µè¢«é¸æ“‡ã€‚ +æœªé¸æ“‡åœ°æ®µã€‚ </notification> <notification name="CannotBuyLandNoRegion"> - Unable to buy land: -Cannot find the region this land is in. + 無法購買土地: +找ä¸åˆ°é€™åœŸåœ°æ‰€åœ¨çš„地å€ã€‚ </notification> <notification name="CannotCloseFloaterBuyLand"> - You cannot close the Buy Land window until [APP_NAME] estimates the price of this transaction. + å¿…é ˆç‰å¾… [APP_NAME] 估計æ¤äº¤æ˜“çš„åƒ¹æ ¼å¾Œï¼Œä½ æ‰èƒ½é—œé–‰ã€Œè³¼è²·åœŸåœ°ã€è¦–窗。 </notification> <notification name="CannotDeedLandNothingSelected"> 無法讓渡土地: -無地段被é¸å–。 +æœªé¸æ“‡åœ°æ®µã€‚ </notification> <notification name="CannotDeedLandNoGroup"> 無法讓渡土地: @@ -786,7 +844,7 @@ Cannot find the region this land is in. </notification> <notification name="CannotDeedLandNoRegion"> 無法讓渡土地: -無法發ç¾é€™å¡ŠåœŸåœ°æ‰€åœ¨çš„地å€ã€‚ +找ä¸åˆ°é€™åœŸåœ°æ‰€åœ¨çš„地å€ã€‚ </notification> <notification name="CannotDeedLandMultipleSelected"> 無法讓渡土地: @@ -802,7 +860,7 @@ Cannot find the region this land is in. </notification> <notification name="CannotDeedLandNoTransfer"> 無法讓渡土地: -æ¤ [REGION] 地å€ä¸¦ä¸å…許土地轉移。 +「[REGION]ã€åœ°å€ä¸å…許土地轉移。 </notification> <notification name="CannotReleaseLandWatingForServer"> 無法放棄土地: @@ -823,11 +881,11 @@ Cannot find the region this land is in. </notification> <notification name="CannotReleaseLandRegionNotFound"> 無法放棄土地: -無法發ç¾é€™å¿«åœŸåœ°æ‰€åœ¨çš„地å€ã€‚ +找ä¸åˆ°é€™åœŸåœ°æ‰€åœ¨çš„地å€ã€‚ </notification> <notification name="CannotReleaseLandNoTransfer"> 無法放棄土地: -æ¤ [REGION] 地å€ä¸¦ä¸è¨±åœŸåœ°è½‰ç§»ã€‚ +「[REGION]ã€åœ°å€ä¸å…許土地轉移。 </notification> <notification name="CannotReleaseLandPartialSelection"> 無法放棄土地: @@ -845,7 +903,7 @@ Cannot find the region this land is in. <notification name="CannotDivideLandNothingSelected"> 無法分割土地: -無地段被é¸å–。 +æœªé¸æ“‡åœ°æ®µã€‚ </notification> <notification name="CannotDivideLandPartialSelection"> 無法分割土地: @@ -854,22 +912,22 @@ Cannot find the region this land is in. 請試著é¸å–å…¶ä¸éƒ¨åˆ†åœ°æ®µã€‚ </notification> <notification name="LandDivideWarning"> - 分割土地會將佌地段一分為二,æ¯ä¸€å€‹åœ°æ®µå°‡éƒ½å„自有其è¨å®šã€‚ 在這個æ“作之後,一些è¨å®šå€¼å°‡æœƒå›žå¾©åˆ°é è¨å€¼ã€‚ + 分割土地將把地段分為兩份,æ¯å€‹æ–°åœ°æ®µæœ‰å„自的è¨å®šã€‚ 完æˆå¾Œï¼Œéƒ¨åˆ†è¨å®šå°‡é‡è¨ç‚ºé è¨å€¼ã€‚ 進行分割土地? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="CannotDivideLandNoRegion"> 無法分割土地: -無法發ç¾é€™å¡ŠåœŸåœ°æ‰€åœ¨çš„地å€ã€‚ +找ä¸åˆ°é€™åœŸåœ°æ‰€åœ¨çš„地å€ã€‚ </notification> <notification name="CannotJoinLandNoRegion"> 無法åˆä½µåœŸåœ°ï¼š -無法發ç¾é€™å¡ŠåœŸåœ°æ‰€åœ¨çš„地å€ã€‚ +找ä¸åˆ°é€™åœŸåœ°æ‰€åœ¨çš„地å€ã€‚ </notification> <notification name="CannotJoinLandNothingSelected"> 無法åˆä½µåœŸåœ°ï¼š -無地段被é¸å–。 +æœªé¸æ“‡åœ°æ®µã€‚ </notification> <notification name="CannotJoinLandEntireParcelSelected"> 無法åˆä½µåœŸåœ°ï¼š @@ -891,42 +949,42 @@ Cannot find the region this land is in. <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmNotecardSave"> - 在物å“能被覆製或察看å‰ï¼Œé€™è¨˜äº‹å¡å¿…é ˆå…ˆé€²è¡Œå„²å˜ã€‚儲å˜è¨˜äº‹å¡ï¼Ÿ + 覆製或察看å‰ï¼Œé€™è¨˜äº‹å¡å¿…é ˆå…ˆé€²è¡Œå„²å˜ã€‚ 儲å˜è¨˜äº‹å¡ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmItemCopy"> 覆製這個物å“åˆ°ä½ çš„æ”¶ç´å€ï¼Ÿ - <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="覆製"/> + <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="æšåº¨"/> </notification> <notification name="ResolutionSwitchFail"> - Failed to switch resolution to [RESX] by [RESY] + 無法將解æžåº¦èª¿ç‚º [RESX] X [RESY] </notification> <notification name="ErrorUndefinedGrasses"> - Error: Undefined grasses: [SPECIES] + 錯誤:未定義的è‰ç¨®ï¼š[SPECIES] </notification> <notification name="ErrorUndefinedTrees"> - Error: Undefined trees: [SPECIES] + 錯誤:未定義的樹種:[SPECIES] </notification> <notification name="CannotSaveWearableOutOfSpace"> - Unable to save '[NAME]' to wearable file. You will need to free up some space on your computer and save the wearable again. + 無法將「[NAME]ã€å„²å˜ç‚ºå¯ç©¿è£æ‰®æª”案。 ä½ éœ€è¦ç©ºå‡ºä¸€äº›é›»è…¦ç©ºé–“,å†è©¦è‘—儲å˜å¯ç©¿è£æ‰®ã€‚ </notification> <notification name="CannotSaveToAssetStore"> - Unable to save [NAME] to central asset store. -This is usually a temporary failure. Please customize and save the wearable again in a few minutes. + 無法將「[NAME]ã€å„²å˜åˆ°ä¸å¤®è³‡ç”¢å„²åº«ã€‚ +這異常狀æ³é€šå¸¸åªæ˜¯æš«æ™‚的。 è«‹ç¨å¾…幾分é˜å¾Œï¼Œå†è‡ªè¨‚並儲å˜å¯ç©¿è£æ‰®ã€‚ </notification> <notification name="YouHaveBeenLoggedOut"> - Darn. You have been logged out of [SECOND_LIFE] + ç³Ÿç³•ï¼ ä½ å·²è¢«ç™»å‡º [SECOND_LIFE] [MESSAGE] - <usetemplate name="okcancelbuttons" notext="çµæŸé€€å‡º" yestext="View IM & Chat"/> + <usetemplate name="okcancelbuttons" notext="çµæŸé€€å‡º" yestext="察看 IM å’ŒèŠå¤©å…§å®¹"/> </notification> <notification name="OnlyOfficerCanBuyLand"> - Unable to buy land for the group: -You do not have permission to buy land for your active group. + 無法為這群組購買土地: +ä½ æ²’æœ‰æ¬Šé™ç‚ºä½ ç•¶å‰çš„群組購買土地。 </notification> <notification label="åŠ ç‚ºæœ‹å‹" name="AddFriendWithMessage"> - Friends can give permissions to track each other on the map and receive online status updates. + 朋å‹å¯ä»¥å…許彼æ¤åœ¨åœ°åœ–ä¸Šè¿½è¹¤å°æ–¹ï¼Œä¸¦æŽ¥æ”¶å½¼æ¤çš„線上狀態更新訊æ¯ã€‚ -Offer friendship to [NAME]? +å‘ [NAME] 發出交å‹é‚€è«‹ï¼Ÿ <form name="form"> <input name="message"> ä½ é¡˜æ„æˆç‚ºæˆ‘的朋å‹å—Žï¼Ÿ @@ -935,21 +993,55 @@ Offer friendship to [NAME]? <button name="Cancel" text="å–æ¶ˆ"/> </form> </notification> + <notification label="新增自動å–代清單" name="AddAutoReplaceList"> + 新清單å稱: + <form name="form"> + <button name="SetName" text="確定"/> + </form> + </notification> + <notification label="更改自動å–代清單的å稱" name="RenameAutoReplaceList"> + 「[DUPNAME]ã€å稱已有人使用。 + 輸入å¦ä¸€å€‹ç¨ç‰¹çš„å稱: + <form name="form"> + <button name="ReplaceList" text="å–代目å‰çš„æ¸…å–®"/> + <button name="SetName" text="使用新å稱"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + é—œéµå—å¿…é ˆæ˜¯ä¸€å€‹å—,å–代å—ä¸å¾—空白。 + </notification> + <notification name="InvalidAutoReplaceList"> + 該å–代清單無效。 + </notification> + <notification name="SpellingDictImportRequired"> + ä½ å¿…é ˆæŒ‡å®šä¸€å€‹æª”æ¡ˆã€ä¸€å€‹å稱和一種語言。 + </notification> + <notification name="SpellingDictIsSecondary"> + [DIC_NAME] å—典似乎沒有 "aff" 檔案,這表示該å—典是「次級ã€å—典。 +它å¯ç”¨åšé™„åŠ å—典,但ä¸å¾—作為主è¦å—典。 + +åƒè¦‹ https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + 無法複製 [FROM_NAME] + + 到 [TO_NAME] + </notification> <notification label="儲å˜è£æ‰®" name="SaveOutfitAs"> å„²å˜æˆ‘æ£åœ¨ç©¿çš„ç‚ºæ–°è£æ‰®ï¼š <form name="form"> <input name="message"> - [DESC] (新) + [DESC](新) </input> <button name="OK" text="確定"/> <button name="Cancel" text="å–æ¶ˆ"/> </form> </notification> - <notification label="Save Wearable" name="SaveWearableAs"> + <notification label="儲å˜å¯ç©¿è£æ‰®" name="SaveWearableAs"> 儲å˜ç‰©å“到我的收ç´å€ç‚ºï¼š <form name="form"> <input name="message"> - [DESC] (新) + [DESC](新) </input> <button name="OK" text="確定"/> <button name="Cancel" text="å–æ¶ˆ"/> @@ -966,7 +1058,7 @@ Offer friendship to [NAME]? </form> </notification> <notification name="RemoveFromFriends"> - Do you want to remove [NAME] from your Friends List? + 確定è¦å¾žæœ‹å‹åå–®ä¸ç§»é™¤ <nolink>[NAME]</nolink>? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="RemoveMultipleFromFriends"> @@ -974,148 +1066,147 @@ Offer friendship to [NAME]? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="GodDeleteAllScriptedPublicObjectsByUser"> - Are you sure you want to delete all scripted objects owned by -** [AVATAR_NAME] ** -on all others land in this sim? + ä½ ç¢ºå®šè¦åˆªé™¤æœ¬æ¨¡æ“¬ä¸–界所有其他土地裡,** [AVATAR_NAME] ** æ‰€æ“æœ‰çš„全部帶腳本的物件? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="GodDeleteAllScriptedObjectsByUser"> - Are you sure you want to DELETE ALL scripted objects owned by -** [AVATAR_NAME] ** -on ALL LAND in this sim? + ä½ ç¢ºå®šè¦åˆªé™¤æœ¬æ¨¡æ“¬ä¸–界所有土地裡,** [AVATAR_NAME] ** æ‰€æ“æœ‰çš„全部帶腳本的物件? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="GodDeleteAllObjectsByUser"> - Are you sure you want to DELETE ALL objects (scripted or not) owned by -** [AVATAR_NAME] ** -on ALL LAND in this sim? + ä½ ç¢ºå®šè¦åˆªé™¤æœ¬æ¨¡æ“¬ä¸–界所有土地裡,** [AVATAR_NAME] ** æ‰€æ“æœ‰çš„全部物件(無論是å¦å¸¶è…³æœ¬ï¼‰ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="BlankClassifiedName"> - You must specify a name for your classified. + ä½ çš„å€‹äººå»£å‘Šå¿…é ˆæŒ‡å®šä¸€å€‹å稱。 </notification> <notification name="MinClassifiedPrice"> - Price to pay for listing must be at least L$[MIN_PRICE]. + 購買æ¤åˆŠç™»ç‰©çš„åƒ¹æ ¼å¿…é ˆè‡³å°‘ç‚º L$[MIN_PRICE]。 -Please enter a higher price. +è«‹è¼¸å…¥ä¸€å€‹è¼ƒé«˜çš„åƒ¹æ ¼ã€‚ </notification> <notification name="ConfirmItemDeleteHasLinks"> - At least one of the items you has link items that point to it. If you delete this item, its links will permanently stop working. It is strongly advised to delete the links first. + 所é¸é …ç›®ä¸è‡³å°‘æœ‰ä¸€å€‹å¸¶æœ‰ä¾†è‡ªå…¶ä»–é …ç›®çš„è¯çµã€‚ å¦‚æžœä½ åˆªé™¤é€™ä¸€é …ç›®ï¼Œè¯çµå°‡æ°¸ä¹…失效。 我們強烈建è°ä½ 先刪除è¯çµã€‚ -Are you sure you want to delete these items? +ä½ ç¢ºå®šä½ è¦åˆªé™¤é€™äº›ç‰©é …? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteLock"> - At least one of the items you have selected is locked. + ä½ æ‰€é¸é …ç›®ä¸è‡³å°‘有一個被鎖ä½ã€‚ -Are you sure you want to delete these items? +ä½ ç¢ºå®šä½ è¦åˆªé™¤é€™äº›ç‰©é …? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteNoCopy"> - At least one of the items you have selected is not copyable. + ä½ æ‰€é¸é …ç›®ä¸è‡³å°‘有一個ä¸èƒ½è¤‡è£½ã€‚ -Are you sure you want to delete these items? +ä½ ç¢ºå®šä½ è¦åˆªé™¤é€™äº›ç‰©é …? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteNoOwn"> - You do not own least one of the items you have selected. + ä½ æ‰€é¸é …ç›®ä¸è‡³å°‘æœ‰ä¸€å€‹ä¸æ˜¯ä½ æ‰€æ“æœ‰ã€‚ -Are you sure you want to delete these items? +ä½ ç¢ºå®šä½ è¦åˆªé™¤é€™äº›ç‰©é …? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteLockNoCopy"> - At least one object is locked. -At least one object is not copyable. + 至少有一個物件被鎖ä½ã€‚ +至少有一個物件ä¸èƒ½è¤‡è£½ã€‚ -Are you sure you want to delete these items? +ä½ ç¢ºå®šä½ è¦åˆªé™¤é€™äº›ç‰©é …? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteLockNoOwn"> - At least one object is locked. -You do not own least one object. + 至少有一個物件被鎖ä½ã€‚ +è‡³å°‘æœ‰ä¸€å€‹ç‰©ä»¶ä¸æ˜¯ä½ æ‰€æ“æœ‰ã€‚ -Are you sure you want to delete these items? +ä½ ç¢ºå®šä½ è¦åˆªé™¤é€™äº›ç‰©é …? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteNoCopyNoOwn"> - At least one object is not copyable. -You do not own least one object. + 至少有一個物件ä¸èƒ½è¤‡è£½ã€‚ +è‡³å°‘æœ‰ä¸€å€‹ç‰©ä»¶ä¸æ˜¯ä½ æ‰€æ“æœ‰ã€‚ -Are you sure you want to delete these items? +ä½ ç¢ºå®šä½ è¦åˆªé™¤é€™äº›ç‰©é …? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteLockNoCopyNoOwn"> - At least one object is locked. -At least one object is not copyable. -You do not own least one object. + 至少有一個物件被鎖ä½ã€‚ +至少有一個物件ä¸èƒ½è¤‡è£½ã€‚ +è‡³å°‘æœ‰ä¸€å€‹ç‰©ä»¶ä¸æ˜¯ä½ æ‰€æ“æœ‰ã€‚ -Are you sure you want to delete these items? +ä½ ç¢ºå®šä½ è¦åˆªé™¤é€™äº›ç‰©é …? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmObjectTakeLock"> - At least one object is locked. + 至少有一個物件被鎖ä½ã€‚ -Are you sure you want to take these items? +ä½ ç¢ºå®šä½ è¦æ‹¿å–é€™äº›ç‰©é …ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmObjectTakeNoOwn"> - You do not own all of the objects you are taking. -If you continue, next owner permissions will be applied and possibly restrict your ability to modify or copy them. + ä½ è¦æ‹¿å–的物件ä¸ï¼Œæœ‰äº›ä¸æ˜¯ä½ æ‰€æ“æœ‰ã€‚ +å¦‚æžœç¹¼çºŒï¼Œå°‡å¥—ç”¨ã€Œä¸‹ä¸€å€‹æ‰€æœ‰äººã€æ¬Šé™ï¼Œé€™å¯èƒ½æœƒé™åˆ¶ä½ 修改或複製權。 -Are you sure you want to take these items? +ä½ ç¢ºå®šä½ è¦æ‹¿å–é€™äº›ç‰©é …ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmObjectTakeLockNoOwn"> - At least one object is locked. -You do not own all of the objects you are taking. -If you continue, next owner permissions will be applied and possibly restrict your ability to modify or copy them. -However, you can take the current selection. + 至少有一個物件被鎖ä½ã€‚ +ä½ è¦æ‹¿å–的物件ä¸ï¼Œæœ‰äº›ä¸æ˜¯ä½ æ‰€æ“æœ‰ã€‚ +å¦‚æžœç¹¼çºŒï¼Œå°‡å¥—ç”¨ã€Œä¸‹ä¸€å€‹æ‰€æœ‰äººã€æ¬Šé™ï¼Œé€™å¯èƒ½æœƒé™åˆ¶ä½ 修改或複製權。 +ä¸éŽï¼Œä½ å¯ä»¥æ‹¿å–ç›®å‰æ‰€é¸çš„。 -Are you sure you want to take these items? +ä½ ç¢ºå®šä½ è¦æ‹¿å–é€™äº›ç‰©é …ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="CantBuyLandAcrossMultipleRegions"> - Unable to buy land because selection spans multiple regions. + 無法購買土地,所é¸éƒ¨åˆ†è·¨è¶Šå¤šå€‹åœ°å€ã€‚ -Please select a smaller area and try again. +請縮å°é¸æ“‡ç¯„åœï¼Œå†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="DeedLandToGroup"> - By deeding this parcel, the group will be required to have and maintain sufficient land use credits. -The purchase price of the land is not refunded to the owner. If a deeded parcel is sold, the sale price will be divided evenly among group members. + 若讓渡æ¤åœ°æ®µï¼Œé€™å€‹ç¾¤çµ„å°‡å¿…é ˆå…·å‚™ä¸¦ä¿æŒè¶³å¤ 的土地使用信用é¡åº¦ã€‚ +åœŸåœ°æ”¶è³¼åƒ¹å°‡ä¸æœƒé€€é‚„給所有人。 如果讓渡的地段被售出,售出價將å‡åˆ†çµ¦æ¯ä½ç¾¤çµ„æˆå“¡ã€‚ -Deed this [AREA] m² of land to the group '[GROUP_NAME]'? +是å¦è®“渡這塊 [AREA] 平方公尺的土地給群組「[GROUP_NAME]ã€ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="DeedLandToGroupWithContribution"> - By deeding this parcel, the group will be required to have and maintain sufficient land use credits. -The deed will include a simultaneous land contribution to the group from '[NAME]'. -The purchase price of the land is not refunded to the owner. If a deeded parcel is sold, the sale price will be divided evenly among group members. + 若讓渡æ¤åœ°æ®µï¼Œé€™å€‹ç¾¤çµ„å°‡å¿…é ˆå…·å‚™ä¸¦ä¿æŒè¶³å¤ 的土地使用信用é¡åº¦ã€‚ +æ¤ä¸€è®“æ¸¡å°‡åŒæ™‚包括來自 [NAME] 的,給予群組的土地æç»ã€‚ +åœŸåœ°æ”¶è³¼åƒ¹å°‡ä¸æœƒé€€é‚„給所有人。 如果讓渡的地段被售出,售出價將å‡åˆ†çµ¦æ¯ä½ç¾¤çµ„æˆå“¡ã€‚ -Deed this [AREA] m² of land to the group '[GROUP_NAME]'? +是å¦è®“渡這塊 [AREA] 平方公尺的土地給群組「[GROUP_NAME]ã€ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="DisplaySetToSafe"> - Display settings have been set to safe levels because you have specified the -safe option. + å› ç‚ºä½ æŒ‡å®šäº† -safe é¸é …,已將顯示è¨ç‚ºå®‰å…¨ç‰ç´šã€‚ + </notification> + <notification name="DisplaySetToRecommendedGPUChange"> + ç”±æ–¼ä½ çš„é¡¯åƒå¡æœ‰æ‰€è®Šæ›´ï¼Œå·²å°‡é¡¯ç¤ºç‹€æ…‹è¨ç‚ºæŽ¨è–¦æŽ¡ç”¨çš„ç‰ç´šã€‚ +原顯åƒå¡ï¼š[LAST_GPU] +新顯åƒå¡ï¼š[THIS_GPU] </notification> - <notification name="DisplaySetToRecommended"> - Display settings have been set to recommended levels based on your system configuration. + <notification name="DisplaySetToRecommendedFeatureChange"> + 由於呈åƒå系統有所變更,已將顯示狀態è¨ç‚ºæŽ¨è–¦çš„è¨å®šã€‚ </notification> <notification name="ErrorMessage"> [ERROR_MESSAGE] <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="AvatarMovedDesired"> - Your desired location is not currently available. -You have been moved into a nearby region. + ä½ æ‰€è¦çš„地點目å‰ç„¡æ³•å‰å¾€ã€‚ +ä½ å·²è¢«ç§»å¾€ä¸€å€‹é„°è¿‘åœ°å€ã€‚ </notification> <notification name="AvatarMovedLast"> - Your last location is not currently available. -You have been moved into a nearby region. + ä½ æ‰€è«‹æ±‚çš„åœ°é»žç›®å‰ç„¡æ³•å‰å¾€ã€‚ +ä½ å·²è¢«ç§»å¾€ä¸€å€‹é„°è¿‘åœ°å€ã€‚ </notification> <notification name="AvatarMovedHome"> - Your home location is not currently available. -You have been moved into a nearby region. -You may want to set a new home location. + ä½ è¨ç‚ºå®¶çš„地點目å‰ç„¡æ³•å‰å¾€ã€‚ +ä½ å·²è¢«ç§»å¾€ä¸€å€‹é„°è¿‘åœ°å€ã€‚ +建è°ä½ å¦é¸æ–°åœ°é»žè¨ç‚ºå®¶ã€‚ </notification> <notification name="ClothingLoading"> ä½ çš„æœè£ä»åœ¨ä¸‹è¼‰ä¸ã€‚ @@ -1127,14 +1218,13 @@ You may want to set a new home location. <notification name="FirstRun"> [APP_NAME] 安è£å®Œæˆã€‚ -If this is your first time using [SECOND_LIFE], you will need to create an account before you can log in. -Return to [http://join.secondlife.com secondlife.com] to create a new account? - <usetemplate name="okcancelbuttons" notext="繼續" yestext="新帳戶..."/> +å¦‚æžœä½ æ˜¯ç¬¬ä¸€æ¬¡ä½¿ç”¨ [SECOND_LIFE]ï¼Œä½ å°‡éœ€è¦å»ºç«‹æ–°å¸³è™Ÿæ‰å¯ç™»å…¥ã€‚ + <usetemplate name="okcancelbuttons" notext="繼續" yestext="建立帳號…"/> </notification> <notification name="LoginPacketNeverReceived"> - We're having trouble connecting. There may be a problem with your Internet connection or the [SECOND_LIFE_GRID]. + 連線出ç¾å•題。 å•題å¯èƒ½å‡ºåœ¨ä½ 的網路連線或 [SECOND_LIFE_GRID]。 -You can either check your Internet connection and try again in a few minutes, click Help to view the [SUPPORT_SITE], or click Teleport to attempt to teleport home. +è«‹æª¢æŸ¥ä½ çš„ç¶²è·¯é€£ç·šï¼Œå¹¾åˆ†é˜å¾Œå†è©¦ä¸€æ¬¡ï¼Œæˆ–者點按幫助ç€è¦½ [SUPPORT_SITE],或點按瞬間傳é€è©¦è‘—å›žåˆ°ä½ çš„å®¶ã€‚ <url name="url"> http://secondlife.com/support/ </url> @@ -1145,70 +1235,70 @@ You can either check your Internet connection and try again in a few minutes, cl </form> </notification> <notification name="WelcomeChooseSex"> - Your character will appear in a moment. + ä½ çš„äººç‰©å¾ˆå¿«å°‡æœƒå‡ºç¾ã€‚ -Use arrow keys to walk. -Press the F1 key at any time for help or to learn more about [SECOND_LIFE]. -Please choose the male or female avatar. You can change your mind later. +用方å‘éµè¡Œèµ°ã€‚ +ä»»ä½•æ™‚å€™ä½ éƒ½å¯æŒ‰ F1 éµå¯Ÿçœ‹å¹«åŠ©ï¼Œé€²ä¸€æ¥çžè§£ [SECOND_LIFE]。 +è«‹é¸æ“‡ç”·æ€§æˆ–女性化身。 ä»¥å¾Œä½ ä»å¯æ”¹è®Šé€™å€‹é¸æ“‡ã€‚ <usetemplate name="okcancelbuttons" notext="女性" yestext="男性"/> </notification> <notification name="CantTeleportToGrid"> - Could not teleport to [SLURL] as it's on a different grid ([GRID]) than the current grid ([CURRENT_GRID]). Please close your viewer and try again. + 無法瞬間傳é€åˆ° [SLURL]ï¼Œå®ƒä½æ–¼ä¸åŒçš„ç¶²æ ¼ï¼ˆ[GRID]),目å‰ç¶²æ ¼æ˜¯ [CURRENT_GRID]。 請關閉 Viewer å†è©¦ä¸€æ¬¡ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="GeneralCertificateError"> 無法連接到伺æœå™¨ã€‚ [REASON] -SubjectName: [SUBJECT_NAME_STRING] -IssuerName: [ISSUER_NAME_STRING] -Valid From: [VALID_FROM] -Valid To: [VALID_TO] -MD5 Fingerprint: [SHA1_DIGEST] -SHA1 Fingerprint: [MD5_DIGEST] -Key Usage: [KEYUSAGE] -Extended Key Usage: [EXTENDEDKEYUSAGE] -Subject Key Identifier: [SUBJECTKEYIDENTIFIER] +SubjectName:[SUBJECT_NAME_STRING] +IssuerName:[ISSUER_NAME_STRING] +有效來æºï¼š[VALID_FROM] +有效目標:[VALID_TO] +MD5 指紋:[SHA1_DIGEST] +SHA1 指紋:[MD5_DIGEST] +éµçš„使用:[KEYUSAGE] +延伸éµçš„使用:[EXTENDEDKEYUSAGE] +主題éµè¾¨è˜å…ƒï¼š[SUBJECTKEYIDENTIFIER] <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="TrustCertificateError"> - The certification authority for this server is not known. - -Certificate Information: -SubjectName: [SUBJECT_NAME_STRING] -IssuerName: [ISSUER_NAME_STRING] -Valid From: [VALID_FROM] -Valid To: [VALID_TO] -MD5 Fingerprint: [SHA1_DIGEST] -SHA1 Fingerprint: [MD5_DIGEST] -Key Usage: [KEYUSAGE] -Extended Key Usage: [EXTENDEDKEYUSAGE] -Subject Key Identifier: [SUBJECTKEYIDENTIFIER] - -Would you like to trust this authority? - <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="Trust"/> + 䏿˜Žçš„伺æœå™¨èªè‰æ¬Šé™ã€‚ + +èªè‰è³‡è¨Šï¼š +SubjectName:[SUBJECT_NAME_STRING] +IssuerName:[ISSUER_NAME_STRING] +有效來æºï¼š[VALID_FROM] +有效目標:[VALID_TO] +MD5 指紋:[SHA1_DIGEST] +SHA1 指紋:[MD5_DIGEST] +éµçš„使用:[KEYUSAGE] +延伸éµçš„使用:[EXTENDEDKEYUSAGE] +主題éµè¾¨è˜å…ƒï¼š[SUBJECTKEYIDENTIFIER] + +是å¦ä¿¡ä»»é€™å€‹æ¬Šé™ï¼Ÿ + <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="ä¿¡ä»»"/> </notification> <notification name="NotEnoughCurrency"> - [NAME] L$ [PRICE] You don't have enough L$ to do that. + [NAME] L$ [PRICE] ä½ æ²’æœ‰è¶³å¤ L$ 進行這動作。 </notification> <notification name="GrantedModifyRights"> - [NAME] has given you permission to edit their objects. + [NAME] å·²æŽˆæ¬Šä½ ç·¨è¼¯ä»–å€‘çš„ç‰©ä»¶ã€‚ </notification> <notification name="RevokedModifyRights"> - Your privilege to modify [NAME]'s objects has been revoked + ä½ ä¿®æ”¹ [NAME] 的物件的權é™å·²è¢«æ’¤éŠ·ã€‚ </notification> <notification name="FlushMapVisibilityCaches"> - This will flush the map caches on this region. -This is really only useful for debugging. -(In production, wait 5 minutes, then everyone's map will update after they relog.) + 這將清除本地å€çš„地圖快å–資料。 +這麼åšåªåœ¨é™¤éŒ¯æ™‚有用。 +(實地環境ä¸ï¼Œç‰å¾… 5 分é˜ï¼Œæ¯å€‹äººçš„åœ°åœ–å°‡åœ¨ä»–å€‘é‡æ–°ç™»å…¥å¾Œæ›´æ–°ã€‚) <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="BuyOneObjectOnly"> - Unable to buy more than one object at a time. Please select only one object and try again. + 無法一次購買多個物件。 è«‹åªé¸æ“‡ä¸€å€‹ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="OnlyCopyContentsOfSingleItem"> - Unable to copy the contents of more than one item at a time. -Please select only one object and try again. + ç„¡æ³•ä¸€æ¬¡è¤‡è£½å¤šå€‹ç‰©é …çš„å…§å®¹ã€‚ +è«‹åªé¸æ“‡ä¸€å€‹ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="KickUsersFromRegion"> @@ -1216,66 +1306,66 @@ Please select only one object and try again. <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="EstateObjectReturn"> - Are you sure you want to return objects owned by [USER_NAME]? + ä½ ç¢ºå®šè¦é€è¿” [USER_NAME] æ‰€æ“æœ‰çš„物件? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="InvalidTerrainBitDepth"> - Couldn't set region textures: -Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH]. + 無法è¨å®šåœ°å€æè³ªï¼š +地形æè³ª [TEXTURE_NUM] çš„ä½å…ƒæ·±åº¦ [TEXTURE_BIT_DEPTH] 無效。 -Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click "Apply" again. +è«‹å°‡æè³ª [TEXTURE_NUM] æ›¿æ›æˆ 24 ä½å…ƒ 512x512 或更å°åœ–åƒï¼Œç„¶å¾Œé»žæŒ‰ã€Œå¥—用ã€ã€‚ </notification> <notification name="InvalidTerrainSize"> - Couldn't set region textures: -Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y]. + 無法è¨å®šåœ°å€æè³ªï¼š +地形æè³ª [TEXTURE_NUM] 的尺寸 [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y] 太大。 -Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click "Apply" again. +è«‹å°‡æè³ª [TEXTURE_NUM] æ›¿æ›æˆ 24 ä½å…ƒ 512x512 或更å°åœ–åƒï¼Œç„¶å¾Œé»žæŒ‰ã€Œå¥—用ã€ã€‚ </notification> <notification name="RawUploadStarted"> - 上傳開始。將會花費約兩分é˜ï¼Œé€™å–æ±ºæ–¼ä½ çš„é€£ç·šé€Ÿåº¦ã€‚ + 上傳開始。 è¦–ä½ çš„é€£ç·šé€Ÿåº¦è€Œå®šï¼Œé€™æœ€å¤šéœ€æ™‚å…©åˆ†é˜ã€‚ </notification> <notification name="ConfirmBakeTerrain"> - Do you really want to bake the current terrain, make it the center for terrain raise/lower limits and the default for the 'Revert' tool? + ä½ çœŸçš„è¦ç¢ºå®šç”¢å‡ºç›®å‰åœ°å½¢ï¼Œä½¿å…¶æˆç‚ºåœ°å½¢å‡/陿¥µé™çš„ä¸é–“值,並è¨ç‚ºã€Œå¾©åŽŸã€å·¥å…·çš„é è¨å€¼ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="MaxAllowedAgentOnRegion"> - You can only have [MAX_AGENTS] Allowed Residents. + ä½ æœ€å¤šåªèƒ½æœ‰ [MAX_AGENTS] ä½å…許居民。 </notification> <notification name="MaxBannedAgentsOnRegion"> ä½ åªå¯ä»¥æœ‰æœ€å¤š [MAX_BANNED] ä½è¢«å°éŽ–çš„å±…æ°‘ã€‚ </notification> <notification name="MaxAgentOnRegionBatch"> - Failure while attempting to add [NUM_ADDED] agents: -Exceeds the [MAX_AGENTS] [LIST_TYPE] limit by [NUM_EXCESS]. + è©¦åœ–å¢žåŠ [NUM_ADDED] 人時失敗: +è¶…éŽäººæ•¸ä¸Šé™ [MAX_AGENTS] [LIST_TYPE]ï¼ˆè¶…éŽ [NUM_EXCESS] 人)。 </notification> <notification name="MaxAllowedGroupsOnRegion"> - You can only have [MAX_GROUPS] Allowed Groups. - <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="Bake"/> + ä½ åªèƒ½æœ‰ [MAX_GROUPS] 個å…許的群組。 + <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定產出"/> </notification> <notification name="MaxManagersOnRegion"> ä½ åªå¯ä»¥æœ‰æœ€å¤š [MAX_MANAGER] ä½é ˜åœ°ç¶“ç†ã€‚ </notification> <notification name="OwnerCanNotBeDenied"> - ç„¡æ³•æ·»åŠ é ˜åœ°æ“æœ‰è€…åˆ°é ˜åœ°çš„ '被å°éŽ–çš„å±…æ°‘' åå–®ä¸ã€‚ + ç„¡æ³•æ·»åŠ é ˜åœ°æ‰€æœ‰äººåˆ°é ˜åœ°çš„ '被å°éŽ–çš„å±…æ°‘' åå–®ä¸ã€‚ </notification> <notification name="CanNotChangeAppearanceUntilLoaded"> 無法變更外觀,直到æœè£èˆ‡é«”形下載完畢。 </notification> <notification name="ClassifiedMustBeAlphanumeric"> - The name of your classified must start with a letter from A to Z or a number. No punctuation is allowed. + ä½ çš„å€‹äººå»£å‘Šåç¨±å¿…é ˆä»¥ A-Z å—æ¯æˆ–數å—é–‹é 。 ä¸å…許標點符號。 </notification> <notification name="CantSetBuyObject"> - Can't set Buy Object, because the object is not for sale. -Please set the object for sale and try again. + 無法è¨å®šè³¼è²·ç‰©ä»¶ï¼Œè©²ç‰©ä»¶ç„¡æ³•出售。 +è«‹é¸å®šå‡ºå”®ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="FinishedRawDownload"> - Finished download of raw terrain file to: -[DOWNLOAD_PATH]. + 原始地形檔案下載完æˆï¼š +[DOWNLOAD_PATH]。 </notification> <notification name="DownloadWindowsMandatory"> - 一個新版本的 [APP_NAME] 已經å¯ç”¨ã€‚ + 有個新版本的 [APP_NAME] å¯ä¾›ä½¿ç”¨ã€‚ [MESSAGE] -ä½ å¿…é ˆä¸‹è¼‰é€™å€‹æ›´æ–°ä»¥ä½¿ç”¨ [APP_NAME]。 +ä½ å¿…é ˆä¸‹è¼‰é€™å€‹æ›´æ–°æ‰å¯ä½¿ç”¨ [APP_NAME]。 <usetemplate name="okcancelbuttons" notext="çµæŸé€€å‡º" yestext="下載"/> </notification> <notification name="DownloadWindows"> @@ -1285,89 +1375,86 @@ Please set the object for sale and try again. <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> </notification> <notification name="DownloadWindowsReleaseForDownload"> - An updated version of [APP_NAME] is available. + 一個 [APP_NAME] æ›´æ–°éŽçš„版本已經å¯ç”¨ã€‚ [MESSAGE] -This update is not required, but we suggest you install it to improve performance and stability. +這個更新並éžå¼·åˆ¶æ›´æ–°ï¼Œä½†æˆ‘們建è°ä½ 安è£ä»¥å¢žå¼·æ•ˆèƒ½åŠç©©å®šæ€§ã€‚ <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> </notification> <notification name="DownloadLinuxMandatory"> - A new version of [APP_NAME] is available. + 有個新版本的 [APP_NAME] å¯ä¾›ä½¿ç”¨ã€‚ [MESSAGE] -You must download this update to use [APP_NAME]. +ä½ å¿…é ˆä¸‹è¼‰é€™å€‹æ›´æ–°æ‰å¯ä½¿ç”¨ [APP_NAME]。 <usetemplate name="okcancelbuttons" notext="çµæŸé€€å‡º" yestext="下載"/> </notification> <notification name="DownloadLinux"> - An updated version of [APP_NAME] is available. + 一個 [APP_NAME] æ›´æ–°éŽçš„版本已經å¯ç”¨ã€‚ [MESSAGE] -This update is not required, but we suggest you install it to improve performance and stability. +這個更新並éžå¼·åˆ¶æ›´æ–°ï¼Œä½†æˆ‘們建è°ä½ 安è£ä»¥å¢žå¼·æ•ˆèƒ½åŠç©©å®šæ€§ã€‚ <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> </notification> <notification name="DownloadLinuxReleaseForDownload"> - An updated version of [APP_NAME] is available. + 一個 [APP_NAME] æ›´æ–°éŽçš„版本已經å¯ç”¨ã€‚ [MESSAGE] -This update is not required, but we suggest you install it to improve performance and stability. +這個更新並éžå¼·åˆ¶æ›´æ–°ï¼Œä½†æˆ‘們建è°ä½ 安è£ä»¥å¢žå¼·æ•ˆèƒ½åŠç©©å®šæ€§ã€‚ <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> </notification> <notification name="DownloadMacMandatory"> - A new version of [APP_NAME] is available. + 有個新版本的 [APP_NAME] å¯ä¾›ä½¿ç”¨ã€‚ [MESSAGE] -You must download this update to use [APP_NAME]. +ä½ å¿…é ˆä¸‹è¼‰é€™å€‹æ›´æ–°æ‰å¯ä½¿ç”¨ [APP_NAME]。 -Download to your Applications folder? +下載到 Applications 資料夾? <usetemplate name="okcancelbuttons" notext="çµæŸé€€å‡º" yestext="下載"/> </notification> <notification name="DownloadMac"> - An updated version of [APP_NAME] is available. + 一個 [APP_NAME] æ›´æ–°éŽçš„版本已經å¯ç”¨ã€‚ [MESSAGE] -This update is not required, but we suggest you install it to improve performance and stability. +這個更新並éžå¼·åˆ¶æ›´æ–°ï¼Œä½†æˆ‘們建è°ä½ 安è£ä»¥å¢žå¼·æ•ˆèƒ½åŠç©©å®šæ€§ã€‚ -Download to your Applications folder? +下載到 Applications 資料夾? <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> </notification> <notification name="DownloadMacReleaseForDownload"> - An updated version of [APP_NAME] is available. + 一個 [APP_NAME] æ›´æ–°éŽçš„版本已經å¯ç”¨ã€‚ [MESSAGE] -This update is not required, but we suggest you install it to improve performance and stability. +這個更新並éžå¼·åˆ¶æ›´æ–°ï¼Œä½†æˆ‘們建è°ä½ 安è£ä»¥å¢žå¼·æ•ˆèƒ½åŠç©©å®šæ€§ã€‚ -Download to your Applications folder? +下載到 Applications 資料夾? <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> </notification> <notification name="FailedUpdateInstall"> - An error occurred installing the viewer update. -Please download and install the latest viewer from -http://secondlife.com/download. + å®‰è£æ›´æ–°ç‰ˆ Viewer 時出錯。 +請到 http://secondlife.com/download ä¸‹è¼‰ä¸¦å®‰è£æœ€æ–°ç‰ˆ Viewer。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="FailedRequiredUpdateInstall"> - We were unable to install a required update. -You will be unable to log in until [APP_NAME] has been updated. + 無法安è£å¿…è¦çš„æ›´æ–°ã€‚ +é™¤éž [APP_NAME] æ›´æ–°ï¼Œä½ å°‡ç„¡æ³•ç™»å…¥ã€‚ -Please download and install the latest viewer from -http://secondlife.com/download. +請到 http://secondlife.com/download ä¸‹è¼‰ä¸¦å®‰è£æœ€æ–°ç‰ˆ Viewer。 <usetemplate name="okbutton" yestext="çµæŸé€€å‡º"/> </notification> <notification name="UpdaterServiceNotRunning"> - There is a required update for your Second Life Installation. + ä½ å·²å®‰è£çš„ç¬¬äºŒäººç”Ÿè»Ÿé«”ç¾æœ‰ä¸€å€‹å¿…è¦çš„æ›´æ–°ã€‚ -You may download this update from http://www.secondlife.com/downloads -or you can install it now. +ä½ å¯ä»¥åˆ° http://www.secondlife.com/downloads ä¸‹è¼‰æ¤æ›´æ–°ï¼Œæˆ–者ç¾åœ¨ç«‹å³å®‰è£ã€‚ <usetemplate name="okcancelbuttons" notext="çµæŸé€€å‡ºç¬¬äºŒäººç”Ÿ" yestext="ç«‹å³ä¸‹è¼‰åŠå®‰è£"/> </notification> <notification name="DownloadBackgroundTip"> - We have downloaded an update to your [APP_NAME] installation. -Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update] + æˆ‘å€‘å·²ç‚ºä½ çš„ [APP_NAME] 軟體下載了更新。 +[VERSION] 版本 [[RELEASE_NOTES_FULL_URL] é—œæ–¼æ¤æ›´æ–°çš„資訊] <usetemplate name="okcancelbuttons" notext="ç¨å€™..." yestext="ç«‹å³å®‰è£åŠé‡æ–°å•Ÿå‹• [APP_NAME]"/> </notification> <notification name="DownloadBackgroundDialog"> - We have downloaded an update to your [APP_NAME] installation. -Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update] - <usetemplate name="okcancelbuttons" notext="梢候..." yestext="ç«‹å³å®‰è£åŠé‡æ–°å•Ÿå‹• [APP_NAME]"/> + æˆ‘å€‘å·²ç‚ºä½ çš„ [APP_NAME] 軟體下載了更新。 +[VERSION] 版本 [[RELEASE_NOTES_FULL_URL] é—œæ–¼æ¤æ›´æ–°çš„資訊] + <usetemplate name="okcancelbuttons" notext="ç¨å€™..." yestext="ç«‹å³å®‰è£åŠé‡æ–°å•Ÿå‹• [APP_NAME]"/> </notification> <notification name="RequiredUpdateDownloadedVerboseDialog"> - We have downloaded a required software update. -Version [VERSION] + 我們已下載了一個必è¦çš„軟體更新。 +版本:[VERSION] -We must restart [APP_NAME] to install the update. +æˆ‘é–€å¿…é ˆé‡æ–°å•Ÿå‹• [APP_NAME] ä»¥å®‰è£æ›´æ–°ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="RequiredUpdateDownloadedDialog"> @@ -1375,8 +1462,8 @@ We must restart [APP_NAME] to install the update. <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="DeedObjectToGroup"> - Deeding this object will cause the group to: -* Receive L$ paid into the object + 讓渡æ¤ç‰©ä»¶å°‡å¯è®“這個群組: +* æ”¶å–付給æ¤ç‰©ä»¶çš„ L$ <usetemplate ignoretext="在我讓渡一個物件給群組å‰ç¢ºèª" name="okcancelignore" notext="å–æ¶ˆ" yestext="讓渡"/> </notification> <notification name="WebLaunchExternalTarget"> @@ -1388,7 +1475,7 @@ We must restart [APP_NAME] to install the update. <usetemplate ignoretext="啟動我的ç€è¦½å™¨ä»¥ç®¡ç†æˆ‘的帳戶" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="WebLaunchSecurityIssues"> - Visit the [SECOND_LIFE] Wiki for details of how to report a security issue. + é€ è¨ª [SECOND_LIFE] ç¶åŸºå¯Ÿçœ‹å¦‚何æå ±å®‰å…¨å•題。 <usetemplate ignoretext="開啟我的網é ç€è¦½å™¨ä»¥å¸ç¿’å¦‚ä½•å›žå ±ä¸€å€‹å®‰å…¨æ€§çš„è°é¡Œ" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="WebLaunchQAWiki"> @@ -1412,13 +1499,13 @@ We must restart [APP_NAME] to install the update. <usetemplate ignoretext="開啟我的網é ç€è¦½å™¨ä»¥å¯Ÿçœ‹ LSL å…¥å£" name="okcancelignore" notext="å–æ¶ˆ" yestext="å‰å¾€é é¢"/> </notification> <notification name="ReturnToOwner"> - ä½ ç¢ºå®šè¦é€€å›žæ‰€é¸æ“‡çš„ç‰©ä»¶çµ¦å®ƒå€‘çš„æ“æœ‰è€…嗎? å¯è½‰ç§»ä¸¦è®“渡的物件將會退回給它們的å‰ä¸€ä½æ“有者。 + ä½ ç¢ºå®šè¦é€è¿”所é¸ç‰©ä»¶çµ¦ç‰©ä¸»ï¼Ÿ å¯è½‰è®“的已讓渡物件將é€è¿”原物主。 *è¦å‘Š* éžå¯è½‰ç§»ä¸¦è®“渡的物件將會被刪除! - <usetemplate ignoretext="åœ¨æˆ‘é€€å›žç‰©ä»¶çµ¦å®ƒå€‘çš„æ“æœ‰è€…å‰ç¢ºèª" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> + <usetemplate ignoretext="在我退回物件給它們的所有人å‰ç¢ºèª" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="GroupLeaveConfirmMember"> - ä½ ç›®å‰æ˜¯ [GROUP] 群組的æˆå“¡ã€‚ + ä½ ç›®å‰æ˜¯ <nolink>[GROUP]</nolink> 群組的æˆå“¡ã€‚ 是å¦è¦é›¢é–‹ç¾¤çµ„? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> @@ -1427,57 +1514,57 @@ We must restart [APP_NAME] to install the update. <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="踢出全部居民"/> </notification> <notification name="MuteLinden"> - Sorry, you cannot block a Linden. + 抱æ‰ï¼Œä½ 無法å°éŽ–ä»»ä½•ä¸€ä½ Linden。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="CannotStartAuctionAlreadyForSale"> - You cannot start an auction on a parcel which is already set for sale. Disable the land sale if you are sure you want to start an auction. + ä½ ç„¡æ³•åœ¨å·²åœ¨å‡ºå”®ä¸çš„地段裡進行æ‹è³£ã€‚ ä½ å¦‚æžœç¢ºå®šè¦æ‹è³£ï¼Œè«‹å…ˆåœæ¢åœŸåœ°å‡ºå”®ã€‚ </notification> - <notification label="Block object by name failed" name="MuteByNameFailed"> - You already have blocked this name. + <notification label="ä¾å稱å°éŽ–ç‰©ä»¶å¤±æ•—" name="MuteByNameFailed"> + ä½ å·²ç¶“å°éŽ–äº†é€™å€‹å稱。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="RemoveItemWarn"> - Though permitted, deleting contents may damage the object. Do you want to delete that item? + é›–ç„¶å…許這麼åšï¼Œåˆªé™¤å…§å®¹å¯èƒ½æœƒç ´å£žç‰©ä»¶ã€‚ ä½ è¦åˆªé™¤è©²ç‰©é …嗎? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="CantOfferCallingCard"> - Cannot offer a calling card at this time. Please try again in a moment. + æ¤æ™‚無法æä¾›å片。 è«‹ç¨å€™å†è©¦ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="CantOfferFriendship"> - Cannot offer friendship at this time. Please try again in a moment. + æ¤æ™‚無法發出交å‹é‚€è«‹ã€‚ è«‹ç¨å€™å†è©¦ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="BusyModeSet"> - Busy mode is set. -Chat and instant messages will be hidden. Instant messages will get your Busy mode response. All teleportation offers will be declined. All inventory offers will go to your Trash. + å·²è¨ç‚ºå¿™ç¢Œæ¨¡å¼ã€‚ +èŠå¤©å’Œå³æ™‚訊æ¯å…§å®¹å°‡è¢«éš±è—。 峿™‚訊æ¯ç™¼é€è€…å°‡æ”¶åˆ°ä½ çš„ã€Œå¿™ç¢Œæ¨¡å¼ã€å›žæ‡‰ã€‚ 所有的瞬間傳é€é‚€è«‹éƒ½å°‡è¢«å©‰æ‹’。 æ¤æ™‚èµ·é€çµ¦ä½ 的收ç´å€ç‰©é …都將丟入垃圾桶。 <usetemplate ignoretext="我變更我的狀態為忙碌模å¼" name="okignore" yestext="確定"/> </notification> <notification name="JoinedTooManyGroupsMember"> - You have reached your maximum number of groups. Please leave another group before joining this one, or decline the offer. -[NAME] has invited you to join a group as a member. + ä½ å·²é”å¯åŒæ™‚åŠ å…¥çš„ç¾¤çµ„æ•¸ä¸Šé™ã€‚ 請先離開å¦ä¸€å€‹ç¾¤çµ„å†åŠ å…¥é€™ä¸€å€‹ï¼Œæˆ–å©‰æ‹’åŠ å…¥é‚€è«‹ã€‚ +[NAME] å·²é‚€è«‹ä½ åŠ å…¥ä¸€å€‹ç¾¤çµ„æˆç‚ºä¸€å“¡ã€‚ <usetemplate name="okcancelbuttons" notext="è¬çµ•" yestext="åŠ å…¥"/> </notification> <notification name="JoinedTooManyGroups"> - You have reached your maximum number of groups. Please leave some group before joining or creating a new one. + ä½ å·²é”å¯åŒæ™‚åŠ å…¥çš„ç¾¤çµ„æ•¸ä¸Šé™ã€‚ 請先離開æŸäº›ç¾¤çµ„å†åŠ å…¥æˆ–æ–°å»ºæ–°ç¾¤çµ„ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="KickUser"> 踢出這個居民並留給他什麼訊æ¯ï¼Ÿ <form name="form"> <input name="message"> - An administrator has logged you off. + 一ä½ç®¡ç†å“¡å·²è¿«ä½¿ä½ 登出。 </input> <button name="OK" text="確定"/> <button name="Cancel" text="å–æ¶ˆ"/> </form> </notification> <notification name="KickAllUsers"> - Kick everyone currently on the grid with what message? + è¸¢å‡ºç¶²æ ¼ä¸Šçš„æ¯å€‹äººï¼Œç•™çµ¦ä»–們什麼訊æ¯ï¼Ÿ <form name="form"> <input name="message"> - An administrator has logged you off. + 一ä½ç®¡ç†å“¡å·²è¿«ä½¿ä½ 登出。 </input> <button name="OK" text="確定"/> <button name="Cancel" text="å–æ¶ˆ"/> @@ -1487,7 +1574,7 @@ Chat and instant messages will be hidden. Instant messages will get your Busy mo å‡çµé€™ä½å±…æ°‘æ™‚åŒæ™‚留下什麼訊æ¯ï¼Ÿ <form name="form"> <input name="message"> - ä½ å·²ç¶“è¢«å‡çµäº†ã€‚ä½ å°‡ä¸èƒ½ç§»å‹•或èŠå¤©ã€‚管ç†å“¡å°‡æœƒä»¥å³æ™‚訊æ¯è¯ç¹«ä½ (IM)。 + ä½ å·²è¢«å‡çµã€‚ ä½ ç„¡æ³•ç§»å‹•æˆ–èŠå¤©ã€‚ 會有管ç†å“¡é€éŽå³æ™‚è¨Šæ¯ IM å’Œä½ è¯çµ¡ã€‚ </input> <button name="OK" text="確定"/> <button name="Cancel" text="å–æ¶ˆ"/> @@ -1497,75 +1584,80 @@ Chat and instant messages will be hidden. Instant messages will get your Busy mo 將這ä½å±…æ°‘è§£å‡ä¸¦åŒæ™‚留下什麼訊æ¯ï¼Ÿ <form name="form"> <input name="message"> - You are no longer frozen. + ä½ å·²è¢«è§£é™¤å‡çµã€‚ </input> <button name="OK" text="確定"/> <button name="Cancel" text="å–æ¶ˆ"/> </form> </notification> <notification name="SetDisplayNameSuccess"> - Hi [DISPLAY_NAME]! + [DISPLAY_NAME]ï¼Œä½ å¥½ï¼ -Just like in real life, it takes a while for everyone to learn about a new name. Please allow several days for [http://wiki.secondlife.com/wiki/Setting_your_display_name your name to update] in objects, scripts, search, etc. +çžè§£é©æ‡‰ä¸€å€‹æ–°åå—æ˜¯éœ€è¦æ™‚間的,æ£å¦‚ç¾å¯¦ç”Ÿæ´»é‚£æ¨£ã€‚ 請給我們幾天時間é‡å°æ‰€æœ‰ç‰©ä»¶ã€è…³æœ¬ã€æœå°‹ç‰æ–¹é¢ [http://wiki.secondlife.com/wiki/Setting_your_display_name æ›´æ–°ä½ çš„åå—]。 </notification> <notification name="SetDisplayNameBlocked"> - 抱æ‰ï¼Œä½ ä¸å¯ä»¥è®Šæ›´ä½ 的顯示åç¨±ã€‚å¦‚æžœä½ è¦ºå¾—é€™æ˜¯éŒ¯èª¤ï¼Œè«‹é€£ç¹«æ”¯æ´å» 商。 + 抱æ‰ï¼Œä½ ç„¡æ³•æ›´æ”¹ä½ çš„é¡¯ç¤ºå。 å¦‚ä½ èªç‚ºæœ‰å‡ºéŒ¯ï¼Œè«‹è¯çµ¡æ”¯æ´äººå“¡ã€‚ </notification> <notification name="SetDisplayNameFailedLength"> - 抱æ‰ï¼Œé€™å稱太長。顯示å稱最大長度為 [LENGTH] å—元。 + 抱æ‰ï¼Œè©²å稱太長。 顯示å稱最大長度為 [LENGTH] å—元。 請嘗試çŸä¸€äº›çš„å稱。 </notification> <notification name="SetDisplayNameFailedGeneric"> - Sorry, we could not set your display name. Please try again later. + 抱æ‰ï¼Œæˆ‘們無法è¨å®šä½ 的顯示å。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="SetDisplayNameMismatch"> - The display names you entered do not match. Please re-enter. + ä½ æ‰€è¼¸å…¥çš„é¡¯ç¤ºåä¸ç›¸ç¬¦ã€‚ è«‹å†è¼¸å…¥ä¸€æ¬¡ã€‚ </notification> <notification name="AgentDisplayNameUpdateThresholdExceeded"> - Sorry, you have to wait longer before you can change your display name. + 抱æ‰ï¼Œä½ å¿…é ˆå†ç‰ä¸€æ®µæ™‚é–“æ‰èƒ½æ›´æ”¹ä½ 的顯示å。 -See http://wiki.secondlife.com/wiki/Setting_your_display_name +åƒè¦‹ http://wiki.secondlife.com/wiki/Setting_your_display_name -Please try again later. +è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="AgentDisplayNameSetBlocked"> - Sorry, we could not set your requested name because it contains a banned word. + 抱æ‰ï¼Œæˆ‘們無法è¨å®šä½ 想è¦çš„åç¨±ï¼Œå®ƒå«æœ‰ç¦ç”¨å—眼。 - Please try a different name. + 請用ä¸åŒçš„å稱試試。 </notification> <notification name="AgentDisplayNameSetInvalidUnicode"> - The display name you wish to set contains invalid characters. + ä½ å¸Œæœ›è¨å®šçš„顯示å嫿œ‰ç„¡æ•ˆå—元。 </notification> <notification name="AgentDisplayNameSetOnlyPunctuation"> - Your display name must contain letters other than punctuation. + ä½ çš„é¡¯ç¤ºåå¿…é ˆåŒ…å«éžæ¨™é»žç¬¦è™Ÿçš„å—元。 </notification> <notification name="DisplayNameUpdate"> - [OLD_NAME] ([SLID]) is now known as [NEW_NAME]. + [OLD_NAME] ([SLID]) ç¾åœ¨æœ‰äº†æ–°åå— [NEW_NAME]。 </notification> <notification name="OfferTeleport"> - Offer a teleport to your location with the following message? + 用下列訊æ¯ç™¼å‡ºçž¬é–“傳é€é‚€è«‹ä¾†åˆ°ä½ çš„ä½ç½®ï¼Ÿ <form name="form"> <input name="message"> - åŠ å…¥æˆ‘åˆ° [REGION] + 在 [REGION] å’Œæˆ‘æœƒé¢ </input> <button name="OK" text="確定"/> <button name="Cancel" text="å–æ¶ˆ"/> </form> </notification> + <notification name="TooManyTeleportOffers"> + ä½ è©¦åœ–é€å‡º [OFFERS] 個瞬間傳é€é‚€è«‹ã€‚ +è¶…éŽäº† [LIMIT] 個的上é™ã€‚ + <usetemplate name="okbutton" yestext="確定"/> + </notification> <notification name="OfferTeleportFromGod"> - God summon Resident to your location? + 用神的權力把居民å¬åˆ°ä½ çš„ä½ç½®ï¼Ÿ <form name="form"> <input name="message"> - Join me in [REGION] + 在 [REGION] å’Œæˆ‘æœƒé¢ </input> <button name="OK" text="確定"/> <button name="Cancel" text="å–æ¶ˆ"/> </form> </notification> <notification name="TeleportFromLandmark"> - Are you sure you want to teleport to <nolink>[LOCATION]</nolink>? - <usetemplate ignoretext="Confirm that I want to teleport to a landmark" name="okcancelignore" notext="å–æ¶ˆ" yestext="瞬間傳é€"/> + ä½ ç¢ºå®šè¦çž¬é–“傳é€åˆ°<nolink>[LOCATION]</nolink>? + <usetemplate ignoretext="ç¢ºèªæˆ‘è¦çž¬é–“傳é€åˆ°æŸå€‹åœ°æ¨™" name="okcancelignore" notext="å–æ¶ˆ" yestext="瞬間傳é€"/> </notification> <notification name="TeleportToPick"> 瞬間傳é€åˆ° [PICK]? @@ -1580,57 +1672,57 @@ Please try again later. <usetemplate ignoretext="ç¢ºèªæˆ‘è¦çž¬é–“傳é€åˆ°æ·å²ç´€éŒ„ä¸çš„ä½ç½®" name="okcancelignore" notext="å–æ¶ˆ" yestext="瞬間傳é€"/> </notification> <notification label="é€å‡ºè¨Šæ¯çµ¦ä½ é ˜åœ°å…§çš„æ¯ä¸€å€‹äºº" name="MessageEstate"> - Type a short announcement which will be sent to everyone currently in your estate. + 輸入簡çŸå…¬å‘Šï¼Œå…¬å‘Šå°‡ç™¼é€çµ¦é ˜åœ°è£¡æ‰€æœ‰äººã€‚ <form name="form"> <button name="OK" text="確定"/> <button name="Cancel" text="å–æ¶ˆ"/> </form> </notification> - <notification label="Change Linden Estate" name="ChangeLindenEstate"> - You are about to change a Linden owned estate (mainland, teen grid, orientation, etc.). + <notification label="更改 Linden é ˜åœ°" name="ChangeLindenEstate"> + ä½ å³å°‡æ›´æ”¹ä¸€å€‹ Linden æ‰€æ“æœ‰çš„é ˜åœ°ï¼ˆå¤§é™¸ã€é’å°‘å¹´ç¶²æ ¼ã€å°Žå¼•å€ç‰ï¼‰ã€‚ -This is EXTREMELY DANGEROUS because it can fundamentally affect the Resident experience. On the mainland, it will change thousands of regions and make the spaceserver hiccup. +這動作éžå¸¸å±éšªï¼Œå®ƒæœƒæ ¹æœ¬å½±éŸ¿æ‰€æœ‰å±…民的體驗。 在大陸上,它將更動數åƒå€‹åœ°å€ï¼Œå°Žè‡´ç©ºé–“伺æœå™¨ç™¼ç”Ÿä¸é †ã€‚ -Proceed? +繼續? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> - <notification label="Change Linden Estate Access" name="ChangeLindenAccess"> - You are about to change the access list for a Linden owned estate (mainland, teen grid, orientation, etc.). + <notification label="更改 Linden é ˜åœ°å‡ºå…¥æ¬Š" name="ChangeLindenAccess"> + ä½ å³å°‡æ›´æ”¹ä¸€å€‹ Linden æ‰€æ“æœ‰é ˜åœ°ï¼ˆå¤§é™¸ã€é’å°‘å¹´ç¶²æ ¼ã€å°Žå¼•å€ç‰ï¼‰çš„出入權。 -This is DANGEROUS and should only be done to invoke the hack allowing objects/L$ to be transfered in/out of a grid. -It will change thousands of regions and make the spaceserver hiccup. +這動作很å±éšªï¼Œåªåœ¨éœ€è¦æŠŠç‰©ä»¶æˆ– L$ é€å‡ºæˆ–é€å…¥ç¶²æ ¼ï¼Œåˆç„¡æ›´å¥½æ–¹æ³•時ä¸å¾—已使用。 +它將更動數åƒå€‹åœ°å€ï¼Œå°Žè‡´ç©ºé–“伺æœå™¨ç™¼ç”Ÿä¸é †ã€‚ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification label="鏿“‡é ˜åœ°" name="EstateAllowedAgentAdd"> - Add to allowed list for this estate only or for [ALL_ESTATES]? + 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] 將它新增到å…許清單? <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> </notification> <notification label="鏿“‡é ˜åœ°" name="EstateAllowedAgentRemove"> - Remove from allowed list for this estate only or for [ALL_ESTATES]? + 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] 將它從å…許清單ä¸ç§»é™¤ï¼Ÿ <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> </notification> <notification label="鏿“‡é ˜åœ°" name="EstateAllowedGroupAdd"> - Add to group allowed list for this estate only or for [ALL_ESTATES]? + 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] 將它新增到群組å…許清單? <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> </notification> <notification label="鏿“‡é ˜åœ°" name="EstateAllowedGroupRemove"> - Remove from group allowed list for this estate only or [ALL_ESTATES]? + 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] 將它從群組å…許清單ä¸ç§»é™¤ï¼Ÿ <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> </notification> <notification label="鏿“‡é ˜åœ°" name="EstateBannedAgentAdd"> - Deny access for this estate only or for [ALL_ESTATES]? + 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] ç¦æ¢å‡ºå…¥ï¼Ÿ <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> </notification> <notification label="鏿“‡é ˜åœ°" name="EstateBannedAgentRemove"> - Remove this Resident from the ban list for access for this estate only or for [ALL_ESTATES]? + 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] å°‡é€™å€‹å±…æ°‘å¾žç¦æ¢å‡ºå…¥æ¸…å–®ä¸é™¤å? <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> </notification> <notification label="鏿“‡é ˜åœ°" name="EstateManagerAdd"> - Add estate manager for this estate only or for [ALL_ESTATES]? + 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] æ–°å¢žé ˜åœ°ç®¡ç†äººï¼Ÿ <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> </notification> <notification label="鏿“‡é ˜åœ°" name="EstateManagerRemove"> - Remove estate manager for this estate only or for [ALL_ESTATES]? + 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] ç§»é™¤é ˜åœ°ç®¡ç†äººï¼Ÿ <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> </notification> <notification label="確èªè¸¢å‡º" name="EstateKickUser"> @@ -1638,251 +1730,295 @@ It will change thousands of regions and make the spaceserver hiccup. <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="EstateChangeCovenant"> - Are you sure you want to change the Estate Covenant? + ä½ ç¢ºå®šè¦æ›´æ”¹é ˜åœ°å¥‘約? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="RegionEntryAccessBlocked"> - You are not allowed in that Region due to your maturity Rating. This may be a result of a lack of information validating your age. - -Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. + ä½ æ‰€æ¬²å‰å¾€çš„地å€å«æœ‰è¶…éŽä½ ç›®å‰å好的分級的內容。 ä½ å¯ä»¥åˆ°ã€Œæˆ‘自己 > å好è¨å®š > 一般è¨å®šã€è®Šæ›´ä½ çš„å好è¨å®šã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - You are not allowed in that region due to your maturity Rating. - -Go to the Knowledge Base for more information about maturity Ratings? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + ä½ æ‰€æ¬²å‰å¾€çš„地å€å«æœ‰ [REGIONMATURITY] çš„åˆ†ç´šå…§å®¹ï¼Œåƒ…é™æˆäººã€‚ <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="I can't enter this Region, due to restrictions of the maturity Rating" name="okcancelignore" notext="關閉" yestext="Go to Knowledge Base"/> + <usetemplate ignoretext="跨越地å€ï¼šä½ 所欲å‰å¾€çš„地å€å«æœ‰é™åˆ¶çµ¦æˆäººçš„內容。" name="okcancelignore" notext="關閉" yestext="å‰å¾€çŸ¥è˜åº«"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - You are not allowed in that region due to your maturity Rating. + ä½ æ‰€æ¬²å‰å¾€çš„地å€åŒ…å« [REGIONMATURITY] åˆ†ç´šçš„å…§å®¹ï¼Œå¯æ˜¯ä½ ç›®å‰çš„å好è¨å®šæŽ’除了 [REGIONMATURITY] 分級的內容。 + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + ä½ æ‰€æ¬²å‰å¾€çš„地å€å«æœ‰ [REGIONMATURITY] çš„åˆ†ç´šå…§å®¹ï¼Œåƒ…é™æˆäººã€‚ </notification> <notification name="RegionEntryAccessBlocked_Change"> - You are not allowed in that Region due to your maturity Rating preference. - -To enter the desired region, please change your maturity Rating preference. This will allow you to search for and access [REGIONMATURITY] content. To undo any changes, go to Me > Preferences > General. + ä½ æ‰€æ¬²å‰å¾€çš„地å€åŒ…å« [REGIONMATURITY] åˆ†ç´šçš„å…§å®¹ï¼Œå¯æ˜¯ä½ ç›®å‰çš„å好è¨å®šæŽ’除了 [REGIONMATURITY] 分級的內容。 ä½ å¯ä»¥è®Šæ›´ä½ çš„å好è¨å®šï¼Œæˆ–å–æ¶ˆå‰å¾€ã€‚ ä½ çš„å好è¨å®šè®Šæ›´å¾Œï¼Œä½ å¯ä»¥è©¦åœ–å†é€²å…¥è©²åœ°å€ã€‚ <form name="form"> - <button name="OK" text="Change Preference"/> - <button name="Cancel" text="Close"/> - <ignore name="ignore" text="My chosen Rating preference prevents me from entering a Region"/> + <button name="OK" text="變更å好è¨å®š"/> + <button name="Cancel" text="å–æ¶ˆ"/> + <ignore name="ignore" text="跨越地å€ï¼šä½ 所欲å‰å¾€çš„地å€å«æœ‰è¢«ä½ ç›®å‰çš„å好è¨å®šæŽ’除的分級內容。"/> </form> </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + 發生技術å•é¡Œï¼Œä½ çš„å好è¨å®šå’Œä¼ºæœå™¨ä¸Šçš„ä¸ä¸€è‡´ã€‚ + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + ä½ æ‰€æ¬²å‰å¾€çš„地å€å«æœ‰è¶…éŽä½ ç›®å‰å好的分級的內容。 ä½ å¯ä»¥åˆ°ã€Œæˆ‘自己 > å好è¨å®š > 一般è¨å®šã€è®Šæ›´ä½ çš„å好è¨å®šã€‚ + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + ä½ æ‰€æ¬²å‰å¾€çš„地å€å«æœ‰ [REGIONMATURITY] çš„åˆ†ç´šå…§å®¹ï¼Œåƒ…é™æˆäººã€‚ + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="瞬間傳é€ï¼šä½ 所欲å‰å¾€çš„地å€å«æœ‰é™åˆ¶çµ¦æˆäººçš„內容。" name="okcancelignore" notext="關閉" yestext="å‰å¾€çŸ¥è˜åº«"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + ä½ æ‰€æ¬²å‰å¾€çš„地å€åŒ…å« [REGIONMATURITY] åˆ†ç´šçš„å…§å®¹ï¼Œå¯æ˜¯ä½ ç›®å‰çš„å好è¨å®šæŽ’除了 [REGIONMATURITY] 分級的內容。 + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + ä½ æ‰€æ¬²å‰å¾€çš„地å€å«æœ‰ [REGIONMATURITY] çš„åˆ†ç´šå…§å®¹ï¼Œåƒ…é™æˆäººã€‚ + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + ä½ æ‰€æ¬²å‰å¾€çš„地å€åŒ…å« [REGIONMATURITY] åˆ†ç´šçš„å…§å®¹ï¼Œå¯æ˜¯ä½ ç›®å‰çš„å好è¨å®šæŽ’除了 [REGIONMATURITY] 分級的內容。 我們å¯ä»¥è®Šæ›´ä½ çš„å好è¨å®šå¥½è®“ä½ ç¹¼çºŒçž¬é–“å‚³é€ï¼Œä½ 也å¯å–消這動作。 + <form name="form"> + <button name="OK" text="變更後繼續"/> + <button name="Cancel" text="å–æ¶ˆ"/> + <ignore name="ignore" text="瞬間傳é€ï¼ˆå¯é‡å•Ÿï¼‰ï¼šä½ 所欲å‰å¾€çš„地å€å«æœ‰è¢«ä½ ç›®å‰çš„å好è¨å®šæŽ’除的分級內容。"/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + ä½ æ‰€æ¬²å‰å¾€çš„地å€åŒ…å« [REGIONMATURITY] åˆ†ç´šçš„å…§å®¹ï¼Œå¯æ˜¯ä½ ç›®å‰çš„å好è¨å®šæŽ’除了 [REGIONMATURITY] 分級的內容。 我們å¯ä»¥è®Šæ›´ä½ çš„å好è¨å®šï¼Œä½ 也å¯å–消瞬間傳é€ã€‚ ä½ çš„å好è¨å®šè®Šæ›´å¾Œï¼Œä½ å¯ä»¥å†å˜—試瞬間傳é€ã€‚ + <form name="form"> + <button name="OK" text="變更å好è¨å®š"/> + <button name="Cancel" text="å–æ¶ˆ"/> + <ignore name="ignore" text="瞬間傳é€ï¼ˆä¸å¯é‡å•Ÿï¼‰ï¼šä½ 所欲å‰å¾€çš„地å€å«æœ‰è¢«ä½ ç›®å‰çš„å好è¨å®šæŽ’除的分級內容。"/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + 發生技術å•é¡Œï¼Œä½ çš„å好è¨å®šå’Œä¼ºæœå™¨ä¸Šçš„ä¸ä¸€è‡´ã€‚ + <usetemplate name="okbutton" yestext="確定"/> + </notification> <notification name="PreferredMaturityChanged"> - Your maturity Rating preference is now [RATING]. + ä½ å°‡ä¸å†æ”¶åˆ°é€šçŸ¥ï¼Œå‘ŠçŸ¥ä½ å³å°‡é€²å…¥ä¸€å€‹ [RATING] 內容分級的地å€ã€‚ ä½ å¯ä»¥åˆ°é¸å–®åˆ—底下的「我自己 > å好è¨å®š > 一般è¨å®šã€è®Šæ›´ä½ 的內容å好。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="MaturityChangeError"> + æˆ‘å€‘æ¤æ™‚ç„¡æ³•è®Šæ›´ä½ çš„å好è¨å®šï¼Œè®“ä½ è§€çœ‹ [PREFERRED_MATURITY] 分級的內容。 ä½ çš„å好è¨å®šå·²ç¶“é‡è¨ï¼Œå¯è§€çœ‹ [ACTUAL_MATURITY] 的分級內容。 ä½ å¯ä»¥åˆ°é¸å–®åˆ—的「我自己 > å好è¨å®š > 一般è¨å®šã€å†æ¬¡è®Šæ›´ä½ çš„å好。 + <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="LandClaimAccessBlocked"> - You cannot claim this land due to your maturity Rating. This may be a result of a lack of information validating your age. - -Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. + ä½ æ‰€æ¬²æ”¶å–çš„åœŸåœ°å«æœ‰è¶…éŽä½ ç›®å‰å好的分級內容。 ä½ å¯ä»¥åˆ°ã€Œæˆ‘自己 > å好è¨å®š > 一般è¨å®šã€è®Šæ›´ä½ çš„å好è¨å®šã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - You cannot claim this land due to your maturity Rating. - -Go to the Knowledge Base for more information about maturity Ratings? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + åªæœ‰æˆäººæ‰èƒ½æ”¶å–這土地。 <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="I can't claim this Land, due to restrictions of the maturity Rating" name="okcancelignore" notext="關閉" yestext="Go to Knowledge Base"/> + <usetemplate ignoretext="åªæœ‰æˆäººæ‰èƒ½æ”¶å–這土地。" name="okcancelignore" notext="關閉" yestext="å‰å¾€çŸ¥è˜åº«"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - You cannot claim this land due to your maturity Rating. + ä½ æ‰€æ¬²æ”¶å–çš„åœŸåœ°åŒ…å« [REGIONMATURITY] åˆ†ç´šçš„å…§å®¹ï¼Œå¯æ˜¯ä½ ç›®å‰çš„å好è¨å®šæŽ’除了 [REGIONMATURITY] 分級的內容。 + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + ä½ æ‰€æ¬²æ”¶å–çš„åœŸåœ°åŒ…å« [REGIONMATURITY] çš„åˆ†ç´šå…§å®¹ï¼Œåƒ…é™æˆäººã€‚ </notification> <notification name="LandClaimAccessBlocked_Change"> - You cannot claim this land due to your maturity Rating preference. - -You can click 'Change Preference' to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me > Preferences > General. - <usetemplate ignoretext="My chosen Rating preference prevents me from claiming Land" name="okcancelignore" notext="關閉" yestext="Change Preference"/> + ä½ æ‰€æ¬²æ”¶å–çš„åœŸåœ°åŒ…å« [REGIONMATURITY] åˆ†ç´šçš„å…§å®¹ï¼Œå¯æ˜¯ä½ ç›®å‰çš„å好è¨å®šæŽ’除了 [REGIONMATURITY] 分級的內容。 我們å¯ä»¥è®Šæ›´ä½ çš„åå¥½ï¼Œè®“ä½ å†è©¦åœ–æ”¶å–土地。 + <form name="form"> + <button name="OK" text="變更å好è¨å®š"/> + <button name="Cancel" text="å–æ¶ˆ"/> + <ignore name="ignore" text="ä½ æ‰€æ¬²æ”¶å–çš„åœŸåœ°å«æœ‰è¢«ä½ ç›®å‰çš„å好所排除的分級內容。"/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - You cannot buy this land due to your maturity Rating. This may be a result of a lack of information validating your age. - -Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. + ä½ æ‰€æ¬²è³¼è²·çš„åœŸåœ°çš„å…§å®¹åˆ†ç´šè¶…éŽä½ ç›®å‰æ‰€è¨å好。 ä½ å¯ä»¥åˆ°ã€Œæˆ‘自己 > å好è¨å®š > 一般è¨å®šã€è®Šæ›´ä½ çš„å好è¨å®šã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - You cannot buy this land due to your maturity Rating. - -Go to the Knowledge Base for more information about maturity Ratings? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + åªæœ‰æˆäººæ‰èƒ½è³¼è²·é€™åœŸåœ°ã€‚ <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="I can't buy this Land, due to restrictions of the maturity Rating" name="okcancelignore" notext="關閉" yestext="Go to Knowledge Base"/> + <usetemplate ignoretext="åªæœ‰æˆäººæ‰èƒ½è³¼è²·é€™åœŸåœ°ã€‚" name="okcancelignore" notext="關閉" yestext="å‰å¾€çŸ¥è˜åº«"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - You cannot buy this land due to your maturity Rating. + ä½ æ‰€æ¬²è³¼è²·çš„åœŸåœ°åŒ…å« [REGIONMATURITY] åˆ†ç´šçš„å…§å®¹ï¼Œå¯æ˜¯ä½ ç›®å‰çš„å好è¨å®šæŽ’除了 [REGIONMATURITY] 分級的內容。 + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + ä½ æ‰€æ¬²è³¼è²·çš„åœŸåœ°å«æœ‰ [REGIONMATURITY] åˆ†ç´šçš„å…§å®¹ï¼Œåƒ…é™æˆäººã€‚ </notification> <notification name="LandBuyAccessBlocked_Change"> - You cannot buy this land due to your maturity Rating preference. - -You can click 'Change Preference' to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me > Preferences > General. - <usetemplate ignoretext="My chosen Rating preference prevents me from buying Land" name="okcancelignore" notext="關閉" yestext="變更å好è¨å®š"/> + ä½ æ‰€æ¬²è³¼è²·çš„åœŸåœ°åŒ…å« [REGIONMATURITY] åˆ†ç´šçš„å…§å®¹ï¼Œå¯æ˜¯ä½ ç›®å‰çš„å好è¨å®šæŽ’除了 [REGIONMATURITY] 分級的內容。 我們å¯ä»¥è®Šæ›´ä½ çš„åå¥½ï¼Œè®“ä½ å†è©¦åœ–購買土地。 + <form name="form"> + <button name="OK" text="變更å好è¨å®š"/> + <button name="Cancel" text="å–æ¶ˆ"/> + <ignore name="ignore" text="ä½ æ‰€æ¬²è³¼è²·çš„åœŸåœ°å«æœ‰è¢«ä½ ç›®å‰çš„å好所排除的分級內容。"/> + </form> </notification> <notification name="TooManyPrimsSelected"> - There are too many prims selected. Please select [MAX_PRIM_COUNT] or fewer prims and try again + 鏿“‡äº†å¤ªå¤šé …的幾何元件。 è«‹è‡³å¤šé¸æ“‡ [MAX_PRIM_COUNT] é …å¹¾ä½•å…ƒä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="ProblemImportingEstateCovenant"> - Problem importing estate covenant. + åŒ¯å…¥é ˜åœ°å¥‘ç´„æ™‚å‡ºå•題。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="ProblemAddingEstateManager"> - Problems adding a new estate manager. One or more estates may have a full manager list. + æ–°å¢žé ˜åœ°ç®¡ç†äººæ™‚出å•題。 å…¶ä¸ä¸€å€‹é ˜åœ°çš„管ç†äººæ¸…å–®å¯èƒ½å·²ç¶“顿»¿ã€‚ </notification> <notification name="ProblemAddingEstateGeneric"> - Problems adding to this estate list. One or more estates may have a full list. + æ–°å¢žåˆ°é€™å€‹é ˜åœ°æ¸…å–®æ™‚å‡ºå•題。 å…¶ä¸ä¸€å€‹é ˜åœ°çš„æ¸…å–®å¯èƒ½å·²æ»¿ã€‚ </notification> <notification name="UnableToLoadNotecardAsset"> - Unable to load notecard's asset at this time. + æ¤åˆ»ç„¡æ³•載入記事å¡è³‡ç”¢ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="NotAllowedToViewNotecard"> - Insufficient permissions to view notecard associated with asset ID requested. + 權é™ä¸è¶³ç„¡æ³•察看æ¤è³‡ç”¢ç·¨è™Ÿçš„記事å¡ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="MissingNotecardAssetID"> - Asset ID for notecard is missing from database. + 記事å¡çš„è³‡ç”¢ç·¨è™Ÿåœ¨è³‡æ–™åº«ä¸æ‰¾ä¸åˆ°ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="PublishClassified"> - Remember: Classified ad fees are non-refundable. + 請注æ„:個人廣告刊登費æ•ä¸é€€é‚„。 -Publish this classified now for L$[AMOUNT]? +支付 L$ [AMOUNT] 刊載這則個人廣告? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="SetClassifiedMature"> - Does this classified contain Moderate content? + 這則個人廣告是å¦å«é©åº¦æˆäººåˆ†ç´šçš„內容? <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="å¦" yestext="是"/> </notification> <notification name="SetGroupMature"> 這個群組將包å«é©åº¦æˆäººå…§å®¹ï¼Ÿ <usetemplate canceltext="å–æ¶ˆ" name="yesnocancelbuttons" notext="å¦" yestext="是"/> </notification> - <notification label="Confirm restart" name="ConfirmRestart"> - Do you really want to restart this region in 2 minutes? + <notification label="ç¢ºå®šé‡æ–°å•Ÿå‹•" name="ConfirmRestart"> + ä½ ç¢ºå®šè¦åœ¨ 2 分é˜å¾Œé‡æ–°å•Ÿå‹•這個地å€ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> - <notification label="Message everyone in this region" name="MessageRegion"> - Type a short announcement which will be sent to everyone in this region. + <notification label="å°åœ°å€è£¡æ¯å€‹äººç™¼å‡ºè¨Šæ¯" name="MessageRegion"> + 輸入簡çŸå…¬å‘Šï¼Œå…¬å‘Šå°‡ç™¼é€çµ¦åœ°å€è£¡æ‰€æœ‰äººã€‚ <form name="form"> <button name="OK" text="確定"/> <button name="Cancel" text="å–æ¶ˆ"/> </form> </notification> - <notification label="Changed Region Maturity" name="RegionMaturityChange"> - The maturity rating for this region has been updated. -It may take some time for the change to be reflected on the map. - -To enter Adult regions, Residents must be Account Verified, either by age-verification or payment-verification. + <notification label="已變更地å€çš„內容分級" name="RegionMaturityChange"> + æ¤åœ°å€çš„內容分級已經變更。 +å¯èƒ½éœ€è¦ç¨å€™ä¸€æ®µæ™‚é–“ï¼Œåœ°åœ–æ‰æœƒåæ˜ é€™å€‹è®Šæ›´ã€‚ + <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification label="Voice Version Mismatch" name="VoiceVersionMismatch"> - This version of [APP_NAME] is not compatible with the Voice Chat feature in this region. In order for Voice Chat to function correctly you will need to update [APP_NAME]. + <notification label="è²éŸ³ç‰ˆæœ¬ä¸ç›¸ç¬¦" name="VoiceVersionMismatch"> + 這版本的 [APP_NAME] 和本地å€çš„語音èŠå¤©åŠŸèƒ½ä¸ç›¸å®¹ã€‚ 想è¦èªžéŸ³èŠå¤©æ£å¸¸é‹ä½œï¼Œä½ å¿…é ˆæ›´æ–° [APP_NAME]。 </notification> <notification label="無法購買物件" name="BuyObjectOneOwner"> - Cannot buy objects from different owners at the same time. -Please select only one object and try again. + ç„¡æ³•åŒæ™‚å‘ä¸åŒç‰©ä¸»è³¼è²·ç‰©ä»¶ã€‚ +è«‹åªé¸æ“‡ä¸€å€‹ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚ </notification> <notification label="無法購買內容物" name="BuyContentsOneOnly"> - Unable to buy the contents of more than one object at a time. -Please select only one object and try again. + 無法一次購買多個物件的內容。 +è«‹åªé¸æ“‡ä¸€å€‹ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚ </notification> <notification label="無法購買內容物" name="BuyContentsOneOwner"> - Cannot buy objects from different owners at the same time. -Please select only one object and try again. + ç„¡æ³•åŒæ™‚å‘ä¸åŒç‰©ä¸»è³¼è²·ç‰©ä»¶ã€‚ +è«‹åªé¸æ“‡ä¸€å€‹ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="BuyOriginal"> - Buy original object from [OWNER] for L$[PRICE]? -You will become the owner of this object. -You will be able to: - Modify: [MODIFYPERM] - Copy: [COPYPERM] - Resell or Give Away: [RESELLPERM] + å‘ [OWNER] 支付 L$[PRICE],購買原版物件? +ä½ å°‡æˆç‚ºé€™ç‰©ä»¶çš„æ‰€æœ‰äººã€‚ +ä½ å°‡å¯ä»¥ï¼š + 修改:[MODIFYPERM] + 複製:[COPYPERM] + 轉售或é€äººï¼š[RESELLPERM] <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="BuyOriginalNoOwner"> - Buy original object for L$[PRICE]? -You will become the owner of this object. -You will be able to: - Modify: [MODIFYPERM] - Copy: [COPYPERM] - Resell or Give Away: [RESELLPERM] + 支付 L$[PRICE] 購買原版物件? +ä½ å°‡æˆç‚ºé€™ç‰©ä»¶çš„æ‰€æœ‰äººã€‚ +ä½ å°‡å¯ä»¥ï¼š + 修改:[MODIFYPERM] + 複製:[COPYPERM] + 轉售或é€äººï¼š[RESELLPERM] <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="BuyCopy"> - Buy a copy from [OWNER] for L$[PRICE]? -The object will be copied to your inventory. -You will be able to: - Modify: [MODIFYPERM] - Copy: [COPYPERM] - Resell or Give Away: [RESELLPERM] + å‘ [OWNER] 支付 L$[PRICE],購買複製物件? +é€™ç‰©ä»¶å°‡è¤‡è£½åˆ°ä½ çš„æ”¶ç´å€ã€‚ +ä½ å°‡å¯ä»¥ï¼š + 修改:[MODIFYPERM] + 複製:[COPYPERM] + 轉售或é€äººï¼š[RESELLPERM] <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="BuyCopyNoOwner"> - Buy a copy for L$[PRICE]? -The object will be copied to your inventory. -You will be able to: - Modify: [MODIFYPERM] - Copy: [COPYPERM] - Resell or Give Away: [RESELLPERM] + 支付 L$[PRICE] 購買複製物件? +é€™ç‰©ä»¶å°‡è¤‡è£½åˆ°ä½ çš„æ”¶ç´å€ã€‚ +ä½ å°‡å¯ä»¥ï¼š + 修改:[MODIFYPERM] + 複製:[COPYPERM] + 轉售或é€äººï¼š[RESELLPERM] <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="BuyContents"> - Buy contents from [OWNER] for L$[PRICE]? -They will be copied to your inventory. + å‘ [OWNER] 支付 L$[PRICE] 購買內容? +å…§å®¹å°‡è¤‡è£½åˆ°ä½ çš„æ”¶ç´å€ã€‚ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="BuyContentsNoOwner"> - Buy contents for L$[PRICE]? -They will be copied to your inventory. + 支付 L$[PRICE] 購買內容? +å…§å®¹å°‡è¤‡è£½åˆ°ä½ çš„æ”¶ç´å€ã€‚ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmPurchase"> - This transaction will: + é€™é …äº¤æ˜“å°‡æœƒï¼š [ACTION] -Are you sure you want to proceed with this purchase? +ä½ ç¢ºå®šè¦è³¼è²·ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmPurchasePassword"> - This transaction will: + é€™é …äº¤æ˜“å°‡æœƒï¼š [ACTION] -Are you sure you want to proceed with this purchase? -Please re-enter your password and click OK. +ä½ ç¢ºå®šè¦è³¼è²·ï¼Ÿ +è«‹é‡æ–°è¼¸å…¥å¯†ç¢¼å†é»žæŒ‰ç¢ºå®šã€‚ <form name="form"> <button name="ConfirmPurchase" text="確定"/> <button name="Cancel" text="å–æ¶ˆ"/> </form> </notification> <notification name="SetPickLocation"> - Note: -You have updated the location of this pick but the other details will retain their original values. + 附註: +ä½ å·²ç¶“æ›´æ–°é€™å€‹ç²¾é¸åœ°é»žçš„地點細節,其他細節將ä¿ç•™åŽŸå…§å®¹ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="MoveInventoryFromObject"> - You have selected 'no copy' inventory items. -These items will be moved to your inventory, not copied. + ä½ é¸æ“‡äº†ã€Œç¦æ¢è¤‡è£½ã€çš„æ”¶ç´å€ç‰©é …。 +é€™äº›ç‰©é …å°‡è¢«ç§»åˆ°ä½ çš„æ”¶ç´å€ï¼Œä¸æœƒè¢«è¤‡è£½ã€‚ -Move the inventory item(s)? - <usetemplate ignoretext="Warn me before I move 'no-copy' items from an object" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> +è¦ç§»å‹•æ”¶ç´å€ç‰©é …嗎? + <usetemplate ignoretext="在我從物件ä¸ç§»å‹•ã€Œç¦æ¢è¤‡è£½ã€ç‰©é …之å‰è¦å‘Šæˆ‘" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="MoveInventoryFromScriptedObject"> - You have selected 'no copy' inventory items. These items will be moved to your inventory, not copied. -Because this object is scripted, moving these items to your inventory may cause the script to malfunction. + ä½ é¸æ“‡äº†ã€Œç¦æ¢è¤‡è£½ã€çš„æ”¶ç´å€ç‰©é …。 é€™äº›ç‰©é …å°‡è¢«ç§»åˆ°ä½ çš„æ”¶ç´å€ï¼Œä¸æœƒè¢«è¤‡è£½ã€‚ +ç”±æ–¼é€™ç‰©ä»¶å¸¶æœ‰è…³æœ¬ï¼Œç§»å‹•é€™äº›ç‰©é …åˆ°æ”¶ç´å€å¯èƒ½æœƒå°Žè‡´è…³æœ¬é‹ä½œä¸æ£å¸¸ã€‚ -Move the inventory item(s)? - <usetemplate ignoretext="Warn me before I move 'no-copy' items which might break a scripted object" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> +è¦ç§»å‹•æ”¶ç´å€ç‰©é …嗎? + <usetemplate ignoretext="在我移動å¯èƒ½ç ´å£žå¸¶è…³æœ¬ç‰©ä»¶çš„ã€Œç¦æ¢è¤‡è£½ã€ç‰©é …之å‰è¦å‘Šæˆ‘" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ClickActionNotPayable"> - Warning: The 'Pay object' click action has been set, but it will only work if a script is added with a money() event. + è¦å‘Šï¼šã€Œæ”¯ä»˜ç‰©ä»¶ã€é»žæŒ‰å‹•作已è¨å®šï¼Œä½†æ–°å¢žçš„è…³æœ¬å¿…é ˆå«æœ‰ money() äº‹ä»¶ï¼Œè©²å‹•ä½œæ‰æœ‰ä½œç”¨ã€‚ <form name="form"> - <ignore name="ignore" text="I set the action 'Pay object' when building an object without a money() script"/> + <ignore name="ignore" text="我在創建ä¸å« money() 腳本的物件時è¨å®šäº†ã€Œæ”¯ä»˜ç‰©ä»¶ã€å‹•作"/> </form> </notification> <notification name="OpenObjectCannotCopy"> - There are no items in this object that you are allowed to copy. + é€™ç‰©ä»¶ä¸æ²’æœ‰ä»»ä½•å‡†è¨±ä½ è¤‡è£½çš„ç‰©é …ã€‚ </notification> <notification name="WebLaunchAccountHistory"> å‰å¾€ä½ çš„[http://secondlife.com/account/ 塗鴉牆]ä»¥å¯Ÿçœ‹ä½ çš„å¸³æˆ¶æ·å²ç´€éŒ„? @@ -1892,58 +2028,70 @@ Move the inventory item(s)? ä½ ç¢ºå®šä½ è¦çµæŸé€€å‡ºï¼Ÿ <usetemplate ignoretext="ç•¶æˆ‘çµæŸé€€å‡ºæ™‚進行確èª" name="okcancelignore" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/> </notification> + <notification name="ConfirmRestoreToybox"> + 這動作將會æ¢å¾©ä½ é è¨çš„æŒ‰éˆ•和工具列。 + +ä½ ä¸èƒ½å–消這動作。 + <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> + </notification> + <notification name="ConfirmClearAllToybox"> + é€™å‹•ä½œå°‡æŠŠæ‰€æœ‰æŒ‰éˆ•æ”¶å…¥å·¥å…·ç®±ï¼Œä½ çš„å·¥å…·åˆ—å°‡æœƒæ¸…ç©ºã€‚ + +ä½ ä¸èƒ½å–消這動作。 + <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> + </notification> <notification name="DeleteItems"> [QUESTION] <usetemplate ignoretext="刪除物å“å‰ç¢ºèª" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="HelpReportAbuseEmailLL"> - Use this tool to report violations of the [http://secondlife.com/corporate/tos.php Terms of Service] and [http://secondlife.com/corporate/cs.php Community Standards]. + ä½¿ç”¨é€™å€‹å·¥å…·èˆ‰å ±ä»»ä½•é•å[http://secondlife.com/corporate/tos.php æœå‹™æ¢æ¬¾]å’Œ[http://secondlife.com/corporate/cs.php 社群準則]的情事。 -All reported abuses are investigated and resolved. +æ‰€æœ‰èˆ‰å ±çš„é•è¦äº‹ä»¶éƒ½æœ‰äººèª¿æŸ¥ï¼ŒåŠ ä»¥è§£æ±ºã€‚ </notification> <notification name="HelpReportAbuseSelectCategory"> - Please select a category for this abuse report. -Selecting a category helps us file and process abuse reports. + è«‹é¸æ“‡é©åˆé€™æ¬¡é•è¦èˆ‰å ±çš„類別。 +é¸å°é¡žåˆ¥å¯ä»¥å¹«åŠ©æˆ‘å€‘æ¸é¡žä¸¦è™•ç†é•è¦èˆ‰å ±ã€‚ </notification> <notification name="HelpReportAbuseAbuserNameEmpty"> - Please enter the name of the abuser. -Entering an accurate value helps us file and process abuse reports. + 請輸入é•è¦äººçš„åå—。 +輸入準確的內容å¯ä»¥å¹«åŠ©æˆ‘å€‘æ¸é¡žä¸¦è™•ç†é•è¦èˆ‰å ±ã€‚ </notification> <notification name="HelpReportAbuseAbuserLocationEmpty"> - Please enter the location where the abuse took place. -Entering an accurate value helps us file and process abuse reports. + 請輸入é•è¦æƒ…事發生地點。 +輸入準確的內容å¯ä»¥å¹«åŠ©æˆ‘å€‘æ¸é¡žä¸¦è™•ç†é•è¦èˆ‰å ±ã€‚ </notification> <notification name="HelpReportAbuseSummaryEmpty"> - Please enter a summary of the abuse that took place. -Entering an accurate summary helps us file and process abuse reports. + 請概述é•è¦æƒ…事。 +準確的概述å¯ä»¥å¹«åŠ©æˆ‘å€‘æ¸é¡žä¸¦è™•ç†é•è¦èˆ‰å ±ã€‚ </notification> <notification name="HelpReportAbuseDetailsEmpty"> - Please enter a detailed description of the abuse that took place. -Be as specific as you can, including names and the details of the incident you are reporting. -Entering an accurate description helps us file and process abuse reports. + 請詳述é•è¦æƒ…事。 +請儘å¯èƒ½æä¾›å…·é«”è©³æƒ…ï¼ŒåŒ…æ‹¬ä½ è¦èˆ‰å ±çš„æ¡ˆæƒ…細節和涉案的å稱。 +準確的詳述å¯ä»¥å¹«åŠ©æˆ‘å€‘æ¸é¡žä¸¦è™•ç†é•è¦èˆ‰å ±ã€‚ </notification> <notification name="HelpReportAbuseContainsCopyright"> - Dear Resident, + 這ä½å±…æ°‘ï¼Œä½ å¥½ï¼š -You appear to be reporting intellectual property infringement. Please make sure you are reporting it correctly: +ä½ ä¼¼ä¹Žæ£åœ¨èˆ‰å ±æœ‰äººä¾µçŠ¯æ™ºæ…§è²¡ç”¢æ¬Šã€‚ è«‹ç¢ºå®šä½ èˆ‰å ±å…§å®¹ç¢ºé‘¿ç„¡èª¤ï¼š -(1) The Abuse Process. You may submit an abuse report if you believe a Resident is exploiting the [SECOND_LIFE] permissions system, for example, by using CopyBot or similar copying tools, to infringe intellectual property rights. The Abuse Team investigates and issues appropriate disciplinary action for behavior that violates the [SECOND_LIFE] [http://secondlife.com/corporate/tos.php Terms of Service] or [http://secondlife.com/corporate/cs.php Community Standards]. However, the Abuse Team does not handle and will not respond to requests to remove content from the [SECOND_LIFE] world. +(1) é•è¦èˆ‰å ±è™•ç†ç¨‹åºã€‚ ä½ è‹¥ç›¸ä¿¡æœ‰å±…æ°‘åˆ©ç”¨ [SECOND_LIFE] 權é™é‚行侵犯智慧財產權,如使用複製機器程å¼ç¢¼(CopyBot)æˆ–å…¶ä»–é¡žä¼¼è¤‡è£½å·¥å…·ï¼Œå¾—ä»¥èˆ‰å ±æ¤æƒ…事。 é•è¦è™•ç†å°çµ„會就任何é•å[SECOND_LIFE][http://secondlife.com/corporate/tos.php æœå‹™æ¢æ¬¾]或[http://secondlife.com/corporate/cs.php 社群準則]的行為展開調查,並採å–é©ç•¶è™•置。 然而,é•è¦è™•ç†å°çµ„並ä¸å—ç†è¦æ±‚å°‡æŸå…§å®¹è‡ª[SECOND_LIFE]è™›æ“¬ä¸–ç•Œåˆªé™¤ï¼Œé€™é¡žè¦æ±‚å°‡ä¸äºˆå›žæ‡‰ã€‚ -(2) The DMCA or Content Removal Process. To request removal of content from [SECOND_LIFE], you MUST submit a valid notification of infringement as provided in our [http://secondlife.com/corporate/dmca.php DMCA Policy]. +(2) DMCA(刪除內容作æ¥ç¨‹åºï¼‰ã€‚ è‹¥æ¬²è¦æ±‚刪除[SECOND_LIFE]å…§å®¹ï¼Œä½ å¿…é ˆæŒ‰ç…§[http://secondlife.com/corporate/dmca.php DMCA 政ç–]æå‡ºæœ‰æ•ˆçš„侵權通知。 -If you still wish to continue with the abuse process, please close this window and finish submitting your report. You may need to select the specific category 'CopyBot or Permissions Exploit'. +å¦‚æžœä½ ä»å¸Œæœ›ç¹¼çºŒï¼Œè«‹é—œé–‰æ¤è¦–窗,完æˆèˆ‰å ±ã€‚ ä½ å¯èƒ½éœ€è¦é¸æ“‡ã€ŒCopyBot 或濫用權é™ã€é€™ä¸€å…·é«”類別。 -Thank you, +è¬è¬ä½ , -Linden Lab +林登實驗室謹上 </notification> <notification name="FailedRequirementsCheck"> - The following required components are missing from [FLOATER]: + [FLOATER] 裡找ä¸åˆ°ä¸‹åˆ—å¿…è¦å…ƒä»¶ï¼š [COMPONENTS] </notification> <notification label="å–ä»£ç¾æœ‰çš„附件" name="ReplaceAttachment"> - There is already an object attached to this point on your body. -Do you want to replace it with the selected object? + ä½ èº«ä¸Šçš„é€™å€‹éƒ¨ä½å·²ç¶“附著了物件。 +ä½ è¦ç”¨æ‰€é¸ç‰©ä»¶å°‡å®ƒå–代嗎? <form name="form"> <ignore name="ignore" text="ä»¥æ‰€é¸æ“‡çš„物å“å–ä»£ç¾æœ‰çš„é™„åŠ ç‰©"/> <button ignore="自動å–代" name="Yes" text="確定"/> @@ -1951,9 +2099,9 @@ Do you want to replace it with the selected object? </form> </notification> <notification label="忙碌模å¼è¦å‘Š" name="BusyModePay"> - You are in Busy Mode, which means you will not receive any items offered in exchange for this payment. + ä½ ç¾åœ¨è™•於忙碌模å¼ï¼Œé€™æ„å‘³è‘—ä½ ä»˜è²»å¾Œä»å°‡ä¸æœƒæ”¶åˆ°ä»»ä½•ç‰©é …ã€‚ -Would you like to leave Busy Mode before completing this transaction? +ä½ æ˜¯å¦è¦å…ˆé›¢é–‹å¿™ç¢Œæ¨¡å¼ï¼Œå†å®Œæˆäº¤æ˜“? <form name="form"> <ignore name="ignore" text="ç•¶æˆ‘åœ¨å¿™ç¢Œæ¨¡å¼æ™‚ï¼Œå°‡è¦æ”¯ä»˜é‡‘錢或給他人物件"/> <button ignore="總是離開忙碌模å¼" name="Yes" text="確定"/> @@ -1961,7 +2109,7 @@ Would you like to leave Busy Mode before completing this transaction? </form> </notification> <notification name="ConfirmDeleteProtectedCategory"> - 資料夾 '[FOLDERNAME]' 是系統資料夾。刪除系統資料夾將導致ä¸ç©©å®šã€‚ä½ ç¢ºå®šä½ è¦åˆªé™¤å®ƒï¼Ÿ + 「[FOLDERNAME]ã€å±¬æ–¼ç³»çµ±è³‡æ–™å¤¾ã€‚ 刪除系統資料夾å¯èƒ½å°Žè‡´ç³»çµ±ä¸ç©©å®šã€‚ ä½ ç¢ºå®šè¦åŠ ä»¥åˆªé™¤ï¼Ÿ <usetemplate ignoretext="在我刪除系統資料夾å‰ç¢ºèª" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="ConfirmEmptyTrash"> @@ -1972,6 +2120,10 @@ Would you like to leave Busy Mode before completing this transaction? ä½ ç¢ºå®šè¦åˆªé™¤ä½ 的旅行ã€ç¶²é åŠæœå°‹æ·å²ç´€éŒ„嗎? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> + <notification name="ConfirmClearCache"> + ç¢ºå®šè¦æ¸…é™¤ä½ Viewer 的快å–? + <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> + </notification> <notification name="ConfirmClearCookies"> ä½ ç¢ºå®šè¦æ¸…é™¤ä½ çš„ cookies 嗎? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="是"/> @@ -1988,7 +2140,7 @@ Would you like to leave Busy Mode before completing this transaction? 下列的 SLurl ä½ç½®å·²ç¶“è¦†è£½åˆ°ä½ çš„å‰ªè²¼ç°¿ä¸Šï¼š [SLURL] -Link to this from a web page to give others easy access to this location, or try it out yourself by pasting it into the address bar of any web browser. +從æŸå€‹ç¶²é 連çµåˆ°é€™è£¡ï¼Œè®“其他人更容易知é“這個地點,或請自行嘗試將它貼到任何網é ç€è¦½å™¨çš„åœ°å€æ¬„裡。 <form name="form"> <ignore name="ignore" text="SLurl 已經覆製到我的剪貼簿。"/> </form> @@ -1997,48 +2149,30 @@ Link to this from a web page to give others easy access to this location, or try ä½ è¦è¦†å¯«å·²å„²å˜çš„é è¨é…置嗎? <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> </notification> - <notification name="WLDeletePresetAlert"> - ä½ è¦åˆªé™¤ [SKY]? - <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> - </notification> <notification name="WLNoEditDefault"> - You cannot edit or delete a default preset. + ä½ ä¸èƒ½ç·¨è¼¯æˆ–刪除é è¨çš„è¨å®šã€‚ </notification> <notification name="WLMissingSky"> - This day cycle file references a missing sky file: [SKY]. + é€™å€‹ã€Œä¸€æ—¥å¾ªç’°ã€æª”案åƒè€ƒäº†ä¸€å€‹ä¸å˜åœ¨çš„天空檔案:[SKY]。 </notification> - <notification name="PPSaveEffectAlert"> - PostProcess Effect exists. Do you still wish overwrite it? - <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> + <notification name="WLRegionApplyFail"> + 抱æ‰ï¼Œè¨å®šç„¡æ³•套用到地å€ã€‚ 離開地å€å†è¿”回也許å¯ä»¥è§£æ±ºé€™å€‹å•題。 æ‰€å¾—çš„åŽŸå› ç‚ºï¼š[FAIL_REASON] </notification> - <notification name="NewSkyPreset"> - Give me a name for the new sky. - <form name="form"> - <input name="message"> - æ–°é è¨é…é…ç½® - </input> - <button name="OK" text="確定"/> - <button name="Cancel" text="å–æ¶ˆ"/> - </form> - </notification> - <notification name="ExistsSkyPresetAlert"> - Preset already exists! + <notification name="EnvCannotDeleteLastDayCycleKey"> + ç„¡æ³•åˆªé™¤æ¤æ—¥å¾ªç’°çš„æœ€å¾Œä¸€çµ„è¨å®šï¼Œæ—¥å¾ªç’°ä¸å¾—為空白。 ä½ æ‡‰è©²ä¿®æ”¹æœ€å¾Œä¸€çµ„è³‡æ–™ï¼Œä¸è¦è©¦åœ–刪除,然後å†å»ºç«‹æ–°çš„。 + <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="NewWaterPreset"> - Give me a name for the new water preset. - <form name="form"> - <input name="message"> - New Preset - </input> - <button name="OK" text="確定"/> - <button name="Cancel" text="å–æ¶ˆ"/> - </form> + <notification name="DayCycleTooManyKeyframes"> + ä½ ç„¡æ³•æ–°å¢žæ›´å¤šçš„ keyframe 到這個日循環。 [SCOPE] 範åœçš„æ—¥å¾ªç’°æœ€å¤šå…許 [MAX] 個 keyframe。 + <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="ExistsWaterPresetAlert"> - Preset already exists! + <notification name="EnvUpdateRate"> + ä½ è‡³å¤šåªèƒ½æ¯ [WAIT] 秒更新一次地å€çš„環境è¨å®šã€‚ è«‹ç‰åˆ°é€™æ®µæ™‚é–“éŽåŽ»äº†å†è©¦ä¸€æ¬¡ã€‚ + <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="WaterNoEditDefault"> - You cannot edit or delete a default preset. + <notification name="PPSaveEffectAlert"> + PostProcess 效果已經å˜åœ¨ã€‚ ä½ æ˜¯å¦ä»è¦æŠŠå®ƒè¦†å¯«æŽ‰ï¼Ÿ + <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> </notification> <notification name="ChatterBoxSessionStartError"> 無法開始一個與 [RECIPIENT] 他的新èŠå¤©æœƒè©±ã€‚ @@ -2056,10 +2190,10 @@ Link to this from a web page to give others easy access to this location, or try <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="Cannot_Purchase_an_Attachment"> - You can't buy an object while it is attached. + ä½ ä¸èƒ½è³¼è²·å·²é™„著的物件。 </notification> - <notification label="About Requests for the Debit Permission" name="DebitPermissionDetails"> - Granting this request gives a script ongoing permission to take Linden dollars (L$) from your account. To revoke this permission, the object owner must delete the object or reset the scripts in the object. + <notification label="關於借記權é™è¦æ±‚" name="DebitPermissionDetails"> + è‹¥ä½ åŒæ„é€™è¦æ±‚,將å…è¨±è…³æœ¬å¾žä½ çš„å¸³æˆ¶ä¸é‡è¦†å–走林登幣(L$)。 ç‰©ä»¶æ‰€æœ‰äººå¿…é ˆåˆªé™¤è©²ç‰©ä»¶ï¼Œæˆ–é‡è¨ç‰©ä»¶è£¡çš„腳本,æ‰èƒ½æ’¤éŠ·é€™ä¸€æ¬Šé™ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="AutoWearNewClothing"> @@ -2067,25 +2201,23 @@ Link to this from a web page to give others easy access to this location, or try <usetemplate ignoretext="ç·¨è¼¯å¤–è§€æ™‚èƒ½ç©¿ä¸Šæˆ‘æ‰€å‰µé€ çš„æœè£" name="okcancelignore" notext="å¦" yestext="是"/> </notification> <notification name="NotAgeVerified"> - You must be age-verified to visit this area. Do you want to go to the [SECOND_LIFE] website and verify your age? - -[_URL] - <url name="url"> - https://secondlife.com/account/verification.php - </url> - <usetemplate ignoretext="I have not verified my age" name="okcancelignore" notext="å¦" yestext="是"/> + ä½ æ‰€æ¬²å‰å¾€çš„地點è¨é™çµ¦å¹´æ»¿ 18 æ²çš„居民進入。 + <usetemplate ignoretext="æˆ‘å¹´é½¡ä¸æ»¿è¦å®šï¼Œç„¡æ³•進入有年齡é™åˆ¶çš„å€åŸŸã€‚" name="okignore" yestext="確定"/> + </notification> + <notification name="NotAgeVerified_Notify"> + æ¤åœ°é»žé™åˆ¶ç‚ºå¹´æ»¿ 18 æ²ã€‚ </notification> <notification name="Cannot enter parcel: no payment info on file"> - You must have payment information on file to visit this area. Do you want to go to the [SECOND_LIFE] website and set this up? + ä½ å¿…é ˆæä¾›ä»˜æ¬¾è³‡æ–™æ‰èƒ½é€²å…¥é€™å€åŸŸã€‚ ä½ æ˜¯å¦è¦å‰å¾€ [SECOND_LIFE] 網站è¨å®šä»˜æ¬¾è³‡æ–™ï¼Ÿ [_URL] <url name="url"> https://secondlife.com/account/ </url> - <usetemplate ignoretext="I lack payment information on file" name="okcancelignore" notext="å¦" yestext="是"/> + <usetemplate ignoretext="我沒有é 留付款資料。" name="okcancelignore" notext="å¦" yestext="是"/> </notification> <notification name="MissingString"> - The string [STRING_NAME] is missing from strings.xml + strings.xml 䏿‰¾ä¸åˆ°å—串 [STRING_NAME] </notification> <notification name="SystemMessageTip"> [MESSAGE] @@ -2103,38 +2235,38 @@ Link to this from a web page to give others easy access to this location, or try å–æ¶ˆè²¼ä¸Š </notification> <notification name="ReplacedMissingWearable"> - Replaced missing clothing/body part with default. + 已用é è¨å€¼è£œè¶³ç©ºç¼ºçš„è¡£æœ/身體部ä½ã€‚ </notification> <notification name="GroupNotice"> - Topic: [SUBJECT], Message: [MESSAGE] + 主旨:[SUBJECT],訊æ¯ï¼š[MESSAGE] </notification> <notification name="FriendOnline"> - [NAME] 上線 + <nolink>[NAME]</nolink> ç›®å‰åœ¨ç·šä¸Š </notification> <notification name="FriendOffline"> - [NAME] 離線 + <nolink>[NAME]</nolink> ç›®å‰é›¢ç·š </notification> <notification name="AddSelfFriend"> - Although you're very nice, you can't add yourself as a friend. + é›–ç„¶ä½ äººå¾ˆå¥½ï¼Œä½ é‚„æ˜¯ä¸èƒ½æŠŠè‡ªå·±åŠ ç‚ºæœ‹å‹ã€‚ </notification> <notification name="UploadingAuctionSnapshot"> - Uploading in-world and web site snapshots... -(Takes about 5 minutes.) + æ£åœ¨ä¸Šå‚³è™›æ“¬ä¸–界和網站快照… +(需時約 5 分é˜ã€‚) </notification> <notification name="UploadPayment"> ä½ æ”¯ä»˜ L$[AMOUNT] 上傳。 </notification> <notification name="UploadWebSnapshotDone"> - Web site snapshot upload done. + 網站快照上傳完æˆã€‚ </notification> <notification name="UploadSnapshotDone"> - In-world snapshot upload done + 虛擬世界快照上傳完æˆã€‚ </notification> <notification name="TerrainDownloaded"> 地形 .raw 檔已下載 </notification> <notification name="GestureMissing"> - 嗯,姿勢 [NAME] 在資料庫ä¸éºå¤±ã€‚ + å§¿å‹¢ [NAME] 在資料庫ä¸éºå¤±ã€‚ </notification> <notification name="UnableToLoadGesture"> 無法載入姿勢 [NAME]。 @@ -2143,7 +2275,7 @@ Link to this from a web page to give others easy access to this location, or try 資料庫ä¸çš„地標éºå¤±ã€‚ </notification> <notification name="UnableToLoadLandmark"> - 無法載入地標,請å†è©¦ä¸€æ¬¡ã€‚ + 無法載入地標。 è«‹å†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="CapsKeyOn"> ä½ çš„å¤§å¯«éµå·²å•Ÿç”¨ã€‚ @@ -2158,6 +2290,12 @@ Link to this from a web page to give others easy access to this location, or try <notification name="RezItemNoPermissions"> 產生物件時發生權é™è¡çªã€‚ </notification> + <notification name="IMAcrossParentEstates"> + 無法å°ä¸åŒçš„æ¯é ˜åœ°ç™¼å‡ºå³æ™‚訊æ¯ã€‚ + </notification> + <notification name="TransferInventoryAcrossParentEstates"> + æ”¶ç´å€ç„¡æ³•轉移到ä¸åŒçš„æ¯é ˜åœ°ã€‚ + </notification> <notification name="UnableToLoadNotecard"> 無法載入記事å¡ã€‚ è«‹å†è©¦ä¸€æ¬¡ã€‚ @@ -2169,28 +2307,28 @@ Link to this from a web page to give others easy access to this location, or try 察看腳本時發生權é™è¡çªã€‚ </notification> <notification name="UnableToLoadScript"> - 無法載入腳本。請å†è©¦ä¸€æ¬¡ã€‚ + 無法載入腳本。 è«‹å†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="IncompleteInventory"> - The complete contents you are offering are not yet locally available. Please try offering those items again in a minute. + ä½ æ‰€æä¾›çš„完整內容在本地還無法å–得。 請幾分é˜å¾Œå†è©¦è‘—æä¾›é€™äº›ç‰©é …。 </notification> <notification name="CannotModifyProtectedCategories"> - You cannot modify protected categories. + ä½ ä¸èƒ½ä¿®æ”¹å—ä¿è·çš„類別。 </notification> <notification name="CannotRemoveProtectedCategories"> - You cannot remove protected categories. + ä½ ä¸èƒ½ç§»é™¤å—ä¿è·çš„類別。 </notification> <notification name="UnableToBuyWhileDownloading"> - Unable to buy while downloading object data. -Please try again. + æ£åœ¨ä¸‹è¼‰ç‰©ä»¶è³‡æ–™ï¼Œç„¡æ³•購買。 +è«‹å†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="UnableToLinkWhileDownloading"> - Unable to link while downloading object data. -Please try again. + æ£åœ¨ä¸‹è¼‰ç‰©ä»¶è³‡æ–™ï¼Œç„¡æ³•è¯çµã€‚ +è«‹å†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="CannotBuyObjectsFromDifferentOwners"> - You can only buy objects from one owner at a time. -Please select a single object. + ä½ ä¸€æ¬¡åªèƒ½å‘一ä½ç‰©ä¸»è³¼è²·ç‰©ä»¶ã€‚ +è«‹é¸æ“‡ä¸€å€‹å–®ä¸€ç‰©ä»¶ã€‚ </notification> <notification name="ObjectNotForSale"> 這物件ä¸å‡ºå”®ã€‚ @@ -2211,7 +2349,7 @@ Please select a single object. [NAME] è¬çµ•ä½ æä¾›çš„æ”¶ç´å€ç‰©å“。 </notification> <notification name="ObjectMessage"> - [NAME]: [MESSAGE] + [NAME]:[MESSAGE] </notification> <notification name="CallingCardAccepted"> ä½ çš„å片已被接å—。 @@ -2220,24 +2358,25 @@ Please select a single object. ä½ çš„å片已被拒絕。 </notification> <notification name="TeleportToLandmark"> - You can teleport to locations like '[NAME]' by opening the Places panel on the right side of your screen, and then select the Landmarks tab. -Click on any landmark to select it, then click 'Teleport' at the bottom of the panel. -(You can also double-click on the landmark, or right-click it and choose 'Teleport'.) + è¦çž¬é–“傳é€åˆ°ã€Œ[NAME]ã€ç‰åœ°é»žï¼Œè«‹é»žæŒ‰ã€Œåœ°é»žã€æŒ‰éˆ•, + ç„¶å¾Œåœ¨é–‹å•Ÿçš„è¦–çª—è£¡ï¼Œé¸æ“‡ã€Œåœ°æ¨™ã€é 籤。 點按任何 + åœ°æ¨™åŠ ä»¥é¸æ“‡ï¼Œå†é»žæŒ‰è¦–窗底下的「瞬間傳é€ã€æŒ‰éˆ•。 + ï¼ˆä½ é‚„å¯ä»¥ç›´æŽ¥æŒ‰å…©ä¸‹é‚£å€‹åœ°æ¨™ï¼Œæˆ–æŒ‰æ»‘é¼ å³éµï¼Œé¸æ“‡ã€Œçž¬é–“傳é€ã€ã€‚) </notification> <notification name="TeleportToPerson"> - You can contact Residents like '[NAME]' by opening the People panel on the right side of your screen. -Select the Resident from the list, then click 'IM' at the bottom of the panel. -(You can also double-click on their name in the list, or right-click and choose 'IM'). + è¦è¯çµ¡å¦‚「[NAME]ã€çš„任何一ä½å±…æ°‘ï¼Œè«‹é»žæŒ‰ã€Œäººç¾¤ã€æŒ‰éˆ•,從打開的視窗ä¸é¸æ“‡ä¸€ä½å±…民,å†é»žæŒ‰è¦–窗底下的「IMã€ã€‚ + + ï¼ˆä½ é‚„å¯ä»¥å¾žæ¸…單直接按兩下åå—ï¼Œæˆ–æŒ‰æ»‘é¼ å³éµï¼Œé¸æ“‡ã€ŒIMã€ã€‚) </notification> <notification name="CantSelectLandFromMultipleRegions"> - Can't select land across server boundaries. -Try selecting a smaller piece of land. + ç„¡æ³•é¸æ“‡è¶…出伺æœå™¨é‚Šç•Œçš„土地。 +è«‹è©¦è‘—ç¸®å°æ‰€é¸çš„土地。 </notification> <notification name="SearchWordBanned"> - Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards. + æ ¹æ“šã€Œç¤¾ç¾¤æº–å‰‡ã€æ‰€æ˜Žè¨‚的內容é™åˆ¶ï¼Œå·²æŽ’é™¤ä½ æ‰€æœå°‹çš„æŸäº›å—眼。 </notification> <notification name="NoContentToSearch"> - Please select at least one type of content to search (General, Moderate, or Adult). + è«‹è‡³å°‘é¸æ“‡ä¸€ç¨®è¦æœç´¢çš„內容分級(一般普級ã€é©åº¦æˆäººã€å®Œå…¨æˆäººï¼‰ã€‚ </notification> <notification name="SystemMessage"> [MESSAGE] @@ -2248,6 +2387,9 @@ Try selecting a smaller piece of land. <notification name="PaymentSent"> [MESSAGE] </notification> + <notification name="PaymentFailure"> + [MESSAGE] + </notification> <notification name="EventNotification"> 活動通知: @@ -2259,179 +2401,205 @@ Try selecting a smaller piece of land. </form> </notification> <notification name="TransferObjectsHighlighted"> - All objects on this parcel that will transfer to the purchaser of this parcel are now highlighted. + 這地段上,所有將轉移給地段購買人的物件,ç¾å·²å‘ˆé«˜äº®é¡¯ç¤ºã€‚ -* Trees and grasses that will transfer are not highlighted. +* å³å°‡è½‰ç§»çš„æ¨¹å’Œè‰ä¸æœƒä»¥é«˜äº®é¡¯ç¤ºã€‚ <form name="form"> - <button name="Done" text="Done"/> + <button name="Done" text="完æˆ"/> </form> </notification> <notification name="DeactivatedGesturesTrigger"> - Deactivated gestures with same trigger: + 以åŒä¸€è§¸ç™¼åœç”¨çš„姿勢: [NAMES] </notification> <notification name="NoQuickTime"> - Apple's QuickTime software does not appear to be installed on your system. -If you want to view streaming media on parcels that support it you should go to the [http://www.apple.com/quicktime QuickTime site] and install the QuickTime Player. + ä½ çš„ç³»çµ±ä¼¼ä¹Žæœªå®‰è£ Apple çš„ QuickTime 軟體。 +å¦‚æžœä½ è¦åœ¨æ”¯æ´ä¸²æµåª’體的地段上觀看這類媒體,請到[http://www.apple.com/quicktime QuickTime 網站]å®‰è£ QuickTime æ’æ”¾å™¨ã€‚ </notification> <notification name="NoPlugin"> - No Media Plugin was found to handle the "[MIME_TYPE]" mime type. Media of this type will be unavailable. + 找ä¸åˆ°åª’é«”æ’件來處ç†ã€Œ[MIME_TYPE]ã€mine 類型。 這類媒體將無法使用。 </notification> <notification name="MediaPluginFailed"> - The following Media Plugin has failed: + 以下的媒體æ’件失éˆï¼š [PLUGIN] -Please re-install the plugin or contact the vendor if you continue to experience problems. +å¦‚æžœä½ ç¹¼çºŒå‡ºç¾é€™ç‹€æ³ï¼Œè«‹é‡æ–°å®‰è£æ’件,或è¯çµ¡å…¶æä¾›å» 家。 <form name="form"> - <ignore name="ignore" text="A Media Plugin fails to run"/> + <ignore name="ignore" text="有一個媒體æ’件無法執行"/> </form> </notification> <notification name="OwnedObjectsReturned"> - The objects you own on the selected parcel of land have been returned back to your inventory. + ä½ åœ¨æ‰€é¸åœ°æ®µä¸Šæ‰€æ“有的物件已被é€è¿”ä½ çš„æ”¶ç´å€ã€‚ </notification> <notification name="OtherObjectsReturned"> - The objects on the selected parcel of land that is owned by [NAME] have been returned to his or her inventory. + 在所é¸åœ°æ®µä¸Šç”± [NAME] æ‰€æ“æœ‰çš„物件已被é€è¿”å…¶æ”¶ç´å€ã€‚ </notification> <notification name="OtherObjectsReturned2"> - The objects on the selected parcel of land owned by the Resident '[NAME]' have been returned to their owner. + 在所é¸åœ°æ®µä¸Šç”±å±…æ°‘ '[NAME]' æ‰€æ“æœ‰çš„物件已被é€è¿”å…¶æ”¶ç´å€ã€‚ </notification> <notification name="GroupObjectsReturned"> - The objects on the selected parcel of land shared with the group [GROUPNAME] have been returned back to their owner's inventory. -Transferable deeded objects have been returned to their previous owners. -Non-transferable objects that are deeded to the group have been deleted. + 在所é¸åœ°æ®µä¸Šå’Œç¾¤çµ„ '[GROUPNAME]' 分享的物件已被é€è¿”其所有人的收ç´å€ã€‚ +å¯è½‰è®“的已讓渡物件已é€è¿”給å‰ç‰©ä¸»ã€‚ +讓渡給這個群組的ä¸å¯è½‰è®“物件已被刪除。 </notification> <notification name="UnOwnedObjectsReturned"> - The objects on the selected parcel that are NOT owned by you have been returned to their owners. + 在所é¸åœ°æ®µä¸Šä¸æ˜¯ä½ æ“æœ‰çš„物件已é€è¿”給其所有人。 </notification> <notification name="ServerObjectMessage"> - Message from [NAME]: + 來自 [NAME] 的訊æ¯ï¼š <nolink>[MSG]</nolink> </notification> <notification name="NotSafe"> - This land has damage enabled. -You can be hurt here. If you die, you will be teleported to your home location. + 這塊土地å…許傷害。 +åœ¨é€™è£¡ä½ å¯èƒ½æœƒå—傷害。 ä½ å¦‚æžœæ»äº¡ï¼Œæœƒè¢«çž¬é–“傳é€å›žä½ 的家。 </notification> <notification name="NoFly"> - 這å€åŸŸé—œé–‰ä¸¦ç¦æ¢é£›è¡Œã€‚ + 這å€åŸŸç¦æ¢é£›è¡Œã€‚ ä½ ä¸èƒ½åœ¨æ¤è™•飛行。 </notification> <notification name="PushRestricted"> - This area does not allow pushing. You can't push others here unless you own the land. + 這å€åŸŸä¸å…許推撞。 除éžä½ æ“æœ‰é€™å¡ŠåœŸåœ°ï¼Œå¦å‰‡ä½ ä¸èƒ½æŽ¨æ’žåˆ¥äººã€‚ </notification> <notification name="NoVoice"> - This area has voice chat disabled. You won't be able to hear anyone talking. + 這å€åŸŸç¦æ¢èªžéŸ³èŠå¤©ã€‚ ä½ å°‡ä¸æœƒè½åˆ°ä»»ä½•人說話。 </notification> <notification name="NoBuild"> - This area has building disabled. You can't build or rez objects here. + 這å€åŸŸç¦æ¢å»ºé€ 物件。 ä½ ä¸èƒ½åœ¨æ¤å»ºé€ 或產生物件。 + </notification> + <notification name="PathfindingDirty"> + 這地å€çš„尋徑功能有所變更,待儲å˜ã€‚ å¦‚æžœä½ æœ‰å»ºè£½æ¬Šï¼Œä½ å¯ä»¥é»žæŒ‰ã€Œé‡æ–°ç”¢å‡ºåœ°å€ã€æŒ‰éˆ•釿–°ç”¢å‡ºåœ°å€ã€‚ + </notification> + <notification name="DynamicPathfindingDisabled"> + 這地å€ä¸¦æœªå•Ÿç”¨å‹•態尋徑。 使用尋徑 LSL 呼å«çš„帶腳本物件,在æ¤åœ°å€å¯èƒ½ç„¡æ³•æ£å¸¸é‹ä½œã€‚ + </notification> + <notification name="PathfindingRebakeNavmesh"> + 更改本地å€çš„æŸäº›ç‰©ä»¶å°‡å°Žè‡´å…¶ä»–ç§»å‹•ç‰©ä»¶çš„é‹ä½œç™¼ç”Ÿå•題。 è¦ä½¿ç§»å‹•物件æ£å¸¸é‹ä½œï¼Œè«‹é»žæŒ‰ã€Œé‡æ–°ç”¢å‡ºåœ°å€ã€æŒ‰éˆ•。 欲ç²çŸ¥è©³æƒ…è«‹é¸æ“‡ã€Œå¹«åŠ©ã€ã€‚ + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="幫助" ignoretext="更改本地å€çš„æŸäº›ç‰©ä»¶å°‡å°Žè‡´å…¶ä»–ç§»å‹•ç‰©ä»¶çš„é‹ä½œç™¼ç”Ÿå•題。" name="okhelpignore" yestext="確定"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + 發生錯誤。 å•題å¯èƒ½å‡ºåœ¨ç¶²è·¯æˆ–伺æœå™¨ï¼Œä¹Ÿå¯èƒ½å› ç‚ºä½ ç„¡æ¬Šå»ºè£½ç‰©ä»¶ã€‚ 有時,åªè¦ç™»å‡ºå†ç™»å…¥å³èƒ½è§£æ±ºé€™é¡žå•題。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SeeAvatars"> + 本地段隱è—其內的化身和èŠå¤©æ–‡å—,其他地段看ä¸åˆ°ã€‚ ä½ çœ‹ä¸è¦‹åœ°æ®µå¤–的居民,他們也看ä¸è¦‹ä½ 。 é »é“ 0 çš„èŠå¤©æ–‡å—也被å°éŽ–ã€‚ </notification> <notification name="ScriptsStopped"> - An administrator has temporarily stopped scripts in this region. + æŸç®¡ç†å“¡å·²æš«æ™‚åœæ¢å€åŸŸè£¡çš„腳本。 </notification> <notification name="ScriptsNotRunning"> - This region is not running any scripts. + 這å€åŸŸæ²’有執行任何腳本。 </notification> <notification name="NoOutsideScripts"> - This land has outside scripts disabled. + 這塊土地ç¦ç”¨å¤–來腳本。 -No scripts will work here except those belonging to the land owner. +åªæœ‰å±¬æ–¼åœŸåœ°æ‰€æœ‰äººçš„腳本在æ¤å¯ä»¥æ£å¸¸åŸ·è¡Œã€‚ </notification> <notification name="ClaimPublicLand"> - You can only claim public land in the Region you're in. + ä½ åªèƒ½åœ¨ä½ 所處的å€åŸŸæ”¶å–公共土地。 </notification> <notification name="RegionTPAccessBlocked"> - You aren't allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer. - -Please go to the Knowledge Base for details on accessing areas with this maturity Rating. + ä½ æ‰€æ¬²å‰å¾€çš„地å€å«æœ‰è¶…éŽä½ ç›®å‰å好的分級的內容。 ä½ å¯ä»¥åˆ°ã€Œæˆ‘自己 > å好è¨å®š > 一般è¨å®šã€è®Šæ›´ä½ çš„å好è¨å®šã€‚ </notification> <notification name="URBannedFromRegion"> - You are banned from the region. + 這個å€åŸŸç¦æ¢ä½ 進入。 </notification> <notification name="NoTeenGridAccess"> - Your account cannot connect to this teen grid region. + ä½ çš„å¸³æˆ¶ä¸å¯é€£æŽ¥åˆ°é€™å€‹é’å°‘å¹´ç¶²æ ¼å€åŸŸã€‚ </notification> <notification name="ImproperPaymentStatus"> - You do not have proper payment status to enter this region. + ä½ æ²’æœ‰é©ç•¶çš„付款狀態,ä¸èƒ½é€²å…¥é€™å€åŸŸã€‚ </notification> - <notification name="MustGetAgeRgion"> - ä½ å¿…é ˆé€šéŽå¹´é½¡èªè‰ä»¥é€²å…¥é€™åœ°å€ã€‚ + <notification name="MustGetAgeRegion"> + ä½ å¿…é ˆå¹´æ»¿ 18 æ²æ‰å¯é€²å…¥é€™åœ°å€ã€‚ </notification> <notification name="MustGetAgeParcel"> - ä½ å¿…é ˆé€šéŽå¹´é½¡é©—è‰ä»¥é€²å…¥é€™åœ°æ®µã€‚ + ä½ å¿…é ˆå¹´æ»¿ 18 æ²æ‰å¯é€²å…¥é€™åœ°æ®µã€‚ </notification> <notification name="NoDestRegion"> - 無目的地地å€ç™¼ç¾ã€‚ + 找ä¸åˆ°ç›®çš„地地å€ã€‚ </notification> <notification name="NotAllowedInDest"> - You are not allowed into the destination. + ä½ ä¸å‡†å‰å¾€ç›®çš„地。 </notification> <notification name="RegionParcelBan"> - Cannot region cross into banned parcel. Try another way. + 無法跨出地å€é€²å…¥ç¦æ¢ä½ 的地段。 è«‹æ›ä¸€å€‹æ–¹å¼ã€‚ </notification> <notification name="TelehubRedirect"> - You have been redirected to a telehub. + ä½ å·²è¢«é‡æ–°å°Žå¾€ä¸€å€‹çž¬é–“傳é€ä¸å¿ƒã€‚ </notification> <notification name="CouldntTPCloser"> - Could not teleport closer to destination. + 無法瞬間傳é€åˆ°æ›´æŽ¥è¿‘目的地的地點。 </notification> <notification name="TPCancelled"> 瞬間傳é€å·²å–消。 </notification> <notification name="FullRegionTryAgain"> - The region you are attempting to enter is currently full. -Please try again in a few moments. + ä½ è©¦åœ–é€²å…¥çš„åœ°å€ç›®å‰äººæ»¿ã€‚ +è«‹ç¨å¾…一會兒å†è©¦ã€‚ </notification> <notification name="GeneralFailure"> 一般故障。 </notification> <notification name="RoutedWrongRegion"> - 路由導å‘到錯誤地å€ã€‚è«‹å†è©¦ä¸€æ¬¡ã€‚ + 被繞往錯誤的地å€ã€‚ è«‹å†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="NoValidAgentID"> - No valid agent id. + 沒有有效的化身編號。 </notification> <notification name="NoValidSession"> - No valid session id. + 沒有有效的時域編號。 </notification> <notification name="NoValidCircuit"> - No valid circuit code. + 沒有有效的線路碼。 </notification> <notification name="NoValidTimestamp"> - No valid timestamp. + 沒有有效的時間戳記。 </notification> <notification name="NoPendingConnection"> - Unable to create pending connection. + 無法建立待通的連線。 </notification> <notification name="InternalUsherError"> - Internal error attempting to connect agent usher. + 試圖連接用戶引導時發生內部錯誤。 </notification> <notification name="NoGoodTPDestination"> - Unable to find a good teleport destination in this region. + åœ¨é€™åœ°å€æ‰¾ä¸åˆ°åˆé©çš„瞬間傳é€ç›®çš„地。 </notification> <notification name="InternalErrorRegionResolver"> - Internal error attempting to activate region resolver. + 試圖啟動å€åŸŸè§£æžå™¨æ™‚發生內部錯誤。 </notification> <notification name="NoValidLanding"> - A valid landing point could not be found. + 找ä¸åˆ°æœ‰æ•ˆçš„登陸地點。 </notification> <notification name="NoValidParcel"> - No valid parcel could be found. + 找ä¸åˆ°æœ‰æ•ˆçš„地段。 </notification> <notification name="ObjectGiveItem"> - An object named <nolink>[OBJECTFROMNAME]</nolink> owned by [NAME_SLURL] has given you this [OBJECTTYPE]: -[ITEM_SLURL] + å為 <nolink>[OBJECTFROMNAME]</nolink>ã€ç”± [NAME_SLURL] æ“æœ‰çš„ç‰©ä»¶çµ¦äº†ä½ é€™å€‹ [OBJECTTYPE]: +<nolink>[ITEM_SLURL]</nolink> + <form name="form"> + <button name="Keep" text="ä¿ç•™"/> + <button name="Discard" text="丟棄"/> + <button name="Mute" text="å°éŽ–æ‰€æœ‰äºº"/> + </form> + </notification> + <notification name="OwnObjectGiveItem"> + ä½ å為 <nolink>[OBJECTFROMNAME]</nolink> çš„ç‰©ä»¶çµ¦äº†ä½ é€™å€‹ [OBJECTTYPE]: +<nolink>[ITEM_SLURL]</nolink> <form name="form"> - <button name="Keep" text="Keep"/> - <button name="Discard" text="Discard"/> - <button name="Mute" text="Block"/> + <button name="Keep" text="ä¿ç•™"/> + <button name="Discard" text="丟棄"/> </form> </notification> <notification name="UserGiveItem"> - [NAME_SLURL] has given you this [OBJECTTYPE]: + [NAME_SLURL] çµ¦äº†ä½ é€™å€‹ [OBJECTTYPE]: [ITEM_SLURL] <form name="form"> - <button name="Show" text="Show"/> - <button name="Discard" text="Discard"/> - <button name="Mute" text="Block"/> + <button name="Show" text="顯示"/> + <button name="Discard" text="丟棄"/> + <button name="Mute" text="å°éŽ–"/> </form> </notification> <notification name="GodMessage"> @@ -2448,16 +2616,37 @@ Please try again in a few moments. </form> </notification> <notification name="TeleportOffered"> - [NAME_SLURL] has offered to teleport you to their location: + [NAME_SLURL] 想è¦çž¬é–“傳é€ä½ 到他的地點: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="瞬間傳é€"/> <button name="Cancel" text="å–æ¶ˆ"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] 想è¦çž¬é–“傳é€ä½ 到他的地點: + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +æ¤åœ°å€åŒ…å« [REGION_CONTENT_MATURITY] çš„åˆ†ç´šå…§å®¹ï¼Œå¯æ˜¯ä½ ç›®å‰çš„å好è¨å®šæŽ’除了 [REGION_CONTENT_MATURITY] 的分級內容。 我們å¯ä»¥è®Šæ›´ä½ çš„å好è¨å®šå¥½è®“ä½ ç¹¼çºŒçž¬é–“å‚³é€ï¼Œä½ 也å¯å–消這動作。 + <form name="form"> + <button name="Teleport" text="變更後繼續"/> + <button name="Cancel" text="å–æ¶ˆ"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] 想è¦çž¬é–“傳é€ä½ 到他的地點: + +“[MESSAGE]†+<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +坿˜¯ï¼Œæ¤åœ°å€å«æœ‰åƒ…陿ˆäººçš„內容。 + </notification> <notification name="TeleportOfferSent"> - Teleport offer sent to [TO_NAME] + å·²å‘ [TO_NAME] 發出瞬間傳é€é‚€è«‹ </notification> <notification name="GotoURL"> [MESSAGE] @@ -2468,33 +2657,33 @@ Please try again in a few moments. </form> </notification> <notification name="OfferFriendship"> - [NAME_SLURL] is offering friendship. + [NAME_SLURL] 想æˆç‚ºä½ 的朋å‹ã€‚ [MESSAGE] -(By default, you will be able to see each other's online status.) +ï¼ˆæ ¹æ“šé è¨è¨å®šï¼Œä½ 們將å¯çœ‹åˆ°å½¼æ¤çš„線上狀態。) <form name="form"> <button name="Accept" text="接å—"/> <button name="Decline" text="è¬çµ•"/> </form> </notification> <notification name="FriendshipOffered"> - You have offered friendship to [TO_NAME] + 已經邀請 [TO_NAME] æˆç‚ºæœ‹å‹ </notification> <notification name="OfferFriendshipNoMessage"> - [NAME_SLURL] is offering friendship. + [NAME_SLURL] 想æˆç‚ºä½ 的朋å‹ã€‚ -(By default, you will be able to see each other's online status.) +ï¼ˆæ ¹æ“šé è¨è¨å®šï¼Œä½ 們將å¯çœ‹åˆ°å½¼æ¤çš„線上狀態。) <form name="form"> <button name="Accept" text="接å—"/> <button name="Decline" text="è¬çµ•"/> </form> </notification> <notification name="FriendshipAccepted"> - [NAME] accepted your friendship offer. + <nolink>[NAME]</nolink> 接å—äº†ä½ çš„äº¤å‹é‚€è«‹ã€‚ </notification> <notification name="FriendshipDeclined"> - [NAME] è¬çµ•ä½ çš„äº¤å‹é‚€è«‹ã€‚ + <nolink>[NAME]</nolink> å©‰æ‹’äº†ä½ çš„äº¤å‹é‚€è«‹ã€‚ </notification> <notification name="FriendshipAcceptedByMe"> 交å‹é‚€è«‹è¢«æŽ¥å—。 @@ -2503,208 +2692,206 @@ Please try again in a few moments. 交å‹é‚€è«‹è¢«è¬çµ•。 </notification> <notification name="OfferCallingCard"> - [NAME] is offering their calling card. -This will add a bookmark in your inventory so you can quickly IM this Resident. + [NAME] é€çµ¦ä½ ä»–çš„å片。 +é€™å°‡åœ¨ä½ çš„æ”¶ç´å€æ–°å¢žä¸€å€‹æ›¸ç±¤ï¼Œæ–¹ä¾¿ä½ 和這ä½å±…æ°‘äº’å‚³å³æ™‚訊æ¯ã€‚ <form name="form"> <button name="Accept" text="接å—"/> <button name="Decline" text="è¬çµ•"/> </form> </notification> <notification name="RegionRestartMinutes"> - This region will restart in [MINUTES] minutes. -If you stay in this region you will be logged out. + 本地å€å°‡åœ¨ [MINUTES] 分é˜å¾Œé‡æ–°å•Ÿå‹•。 +å¦‚æžœä½ ç¹¼çºŒç•™åœ¨é€™åœ°å€ï¼Œä½ 將會被登出。 </notification> <notification name="RegionRestartSeconds"> - This region will restart in [SECONDS] seconds. -If you stay in this region you will be logged out. + 本地å€å°‡åœ¨ [SECONDS] ç§’å¾Œé‡æ–°å•Ÿå‹•。 +å¦‚æžœä½ ç¹¼çºŒç•™åœ¨é€™åœ°å€ï¼Œä½ 將會被登出。 </notification> <notification name="LoadWebPage"> 載入網é [URL]? [MESSAGE] -From object: <nolink>[OBJECTNAME]</nolink>, owner: [NAME]? +來æºç‰©ä»¶ï¼š<nolink>[OBJECTNAME]</nolink>(所有人是 [NAME])? <form name="form"> <button name="Gotopage" text="å‰å¾€é é¢"/> <button name="Cancel" text="å–æ¶ˆ"/> </form> </notification> <notification name="FailedToFindWearableUnnamed"> - Failed to find [TYPE] in database. + 資料庫找ä¸åˆ° [TYPE]。 </notification> <notification name="FailedToFindWearable"> - Failed to find [TYPE] named [DESC] in database. + 資料庫找ä¸åˆ°å為 [DESC] çš„ [TYPE]。 </notification> <notification name="InvalidWearable"> - The item you are trying to wear uses a feature that your Viewer can't read. Please upgrade your version of [APP_NAME] to wear this item. + ä½ æƒ³è¦ç©¿è‘—çš„ç‰©é …å¸¶æœ‰ä¸€å€‹ä¸æ˜¯ä½ ç›®å‰ Viewer ç‰ˆæœ¬èƒ½å¤ è®€å–的特性。 è«‹æ›´æ–°ä½ çš„ [APP_NAME] 版本å†ç©¿è‘—è©²ç‰©é …ã€‚ </notification> <notification name="ScriptQuestion"> - '<nolink>[OBJECTNAME]</nolink>', an object owned by '[NAME]', would like to: + '<nolink>[OBJECTNAME]</nolink>',一個由 '[NAME]' æ“æœ‰çš„物件,想è¦ï¼š [QUESTIONS] -Is this OK? +是å¦åŒæ„? <form name="form"> <button name="Yes" text="是"/> <button name="No" text="å¦"/> - <button name="Mute" text="Block"/> + <button name="Mute" text="å°éŽ–"/> </form> </notification> <notification name="ScriptQuestionCaution"> - An object named '<nolink>[OBJECTNAME]</nolink>', owned by '[NAME]' would like to: - -[QUESTIONS] -If you do not trust this object and its creator, you should deny the request. - -Grant this request? + è¦å‘Šï¼šç‰©ä»¶ '<nolink>[OBJECTNAME]</nolink>' è¦æ±‚全權å˜å–ä½ çš„æž—ç™»å¹£å¸³æˆ¶ã€‚ ä½ å¦‚æžœå…許å˜å–帳戶,它將å¯åœ¨ä»»ä½•æ™‚å€™å¾žä½ å¸³æˆ¶å–èµ°è³‡é‡‘ï¼Œæˆ–å®Œå…¨åŠ ä»¥æ¸…ç©ºï¼Œæˆ–å®šæœŸå–èµ°éƒ¨åˆ†è³‡é‡‘ï¼Œä¸”ä¸æœƒç™¼å‡ºè¦å‘Šã€‚ + +這很å¯èƒ½æ˜¯ç¨®ä¸ç•¶çš„è¦æ±‚。 å¦‚æžœä½ ä¸å®Œå…¨çžè§£å®ƒç‚ºä½•è¦æ±‚å˜å–ä½ çš„å¸³æˆ¶ï¼Œè«‹å‹¿å…准。 <form name="form"> - <button name="Grant" text="Grant"/> - <button name="Deny" text="Deny"/> - <button name="Details" text="細節..."/> + <button name="Grant" text="å…許全權å˜å–"/> + <button name="Deny" text="拒絕"/> </form> </notification> <notification name="ScriptDialog"> - [NAME]'s '<nolink>[TITLE]</nolink>' + [NAME] çš„ '<nolink>[TITLE]</nolink>' [MESSAGE] <form name="form"> - <button name="Ignore" text="忽視"/> + <button name="Client_Side_Mute" text="å°éŽ–"/> + <button name="Client_Side_Ignore" text="忽視"/> </form> </notification> <notification name="ScriptDialogGroup"> - [GROUPNAME]'s '<nolink>[TITLE]</nolink>' + [GROUPNAME] çš„ '<nolink>[TITLE]</nolink>' [MESSAGE] <form name="form"> - <button name="Ignore" text="忽視"/> + <button name="Client_Side_Mute" text="å°éŽ–"/> + <button name="Client_Side_Ignore" text="忽視"/> </form> </notification> <notification name="BuyLindenDollarSuccess"> - Thank you for your payment! + 感è¬ä½ ä»˜æ¬¾ï¼ -Your L$ balance will be updated when processing completes. If processing takes more than 20 mins, your transaction may be cancelled. In that case, the purchase amount will be credited to your US$ balance. +處ç†å®Œæˆå¾Œï¼Œä½ çš„ L$ 餘é¡å°‡æœƒæ›´æ–°ã€‚ 如果處ç†éŽç¨‹è¶…éŽ 20 分é˜ï¼Œä½ 的交易å¯èƒ½è¢«å–消。 在這狀æ³ä¸‹ï¼Œè³¼è²·é‡‘é¡å°‡é€€å›žçµ¦ä½ çš„ US$ 餘é¡ã€‚ -The status of your payment can be checked on your Transaction History page on your [http://secondlife.com/account/ Dashboard] +ä½ å¯ä»¥åˆ°ä½ çš„[http://secondlife.com/account/ 塗鴉牆]上的交易æ·å²è¨˜éŒ„é é¢ï¼Œå¯Ÿçœ‹ä»˜æ¬¾ç‹€æ…‹ã€‚ </notification> <notification name="FirstOverrideKeys"> - Your movement keys are now being handled by an object. -Try the arrow keys or AWSD to see what they do. -Some objects (like guns) require you to go into mouselook to use them. -Press 'M' to do this. + ä½ çš„æ–¹å‘éµç¾åœ¨ç”±ä¸€å€‹ç‰©ä»¶ä¸»æŽ§ã€‚ +請試試方å‘鵿ˆ– AWSD éµçœ‹æœ‰ä»€éº¼å應。 +æœ‰äº›ç‰©ä»¶ï¼ˆä¾‹å¦‚æ§æžï¼‰éœ€è¦ä½ åˆ‡æ›æˆç¬¬ä¸€äººç¨±è¦–è§’æ‰æœ‰ä½œç”¨ã€‚ +請按 M éµåšåˆ‡æ›ã€‚ </notification> <notification name="FirstSandbox"> - This is a sandbox area, and is meant to help Residents learn how to build. + 這個一個沙盤å€ï¼Œæ—¨åœ¨å¹«åŠ©å±…æ°‘å¸ç¿’如何建製物件。 -Things you build here will be deleted after you leave, so don't forget to right-click and choose 'Take' to move your creation to your Inventory. +ä½ åœ¨é€™è£¡å»ºè£½çš„ç‰©ä»¶ï¼Œåœ¨ä½ é›¢é–‹å¾Œå°‡è¢«åˆªé™¤ã€‚åˆ¥å¿˜äº†æŒ‰æ»‘é¼ å³éµï¼Œé¸æ“‡ã€Œæ‹¿å–ã€ï¼Œå°‡ä½ 的建製物é€åˆ°ä½ 的收ç´å€ã€‚ </notification> <notification name="MaxListSelectMessage"> - You may only select up to [MAX_SELECT] items from this list. + ä½ æœ€å¤šåªèƒ½å¾žé€™æ¸…å–®ä¸é¸å– [MAX_SELECT] å€‹ç‰©é …ã€‚ </notification> <notification name="VoiceInviteP2P"> - [NAME] is inviting you to a Voice Chat call. -Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller. + [NAME] æ£é‚€è«‹ä½ åŠ å…¥èªžéŸ³èŠå¤©ã€‚ +點按「接å—ã€åŠ å…¥é€šè©±ï¼Œæˆ–ã€Œè¬çµ•ã€é‚€è«‹ã€‚ 點按「å°éŽ–ã€ä¾¿å¯å°éŽ–é€™å€‹ç™¼è©±äººã€‚ <form name="form"> <button name="Accept" text="接å—"/> <button name="Decline" text="è¬çµ•"/> - <button name="Mute" text="Block"/> + <button name="Mute" text="å°éŽ–"/> </form> </notification> <notification name="AutoUnmuteByIM"> - [NAME] was sent an instant message and has been automatically unblocked. + [NAME] å·²æ”¶åˆ°ä¸€å‰‡å³æ™‚訊æ¯ï¼Œä¸¦å·²è¢«è‡ªå‹•解除å°éŽ–ã€‚ </notification> <notification name="AutoUnmuteByMoney"> - [NAME] was given money and has been automatically unblocked. + [NAME] 已收到錢,並已被自動解除å°éŽ–ã€‚ </notification> <notification name="AutoUnmuteByInventory"> - [NAME] was offered inventory and has been automatically unblocked. + [NAME] å·²å¾—çŸ¥ä½ è¦è´ˆé€æ”¶ç´ç‰©ä»¶ï¼Œä¸¦å·²è¢«è‡ªå‹•解除å°éŽ–ã€‚ </notification> <notification name="VoiceInviteGroup"> - [NAME] has joined a Voice Chat call with the group [GROUP]. -Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller. + [NAME] å·²åŠ å…¥å’Œç¾¤çµ„ [GROUP] 的語音èŠå¤©é€šè©±ã€‚ +點按「接å—ã€åŠ å…¥é€šè©±ï¼Œæˆ–ã€Œè¬çµ•ã€é‚€è«‹ã€‚ 點按「å°éŽ–ã€ä¾¿å¯å°éŽ–é€™å€‹ç™¼è©±äººã€‚ <form name="form"> <button name="Accept" text="接å—"/> <button name="Decline" text="è¬çµ•"/> - <button name="Mute" text="Block"/> + <button name="Mute" text="å°éŽ–"/> </form> </notification> <notification name="VoiceInviteAdHoc"> - [NAME] has joined a voice chat call with a conference chat. -Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller. + [NAME] å·²åŠ å…¥å¤šæ–¹èªžéŸ³é€šè©±ã€‚ +點按「接å—ã€åŠ å…¥é€šè©±ï¼Œæˆ–ã€Œè¬çµ•ã€é‚€è«‹ã€‚ 點按「å°éŽ–ã€ä¾¿å¯å°éŽ–é€™å€‹ç™¼è©±äººã€‚ <form name="form"> <button name="Accept" text="接å—"/> <button name="Decline" text="è¬çµ•"/> - <button name="Mute" text="Block"/> + <button name="Mute" text="å°éŽ–"/> </form> </notification> <notification name="InviteAdHoc"> - [NAME] is inviting you to a conference chat. -Click Accept to join the chat or Decline to decline the invitation. Click Block to block this caller. + [NAME] æ£é‚€è«‹ä½ åŠ å…¥å¤šæ–¹é€šè©±ã€‚ +點按「接å—ã€åŠ å…¥é€šè©±ï¼Œæˆ–ã€Œè¬çµ•ã€é‚€è«‹ã€‚ 點按「å°éŽ–ã€ä¾¿å¯å°éŽ–é€™å€‹ç™¼è©±äººã€‚ <form name="form"> <button name="Accept" text="接å—"/> <button name="Decline" text="è¬çµ•"/> - <button name="Mute" text="Block"/> + <button name="Mute" text="å°éŽ–"/> </form> </notification> <notification name="VoiceChannelFull"> - The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum capacity. Please try again later. + ä½ è©¦åœ–åŠ å…¥ [VOICE_CHANNEL_NAME] 語音通話,ä¸éŽå®ƒå·²é”è² è¼‰ä¸Šé™ã€‚ è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="ProximalVoiceChannelFull"> - We're sorry. This area has reached maximum capacity for voice conversations. Please try to use voice in another area. + 很抱æ‰ã€‚ 這å€åŸŸå·²é”èªžéŸ³é€šè©±çš„è² è¼‰ä¸Šé™ã€‚ 請到å¦ä¸€å€‹å€åŸŸä½¿ç”¨èªžéŸ³ã€‚ </notification> <notification name="VoiceChannelDisconnected"> - You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnected to Nearby Voice Chat. + ä½ çš„ [VOICE_CHANNEL_NAME] é€šè©±å·²ç¶“ä¸æ–·ã€‚ ç¾åœ¨ä½ 將釿–°é€£é€šåˆ°é™„近的語音èŠå¤©ã€‚ </notification> <notification name="VoiceChannelDisconnectedP2P"> - [VOICE_CHANNEL_NAME] has ended the call. You will now be reconnected to Nearby Voice Chat. + [VOICE_CHANNEL_NAME] èªžéŸ³é€šè©±å·²çµæŸã€‚ ç¾åœ¨ä½ 將釿–°é€£é€šåˆ°é™„近的語音èŠå¤©ã€‚ </notification> <notification name="P2PCallDeclined"> - [VOICE_CHANNEL_NAME] has declined your call. You will now be reconnected to Nearby Voice Chat. + [VOICE_CHANNEL_NAME] æ‹’çµ•ä½ åŠ å…¥èªžéŸ³é€šè©±ã€‚ ç¾åœ¨ä½ 將釿–°é€£é€šåˆ°é™„近的語音èŠå¤©ã€‚ </notification> <notification name="P2PCallNoAnswer"> - [VOICE_CHANNEL_NAME] is not available to take your call. You will now be reconnected to Nearby Voice Chat. + [VOICE_CHANNEL_NAME] ç„¡æ³•æŽ¥é€šä½ çš„é€šè©±ã€‚ ç¾åœ¨ä½ 將釿–°é€£é€šåˆ°é™„近的語音èŠå¤©ã€‚ </notification> <notification name="VoiceChannelJoinFailed"> - Failed to connect to [VOICE_CHANNEL_NAME], please try again later. You will now be reconnected to Nearby Voice Chat. + 無法連通 [VOICE_CHANNEL_NAME],,請ç¨å€™å†è©¦ã€‚ ç¾åœ¨ä½ 將釿–°é€£é€šåˆ°é™„近的語音èŠå¤©ã€‚ </notification> <notification name="VoiceLoginRetry"> - We are creating a voice channel for you. This may take up to one minute. + 我們æ£ç‚ºä½ å»ºç«‹èªžéŸ³é »é“。 這至多å¯èƒ½éœ€æ™‚一分é˜ã€‚ </notification> <notification name="VoiceEffectsExpired"> - One or more of your subscribed Voice Morphs has expired. -[[URL] Click here] to renew your subscription. + è‡³å°‘ä¸€å€‹ä½ è¨‚ç”¨çš„è®Šè²æ•ˆæžœå·²ç¶“éŽæœŸã€‚ +[[URL] 點按這裡] 繼續訂用。 </notification> <notification name="VoiceEffectsExpiredInUse"> - The active Voice Morph has expired, your normal voice settings have been applied. -[[URL] Click here] to renew your subscription. + 使用ä¸çš„è®Šè²æ•ˆæžœå·²ç¶“éŽæœŸï¼Œå·²ç”¨ä½ 平時的è²éŸ³è¨å®šå–代。 +[[URL] 點按這裡] 繼續訂用。 </notification> <notification name="VoiceEffectsWillExpire"> - One or more of your Voice Morphs will expire in less than [INTERVAL] days. -[[URL] Click here] to renew your subscription. + è‡³å°‘ä¸€å€‹ä½ è¨‚ç”¨çš„è®Šè²æ•ˆæžœå°‡åœ¨ [INTERVAL] 天後到期。 +[[URL] 點按這裡] 繼續訂用。 </notification> <notification name="VoiceEffectsNew"> - New Voice Morphs are available! + æ–°çš„è®Šè²æ•ˆæžœä¸Šå¸‚äº†ï¼ </notification> <notification name="Cannot enter parcel: not a group member"> - Only members of a certain group can visit this area. + åªæœ‰æŸç‰¹å®šç¾¤çµ„çš„æˆå“¡æ‰èƒ½é€²å…¥é€™å€åŸŸã€‚ </notification> <notification name="Cannot enter parcel: banned"> - Cannot enter parcel, you have been banned. + ä½ å·²è¢«ç¦å…¥ï¼Œå› æ¤ç„¡æ³•進入這地段。 </notification> <notification name="Cannot enter parcel: not on access list"> - Cannot enter parcel, you are not on the access list. + ç„¡æ³•é€²å…¥é€™åœ°æ®µï¼Œä½ ä¸åœ¨å‡ºå…¥è¨±å¯åå–®ä¸ã€‚ </notification> <notification name="VoiceNotAllowed"> - You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME]. + ä½ ç„¡æ¬Šé€£é€š [VOICE_CHANNEL_NAME] 語音èŠå¤©ã€‚ </notification> <notification name="VoiceCallGenericError"> - An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_NAME]. Please try again later. + 試圖連通 [VOICE_CHANNEL_NAME] 語音èŠå¤©æ™‚發生錯誤。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚ </notification> <notification name="UnsupportedCommandSLURL"> - ä½ æ‰€é»žæ“Šçš„ SLurl ä½ç½®ä¸¦ä¸è¢«æ”¯æ´ã€‚ + ä½ æ‰€é»žæŒ‰çš„ SLurl ä½ç½®ä¸¦ä¸è¢«æ”¯æ´ã€‚ </notification> <notification name="BlockedSLURL"> - A SLurl was received from an untrusted browser and has been blocked for your security. + 從未被信任的ç€è¦½å™¨æŽ¥æ”¶åˆ°ä¸€å€‹ SLurlï¼Œç‚ºäº†ä½ çš„å®‰å…¨èµ·è¦‹ï¼Œå·²å°‡å®ƒå°éŽ–ã€‚ </notification> <notification name="ThrottledSLURL"> - Multiple SLurls were received from an untrusted browser within a short period. -They will be blocked for a few seconds for your security. + çŸæ™‚間內從一個ä¸è¢«ä¿¡ä»»çš„ç€è¦½å™¨æŽ¥æ”¶åˆ°å¤šå€‹ SLurl。 +ç‚ºäº†ä½ çš„å®‰å…¨èµ·è¦‹ï¼Œå®ƒå€‘å°‡è¢«å°éŽ–å¹¾ç§’é˜ã€‚ </notification> <notification name="IMToast"> [MESSAGE] @@ -2713,45 +2900,72 @@ They will be blocked for a few seconds for your security. </form> </notification> <notification name="ConfirmCloseAll"> - ä½ ç¢ºå®šè¦é—œé–‰å…¨éƒ¨ IMs å°è©±è¦–窗? + ä½ ç¢ºå®šè¦é—œé–‰æ‰€æœ‰çš„ IM? <usetemplate ignoretext="在我關閉全部的 IMs å°è©±è¦–窗å‰ç¢ºèªã€‚" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="AttachmentSaved"> 附件已儲å˜ã€‚ </notification> <notification name="UnableToFindHelpTopic"> - Unable to find the help topic for this element. + 找ä¸åˆ°é€™å€‹å…ƒä»¶çš„幫助主題。 </notification> <notification name="ObjectMediaFailure"> - Server Error: Media update or get failed. + 伺æœå™¨éŒ¯èª¤ï¼šåª’體更新或å–得失敗。 '[ERROR]' <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="TextChatIsMutedByModerator"> - Your text chat has been muted by moderator. + 主æŒäººå·²è¨å®šå¿½ç•¥ä½ 的文å—èŠå¤©å…§å®¹ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="VoiceIsMutedByModerator"> - Your voice has been muted by moderator. + 主æŒäººå·²å°‡ä½ 的語音消音。 <usetemplate name="okbutton" yestext="確定"/> </notification> + <notification name="UploadCostConfirmation"> + 上傳將花費 L$[PRICE],是å¦ç¹¼çºŒï¼Ÿ + <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="上傳"/> + </notification> <notification name="ConfirmClearTeleportHistory"> - Are you sure you want to delete your teleport history? + ç¢ºå®šæ¸…é™¤ä½ çš„çž¬é–“å‚³é€æ·å²è¨˜éŒ„? <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification name="BottomTrayButtonCanNotBeShown"> - Selected button can not be shown right now. -The button will be shown when there is enough space for it. + æ‰€é¸æŒ‰éˆ•ç›®å‰ç„¡æ³•顯示。 +ç‰åˆ°ç©ºé–“è¶³å¤ ï¼ŒæŒ‰éˆ•å°‡æœƒé¡¯ç¤ºå‡ºä¾†ã€‚ </notification> <notification name="ShareNotification"> - Select residents to share with. + é¸å–è¦åˆ†äº«çš„居民。 + </notification> + <notification name="MeshUploadError"> + [LABEL] 上傳失敗:[MESSAGE] [IDENTIFIER] + +詳見記錄檔。 + </notification> + <notification name="MeshUploadPermError"> + 請求網é¢ä¸Šå‚³æ¬Šé™æ™‚出錯。 + </notification> + <notification name="RegionCapabilityRequestError"> + 無法å–得地å€èƒ½åŠ› '[CAPABILITY]'。 </notification> <notification name="ShareItemsConfirmation"> - Are you sure you want to share the following items: + è«‹ç¢ºå®šä½ è¦å’Œå±…æ°‘åˆ†äº«é€™äº›ç‰©é …ï¼š + +<nolink>[ITEMS]</nolink> + +居民: + +[RESIDENTS] + <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> + </notification> + <notification name="ShareFolderConfirmation"> + 一次åªèƒ½åˆ†äº«ä¸€å€‹è³‡æ–™å¤¾ã€‚ + +è«‹ç¢ºå®šä½ è¦å’Œå±…æ°‘åˆ†äº«é€™äº›ç‰©é …ï¼š <nolink>[ITEMS]</nolink> -With the following Residents: +居民: [RESIDENTS] <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/> @@ -2762,117 +2976,140 @@ With the following Residents: <notification name="DeedToGroupFail"> 讓渡給群組失敗。 </notification> + <notification name="ReleaseLandThrottled"> + ç›®å‰ç„¡æ³•éºæ£„ [PARCEL_NAME] 地段。 + </notification> + <notification name="ReleasedLandWithReclaim"> + [AREA] 平方公尺的地段「[PARCEL_NAME]ã€å·²é‡‹å‡ºã€‚ + +ä½ é ˆåœ¨ [RECLAIM_PERIOD] å°æ™‚å…§é ˜å›žï¼ˆèŠ±è²» L$0),å¦å‰‡å°‡é–‹æ”¾å‡ºå”®çµ¦ä»»ä½•人。 + </notification> + <notification name="ReleasedLandNoReclaim"> + [AREA] 平方公尺的地段「[PARCEL_NAME]ã€å·²é‡‹å‡ºã€‚ + +ç¾å·²é–‹æ”¾å‡ºå”®çµ¦ä»»ä½•人。 + </notification> <notification name="AvatarRezNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' declouded after [TIME] seconds. + (å˜çºŒ [EXISTENCE] ç§’é˜ï¼‰ +化身 '[NAME]' 在 [TIME] 秒內完全呈ç¾ã€‚ </notification> <notification name="AvatarRezSelfBakedDoneNotification"> - ( [EXISTENCE] seconds alive ) -You finished baking your outfit after [TIME] seconds. + (å˜çºŒ [EXISTENCE] ç§’é˜ï¼‰ +ä½ çš„è£æ‰®åœ¨ [TIME] 秒內定貌。 </notification> <notification name="AvatarRezSelfBakedUpdateNotification"> - ( [EXISTENCE] seconds alive ) -You sent out an update of your appearance after [TIME] seconds. + (å˜çºŒ [EXISTENCE] ç§’é˜ï¼‰ +ä½ åœ¨ [TIME] 秒後é€å‡ºæ›´æ–°å¤–觀請求。 [STATUS] </notification> <notification name="AvatarRezCloudNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' became cloud. + (å˜çºŒ [EXISTENCE] ç§’é˜ï¼‰ +化身 '[NAME]' 已雲化。 </notification> <notification name="AvatarRezArrivedNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' appeared. + (å˜çºŒ [EXISTENCE] ç§’é˜ï¼‰ +化身 '[NAME]' 已出ç¾ã€‚ </notification> <notification name="AvatarRezLeftCloudNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' left after [TIME] seconds as cloud. + (å˜çºŒ [EXISTENCE] ç§’é˜ï¼‰ +化身 '[NAME]' 在雲化 [TIME] 秒後離開。 </notification> <notification name="AvatarRezEnteredAppearanceNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' entered appearance mode. + (å˜çºŒ [EXISTENCE] ç§’é˜ï¼‰ +化身 '[NAME]' 進入外觀模å¼ã€‚ </notification> <notification name="AvatarRezLeftAppearanceNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' left appearance mode. + (å˜çºŒ [EXISTENCE] ç§’é˜ï¼‰ +化身 '[NAME]' 離開外觀模å¼ã€‚ </notification> <notification name="NoConnect"> - We're having trouble connecting using [PROTOCOL] [HOSTID]. -Please check your network and firewall setup. + 使用 [PROTOCOL] [HOSTID] 連線時出了å•題。 +è«‹æª¢æŸ¥ä½ çš„ç¶²è·¯å’Œé˜²ç«ç‰†è¨å®šã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="NoVoiceConnect"> - We're having trouble connecting to your voice server: + 試圖連接語音伺æœå™¨æ™‚出了å•題: [HOSTID] -Voice communications will not be available. -Please check your network and firewall setup. +將無法用語音æºé€šã€‚ +è«‹æª¢æŸ¥ä½ çš„ç¶²è·¯å’Œé˜²ç«ç‰†è¨å®šã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="AvatarRezLeftNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' left as fully loaded. + (å˜çºŒ [EXISTENCE] ç§’é˜ï¼‰ +化身 '[NAME]' 在完全載入狀æ³ä¸‹é›¢é–‹ã€‚ </notification> <notification name="AvatarRezSelfBakedTextureUploadNotification"> - ( [EXISTENCE] seconds alive ) -You uploaded a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds. + (å˜çºŒ [EXISTENCE] ç§’é˜ï¼‰ +ä½ åœ¨ [TIME] ç§’é˜å¾Œç‚º '[BODYREGION]' 上傳了一個 [RESOLUTION] 的定貌æè³ªã€‚ </notification> <notification name="AvatarRezSelfBakedTextureUpdateNotification"> - ( [EXISTENCE] seconds alive ) -You locally updated a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds. + (å˜çºŒ [EXISTENCE] ç§’é˜ï¼‰ +ä½ åœ¨ [TIME] ç§’é˜å¾Œåœ¨æœ¬åœ°ç‚º '[BODYREGION]' 更新了一個 [RESOLUTION] 的定貌æè³ªã€‚ + </notification> + <notification name="LivePreviewUnavailable"> + 我們無法顯示這個æè³ªçš„é è¦½ï¼Œå› ç‚ºå®ƒè¨ç‚ºã€Œç¦æ¢è¤‡è£½ã€ä¸” / æˆ–ã€Œç¦æ¢è½‰ç§»ã€ã€‚ + <usetemplate ignoretext="ã€Œç¦æ¢è¤‡è£½ã€å’Œã€Œç¦æ¢è½‰ç§»ã€çš„æè³ªè‹¥ä¸èƒ½ä½¿ç”¨å¯¦æ™‚é 覽模å¼ï¼Œè«‹çµ¦æˆ‘è¦ç¤ºã€‚" name="okignore" yestext="確定"/> </notification> <notification name="ConfirmLeaveCall"> ä½ ç¢ºå®šè¦é›¢é–‹é€™æ®µé€šè©±ï¼Ÿ <usetemplate ignoretext="æˆ‘çµæŸé€šè©±å‰é€²è¡Œç¢ºèª" name="okcancelignore" notext="å¦" yestext="是"/> </notification> <notification name="ConfirmMuteAll"> - You have selected to mute all participants in a group call. -This will also cause all residents that later join the call to be -muted, even after you have left the call. + ä½ å·²é¸æ“‡è¦å°‡æ‰€æœ‰åƒèˆ‡ç¾¤çµ„通話的人消音。 +é€™å°‡å°Žè‡´å¾Œä¾†åŠ å…¥é€šè©±çš„æ‰€æœ‰å±…æ°‘åŒæ¨£è¢« +消音,å³ä½¿åœ¨ä½ 離開通話後也一樣。 -Mute everyone? +把所有人消音? <usetemplate ignoretext="åœ¨æˆ‘å°æ‰€æœ‰ç¾¤çµ„通話的åƒèˆ‡è€…予以éœéŸ³å‰ç¢ºèª" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> </notification> <notification label="èŠå¤©" name="HintChat"> - To join the conversation, type into the chat field below. + è‹¥è¦åŠ å…¥å°è©±ï¼Œè«‹åœ¨ä¸‹æ–¹çš„èŠå¤©æ¬„裡打å—。 </notification> - <notification label="Stand" name="HintSit"> - To stand up and exit the sitting position, click the Stand button. + <notification label="站立" name="HintSit"> + è‹¥è¦ä¸æ¢åå§¿ç«™èµ·èº«ä¾†ï¼Œè«‹æŒ‰ã€Œç«™ç«‹ã€æŒ‰éˆ•。 </notification> - <notification label="Speak" name="HintSpeak"> - Click the Speak button to turn your microphone on and off. + <notification label="說話" name="HintSpeak"> + é»žæŒ‰ã€Œèªªè©±ã€æŒ‰éˆ•來打開或關閉麥克風。 -Click on the up arrow to see the voice control panel. +點按å‘上ç®é éµï¼Œå¯é¡¯ç¤ºè²éŸ³æŽ§åˆ¶é¢æ¿ã€‚ -Hiding the Speak button will disable the voice feature. +éš±è—ã€Œèªªè©±ã€æŒ‰éˆ•å°‡åœç”¨èªžéŸ³åŠŸèƒ½ã€‚ </notification> <notification label="探索世界" name="HintDestinationGuide"> - The Destination Guide contains thousands of new places to discover. Select a location and choose Teleport to start exploring. + 目的地指å—包å«ä¸Šåƒå€‹å€¼å¾—探索的新地點。 鏿“‡ä¸€å€‹åœ°é»žï¼Œç„¶å¾Œã€Œçž¬é–“傳é€ã€å‰å¾€ï¼Œé–‹å§‹ä½ çš„æŽ¢ç´¢ï¼ </notification> <notification label="å´é‚Šæ¬„" name="HintSidePanel"> - Get quick access to your inventory, outfits, profiles and more in the side panel. + ä½ å¯ä»¥å¾žå´é‚Šæ¬„進入收ç´å€ã€è£æ‰®ã€å€‹äººæª”案ç‰ï¼Œæ–¹ä¾¿åˆè¿…速。 </notification> <notification label="移動" name="HintMove"> - To walk or run, open the Move Panel and use the directional arrows to navigate. You can also use the directional keys on your keyboard. + 若想行走或跑æ¥ï¼Œè«‹æ‰“開「移動ã€é¢æ¿ï¼Œä½¿ç”¨æ–¹å‘ç®é 來移動。 也å¯ä»¥ä½¿ç”¨éµç›¤ä¸Šçš„æ–¹å‘éµã€‚ </notification> <notification label="" name="HintMoveClick"> - 1. Click to Walk -Click anywhere on the ground to walk to that spot. + 1. 點按一下就å¯è¡Œèµ° +點按地é¢ä¸Šä»»ä½•一點,就å¯ä»¥èµ°åˆ°é‚£è£¡ã€‚ -2. Click and Drag to Rotate View -Click and drag anywhere on the world to rotate your view +2. 按ä½ä¸¦æ‹–曳,å¯ä»¥æ—‹è½‰è¦–野 +在虛擬世界裡按ä½ä¸¦æ‹–æ›³ä»»ä½•ä¸€é»žï¼Œå°±å¯æ—‹è½‰ä½ 的視野 </notification> <notification label="顯示å稱" name="HintDisplayName"> - Set your customizable display name here. This is in addition to your unique username, which can't be changed. You can change how you see other people's names in your preferences. + åœ¨é€™è£¡è‡ªè¨‚ä½ çš„é¡¯ç¤ºå稱。 顯示å稱和使用者å稱有別,後者ç¨ä¸€ç„¡äºŒè€Œä¸”ä¸èƒ½è®Šæ›´ã€‚ ä½ å¯ä»¥åœ¨å好è¨å®šè£¡ï¼Œè®Šæ›´è¦å¦‚何察看別人的å稱。 </notification> - <notification label="View" name="HintView"> - To change your camera view, use the Orbit and Pan controls. Reset your view by pressing Escape or walking. + <notification label="視角" name="HintView"> + è¦æ”¹è®Šæ”影機視角,請用「環繞ã€å’Œã€Œå¹³ç§»ã€æŽ§åˆ¶ã€‚ 按 Escape éµï¼Œæˆ–走動一下,便å¯é‡è¨ä½ 的視野。 </notification> <notification label="æ”¶ç´å€" name="HintInventory"> - Check your inventory to find items. Newest items can be easily found in the Recent tab. + 到收ç´å€æ‰¾å°‹ç‰©é …。 在「新近ã€é 籤裡å¯ç«‹åˆ»çœ‹åˆ°æ–°è¿‘çš„ç‰©é …ã€‚ </notification> <notification label="ä½ å¾—åˆ°æž—ç™»å¹£!" name="HintLindenDollar"> - Here's your current balance of L$. Click Buy L$ to purchase more Linden Dollars. + é€™è£¡é¡¯ç¤ºä½ ç›®å‰çš„ L$ 餘é¡ã€‚ 點按「購買 L$ã€å¯æ·»è³¼æž—登幣。 + </notification> + <notification name="LowMemory"> + ä½ çš„å¯ç”¨è¨˜æ†¶é«”很å°ã€‚ 第二人生部分功能將åœç”¨ï¼Œä»¥å…當機。 請關閉其他應用程å¼ã€‚ 這狀æ³è‹¥æŒçºŒï¼Œè«‹é‡å•Ÿç¬¬äºŒäººç”Ÿã€‚ + </notification> + <notification name="ForceQuitDueToLowMemory"> + 記憶體ä¸è¶³ï¼Œç¬¬äºŒäººç”Ÿå°‡æ–¼ 30 秒後關閉離開。 </notification> <notification name="PopupAttempt"> 一個çªé¡¯å¼è¦–窗開啟時被阻擋。 @@ -2881,54 +3118,171 @@ Click and drag anywhere on the world to rotate your view <button name="open" text="開啟çªé¡¯å¼è¦–窗"/> </form> </notification> + <notification name="SOCKS_NOT_PERMITTED"> + SOCKS 5 代ç†ä¼ºæœå™¨ "[HOST]:[PORT]" 拒絕連通,è¦å‰‡é›†ä¸å…許。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_CONNECT_ERROR"> + SOCKS 5 代ç†ä¼ºæœå™¨ "[HOST]:[PORT]" 拒絕連通,無法打開 TCP é »é“。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_NOT_ACCEPTABLE"> + SOCKS 5 代ç†ä¼ºæœå™¨ "[HOST]:[PORT]" 拒絕所é¸çš„é‘’èªæ–¹æ³•。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_AUTH_FAIL"> + SOCKS 5 代ç†ä¼ºæœå™¨ "[HOST]:[PORT]" å›žå ±ï¼šä½ çš„é‘’èªè³‡æ–™ç„¡æ•ˆã€‚ + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_UDP_FWD_NOT_GRANTED"> + SOCKS 5 代ç†ä¼ºæœå™¨ "[HOST]:[PORT]" 拒絕 UDP è¯çµè«‹æ±‚。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_HOST_CONNECT_FAILED"> + 無法連通 SOCKS 5 代ç†ä¼ºæœå™¨ "[HOST]:[PORT]"。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_UNKNOWN_STATUS"> + 伺æœå™¨ "[HOST]:[PORT]" ç™¼ç”Ÿä¸æ˜Žçš„代ç†ä¼ºæœå™¨éŒ¯èª¤ã€‚ + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_INVALID_HOST"> + 無效的 SOCKS 代ç†ä¼ºæœå™¨ä½å€æˆ–åŸ è™Ÿ "[HOST]:[PORT]"。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_BAD_CREDS"> + 無效的 SOCKS 5 使用者å稱或密碼。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="PROXY_INVALID_HTTP_HOST"> + 無效的 HTTP 代ç†ä¼ºæœå™¨ä½å€æˆ–åŸ è™Ÿ "[HOST]:[PORT]"。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="PROXY_INVALID_SOCKS_HOST"> + 無效的 SOCKS 代ç†ä¼ºæœå™¨ä½å€æˆ–åŸ è™Ÿ "[HOST]:[PORT]"。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="ChangeProxySettings"> + 釿–°å•Ÿå‹• [APP_NAME] 後將採用新的代ç†ä¼ºæœå™¨è¨å®šã€‚ + <usetemplate name="okbutton" yestext="確定"/> + </notification> <notification name="AuthRequest"> - The site at '<nolink>[HOST_NAME]</nolink>' in realm '[REALM]' requires a user name and password. + '[REALM]' é ˜åŸŸçš„ '<nolink>[HOST_NAME]</nolink>' 站點需è¦ä½¿ç”¨è€…å稱和密碼。 <form name="form"> - <input name="username" text="User Name"/> - <input name="password" text="Password"/> - <button name="ok" text="Submit"/> + <input name="username" text="使用者å稱"/> + <input name="password" text="密碼"/> + <button name="ok" text="æäº¤"/> <button name="cancel" text="å–æ¶ˆ"/> </form> </notification> - <notification label="" name="ModeChange"> - 改變劉覽器模å¼è¦æ±‚ä½ å¿…é ˆçµæŸé€€å‡ºä¸¦é‡æ–°å•Ÿå‹•。 - <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/> - </notification> <notification label="" name="NoClassifieds"> - Creation and editing of Classifieds is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen. + åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½æ–°å»ºæˆ–編輯個人廣告。 ä½ æ˜¯å¦æƒ³è¦çµæŸé›¢é–‹ï¼Œä»¥ä¾¿è®Šæ›´æ¨¡å¼ï¼Ÿ ä½ å¯åœ¨ç™»å…¥ç•«é¢é¸æ“‡æƒ³è¦çš„æ¨¡å¼ã€‚ <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/> </notification> <notification label="" name="NoGroupInfo"> - Creation and editing of Groups is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen. + åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½æ–°å»ºæˆ–編輯群組。 ä½ æ˜¯å¦æƒ³è¦çµæŸé›¢é–‹ï¼Œä»¥ä¾¿è®Šæ›´æ¨¡å¼ï¼Ÿ ä½ å¯åœ¨ç™»å…¥ç•«é¢é¸æ“‡æƒ³è¦çš„æ¨¡å¼ã€‚ + <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/> + </notification> + <notification label="" name="NoPlaceInfo"> + åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½å¯Ÿçœ‹åœ°é»žæª”案。 ä½ æ˜¯å¦æƒ³è¦çµæŸé›¢é–‹ï¼Œä»¥ä¾¿è®Šæ›´æ¨¡å¼ï¼Ÿ ä½ å¯åœ¨ç™»å…¥ç•«é¢é¸æ“‡æƒ³è¦çš„æ¨¡å¼ã€‚ <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/> </notification> <notification label="" name="NoPicks"> - Creation and editing of Picks is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen. + åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½æ–°å»ºæˆ–編輯精é¸åœ°é»žã€‚ ä½ æ˜¯å¦æƒ³è¦çµæŸé›¢é–‹ï¼Œä»¥ä¾¿è®Šæ›´æ¨¡å¼ï¼Ÿ ä½ å¯åœ¨ç™»å…¥ç•«é¢é¸æ“‡æƒ³è¦çš„æ¨¡å¼ã€‚ <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/> </notification> <notification label="" name="NoWorldMap"> - Viewing of the world map is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen. + åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½å¯Ÿçœ‹ä¸–界地圖。 ä½ æ˜¯å¦æƒ³è¦çµæŸé›¢é–‹ï¼Œä»¥ä¾¿è®Šæ›´æ¨¡å¼ï¼Ÿ ä½ å¯åœ¨ç™»å…¥ç•«é¢é¸æ“‡æƒ³è¦çš„æ¨¡å¼ã€‚ <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/> </notification> <notification label="" name="NoVoiceCall"> - Voice calls are only available in Advanced mode. Would you like to logout and change modes? + åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½ä½¿ç”¨èªžéŸ³é€šè©±ã€‚ ä½ æ˜¯å¦è¦ç™»å‡ºä¸¦ä¸”變更模å¼ï¼Ÿ <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/> </notification> <notification label="" name="NoAvatarShare"> - Sharing is only available in Advanced mode. Would you like to logout and change modes? + åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½ä½¿ç”¨åˆ†äº«åŠŸèƒ½ã€‚ ä½ æ˜¯å¦è¦ç™»å‡ºä¸¦ä¸”變更模å¼ï¼Ÿ <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/> </notification> <notification label="" name="NoAvatarPay"> - Paying other residents is only available in Advanced mode. Would you like to logout and change modes? + åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½ä»˜è²»çµ¦å…¶ä»–居民。 ä½ æ˜¯å¦è¦ç™»å‡ºä¸¦ä¸”變更模å¼ï¼Ÿ <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/> </notification> - <global name="UnsupportedCPU"> - - ä½ çš„ CPU é‹ç®—速度未é”到系統最低é…å‚™è¦æ±‚。 - </global> + <notification label="" name="NoInventory"> + åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½å¯Ÿçœ‹æ”¶ç´å€ã€‚ ä½ æ˜¯å¦è¦ç™»å‡ºä¸¦ä¸”變更模å¼ï¼Ÿ + <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/> + </notification> + <notification label="" name="NoAppearance"> + åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½ä½¿ç”¨å¤–觀編輯器。 ä½ æ˜¯å¦è¦ç™»å‡ºä¸¦ä¸”變更模å¼ï¼Ÿ + <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/> + </notification> + <notification label="" name="NoSearch"> + åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½æœå°‹ã€‚ ä½ æ˜¯å¦è¦ç™»å‡ºä¸¦ä¸”變更模å¼ï¼Ÿ + <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/> + </notification> + <notification label="" name="ConfirmHideUI"> + é€™å°‡æœƒéš±è—æ‰€æœ‰é¸å–®å…§å®¹å’ŒæŒ‰éˆ•。 è¦æ¢å¾©åŽŸç‹€ï¼Œå†é»žæŒ‰ [SHORTCUT] 一次。 + <usetemplate ignoretext="éš±è—使用者介é¢å‰å…ˆç¢ºèª" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + 所é¸çš„一些è¯çµé›†çš„幻影旗標將被切æ›ã€‚ + +ä½ ç¢ºå®šè¦ç¹¼çºŒå—Žï¼Ÿ + <usetemplate ignoretext="所é¸çš„一些è¯çµé›†çš„幻影旗標將被切æ›ã€‚" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + æ‰€é¸æŸäº›è¯çµé›†å› 權é™å•題,無法è¨å®šç‚º '[REQUESTED_TYPE]'。 這些è¯çµé›†å°‡è¢«è¨ç‚º '[RESTRICTED_TYPE]'。 + +ä½ ç¢ºå®šè¦ç¹¼çºŒå—Žï¼Ÿ + <usetemplate ignoretext="æ‰€é¸æŸäº›è¯çµé›†å› 權é™å•題,無法è¨å®šã€‚" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + æ‰€é¸æŸäº›è¯çµé›†ç„¡æ³•è¨ç‚º '[REQUESTED_TYPE]'ï¼Œå› ç‚ºå½¢ç‹€å±¬æ–¼éžå‡¸é¢ã€‚ + +ä½ ç¢ºå®šè¦ç¹¼çºŒå—Žï¼Ÿ + <usetemplate ignoretext="æ‰€é¸æŸäº›è¯çµé›†å› 為形狀屬於éžå‡¸é¢ï¼Œç„¡æ³•è¨å®š" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + 所é¸çš„一些è¯çµé›†çš„幻影旗標將被切æ›ã€‚ + +æ‰€é¸æŸäº›è¯çµé›†å› 權é™å•題,無法è¨å®šç‚º '[REQUESTED_TYPE]'。 這些è¯çµé›†å°‡è¢«è¨ç‚º '[RESTRICTED_TYPE]'。 + +ä½ ç¢ºå®šè¦ç¹¼çºŒå—Žï¼Ÿ + <usetemplate ignoretext="所é¸çš„一些è¯çµé›†çš„å¹»å½±æ——æ¨™å¯æˆåŠŸåˆ‡æ›ï¼Œå…¶ä»–çš„å‰‡å› æ¬Šé™å•題而無法è¨å®šã€‚" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + 所é¸çš„一些è¯çµé›†çš„幻影旗標將被切æ›ã€‚ + +æ‰€é¸æŸäº›è¯çµé›†ç„¡æ³•è¨ç‚º '[REQUESTED_TYPE]'ï¼Œå› ç‚ºå½¢ç‹€å±¬æ–¼éžå‡¸é¢ã€‚ + +ä½ ç¢ºå®šè¦ç¹¼çºŒå—Žï¼Ÿ + <usetemplate ignoretext="所é¸çš„一些è¯çµé›†çš„å¹»å½±æ——æ¨™å¯æˆåŠŸåˆ‡æ›ï¼Œå…¶ä»–çš„å‰‡å› å½¢ç‹€å±¬æ–¼éžå‡¸é¢è€Œç„¡æ³•è¨å®š" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + æ‰€é¸æŸäº›è¯çµé›†å› 權é™å•題,無法è¨å®šç‚º '[REQUESTED_TYPE]'。 這些è¯çµé›†å°‡è¢«è¨ç‚º '[RESTRICTED_TYPE]'。 + +æ‰€é¸æŸäº›è¯çµé›†ç„¡æ³•è¨ç‚º '[REQUESTED_TYPE]'ï¼Œå› ç‚ºå½¢ç‹€å±¬æ–¼éžå‡¸é¢ã€‚ 這些è¯çµé›†çš„ä½¿ç”¨é¡žåž‹å°‡ç¶æŒä¸è®Šã€‚ + +ä½ ç¢ºå®šè¦ç¹¼çºŒå—Žï¼Ÿ + <usetemplate ignoretext="æ‰€é¸æŸäº›è¯çµé›†å› 權é™ä¸è¶³ï¼Œä¸”形狀屬於éžå‡¸é¢ï¼Œå› æ¤ç„¡æ³•è¨å®šã€‚" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + 所é¸çš„一些è¯çµé›†çš„幻影旗標將被切æ›ã€‚ + +æ‰€é¸æŸäº›è¯çµé›†å› 權é™å•題,無法è¨å®šç‚º '[REQUESTED_TYPE]'。 這些è¯çµé›†å°‡è¢«è¨ç‚º '[RESTRICTED_TYPE]'。 + +æ‰€é¸æŸäº›è¯çµé›†ç„¡æ³•è¨ç‚º '[REQUESTED_TYPE]'ï¼Œå› ç‚ºå½¢ç‹€å±¬æ–¼éžå‡¸é¢ã€‚ 這些è¯çµé›†çš„ä½¿ç”¨é¡žåž‹å°‡ç¶æŒä¸è®Šã€‚ + +ä½ ç¢ºå®šè¦ç¹¼çºŒå—Žï¼Ÿ + <usetemplate ignoretext="所é¸çš„一些è¯çµé›†çš„幻影旗標將被切æ›ï¼Œå…¶ä»–å‰‡å› æ¬Šé™ä¸è¶³ä¸”形狀屬於éžå‡¸é¢ï¼Œå› æ¤ç„¡æ³•è¨å®šã€‚" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + 所é¸çš„物件會影響導航網é¢ã€‚ 將它改為彈性路徑,將使它從導航網é¢ä¸è¢«ç§»é™¤ã€‚ + <usetemplate ignoretext="所é¸çš„物件會影響導航網é¢ã€‚ 將它改為彈性路徑,將使它從導航網é¢ä¸è¢«ç§»é™¤ã€‚" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/> + </notification> <global name="UnsupportedGLRequirements"> - You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_NAME] requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system. + ä½ çš„ç¡¬é«”è¨å‚™ä¼¼ä¹Žä¸ç¬¦ [APP_NAME] çš„è¦æ±‚。 [APP_NAME] 需è¦å¯ä»¥æ”¯æ´å¤šæè³ªçš„ OpenGL 顯åƒå¡ã€‚ 在這狀æ³ä¸‹ï¼Œè«‹ç¢ºå®šä½ 的顯åƒå¡å®‰è£äº†æœ€æ–°çš„驅動程å¼ï¼Œä½œæ¥ç³»çµ±ä¹Ÿå®‰è£äº†æœ€æ–°çš„æœå‹™åŒ…å’ŒåµŒè£œç¨‹å¼ã€‚ -If you continue to have problems, please visit the [SUPPORT_SITE]. +å¦‚æžœä½ ç¹¼çºŒé‡åˆ°å•題,請å‰å¾€ [SUPPORT_SITE] 求助。 </global> <global name="UnsupportedCPUAmount"> 796 @@ -2944,9 +3298,29 @@ If you continue to have problems, please visit the [SUPPORT_SITE]. </global> <global name="You can only set your 'Home Location' on your land or at a mainland Infohub."> è‹¥ä½ æ“æœ‰ä¸€å¡ŠåœŸåœ°ï¼Œä½ å¯ä»¥æ¨™è¨˜å®ƒæˆç‚ºä½ 的家的ä½ç½®ã€‚ -æˆ–è€…ï¼Œä½ å¯ä»¥å¯Ÿçœ‹åœ°åœ–尋找標記為 "資訊ä¸å¿ƒ" 的地方。 +æˆ–è€…ï¼Œä½ å¯ä»¥å¯Ÿçœ‹åœ°åœ–,尋找標記為「資訊ä¸å¿ƒã€çš„地方。 </global> <global name="You died and have been teleported to your home location"> ä½ å·²ç¶“æ»äº¡ä¸¦ä¸”被瞬間傳é€å›žä½ 的家的ä½ç½®ã€‚ </global> + <notification name="LocalBitmapsUpdateFileNotFound"> + [FNAME] 無法更新,找ä¸åˆ°è©²æª”案。 +未來將ä¸å†æ›´æ–°è©²æª”案。 + </notification> + <notification name="LocalBitmapsUpdateFailedFinal"> + [FNAME] 無法開啟或解碼,已嘗試 [NRETRIES] 次,該檔案已被èªå®šç‚ºæ¯€å£žã€‚ +未來將ä¸å†æ›´æ–°è©²æª”案。 + </notification> + <notification name="LocalBitmapsVerifyFail"> + 試圖新增一個無效或無法讀å–çš„åœ–åƒæª” [FNAME],該檔無法開啟或解碼。 +已喿¶ˆé€™ä¸€å˜—試。 + </notification> + <notification name="PathfindingReturnMultipleItems"> + ä½ æ£é€€å›ž [NUM_ITEMS] å€‹ç‰©é …ã€‚ ä½ ç¢ºå®šä½ è¦ç¹¼çºŒï¼Ÿ + <usetemplate ignoretext="ç¢ºå®šé€€å›žå¤šå€‹ç‰©é …ï¼Ÿ" name="okcancelignore" notext="å¦" yestext="是"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + ä½ æ£åœ¨åˆªé™¤ [NUM_ITEMS] å€‹ç‰©é …ã€‚ ä½ ç¢ºå®šä½ è¦ç¹¼çºŒï¼Ÿ + <usetemplate ignoretext="確定è¦åˆªé™¤å¤šå€‹ç‰©é …?" name="okcancelignore" notext="å¦" yestext="是"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml index eccb938f15..1c8b56b3d6 100644 --- a/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="avatar_list_item"> <string name="FormatSeconds"> - [COUNT]s + [COUNT] ç§’ </string> <string name="FormatMinutes"> - [COUNT]m + [COUNT] 分 </string> <string name="FormatHours"> - [COUNT]h + [COUNT] 時 </string> <string name="FormatDays"> - [COUNT]d + [COUNT] æ—¥ </string> <string name="FormatWeeks"> - [COUNT]w + [COUNT] 週 </string> <string name="FormatMonths"> - [COUNT]mon + [COUNT] 月 </string> <string name="FormatYears"> - [COUNT]y + [COUNT] å¹´ </string> - <text name="avatar_name" value="(載入)"/> - <text name="last_interaction" value="0s"/> + <text name="avatar_name" value="(載入ä¸ï¼‰"/> + <text name="last_interaction" value="0 ç§’"/> <icon name="permission_edit_theirs_icon" tool_tip="ä½ ä¸èƒ½ç·¨è¼¯é€™ä½æœ‹å‹çš„物件"/> <icon name="permission_edit_mine_icon" tool_tip="這使œ‹å‹èƒ½ç·¨è¼¯ã€åˆªé™¤æˆ–å–å¾—ä½ çš„ç‰©ä»¶"/> <icon name="permission_map_icon" tool_tip="這使œ‹å‹èƒ½åœ¨åœ°åœ–ä¸Šæ‰¾åˆ°ä½ çš„ä½ç½®"/> diff --git a/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml index 550868e5e5..fef692c1c5 100644 --- a/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml +++ b/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="wearable_item"> <text name="item_name" value="..."/> - <panel name="btn_lock" tool_tip="ä½ ä¸¦æ²’æœ‰æ¬Šé™é€²è¡Œç·¨è¼¯"/> + <panel name="btn_lock" tool_tip="ä½ æ²’æœ‰ç·¨è¼¯æ¬Š"/> <panel name="btn_edit_panel"> <button name="btn_edit" tool_tip="編輯這個體形"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml index 5e269fcd09..e4e7a661a7 100644 --- a/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml +++ b/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="clothing_list_button_bar_panel"> - <button label="Switch" name="switch_btn"/> + <button label="切æ›" name="switch_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_bottomtray.xml b/indra/newview/skins/default/xui/zh/panel_bottomtray.xml deleted file mode 100644 index 734b83e6cc..0000000000 --- a/indra/newview/skins/default/xui/zh/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Turns microphone on/off"/> - <string name="VoiceControlBtnToolTip" value="顯示 / éš±è— èªžéŸ³æŽ§åˆ¶æ¿"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Speak" label_selected="Speak" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="å§¿å‹¢" name="Gesture" tool_tip="顯示 / éš±è— å§¿å‹¢"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="移動" name="movement_btn" tool_tip="顯示 / éš±è— ç§»å‹•æŽ§åˆ¶"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="視角" name="camera_btn" tool_tip="顯示 / éš±è— æ”影機控制"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button name="snapshots" tool_tip="æ‹æ”å¿«ç…§"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="å»ºé€ " name="build_btn" tool_tip="顯示 / éš±è— å»ºé€ å·¥å…·"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="æœå°‹" name="search_btn" tool_tip="顯示 / éš±è— æœå°‹"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="地圖" name="world_map_btn" tool_tip="顯示 / éš±è— ä¸–ç•Œåœ°åœ–"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="è¿·ä½ åœ°åœ–" name="mini_map_btn" tool_tip="顯示 / éš±è— è¿·ä½ åœ°åœ–"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Conversations"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="通知"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/zh/panel_chiclet_bar.xml new file mode 100644 index 0000000000..69340349bc --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_chiclet_bar.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="chiclet_bar"> + <layout_stack name="toolbar_stack"> + <layout_panel name="im_well_panel"> + <chiclet_im_well name="im_well"> + <button name="Unread IM messages" tool_tip="交談"/> + </chiclet_im_well> + </layout_panel> + <layout_panel name="notification_well_panel"> + <chiclet_notification name="notification_well"> + <button name="Unread" tool_tip="通知"/> + </chiclet_notification> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_classified_info.xml b/indra/newview/skins/default/xui/zh/panel_classified_info.xml index cf3113ef1c..6f2dd89318 100644 --- a/indra/newview/skins/default/xui/zh/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/zh/panel_classified_info.xml @@ -16,33 +16,33 @@ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] </panel.string> <panel.string name="auto_renew_on"> - Enabled + 已啟用 </panel.string> <panel.string name="auto_renew_off"> - Disabled + å·²åœç”¨ </panel.string> - <text name="title" value="Classified Info"/> + <text name="title" value="個人廣告資訊"/> <scroll_container name="profile_scroll"> <panel name="scroll_content_panel"> <text_editor name="classified_name" value="[name]"/> <text name="classified_location_label" value="ä½ç½®ï¼š"/> <text_editor name="classified_location" value="[loading...]"/> - <text name="content_type_label" value="Content Type:"/> + <text name="content_type_label" value="內容類型:"/> <text_editor name="content_type" value="[content type]"/> - <text name="category_label" value="Category:"/> + <text name="category_label" value="分類:"/> <text_editor name="category" value="[category]"/> - <text name="creation_date_label" value="Creation date:"/> - <text_editor name="creation_date" tool_tip="Creation date" value="[date]"/> - <text name="price_for_listing_label" value="Price for listing:"/> - <text_editor name="price_for_listing" tool_tip="Price for listing." value="[price]"/> + <text name="creation_date_label" value="建立日期:"/> + <text_editor name="creation_date" tool_tip="建立日期" value="[date]"/> + <text name="price_for_listing_label" value="刊登費:"/> + <text_editor name="price_for_listing" tool_tip="刊登費。" value="[price]"/> <layout_stack name="descr_stack"> <layout_panel name="clickthrough_layout_panel"> - <text name="click_through_label" value="Clicks:"/> - <text_editor name="click_through_text" tool_tip="Click through data" value="[clicks]"/> + <text name="click_through_label" value="點按:"/> + <text_editor name="click_through_text" tool_tip="點進資料" value="[clicks]"/> </layout_panel> <layout_panel name="price_layout_panel"> - <text name="auto_renew_label" value="Auto renew:"/> - <text name="auto_renew" value="Enabled"/> + <text name="auto_renew_label" value="自動續訂:"/> + <text name="auto_renew" value="已啟用"/> </layout_panel> <layout_panel name="descr_layout_panel"> <text name="classified_desc_label" value="æè¿°ï¼š"/> diff --git a/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml index 1185336a2d..55e72f5347 100644 --- a/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml +++ b/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml @@ -2,8 +2,8 @@ <panel name="wearable_item"> <button name="btn_delete" tool_tip="ç”±è£æ‰®ç§»é™¤"/> <text name="item_name" value="..."/> - <panel name="btn_lock" tool_tip="ä½ ä¸¦æ²’æœ‰æ¬Šé™åŽ»ç·¨è¼¯"/> + <panel name="btn_lock" tool_tip="ä½ æ²’æœ‰ç·¨è¼¯æ¬Š"/> <panel name="btn_edit_panel"> - <button name="btn_edit" tool_tip="Edit this wearable"/> + <button name="btn_edit" tool_tip="編輯這å¯ç©¿è£æ‰®"/> </panel> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml b/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml index 309ab1c0d4..c074abb568 100644 --- a/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml +++ b/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml @@ -2,7 +2,7 @@ <panel name="cof_wearables"> <accordion name="cof_wearables_accordion"> <accordion_tab name="tab_clothing" title="æœè£"/> - <accordion_tab name="tab_attachments" title="Attachments"/> + <accordion_tab name="tab_attachments" title="附件"/> <accordion_tab name="tab_body_parts" title="身體部ä½"/> </accordion> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml b/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml index eda4e99a13..32765a3e16 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml @@ -2,11 +2,11 @@ <panel name="edit_alpha_panel"> <scroll_container name="avatar_alpha_color_panel_scroll"> <panel name="avatar_alpha_color_panel"> - <texture_picker label="下åŠèº«åŠé€æ˜Ž" name="Lower Alpha" tool_tip="點擊以挑é¸åœ–åƒ"/> - <texture_picker label="上åŠèº«åŠé€æ˜Ž" name="Upper Alpha" tool_tip="點擊以挑é¸åœ–åƒ"/> - <texture_picker label="é 部åŠé€æ˜Ž" name="Head Alpha" tool_tip="點擊以挑é¸åœ–åƒ"/> - <texture_picker label="眼ç›åŠé€æ˜Ž" name="Eye Alpha" tool_tip="點擊以挑é¸åœ–åƒ"/> - <texture_picker label="é é«®åŠé€æ˜Ž" name="Hair Alpha" tool_tip="點擊以挑é¸åœ–åƒ"/> + <texture_picker label="下åŠèº«åŠé€æ˜Ž" name="Lower Alpha" tool_tip="點按以挑é¸åœ–片"/> + <texture_picker label="上åŠèº«åŠé€æ˜Ž" name="Upper Alpha" tool_tip="點按以挑é¸åœ–片"/> + <texture_picker label="é 部åŠé€æ˜Ž" name="Head Alpha" tool_tip="點按以挑é¸åœ–片"/> + <texture_picker label="眼ç›åŠé€æ˜Ž" name="Eye Alpha" tool_tip="點按以挑é¸åœ–片"/> + <texture_picker label="é é«®åŠé€æ˜Ž" name="Hair Alpha" tool_tip="點按以挑é¸åœ–片"/> </panel> </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml index f12701c981..b06ece02ad 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml @@ -1,24 +1,24 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Edit Classified" name="panel_edit_classified"> +<panel label="編輯個人廣告" name="panel_edit_classified"> <panel.string name="location_notice"> (儲å˜å¾Œå°‡æœƒæ›´æ–°ï¼‰ </panel.string> <string name="publish_label"> - Publish + 發布 </string> <string name="save_label"> å„²å˜ </string> <text name="title"> - Edit Classified + 編輯個人廣告 </text> <scroll_container name="profile_scroll"> <panel name="scroll_content_panel"> <panel name="snapshot_panel"> - <icon label="" name="edit_icon" tool_tip="é»žæ“Šä»¥é¸æ“‡åœ–åƒ"/> + <icon label="" name="edit_icon" tool_tip="é»žæŒ‰ä»¥é¸æ“‡åœ–åƒ"/> </panel> <text name="Name:"> - Title: + 標題: </text> <text name="description_label"> æè¿°ï¼š @@ -29,16 +29,16 @@ <text name="classified_location"> 載入ä¸... </text> - <button label="Set to Current Location" name="set_to_curr_location_btn"/> - <text name="category_label" value="Category:"/> - <text name="content_type_label" value="Content type:"/> + <button label="è¨å®šç‚ºç›®å‰ä½ç½®" name="set_to_curr_location_btn"/> + <text name="category_label" value="分類:"/> + <text name="content_type_label" value="內容類型:"/> <icons_combo_box label="一般普級內容" name="content_type"> - <icons_combo_box.item label="é©åº¦æˆäººå…§å®¹" name="mature_ci" value="Mature"/> - <icons_combo_box.item label="一般普級內容" name="pg_ci" value="PG"/> + <icons_combo_box.item label="é©åº¦æˆäººå…§å®¹" name="mature_ci" value="é©åº¦æˆäºº"/> + <icons_combo_box.item label="一般普級內容" name="pg_ci" value="一般普級"/> </icons_combo_box> - <check_box label="Auto renew each week" name="auto_renew"/> - <text name="price_for_listing_label" value="Price for listing:"/> - <spinner label="L$" name="price_for_listing" tool_tip="Price for listing." value="50"/> + <check_box label="æ¯æ˜ŸæœŸè‡ªå‹•續訂" name="auto_renew"/> + <text name="price_for_listing_label" value="刊登費:"/> + <spinner label="L$" name="price_for_listing" tool_tip="刊登費。" value="50"/> </panel> </scroll_container> <panel label="bottom_panel" name="bottom_panel"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml b/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml index 40dd61971a..f44d411908 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_eyes_panel"> <panel name="avatar_eye_color_panel"> - <texture_picker label="Iris" name="Iris" tool_tip="點擊以挑é¸åœ–åƒ"/> + <texture_picker label="虹膜" name="Iris" tool_tip="點按以挑é¸åœ–片"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml b/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml index 7b39e33a9b..d107eea553 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_gloves_panel"> <panel name="avatar_gloves_color_panel"> - <texture_picker label="æè³ª" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + <texture_picker label="æè³ª" name="Fabric" tool_tip="點按以挑é¸åœ–片"/> + <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_hair.xml b/indra/newview/skins/default/xui/zh/panel_edit_hair.xml index a7440093bc..65f78f9273 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_hair.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_hair.xml @@ -1,14 +1,14 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_hair_panel"> <panel name="avatar_hair_color_panel"> - <texture_picker label="æè³ª" name="Texture" tool_tip="點擊以挑é¸åœ–åƒ"/> + <texture_picker label="æè³ª" name="Texture" tool_tip="點按以挑é¸åœ–片"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> <accordion_tab name="hair_color_tab" title="é¡è‰²"/> - <accordion_tab name="hair_style_tab" title="Style"/> - <accordion_tab name="hair_eyebrows_tab" title="Eyebrows"/> - <accordion_tab name="hair_facial_tab" title="Facial"/> + <accordion_tab name="hair_style_tab" title="é¢¨æ ¼"/> + <accordion_tab name="hair_eyebrows_tab" title="眉毛"/> + <accordion_tab name="hair_facial_tab" title="é¡é¢"/> </accordion> </panel> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml b/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml index dcef070e2e..61e45f911e 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_jacket_panel"> <panel name="avatar_jacket_color_panel"> - <texture_picker label="上åŠèº«æè³ª" name="Upper Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/> - <texture_picker label="下åŠèº«æè³ª" name="Lower Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + <texture_picker label="上åŠèº«æè³ª" name="Upper Fabric" tool_tip="點按以挑é¸åœ–片"/> + <texture_picker label="下åŠèº«æè³ª" name="Lower Fabric" tool_tip="點按以挑é¸åœ–片"/> + <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_pants.xml b/indra/newview/skins/default/xui/zh/panel_edit_pants.xml index 01b875f1bd..846ed72961 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_pants.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_pants.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_pants_panel"> <panel name="avatar_pants_color_panel"> - <texture_picker label="æè³ª" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/> + <texture_picker label="æè³ª" name="Fabric" tool_tip="點按以挑é¸åœ–片"/> + <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_pick.xml b/indra/newview/skins/default/xui/zh/panel_edit_pick.xml index 6ac7226185..faee42fd0e 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_pick.xml @@ -1,14 +1,14 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="編輯精é¸åœ°é»ž" name="panel_edit_pick"> <panel.string name="location_notice"> - (將在儲å˜å¾Œæ›´æ–°ï¼‰ + (儲å˜å¾Œå°‡æœƒæ›´æ–°ï¼‰ </panel.string> <text name="title"> 編輯精é¸åœ°é»ž </text> <scroll_container name="profile_scroll"> <panel name="scroll_content_panel"> - <icon label="" name="edit_icon" tool_tip="é»žæ“Šä»¥é¸æ“‡åœ–åƒ"/> + <icon label="" name="edit_icon" tool_tip="é»žæŒ‰ä»¥é¸æ“‡åœ–åƒ"/> <text name="Name:"> 標題: </text> @@ -29,7 +29,7 @@ <layout_panel name="layout_panel1"> <button label="儲å˜ç²¾é¸åœ°é»ž" name="save_changes_btn"/> </layout_panel> - <layout_panel name="layout_panel1"> + <layout_panel name="layout_panel2"> <button label="å–æ¶ˆ" name="cancel_btn"/> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_profile.xml b/indra/newview/skins/default/xui/zh/panel_edit_profile.xml index 7734c3a417..849b82c71a 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_profile.xml @@ -7,15 +7,15 @@ <string name="RegisterDateFormat"> [REG_DATE] ([AGE]) </string> - <string name="AcctTypeResident" value="Resident"/> - <string name="AcctTypeTrial" value="Trial"/> - <string name="AcctTypeCharterMember" value="Charter Member"/> - <string name="AcctTypeEmployee" value="Linden Lab Employee"/> - <string name="PaymentInfoUsed" value="Payment Info Used"/> - <string name="PaymentInfoOnFile" value="Payment Info On File"/> - <string name="NoPaymentInfoOnFile" value="No Payment Info On File"/> - <string name="AgeVerified" value="Age-verified"/> - <string name="NotAgeVerified" value="Not Age-verified"/> + <string name="AcctTypeResident" value="å±…æ°‘"/> + <string name="AcctTypeTrial" value="試用"/> + <string name="AcctTypeCharterMember" value="è€ç‰Œ Charter æˆå“¡"/> + <string name="AcctTypeEmployee" value="林登實驗室員工"/> + <string name="PaymentInfoUsed" value="使用的付款資料"/> + <string name="PaymentInfoOnFile" value="é 留付款資料"/> + <string name="NoPaymentInfoOnFile" value="未é 留付款資料"/> + <string name="AgeVerified" value="通éŽå¹´é½¡é©—è‰"/> + <string name="NotAgeVerified" value="未通éŽå¹´é½¡é©—è‰"/> <string name="partner_edit_link_url"> http://www.secondlife.com/account/partners.php?lang=en </string> @@ -34,22 +34,22 @@ <panel name="second_life_image_panel"> <text name="second_life_photo_title_text" value="[SECOND_LIFE]:"/> </panel> - <icon label="" name="2nd_life_edit_icon" tool_tip="é»žæ“Šä»¥é¸æ“‡åœ–åƒ"/> + <icon label="" name="2nd_life_edit_icon" tool_tip="é»žæŒ‰ä»¥é¸æ“‡åœ–åƒ"/> </panel> <panel name="first_life_image_panel"> <text name="real_world_photo_title_text" value="真實世界:"/> </panel> - <icon label="" name="real_world_edit_icon" tool_tip="é»žæ“Šä»¥é¸æ“‡åœ–åƒ"/> + <icon label="" name="real_world_edit_icon" tool_tip="é»žæŒ‰ä»¥é¸æ“‡åœ–åƒ"/> <text name="title_homepage_text"> 首é : </text> <line_editor name="homepage_edit" value="http://"/> <text name="title_acc_status_text" value="我的帳戶:"/> - <text_editor name="acc_status_text" value="Resident. No payment info on file."/> + <text_editor name="acc_status_text" value="居民。 未é 留付款資料。"/> <text name="my_account_link" value="[[URL] å‰å¾€æˆ‘的塗鴉牆]"/> <text name="title_partner_text" value="我的é…å¶ï¼š"/> <panel name="partner_data_panel"> - <text initial_value="(retrieving)" name="partner_text"/> + <text initial_value="(檢索ä¸ï¼‰" name="partner_text"/> </panel> <text name="partner_edit_link" value="[[URL] 編輯]"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml b/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml index f8ff76aa9b..bc69f2ffc4 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_shirt_panel"> <panel name="avatar_shirt_color_panel"> - <texture_picker label="æè³ª" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/> + <texture_picker label="æè³ª" name="Fabric" tool_tip="點按以挑é¸åœ–片"/> + <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml b/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml index 97e43f5753..e190bb5bd8 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_shoes_panel"> <panel name="avatar_shoes_color_panel"> - <texture_picker label="æè³ª" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/> - <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/> + <texture_picker label="æè³ª" name="Fabric" tool_tip="點按以挑é¸åœ–片"/> + <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_skin.xml b/indra/newview/skins/default/xui/zh/panel_edit_skin.xml index fdd6d05ca5..d8552f52f0 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_skin.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_skin.xml @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_skin_panel"> <panel name="avatar_skin_color_panel"> - <texture_picker label="Head Tattoos" name="Head Tattoos" tool_tip="點擊以挑é¸åœ–åƒ"/> - <texture_picker label="Upper Tattoos" name="Upper Tattoos" tool_tip="點擊以挑é¸åœ–åƒ"/> - <texture_picker label="Lower Tattoos" 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"> - <accordion_tab name="skin_color_tab" title="Skin Color"/> - <accordion_tab name="skin_face_tab" title="Face Detail"/> - <accordion_tab name="skin_makeup_tab" title="Makeup"/> - <accordion_tab name="skin_body_tab" title="Body Detail"/> + <accordion_tab name="skin_color_tab" title="膚色"/> + <accordion_tab name="skin_face_tab" title="臉部細節"/> + <accordion_tab name="skin_makeup_tab" title="化å¦"/> + <accordion_tab name="skin_body_tab" title="身體細節"/> </accordion> </panel> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml b/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml index 10432c16b1..34319fcc01 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_skirt_panel"> <panel name="avatar_skirt_color_panel"> - <texture_picker label="æè³ª" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/> + <texture_picker label="æè³ª" name="Fabric" tool_tip="點按以挑é¸åœ–片"/> + <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_socks.xml b/indra/newview/skins/default/xui/zh/panel_edit_socks.xml index 6727781740..8e19fb5692 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_socks.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_socks.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_socks_panel"> <panel name="avatar_socks_color_panel"> - <texture_picker label="æè³ª" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/> + <texture_picker label="æè³ª" name="Fabric" tool_tip="點按以挑é¸åœ–片"/> + <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml index 1b34a0e0ee..f5111d629a 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_tattoo_panel"> <panel name="avatar_tattoo_color_panel"> - <texture_picker label="é 部刺é’" name="Head Tattoo" tool_tip="點擊以挑é¸åœ–åƒ"/> - <texture_picker label="上åŠèº«åˆºé’" name="Upper Tattoo" tool_tip="點擊以挑é¸ç…§ç‰‡"/> - <texture_picker label="下åŠèº«åˆºé’" name="Lower Tattoo" tool_tip="點擊以挑é¸åœ–åƒ"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/> + <texture_picker label="é 部刺é’" name="Head Tattoo" tool_tip="點按以挑é¸åœ–片"/> + <texture_picker label="上åŠèº«åˆºé’" name="Upper Tattoo" tool_tip="點按以挑é¸åœ–片"/> + <texture_picker label="下åŠèº«åˆºé’" name="Lower Tattoo" tool_tip="點按以挑é¸åœ–片"/> + <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/> </panel> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml b/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml index 15cae8d233..5ead7c9004 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_underpants_panel"> <panel name="avatar_underpants_color_panel"> - <texture_picker label="æè³ª" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + <texture_picker label="æè³ª" name="Fabric" tool_tip="點按以挑é¸åœ–片"/> + <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml index 486175eb64..e497e285c9 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_undershirt_panel"> <panel name="avatar_undershirt_color_panel"> - <texture_picker label="æè³ª" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open Color Picker"/> + <texture_picker label="æè³ª" name="Fabric" tool_tip="點按以挑é¸åœ–片"/> + <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml b/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml index 066b1fd389..4dd7ea6d93 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml @@ -1,43 +1,43 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Wearable" name="panel_edit_wearable"> +<panel label="å¯ç©¿è£æ‰®" name="panel_edit_wearable"> <string name="edit_shape_title"> - Editing Shape + é«”å½¢ç·¨è¼¯ä¸ </string> <string name="edit_skin_title"> - Editing Skin + 編輯皮膚 </string> <string name="edit_hair_title"> - Editing Hair + 編輯é é«® </string> <string name="edit_eyes_title"> - Editing Eyes + ç·¨è¼¯çœ¼ç› </string> <string name="edit_shirt_title"> - Editing Shirt + 編輯襯衫 </string> <string name="edit_pants_title"> - Editing Pants + 編輯褲å </string> <string name="edit_shoes_title"> - Editing Shoes + 編輯鞋å </string> <string name="edit_socks_title"> - Editing Socks + 編輯襪å </string> <string name="edit_jacket_title"> - Editing Jacket + 編輯外套 </string> <string name="edit_skirt_title"> - Editing Skirt + 編輯裙å </string> <string name="edit_gloves_title"> - Editing Gloves + 編輯手套 </string> <string name="edit_undershirt_title"> - Editing Undershirt + 編輯內衣 </string> <string name="edit_underpants_title"> - Editing Underpants + 編輯內褲 </string> <string name="edit_alpha_title"> åŠé€æ˜Žé®ç½©ç·¨è¼¯ä¸ @@ -110,7 +110,7 @@ <panel name="button_panel"> <layout_stack name="button_panel_ls"> <layout_panel name="save_as_btn_lp"> - <button label="å¦å˜" name="save_as_button"/> + <button label="å¦å˜ç‚º" name="save_as_button"/> </layout_panel> <layout_panel name="revert_btn_lp"> <button label="復原變更" name="revert_button"/> diff --git a/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml b/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml index 3915e80d43..f468aba514 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml @@ -8,7 +8,7 @@ <button label="群組通話" name="call_btn"/> </layout_panel> <layout_panel name="end_call_btn_panel"> - <button label="çµæŸé€šè©±" name="end_call_btn"/> + <button label="離開通話" name="end_call_btn"/> </layout_panel> <layout_panel name="voice_ctrls_btn_panel"> <button label="開啟語音控制" name="voice_ctrls_btn"/> diff --git a/indra/newview/skins/default/xui/zh/panel_group_general.xml b/indra/newview/skins/default/xui/zh/panel_group_general.xml index 55cbf5a617..2b16b61dd1 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_general.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_general.xml @@ -1,18 +1,18 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="一般" name="general_tab"> +<panel label="基本資料" name="general_tab"> <panel.string name="help_text"> - The General tab contains general information about this group, a list of members, general Group Preferences and member options. + 基本資料é 籤包å«é—œæ–¼ç¾¤çµ„çš„åŸºæœ¬è³‡è¨Šã€æˆå“¡åå–®ã€ç¾¤çµ„å好è¨å®šå’Œæˆå“¡é¸é …。 -Hover your mouse over the options for more help. +å°‡æ»‘é¼ åœæ‡¸åˆ°é¸é …上,å¯ç²å–更多幫助。 </panel.string> <panel.string name="group_info_unchanged"> - 一般群組資訊已經被變更 + 基本群組資訊已經被變更 </panel.string> <panel.string name="incomplete_member_data_str"> - Retrieving member data + æ£åœ¨æ“·å–æˆå“¡è³‡æ–™ </panel.string> <panel name="group_info_top"> - <texture_picker label="" name="insignia" tool_tip="點擊以挑é¸åœ–åƒ"/> + <texture_picker label="" name="insignia" tool_tip="點按以挑é¸åœ–片"/> <text name="prepend_founded_by"> 創辦人: </text> @@ -30,22 +30,22 @@ Hover your mouse over the options for more help. <name_list.columns label="狀態" name="status"/> </name_list> <text name="my_group_settngs_label"> - 自己 + 我自己 </text> <text name="active_title_label"> 我的é 銜: </text> - <combo_box name="active_title" tool_tip="Sets the title that appears in your avatar's name tag when this group is active."/> - <check_box label="接å—群組通知" name="receive_notices" tool_tip="Sets whether you want to receive Notices from this group. Uncheck this box if this group is spamming you."/> - <check_box label="顯示在我的檔案ä¸" name="list_groups_in_profile" tool_tip="Sets whether you want to show this group in your profile"/> + <combo_box name="active_title" tool_tip="這將è¨å®šç•¶ç¾¤çµ„æœ‰æ•ˆæ™‚ï¼Œé¡¯ç¤ºæ–¼ä½ åŒ–èº«å稱標籤的é 銜。"/> + <check_box label="接å—群組通知" name="receive_notices" tool_tip="è¨å®šä½ 是å¦è¦æŽ¥æ”¶ä¾†è‡ªé€™ç¾¤çµ„的通知。 如果該群組å°ä½ é€å‡ºå¤ªå¤šåžƒåœ¾è³‡è¨Šï¼Œä½ å¯ä»¥ä¸è¦å‹¾é¸æ¤é …目。"/> + <check_box label="顯示在我的檔案ä¸" name="list_groups_in_profile" tool_tip="è¨å®šä½ 是å¦è¦åœ¨ä½ 個人檔案上顯示這個群組"/> <panel name="preferences_container"> <text name="group_settngs_label"> 群組 </text> - <check_box label="任何人都å¯ä»¥åŠ å…¥" name="open_enrollement" tool_tip="Sets whether this group allows new members to join without being invited."/> - <check_box label="åŠ å…¥è²»ç”¨" name="check_enrollment_fee" tool_tip="Sets whether to require an enrollment fee to join the group"/> - <spinner label="L$" name="spin_enrollment_fee" tool_tip="New members must pay this fee to join the group when Enrollment Fee is checked."/> - <combo_box name="group_mature_check" tool_tip="Sets whether your group contains information rated as Moderate"> + <check_box label="任何人都å¯ä»¥åŠ å…¥" name="open_enrollement" tool_tip="è¨å®šé€™å€‹ç¾¤çµ„是å¦å…許新æˆå“¡æœªå—é‚€è«‹è‡ªè¡ŒåŠ å…¥ã€‚"/> + <check_box label="åŠ å…¥è²»ç”¨" name="check_enrollment_fee" tool_tip="è¨å®šæ˜¯å¦è¦å¾µæ”¶ç¾¤çµ„åŠ å…¥è²»"/> + <spinner label="L$" name="spin_enrollment_fee" tool_tip="若勾é¸åŠ å…¥è²»ï¼Œæ–°æˆå“¡å¿…é ˆæ”¯ä»˜é€™ç†è²»ç”¨æ‰èƒ½åŠ å…¥ç¾¤çµ„ã€‚"/> + <combo_box name="group_mature_check" tool_tip="è¨å®šä½ 的群組是å¦å«æœ‰è¢«è¨‚為é©åº¦æˆäººåˆ†ç´šçš„資訊"> <combo_item name="select_mature"> - 鏿“‡å…§å®¹åˆ†ç´š - </combo_item> diff --git a/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml index db01edcdb3..f979a4c53e 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml @@ -19,7 +19,7 @@ <layout_stack name="layout"> <layout_panel name="group_accordions"> <accordion name="groups_accordion"> - <accordion_tab name="group_general_tab" title="一般"/> + <accordion_tab name="group_general_tab" title="基本資料"/> <accordion_tab name="group_roles_tab" title="角色"/> <accordion_tab name="group_notices_tab" title="通知"/> <accordion_tab name="group_land_tab" title="土地 / 資產"/> diff --git a/indra/newview/skins/default/xui/zh/panel_group_invite.xml b/indra/newview/skins/default/xui/zh/panel_group_invite.xml index 07dcb2303e..8921978b20 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_invite.xml @@ -1,24 +1,27 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="邀請一個æˆå“¡" name="invite_panel"> <panel.string name="confirm_invite_owner_str"> - Are you sure you want to invite new owner(s)? This action is permanent! + 確定邀請新的所有人? 這動作一旦完æˆï¼Œä¸èƒ½å–æ¶ˆï¼ </panel.string> <panel.string name="loading"> (載入ä¸...) </panel.string> <panel.string name="already_in_group"> - Some Residents you chose are already in the group, and so were not sent an invitation. + ä½ æ‰€é¸çš„å±…æ°‘æœ‰äº›å·²ç¶“åœ¨ç¾¤çµ„è£¡ï¼Œæ‰€ä»¥ä¸æœƒå†å°ä»–們發é€é‚€è«‹ã€‚ + </panel.string> + <panel.string name="invite_selection_too_large"> + 未é€å‡ºç¾¤çµ„邀請:所é¸çš„居民人數太多。 ç¾¤çµ„é‚€è«‹æ¯æ¬¡ä»¥ 100 人為上é™ã€‚ </panel.string> <text name="help_text"> - You can select multiple Residents to invite to your group. Click 'Open Resident Chooser' to start. + ä½ å¯ä»¥é¸æ“‡é‚€è«‹å¤šä½å±…æ°‘åˆ°ä½ çš„ç¾¤çµ„ä¾†ã€‚ é»žæŒ‰ã€Œé–‹å•Ÿå±…æ°‘é¸æ“‡å·¥å…·ã€é–‹å§‹é¸æ“‡ã€‚ </text> - <button label="é–‹å•Ÿå±…æ°‘é¸æ“‡è¦–窗" name="add_button"/> - <name_list name="invitee_list" tool_tip="Hold the Ctrl key and click Resident names to multi-select"/> - <button label="Remove Selected from List" name="remove_button" tool_tip="Removes the Residents selected above from the invite list"/> + <button label="é–‹å•Ÿå±…æ°‘é¸æ“‡å·¥å…·" name="add_button"/> + <name_list name="invitee_list" tool_tip="按下 Ctrl éµåŒæ™‚點é¸å±…æ°‘çš„åå—,å³å¯é¸å–多個人"/> + <button label="將所é¸çš„從å單移除" name="remove_button" tool_tip="å°‡ä¸Šé¢æ‰€é¸å±…民從邀請åå–®ä¸ç§»é™¤"/> <text name="role_text"> - Choose what Role to assign them to: + 鏿“‡æŒ‡æ´¾çµ¦ä»–們的角色: </text> - <combo_box name="role_name" tool_tip="Choose from the list of Roles you are allowed to assign members to"/> + <combo_box name="role_name" tool_tip="å¾žè§’è‰²æ¸…å–®é¸æ“‡ä½ 有權指派給æˆå“¡çš„角色:"/> <button label="é€å‡ºé‚€è«‹" name="ok_button"/> <button label="å–æ¶ˆ" name="cancel_button"/> <string name="GroupInvitation"> diff --git a/indra/newview/skins/default/xui/zh/panel_group_land_money.xml b/indra/newview/skins/default/xui/zh/panel_group_land_money.xml index 5ac7410c8b..81d5573e1c 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_land_money.xml @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Land & L$" name="land_money_tab"> +<panel label="土地和 L$" name="land_money_tab"> <panel.string name="help_text"> - A warning appears until the Total Land in Use is less than or = to the Total Contribution. + å°‡æŒçºŒå‡ºç¾è¦ç¤ºï¼Œç›´åˆ°ä½¿ç”¨ä¸ç¸½åœŸåœ°å°æ–¼æˆ–ç‰æ–¼ç¸½è²¢ç»é¢ç©ç‚ºæ¢ã€‚ </panel.string> <panel.string name="cant_view_group_land_text"> - You don't have permission to view group owned land + ä½ ç„¡æ¬Šå¯Ÿçœ‹ç¾¤çµ„æ‰€æœ‰åœ°ã€‚ </panel.string> <panel.string name="epmty_view_group_land_text"> æ²’æœ‰é …ç›® </panel.string> <panel.string name="cant_view_group_accounting_text"> - You don't have permission to view the group's accounting information. + ä½ ç„¡æ¬Šå¯Ÿçœ‹è©²ç¾¤çµ„çš„å¸³ç›®è³‡æ–™ã€‚ </panel.string> <panel.string name="loading_txt"> 載入ä¸... @@ -27,42 +27,42 @@ <scroll_list.columns label="éš±è—" name="hidden"/> </scroll_list> <text name="total_contributed_land_label"> - Total contribution: + 總貢ç»ï¼š </text> <text name="total_contributed_land_value"> - [AREA] m² + [AREA] 平方公尺 </text> <button label="地圖" label_selected="地圖" name="map_button"/> <text name="total_land_in_use_label"> - Total land in use: + 使用ä¸åœŸåœ°ç¸½é¢ç©ï¼š </text> <text name="total_land_in_use_value"> - [AREA] m² + [AREA] 平方公尺 </text> <text name="land_available_label"> - Land available: + å¯ç”¨åœŸåœ°ï¼š </text> <text name="land_available_value"> - [AREA] m² + [AREA] 平方公尺 </text> <text name="your_contribution_label"> ä½ çš„æç»ï¼š </text> <text name="your_contribution_units"> - m² + 平方公尺 </text> <text name="your_contribution_max_value"> ([AMOUNT] 最大) </text> <text name="group_over_limit_text"> - More land credits are needed to support land in use + 使用ä¸åœŸåœ°éœ€è¦æ›´å¤§çš„土地é¡åº¦ </text> <text name="group_money_heading"> 群組 L$ </text> </panel> <tab_container name="group_money_tab_container"> - <panel label="PLANNING" name="group_money_planning_tab"> + <panel label="ç–劃" name="group_money_planning_tab"> <text_editor name="group_money_planning_text"> 載入ä¸... </text_editor> @@ -71,15 +71,15 @@ <text_editor name="group_money_details_text"> 載入ä¸... </text_editor> - <button name="earlier_details_button" tool_tip="Back"/> - <button name="later_details_button" tool_tip="Next"/> + <button name="earlier_details_button" tool_tip="返回"/> + <button name="later_details_button" tool_tip="下一個"/> </panel> <panel label="銷售" name="group_money_sales_tab"> <text_editor name="group_money_sales_text"> 載入ä¸... </text_editor> - <button name="earlier_sales_button" tool_tip="Back"/> - <button name="later_sales_button" tool_tip="Next"/> + <button name="earlier_sales_button" tool_tip="返回"/> + <button name="later_sales_button" tool_tip="下一個"/> </panel> </tab_container> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_group_notices.xml b/indra/newview/skins/default/xui/zh/panel_group_notices.xml index 26273dd9ce..ba5f4f1bba 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_notices.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="通知" name="notices_tab"> <panel.string name="help_text"> - Notices let you send a message and an optionally attached item. -Notices only go to group members in Roles with the ability to receive Notices. -You can turn off Notices on the General tab. + 通知å¯è®“ä½ å‚³é€è¨Šæ¯ä¸¦é¸æ“‡æ€§åœ°é™„上一個附件。 +é€šçŸ¥åƒ…èƒ½å‚³çµ¦å¯æŽ¥æ”¶é€šçŸ¥çš„è§’è‰²çš„ç¾¤çµ„æˆå“¡ã€‚ +ä½ å¯åˆ°åŸºæœ¬è³‡æ–™é 籤åœç”¨é€šçŸ¥åŠŸèƒ½ã€‚ </panel.string> <panel.string name="no_notices_text"> 沒有éŽåŽ»çš„é€šçŸ¥ @@ -21,7 +21,7 @@ You can turn off Notices on the General tab. 沒發ç¾ã€‚ </text> <button label="新通知" name="create_new_notice" tool_tip="建立一個新通知"/> - <button name="refresh_notices" tool_tip="Refresh list of notices"/> + <button name="refresh_notices" tool_tip="刷新通知清單。"/> <panel label="建立新通知" name="panel_create_new_notice"> <text name="lbl"> 建立一個通知 @@ -36,19 +36,19 @@ You can turn off Notices on the General tab. 附件: </text> <text name="string"> - å°‡ç‰©å“æ‹–曳並丟於æ¤è™•ä»¥æ·»åŠ ç‚ºé™„ä»¶ï¼š + 拖曳並置放物å“到這裡,å³å¯æ·»åŠ ç‚ºé™„ä»¶ï¼š </text> <button label="æ”¶ç´å€" name="open_inventory" tool_tip="開啟收ç´å€"/> <button name="remove_attachment" tool_tip="ç”±ä½ çš„é€šçŸ¥ç§»é™¤é™„ä»¶"/> <button label="é€å‡º" label_selected="é€å‡º" name="send_notice"/> - <group_drop_target name="drop_target" tool_tip="Drag an inventory item onto this target box to send it with this notice. You must have permission to copy and transfer the item in order to attach it."/> + <group_drop_target name="drop_target" tool_tip="將一個收ç´å€ç‰©é …拖曳到這個目標箱框,便å¯éš¨é€šçŸ¥é€å‡ºè©²ç‰©é …。 ä½ å¿…é ˆæœ‰æ¬Šè¤‡è£½ä¸¦è½‰ç§»æ¤ç‰©é …,æ‰å¯ä»¥é™„åŠ å®ƒã€‚"/> </panel> <panel label="察看éŽåŽ»çš„é€šçŸ¥" name="panel_view_past_notice"> <text name="lbl"> å˜æª”的通知 </text> <text name="lbl2"> - è¦é€å‡ºä¸€å€‹æ–°é€šçŸ¥ï¼Œé»žæ“Š + 按鈕 + è¦é€å‡ºä¸€å€‹æ–°é€šçŸ¥ï¼Œé»žæŒ‰ + 按鈕 </text> <text name="lbl3"> 主旨: diff --git a/indra/newview/skins/default/xui/zh/panel_group_notify.xml b/indra/newview/skins/default/xui/zh/panel_group_notify.xml index 00462d8b0b..08a8c94876 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_notify.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_notify.xml @@ -3,10 +3,10 @@ <string name="message_max_lines_count" value="7"/> <string name="subject_font" value="SANSSERIF_BIG"/> <string name="date_font" value="SANSSERIF"/> - <panel label="header" name="header"> - <text name="title" value="Sender Name / Group Name"/> + <panel label="表é " name="header"> + <text name="title" value="發件者å/群組å"/> </panel> <text_editor name="message" value="訊æ¯"/> - <text name="attachment" value="Attachment"/> + <text name="attachment" value="附件"/> <button label="確定" name="btn_ok"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_group_roles.xml b/indra/newview/skins/default/xui/zh/panel_group_roles.xml index cf5fc26d14..59086c3de2 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_roles.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="æˆå“¡èˆ‡è§’色" name="roles_tab"> <panel.string name="default_needs_apply_text"> - 未儲å˜çš„è¨å®š + è®Šæ›´æœªå„²å˜ </panel.string> <panel.string name="want_apply_text"> ä½ è¦å„²å˜ä½ 的變更嗎? @@ -11,10 +11,10 @@ <panel.string name="help_text"> ä½ å¯ä»¥æ·»åŠ æˆ–ç§»é™¤ä¸€å€‹è§’è‰²æŒ‡æ´¾çµ¦æˆå“¡ã€‚ é¸è²¬å¤šå€‹æˆå“¡æ™‚åŒæ™‚按著 Ctrl éµä¸” -ä½¿ç”¨æ»‘é¼ å·¦éµé»žæ“Šä»–們的åå—。 +ä½¿ç”¨æ»‘é¼ å·¦éµé»žæŒ‰ä»–們的åå—。 </panel.string> <panel.string name="donation_area"> - [AREA] m² + [AREA] 平方公尺 </panel.string> <filter_editor label="æˆå“¡éŽæ¿¾å™¨" name="filter_input"/> <name_list name="member_list"> @@ -27,13 +27,12 @@ </panel> <panel label="角色" name="roles_sub_tab"> <panel.string name="help_text"> - Roles have a title and an allowed list of Abilities -that Members can perform. Members can belong to -one or more Roles. A group can have up to 10 Roles, -including the Everyone and Owner Roles. + 一個角色具備è·ç¨±å’Œè©²è§’色å¯ä½¿ç”¨çš„能力。 +䏀使ˆå“¡å¯æœ‰ä¸€åˆ°å¤šå€‹è§’色。 +ä¸€å€‹ç¾¤çµ„è‡³å¤šå¯æœ‰ 10 個角色,包括「任何人ã€å’Œã€Œæ‰€æœ‰äººã€ã€‚ </panel.string> <panel.string name="cant_delete_role"> - The 'Everyone' and 'Owners' Roles are special and can't be deleted. + 「任何人ã€å’Œã€Œæ‰€æœ‰äººã€æ˜¯ç‰¹è¨è§’色,ä¸å¾—刪除。 </panel.string> <filter_editor label="è§’è‰²éŽæ¿¾å™¨" name="filter_input"/> <scroll_list name="role_list"> @@ -44,13 +43,13 @@ including the Everyone and Owner Roles. <button label="新角色" name="role_create"/> <button label="刪除角色" name="role_delete"/> </panel> - <panel label="能力" name="actions_sub_tab" tool_tip="You can view an Ability's Description and which Roles and Members can execute the Ability."> + <panel label="能力" name="actions_sub_tab" tool_tip="ä½ å¯å¯Ÿçœ‹é—œæ–¼æŸä¸€èƒ½åŠ›çš„èªªæ˜Žï¼Œä¸¦å¾—çŸ¥å“ªäº›è§’è‰²å’Œæˆå“¡æ“有該能力。"> <panel.string name="help_text"> - Abilities allow Members in Roles to do specific -things in this group. There's a broad variety of Abilities. + 「能力ã€å¯è®“群組的æˆå“¡é€éŽè§’è‰²è¡Œä½¿ä¸€å®šçš„è·æ¬Šã€‚ +能力的種類ç¹å¤šã€‚ </panel.string> <filter_editor label="èƒ½åŠ›éŽæ¿¾å™¨" name="filter_input"/> - <scroll_list name="action_list" tool_tip="Select an Ability to view more details"/> + <scroll_list name="action_list" tool_tip="è«‹é¸å–一個能力以察看詳情。"/> </panel> </tab_container> <panel name="members_footer"> @@ -60,7 +59,7 @@ things in this group. There's a broad variety of Abilities. <text name="static2"> å…許的能力 </text> - <scroll_list name="member_allowed_actions" tool_tip="想çžè§£æœ‰é—œæ–¼å…許的能力的細節請查閱能力é 籤"/> + <scroll_list name="member_allowed_actions" tool_tip="想çžè§£æ¯ä¸€é …å…許的能力的詳情請查閱能力é 籤。"/> </panel> <panel name="roles_footer"> <text name="static"> @@ -75,15 +74,15 @@ things in this group. There's a broad variety of Abilities. <text name="static4"> 指派角色 </text> - <check_box label="Reveal members" name="role_visible_in_list" tool_tip="Sets whether members of this role are visible in the General tab to people outside of the group."/> + <check_box label="顯示æˆå“¡" name="role_visible_in_list" tool_tip="è¨å®šæ˜¯å¦è®“群組外的人在「一般ã€é 籤上察看到æ¤è§’色的æˆå“¡ã€‚"/> <text name="static5"> å…許的能力 </text> - <scroll_list name="role_allowed_actions" tool_tip="想çžè§£æœ‰é—œæ–¼æ¯ä¸€é …å…許的能力的細節請查閱能力é 籤"/> + <scroll_list name="role_allowed_actions" tool_tip="想çžè§£æ¯ä¸€é …å…許的能力的詳情請查閱能力é 籤。"/> </panel> <panel name="actions_footer"> <text_editor name="action_description"> - This Ability is 'Eject Members from this Group'. Only an Owner can eject another Owner. + 這個能力å¯ã€Œå°‡æœƒå“¡è‡ªæœ¬ç¾¤çµ„踢出ã€ã€‚ å¿…é ˆæ˜¯æ‰€æœ‰äººæ‰å¯è¸¢å‡ºå¦ä¸€ä½æ‰€æœ‰äººã€‚ </text_editor> <text name="static2"> 有æ¤èƒ½åŠ›çš„è§’è‰² diff --git a/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml b/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml index 703182e04d..e937368a2b 100644 --- a/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml +++ b/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml @@ -8,7 +8,7 @@ <button label="åŠ ç‚ºæœ‹å‹" name="add_friend_btn"/> </layout_panel> <layout_panel name="teleport_btn_panel"> - <button label="瞬間傳é€" name="teleport_btn" tool_tip="Offer to teleport this person"/> + <button label="瞬間傳é€" name="teleport_btn" tool_tip="發出瞬間傳é€é‚€è«‹çµ¦æ¤äºº"/> </layout_panel> <layout_panel name="share_btn_panel"> <button label="分享" name="share_btn"/> diff --git a/indra/newview/skins/default/xui/zh/panel_landmark_info.xml b/indra/newview/skins/default/xui/zh/panel_landmark_info.xml index d86ba7bc7c..b50aa24d3f 100644 --- a/indra/newview/skins/default/xui/zh/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/zh/panel_landmark_info.xml @@ -3,22 +3,22 @@ <string name="title_create_landmark" value="å‰µé€ åœ°æ¨™"/> <string name="title_edit_landmark" value="編輯地標"/> <string name="title_landmark" value="地標"/> - <string name="not_available" value="(N\A)"/> + <string name="not_available" value="(ä¸é©ç”¨ï¼‰"/> <string name="unknown" value="(未知)"/> <string name="public" value="(公開)"/> <string name="server_update_text"> - Place information not available without server update. + åœ°é»žè³‡è¨Šå› ç„¡ä¼ºæœå™¨æ›´æ–°æ•…無法æä¾›ã€‚ </string> <string name="server_error_text"> - Information about this location is unavailable at this time, please try again later. + ç›®å‰ç„¡æ³•å–å¾—æ¤ä½ç½®çš„訊æ¯ï¼Œè«‹ç¨å€™å†è©¦ã€‚ </string> <string name="server_forbidden_text"> - Information about this location is unavailable due to access restrictions. Please check your permissions with the parcel owner. + 權é™ä¸è¶³ï¼Œç„¡æ³•å–å¾—æ¤ä½ç½®çš„資訊。 è«‹å‘åœ°æ®µæ‰€æœ‰äººæŸ¥è©¢ä½ çš„æ¬Šé™ã€‚ </string> <string name="acquired_date"> [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] </string> - <button name="back_btn" tool_tip="Back"/> + <button name="back_btn" tool_tip="返回"/> <text name="title" value="地點檔案"/> <scroll_container name="place_scroll"> <panel name="scrolling_panel"> @@ -27,13 +27,13 @@ <expandable_text name="description" value="Du waltz die spritz"/> <text name="maturity_value" value="未知"/> <panel name="landmark_info_panel"> - <text name="owner_label" value="æ“æœ‰è€…:"/> + <text name="owner_label" value="所有人:"/> <text name="creator_label" value="å‰µé€ è€…ï¼š"/> <text name="created_label" value="å‰µé€ æ–¼ï¼š"/> </panel> <panel name="landmark_edit_panel"> - <text name="title_label" value="Title:"/> - <text name="notes_label" value="My notes:"/> + <text name="title_label" value="標題:"/> + <text name="notes_label" value="我的記事:"/> <text name="folder_label" value="地標ä½ç½®ï¼š"/> </panel> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_login.xml b/indra/newview/skins/default/xui/zh/panel_login.xml index b227fbcfc8..672d9bb1a2 100644 --- a/indra/newview/skins/default/xui/zh/panel_login.xml +++ b/indra/newview/skins/default/xui/zh/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + 登入 + </text> <text name="username_text"> 使用者å稱: </text> @@ -15,34 +15,32 @@ <text name="password_text"> 密碼: </text> - <check_box label="記ä½å¯†ç¢¼ï¼š" name="remember_check"/> - <button label="登入" name="connect_btn"/> - <text name="mode_selection_text"> - 模å¼ï¼š - </text> - <combo_box name="mode_combo" tool_tip="è«‹é¸æ“‡ä½ 的模å¼ã€‚é¸ç”¨åŸºæœ¬æ¨¡å¼å¯ä»¥å¿«é€Ÿã€ç°¡å–®åœ°æŽ¢ç´¢èˆ‡èŠå¤©ï¼›é¸ç”¨é€²éšŽæ¨¡å¼å‰‡å¯ä»¥ä½¿ç”¨æ›´å¤šåŠŸèƒ½ã€‚"> - <combo_box.item label="基本" name="Basic"/> - <combo_box.item label="進階" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> 開始地點: </text> <combo_box name="start_location_combo"> <combo_box.item label="我上一次ä½ç½®" name="MyLastLocation"/> <combo_box.item label="我的家" name="MyHome"/> - <combo_box.item label="< 請輸入地å€å稱 >" name="Typeregionname"/> + <combo_box.item label="<請輸入地å€å稱>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - 註冊 + <layout_panel name="links_login_panel"> + <text name="login_help"> + 登入時需è¦å¹«åŠ©ï¼Ÿ </text> <text name="forgot_password_text"> å¿˜è¨˜ä½ çš„ä½¿ç”¨è€…å稱或密碼? </text> - <text name="login_help"> - 登入時需è¦å¹«åŠ©ï¼Ÿ + <button label="登入" name="connect_btn"/> + <check_box label="記ä½å¯†ç¢¼ï¼š" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + å»ºç«‹ä½ çš„å¸³è™Ÿ </text> + <button label="ç¾åœ¨å°±é–‹å§‹" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_main_inventory.xml b/indra/newview/skins/default/xui/zh/panel_main_inventory.xml index 53ecf3eb19..0ad3d8506d 100644 --- a/indra/newview/skins/default/xui/zh/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/zh/panel_main_inventory.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="事物" name="main inventory panel"> <panel.string name="ItemcountFetching"> - Fetching [ITEM_COUNT] Items... [FILTER] + æ£åœ¨æ“·å– [ITEM_COUNT] å€‹ç‰©é …â€¦ [FILTER] </panel.string> <panel.string name="ItemcountCompleted"> [ITEM_COUNT] ç‰©å“ [FILTER] diff --git a/indra/newview/skins/default/xui/zh/panel_me.xml b/indra/newview/skins/default/xui/zh/panel_me.xml index a236dfc17a..aad1348e46 100644 --- a/indra/newview/skins/default/xui/zh/panel_me.xml +++ b/indra/newview/skins/default/xui/zh/panel_me.xml @@ -1,7 +1,4 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="我的檔案" name="panel_me"> - <tab_container name="tabs"> - <panel label="我的檔案" name="panel_profile"/> - <panel label="我的精é¸åœ°é»ž" name="panel_picks"/> - </tab_container> +<panel label="我的個人檔案" name="panel_me"> + <panel label="我的精é¸åœ°é»ž" name="panel_picks"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml b/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml index 321c003acd..0c11befcf5 100644 --- a/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml +++ b/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="一般" name="Media Settings General"> +<panel label="基本è¨å®š" name="Media Settings General"> <text name="home_label"> 首é : </text> <text name="home_fails_whitelist_label"> - (This page does not pass the specified whitelist) + (這é 颿œªé€šéŽæ‰€æŒ‡å®šçš„è¨±å¯æ¸…單) </text> - <line_editor name="home_url" tool_tip="The home page for this media source"/> + <line_editor name="home_url" tool_tip="這個媒體來æºçš„首é "/> <text name="preview_label"> é 覽 </text> <text name="current_url_label"> ç›®å‰é é¢ï¼š </text> - <text name="current_url" tool_tip="The current page for this media source" value=""/> + <text name="current_url" tool_tip="這個媒體來æºç›®å‰çš„é é¢" value=""/> <button label="é‡è¨" name="current_url_reset_btn"/> - <check_box initial_value="false" label="Auto Loop" name="auto_loop"/> - <check_box initial_value="false" label="First Click Interacts" name="first_click_interact"/> + <check_box initial_value="false" label="è‡ªå‹•é€£çºŒæ’æ”¾" name="auto_loop"/> + <check_box initial_value="false" label="第一次點擊將進行互動" name="first_click_interact"/> <check_box initial_value="false" label="自動縮放" name="auto_zoom"/> <check_box initial_value="false" label="è‡ªå‹•æ’æ”¾åª’é«”" name="auto_play"/> <text name="media_setting_note"> - Note: Residents can override this setting + 注æ„:居民å¯ä»¥å¦å®šé€™é …è¨å®š </text> - <check_box initial_value="false" label="Auto Scale Media on Face of Object" name="auto_scale"/> + <check_box initial_value="false" label="物件臉部媒體自動調整比例" name="auto_scale"/> <text name="size_label"> 尺寸: </text> diff --git a/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml index 173edc76f6..4a1eaef3a1 100644 --- a/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml +++ b/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml @@ -12,7 +12,7 @@ </combo_item> </combo_box> <text name="owner_label"> - æ“æœ‰è€… + 所有人 </text> <check_box initial_value="false" label="å…許導航與互動" name="perms_owner_interact"/> <check_box initial_value="false" label="顯示控制列" name="perms_owner_control"/> diff --git a/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml b/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml index aaaf6bfb94..da84d6fe02 100644 --- a/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml +++ b/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Security" name="Media Settings Security"> - <check_box initial_value="false" label="Only Allow Access to Specified URL patterns" name="whitelist_enable"/> +<panel label="安全" name="Media Settings Security"> + <check_box initial_value="false" label="åªå…許進入符åˆç‰¹å®šå½¢æ…‹çš„ URL 目標" name="whitelist_enable"/> <text name="home_url_fails_some_items_in_whitelist"> - Entries that the home page fails against are marked: + 被首é è¦–ç‚ºå‡ºéŒ¯çš„ç‰©é …å·²æ¨™ç¤ºï¼š </text> <button label="æ·»åŠ " name="whitelist_add"/> <button label="刪除" name="whitelist_del"/> <text name="home_url_fails_whitelist"> - Warning: the home page specified in the General tab fails to pass this whitelist. It has been disabled until a valid entry has been added. + è¦å‘Šï¼šåœ¨åŸºæœ¬è³‡æ–™é 籤裡指定的首é ,未能通éŽé€™ä¸€è¨±å¯æ¸…單。 它已被åœç”¨ï¼Œè«‹è¨å®šæœ‰æ•ˆçš„資料。 </text> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_my_profile.xml b/indra/newview/skins/default/xui/zh/panel_my_profile.xml deleted file mode 100644 index 79817d7be9..0000000000 --- a/indra/newview/skins/default/xui/zh/panel_my_profile.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="檔案" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=en - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=en - </string> - <string name="my_account_link_url" value="http://secondlife.com/account"/> - <string name="no_partner_text" value="ç„¡"/> - <string name="no_group_text" value="ç„¡"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="scroll_content_panel"> - <panel name="second_life_image_panel"> - <text name="display_name_descr_text"> - User name - </text> - <text name="name_descr_text"> - 顯示å稱 - </text> - <button label="檔案" name="see_profile_btn" tool_tip="察看這ä½åŒ–身的檔案"/> - </panel> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml b/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml index 60a5767d09..7a11aa961b 100644 --- a/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml @@ -1,18 +1,23 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="navigation_bar"> - <panel name="navigation_panel"> - <pull_button name="back_btn" tool_tip="å‰å¾€ä¸Šä¸€å€‹ä½ç½®"/> - <pull_button name="forward_btn" tool_tip="å‰å¾€ä¸‹ä¸€å€‹ä½ç½®"/> - <button name="home_btn" tool_tip="瞬間傳é€åˆ°æˆ‘å®¶çš„ä½ç½®"/> - <location_input label="ä½ç½®" name="location_combo"/> - <search_combo_box label="æœå°‹" name="search_combo_box" tool_tip="æœå°‹"> - <combo_editor label="æœå°‹ [SECOND_LIFE]" name="search_combo_editor"/> - </search_combo_box> - </panel> - <favorites_bar name="favorite" tool_tip="拖曳傳é€åœ°æ¨™åˆ°æ¤ä»¥ä¾¿è®“ä½ åœ¨ç¬¬äºŒäººç”Ÿä¸èƒ½å¿«é€Ÿå‚³é€åˆ°ä½ 最愛的地點!!"> - <label name="favorites_bar_label" tool_tip="拖曳傳é€åœ°æ¨™åˆ°æ¤ä»¥ä¾¿è®“ä½ åœ¨ç¬¬äºŒäººç”Ÿä¸èƒ½å¿«é€Ÿå‚³é€åˆ°ä½ 最愛的地點!!"> - 最愛列 - </label> - <chevron_button name=">>" tool_tip="顯示更多我的最愛"/> - </favorites_bar> + <layout_stack name="nvp_stack"> + <layout_panel name="navigation_layout_panel"> + <panel name="navigation_panel"> + <pull_button name="back_btn" tool_tip="å‰å¾€ä¸Šä¸€å€‹ä½ç½®"/> + <pull_button name="forward_btn" tool_tip="å‰å¾€ä¸‹ä¸€å€‹ä½ç½®"/> + <button name="home_btn" tool_tip="瞬間返回我的家"/> + <location_input label="ä½ç½®" name="location_combo"/> + </panel> + </layout_panel> + <layout_panel name="favorites_layout_panel"> + <favorites_bar name="favorite" tool_tip="拖曳傳é€åœ°æ¨™åˆ°æ¤ä»¥ä¾¿è®“ä½ åœ¨ç¬¬äºŒäººç”Ÿä¸èƒ½å¿«é€Ÿå‚³é€åˆ°ä½ 最愛的地點!!"> + <label name="favorites_bar_label" tool_tip="拖曳傳é€åœ°æ¨™åˆ°æ¤ä»¥ä¾¿è®“ä½ åœ¨ç¬¬äºŒäººç”Ÿä¸èƒ½å¿«é€Ÿå‚³é€åˆ°ä½ 最愛的地點!!"> + 最愛列 + </label> + <more_button name=">>" tool_tip="顯示更多我的最愛"> + 詳情 â–¼ + </more_button> + </favorites_bar> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_navmesh_rebake.xml b/indra/newview/skins/default/xui/zh/panel_navmesh_rebake.xml new file mode 100644 index 0000000000..bb52c13a11 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_navmesh_rebake.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_navmesh_rebake"> + <button label="釿–°ç”¢å‡ºåœ°å€" name="navmesh_btn" tool_tip="點按å³å¯é‡æ–°ç”¢å‡ºè©²åœ°å€çš„導航網é¢ã€‚"/> + <button label="æ£åœ¨è«‹æ±‚釿–°ç”¢å‡º" name="navmesh_btn_sending" tool_tip="æ£å‘伺æœå™¨ç™¼é€é‡æ–°ç”¢å‡ºè«‹æ±‚。"/> + <button label="åœ°å€æ£åœ¨é‡æ–°ç”¢å‡º" name="navmesh_btn_baking" tool_tip="åœ°å€æ£åœ¨é‡æ–°ç”¢å‡ºã€‚ 完æˆå¾Œï¼Œé€™å€‹æŒ‰éˆ•將會消失。"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_nearby_chat.xml b/indra/newview/skins/default/xui/zh/panel_nearby_chat.xml new file mode 100644 index 0000000000..fc52168bb7 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_nearby_chat.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="nearby_chat"> + <layout_stack name="stack"> + <layout_panel name="translate_chat_checkbox_lp"> + <check_box label="ç¿»è¯èŠå¤©å…§å®¹" name="translate_chat_checkbox"/> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml index 3cabfcfaba..9489113d09 100644 --- a/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="chat_bar"> - <line_editor label="點擊æ¤è™•é–‹å§‹èŠå¤©ã€‚" name="chat_box" tool_tip="按下 Enter éµä¾†èªªæˆ–按下 Ctrl+Enter 來喊å«"/> +<panel name="nearby_chat"> + <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/zh/panel_nearby_media.xml b/indra/newview/skins/default/xui/zh/panel_nearby_media.xml index 6a4b5fcf35..c11a7a088b 100644 --- a/indra/newview/skins/default/xui/zh/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/zh/panel_nearby_media.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="nearby_media"> <string name="media_item_count_format"> - (%ld media items) + (%ld é …åª’é«”ç‰©ä»¶ï¼‰ </string> <string name="empty_item_text"> - <empty> + <空白> </string> <string name="parcel_media_name"> 地段串æµåª’é«” @@ -18,8 +18,8 @@ <panel name="minimized_controls"> <button label="å…¨éƒ¨åœæ¢" name="all_nearby_media_disable_btn" tool_tip="關閉附近全部的媒體"/> <button label="全部開始" name="all_nearby_media_enable_btn" tool_tip="開啟附近全部的媒體"/> - <button name="open_prefs_btn" tool_tip="Bring up media prefs"/> - <button label="更多 >>" label_selected="<< æ›´å°‘" name="more_btn" tool_tip="進階控制"/> + <button name="open_prefs_btn" tool_tip="打開媒體å好è¨å®š"/> + <button label="細節>>" label_selected="<<基本" name="more_btn" tool_tip="進階控制"/> </panel> <panel name="nearby_media_panel"> <text name="nearby_media_title"> @@ -35,9 +35,9 @@ <combo_box.item label="在其他化身身上" name="OnOthers"/> </combo_box> <scroll_list name="media_list"> - <scroll_list.columns label="Proximity" name="media_proximity"/> - <scroll_list.columns label="Visible" name="media_visibility"/> - <scroll_list.columns label="Class" name="media_class"/> + <scroll_list.columns label="é„°è¿‘" name="media_proximity"/> + <scroll_list.columns label="å¯çœ‹åˆ°" name="media_visibility"/> + <scroll_list.columns label="類型" name="media_class"/> <scroll_list.columns label="å稱" name="media_name"/> <scroll_list.columns label="除錯" name="media_debug"/> </scroll_list> @@ -59,10 +59,10 @@ <button name="mute_btn" tool_tip="éœéŸ³æ‰€é¸æ“‡çš„åª’é«”éŸ³é »"/> </layout_panel> <layout_panel name="zoom"> - <button name="zoom_btn" tool_tip="Zoom into selected media"/> + <button name="zoom_btn" tool_tip="以所é¸åª’體為ä¸å¿ƒæ”¾å¤§"/> </layout_panel> <layout_panel name="unzoom"> - <button name="unzoom_btn" tool_tip="Zoom back from selected media"/> + <button name="unzoom_btn" tool_tip="縮å°é 離所é¸åª’é«”"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_notes.xml b/indra/newview/skins/default/xui/zh/panel_notes.xml deleted file mode 100644 index 875c6bb328..0000000000 --- a/indra/newview/skins/default/xui/zh/panel_notes.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Notes & Privacy" name="panel_notes"> - <layout_stack name="layout"> - <layout_panel name="notes_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <text name="status_message" value="My private notes:"/> - <text name="status_message2" value="å…許這個人å¯ä»¥ï¼š"/> - <check_box label="看到我上線狀態" name="status_check"/> - <check_box label="在地圖上看見我" name="map_check"/> - <check_box label="邊輯,刪除或å–下我的物件" name="objects_check"/> - </panel> - </scroll_container> - </layout_panel> - <layout_panel name="notes_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="åŠ ç‚ºæœ‹å‹" name="add_friend" tool_tip="å‘這個居民æå‡ºäº¤å‹é‚€è«‹"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="é–‹å•Ÿå³æ™‚è¨Šæ¯æœƒè©±"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="通話" name="call" tool_tip="與這ä½å±…民通話"/> - </layout_panel> - <layout_panel name="show_on_map_btn_lp"> - <button label="地圖" name="show_on_map_btn" tool_tip="在地圖上顯示這個居民"/> - </layout_panel> - <layout_panel name="teleport_btn_lp"> - <button label="瞬間傳é€" name="teleport" tool_tip="發給瞬間傳é€è«‹æ±‚"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml new file mode 100644 index 0000000000..8de0bb0e4d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<outbox_inventory_panel name="inventory_outbox" tool_tip="å°‡ç‰©é …æ‹–æ›³ä¸¦ç½®æ”¾åˆ°é€™è£¡ï¼Œæº–å‚™åœ¨ä½ çš„å•†åº—å‡ºå”®"/> diff --git a/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml b/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml index 263106d13a..a698da0ab1 100644 --- a/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml @@ -5,7 +5,7 @@ <string name="unsaved_changes" value="變更未儲å˜"/> <string name="now_editing" value="ç¾åœ¨ç·¨è¼¯ä¸"/> <panel.string name="not_available"> - (N\A) + (ä¸é©ç”¨ï¼‰ </panel.string> <panel.string name="unknown"> (未知) @@ -15,7 +15,7 @@ <string name="Filter.Objects" value="物件"/> <string name="Filter.Clothing" value="æœè£"/> <string name="Filter.Bodyparts" value="身體部ä½"/> - <string name="replace_body_part" value="點擊以å–ä»£ä½ ç¾å˜çš„體形"/> + <string name="replace_body_part" value="點按以å–ä»£ä½ ç¾å˜çš„體形"/> <text name="title" value="ç·¨è¼¯è£æ‰®"/> <panel name="header_panel"> <panel name="outfit_name_and_status"> @@ -39,10 +39,10 @@ </layout_panel> </layout_stack> <panel name="no_add_wearables_button_bar"> - <button name="shop_btn_1" tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it"/> + <button name="shop_btn_1" tool_tip="å‰å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集。 ä½ ä¹Ÿå¯é¸æ“‡ä½ ç©¿è‘—ä¸çš„一個物件,å†é»žæŒ‰é€™è£¡å¯Ÿçœ‹å…¶ä»–åŒé¡žç‰©ä»¶ã€‚"/> </panel> <panel name="add_wearables_button_bar"> - <button name="shop_btn_2" tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it"/> + <button name="shop_btn_2" tool_tip="å‰å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集。 ä½ ä¹Ÿå¯é¸æ“‡ä½ ç©¿è‘—ä¸çš„一個物件,å†é»žæŒ‰é€™è£¡å¯Ÿçœ‹å…¶ä»–åŒé¡žç‰©ä»¶ã€‚"/> </panel> <panel name="save_revert_button_bar"> <layout_stack name="button_bar_ls"> @@ -50,7 +50,7 @@ <button label="儲å˜" name="save_btn"/> </layout_panel> <layout_panel name="revert_btn_lp"> - <button label="復原變更" name="revert_btn" tool_tip="Revert to last saved version"/> + <button label="復原變更" name="revert_btn" tool_tip="æ¢å¾©ä¸Šä¸€å€‹å·²å„²å˜ç‰ˆæœ¬"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml index d9718d8294..8dd93543c0 100644 --- a/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml @@ -4,19 +4,19 @@ ç©¿ä¸Šæ‰€é¸æ“‡çš„è£æ‰® </panel.string> <panel.string name="wear_items_tooltip"> - Wear selected items + ç©¿ä¸Šæ‰€é¸æ“‡çš„物件 </panel.string> <tab_container name="appearance_tabs"> <panel label="æˆ‘çš„è£æ‰®" name="outfitslist_tab"/> - <panel label="WEARING" name="cof_tab"/> + <panel label="ç›®å‰ç©¿è‘—" name="cof_tab"/> </tab_container> <panel name="bottom_panel"> <layout_stack name="bottom_panel_ls"> <layout_panel name="save_btn_lp"> - <button label="å¦å˜" name="save_btn"/> + <button label="å¦å˜ç‚º" name="save_btn"/> </layout_panel> <layout_panel name="wear_btn_lp"> - <button label="Wear" name="wear_btn"/> + <button label="穿上" name="wear_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_list.xml b/indra/newview/skins/default/xui/zh/panel_outfits_list.xml index a4b041469b..cfb0180f9c 100644 --- a/indra/newview/skins/default/xui/zh/panel_outfits_list.xml +++ b/indra/newview/skins/default/xui/zh/panel_outfits_list.xml @@ -1,5 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Outfits"> + <accordion name="outfits_accordion"> + <no_matched_tabs_text name="no_matched_outfits_msg" value="找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試 [secondlife:///app/search/places/ æœå°‹]。"/> + <no_visible_tabs_text name="no_outfits_msg" value="ä½ é‚„æ²’æœ‰ä»»ä½•è£æ‰®ã€‚ 請試試[secondlife:///app/search/all/ æœå°‹]"/> + </accordion> <panel name="bottom_panel"> <menu_button name="options_gear_btn" tool_tip="顯示é¡å¤–é¸é …"/> <button name="trash_btn" tool_tip="åˆªé™¤æ‰€é¸æ“‡çš„è£æ‰®"/> diff --git a/indra/newview/skins/default/xui/zh/panel_people.xml b/indra/newview/skins/default/xui/zh/panel_people.xml index 9c265622fa..59ea7b70e2 100644 --- a/indra/newview/skins/default/xui/zh/panel_people.xml +++ b/indra/newview/skins/default/xui/zh/panel_people.xml @@ -1,23 +1,23 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <!-- Side tray panel --> <panel label="人群" name="people_panel"> - <string name="no_recent_people" value="No recent people. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]."/> - <string name="no_filtered_recent_people" value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]."/> - <string name="no_one_near" value="No one nearby. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]."/> - <string name="no_one_filtered_near" value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]."/> + <string name="no_recent_people" value="沒有最近的人。 想找人見é¢èŠå¤©ï¼Ÿ 請試試[secondlife:///app/search/people æœå°‹]或[secondlife:///app/worldmap 世界地圖]。"/> + <string name="no_filtered_recent_people" value="找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試[secondlife:///app/search/people/[SEARCH_TERM] æœå°‹]。"/> + <string name="no_one_near" value="附近無人。 想找人見é¢èŠå¤©ï¼Ÿ 請試試[secondlife:///app/search/people æœå°‹]或[secondlife:///app/worldmap 世界地圖]。"/> + <string name="no_one_filtered_near" value="找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試[secondlife:///app/search/people/[SEARCH_TERM] æœå°‹]。"/> <string name="no_friends_online" value="無朋å‹ä¸Šç·š"/> <string name="no_friends" value="無朋å‹"/> <string name="no_friends_msg"> - Find friends using [secondlife:///app/search/people Search] or right-click on a Resident to add them as a friend. -Looking for people to hang out with? Try the [secondlife:///app/worldmap World Map]. + 用 [secondlife:///app/search/people æœå°‹] 找朋å‹ï¼Œæˆ–鏿“‡ä¸€ä½å±…æ°‘ï¼Œå†æŒ‰å³éµå°‡ä»–åŠ ç‚ºæœ‹å‹ã€‚ +想找人見é¢èŠå¤©ï¼Ÿ 請試一試 [secondlife:///app/worldmap 世界地圖]。 </string> <string name="no_filtered_friends_msg"> - Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]. + 找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試[secondlife:///app/search/people/[SEARCH_TERM] æœå°‹]。 </string> <string name="people_filter_label" value="äººå“¡éŽæ¿¾å™¨"/> <string name="groups_filter_label" value="ç¾¤çµ„éŽæ¿¾å™¨"/> - <string name="no_filtered_groups_msg" value="沒有發ç¾ä½ è¦æ‰¾çš„嗎?何ä¸è©¦è©¦ [secondlife:///app/search/groups/[SEARCH_TERM] æœå°‹]。"/> - <string name="no_groups_msg" value="æƒ³æ‰¾å°‹ç¾¤çµ„åŠ å…¥å—Žï¼Ÿä½•ä¸è©¦è©¦ [secondlife:///app/search/groups æœå°‹]。"/> + <string name="no_filtered_groups_msg" value="找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試[secondlife:///app/search/groups/[SEARCH_TERM] æœå°‹]。"/> + <string name="no_groups_msg" value="è¦å°‹æ‰¾ç¾¤çµ„è€ƒæ…®åŠ å…¥å—Žï¼Ÿ 請試試[secondlife:///app/search/groups æœå°‹]。"/> <string name="MiniMapToolTipMsg" value="[REGION](雙擊以開啟地圖,按下 shift 鵿‹–曳來平移)"/> <string name="AltMiniMapToolTipMsg" value="[REGION](雙擊以瞬間傳é€ï¼ŒæŒ‰ä¸‹ shift 鵿‹–曳來平移)"/> <filter_editor label="éŽæ¿¾å™¨" name="filter_input"/> @@ -25,7 +25,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M <panel label="附近" name="nearby_panel"> <panel label="bottom_panel" name="bottom_panel"> <menu_button name="nearby_view_sort_btn" tool_tip="é¸é …"/> - <button name="add_friend_btn" tool_tip="æ·»åŠ å·²é¸æ“‡çš„居民到Adä½ çš„æœ‹å‹æ¸…å–®"/> + <button name="add_friend_btn" tool_tip="æ·»åŠ æ‰€é¸çš„å±…æ°‘åˆ°ä½ çš„æœ‹å‹æ¸…å–®"/> </panel> </panel> <panel label="我的朋å‹" name="friends_panel"> @@ -39,7 +39,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M <menu_button name="friends_viewsort_btn" tool_tip="顯示é¡å¤–é¸é …"/> </layout_panel> <layout_panel name="add_btn_panel"> - <button name="add_btn" tool_tip="å‘å±…æ°‘æå‡ºåŠ ç‚ºå¥½å‹é‚€è«‹"/> + <button name="add_btn" tool_tip="å‘居民發出交å‹é‚€è«‹"/> </layout_panel> <layout_panel name="trash_btn_panel"> <dnd_button name="del_btn" tool_tip="ç”±ä½ çš„æœ‹å‹æ¸…å–®ç§»é™¤æ‰€é¸æ“‡çš„人"/> @@ -66,17 +66,17 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M <layout_panel name="view_profile_btn_lp"> <button label="檔案" name="view_profile_btn" tool_tip="顯示圖片ã€ç¾¤çµ„與其他居民資訊"/> </layout_panel> - <layout_panel name="chat_btn_lp"> + <layout_panel name="im_btn_lp"> <button label="IM" name="im_btn" tool_tip="é–‹å•Ÿå³æ™‚è¨Šæ¯æœƒè©±"/> </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="通話" name="call_btn" tool_tip="與æ¤å±…民進行通話"/> + <layout_panel name="call_btn_lp"> + <button label="通話" name="call_btn" tool_tip="和這ä½å±…民通話"/> </layout_panel> - <layout_panel name="chat_btn_lp"> + <layout_panel name="share_btn_lp"> <button label="分享" name="share_btn" tool_tip="分享一個收ç´å€ç‰©å“"/> </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="瞬間傳é€" name="teleport_btn" tool_tip="發給瞬間傳é€è«‹æ±‚"/> + <layout_panel name="teleport_btn_lp"> + <button label="瞬間傳é€" name="teleport_btn" tool_tip="發出瞬間傳é€é‚€è«‹"/> </layout_panel> </layout_stack> <layout_stack name="bottom_bar_ls1"> diff --git a/indra/newview/skins/default/xui/zh/panel_picks.xml b/indra/newview/skins/default/xui/zh/panel_picks.xml index 15733b71b0..98d36eaea0 100644 --- a/indra/newview/skins/default/xui/zh/panel_picks.xml +++ b/indra/newview/skins/default/xui/zh/panel_picks.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="ç²¾é¸åœ°é»ž" name="panel_picks"> <string name="no_picks" value="ç„¡ç²¾é¸åœ°é»ž"/> - <string name="no_classifieds" value="No Classifieds"/> + <string name="no_classifieds" value="ç¦æ¢å€‹äººå»£å‘Š"/> <accordion name="accordion"> <accordion_tab name="tab_picks" title="ç²¾é¸åœ°é»ž"/> - <accordion_tab name="tab_classifieds" title="Classifieds"/> + <accordion_tab name="tab_classifieds" title="個人廣告"/> </accordion> <panel label="bottom_panel" name="edit_panel"> <layout_stack name="edit_panel_ls"> diff --git a/indra/newview/skins/default/xui/zh/panel_place_profile.xml b/indra/newview/skins/default/xui/zh/panel_place_profile.xml index 1772b65434..a364f732d8 100644 --- a/indra/newview/skins/default/xui/zh/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/zh/panel_place_profile.xml @@ -1,20 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="place_profile"> - <string name="on" value="On"/> - <string name="off" value="Off"/> - <string name="anyone" value="Anyone"/> - <string name="available" value="available"/> + <string name="on" value="啟動"/> + <string name="off" value="關閉"/> + <string name="anyone" value="任何人"/> + <string name="available" value="å¯ç”¨çš„"/> <string name="allocated" value="已分é…"/> <string name="title_place" value="地點檔案"/> <string name="title_teleport_history" value="çž¬é–“å‚³é€æ·å²ç´€éŒ„"/> - <string name="not_available" value="(N\A)"/> + <string name="not_available" value="(ä¸é©ç”¨ï¼‰"/> <string name="unknown" value="(未知)"/> <string name="public" value="(公開)"/> <string name="none_text" value="(無)"/> <string name="sale_pending_text" value="(擱置銷售)"/> - <string name="group_owned_text" value="ï¼ˆç¾¤çµ„æ‰€æ“æœ‰ï¼‰"/> + <string name="group_owned_text" value="ï¼ˆç”±ç¾¤çµ„æ‰€æ“æœ‰ï¼‰"/> <string name="price_text" value="L$"/> - <string name="area_text" value="m²"/> + <string name="area_text" value="平方公尺"/> <string name="all_residents_text" value="全部居民"/> <string name="group_text" value="群組"/> <string name="can_resell"> @@ -33,10 +33,10 @@ åœ°é»žè³‡è¨Šå› ç„¡ä¼ºæœå™¨æ›´æ–°æ•…無法æä¾›ã€‚ </string> <string name="server_error_text"> - Information about this location is unavailable at this time, please try again later. + ç›®å‰ç„¡æ³•å–å¾—æ¤ä½ç½®çš„訊æ¯ï¼Œè«‹ç¨å€™å†è©¦ã€‚ </string> <string name="server_forbidden_text"> - Information about this location is unavailable due to access restrictions. Please check your permissions with the parcel owner. + 權é™ä¸è¶³ï¼Œç„¡æ³•å–å¾—æ¤ä½ç½®çš„資訊。 è«‹å‘åœ°æ®µæ‰€æœ‰äººæŸ¥è©¢ä½ çš„æ¬Šé™ã€‚ </string> <string name="acquired_date"> [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] @@ -48,7 +48,7 @@ <text name="region_title" value="SampleRegion"/> <text name="parcel_title" value="SampleParcel, Name Long (145, 228, 26)"/> <expandable_text name="description" value="Du waltz die spritz"/> - <text name="owner_label" value="æ“æœ‰è€…:"/> + <text name="owner_label" value="所有人:"/> <text name="owner_value" value="Alex Superduperlongenamenton"/> <text name="maturity_value" value="未知"/> <accordion name="advanced_info_accordion"> @@ -57,18 +57,20 @@ <text name="rating_label" value="分級:"/> <text name="rating_value" value="未知"/> <text name="voice_label" value="語音:"/> - <text name="voice_value" value="On"/> + <text name="voice_value" value="啟動"/> <text name="fly_label" value="飛行:"/> - <text name="fly_value" value="On"/> + <text name="fly_value" value="啟動"/> <text name="push_label" value="推撞:"/> - <text name="push_value" value="Off"/> + <text name="push_value" value="關閉"/> <text name="build_label" value="å»ºé€ ï¼š"/> - <text name="build_value" value="On"/> + <text name="build_value" value="啟動"/> <text name="scripts_label" value="腳本:"/> - <text name="scripts_value" value="On"/> + <text name="scripts_value" value="啟動"/> <text name="damage_label" value="傷害:"/> - <text name="damage_value" value="Off"/> - <button label="關於土地" name="about_land_btn"/> + <text name="damage_value" value="關閉"/> + <text name="see_avatars_label" value="察看化身:"/> + <text name="see_avatars_value" value="關閉"/> + <button label="土地資料" name="about_land_btn"/> </panel> </accordion_tab> <accordion_tab name="region_information_tab" title="地å€"> @@ -79,21 +81,21 @@ <text name="region_type" value="Moose"/> <text name="region_rating_label" value="分級:"/> <text name="region_rating" value="完全æˆäºº"/> - <text name="region_owner_label" value="æ“æœ‰è€…:"/> + <text name="region_owner_label" value="所有人:"/> <text name="region_owner" value="moose Van Moose extra long name moose"/> <text name="region_group_label" value="群組:"/> <text name="region_group"> The Mighty Moose of mooseville soundvillemoose </text> - <button label="åœ°å€ / é ˜åœ°" name="region_info_btn"/> + <button label="地å€/é ˜åœ°" name="region_info_btn"/> </panel> </accordion_tab> <accordion_tab name="estate_information_tab" title="é ˜åœ°"> <panel name="estate_information_panel"> <text name="estate_name_label" value="é ˜åœ°ï¼š"/> <text name="estate_rating_label" value="分級:"/> - <text name="estate_owner_label" value="æ“æœ‰è€…:"/> - <text name="estate_owner" value="Testing owner name length with long name"/> + <text name="estate_owner_label" value="所有人:"/> + <text name="estate_owner" value="æ£åœ¨æ¸¬è©¦å稱很長很長很長的所有人å稱…"/> <text name="covenant_label" value="契約:"/> </panel> </accordion_tab> diff --git a/indra/newview/skins/default/xui/zh/panel_places.xml b/indra/newview/skins/default/xui/zh/panel_places.xml index 8ac464271e..08cae610f6 100644 --- a/indra/newview/skins/default/xui/zh/panel_places.xml +++ b/indra/newview/skins/default/xui/zh/panel_places.xml @@ -8,7 +8,7 @@ <layout_panel name="lp1"> <layout_stack name="bottom_bar_ls1"> <layout_panel name="teleport_btn_lp"> - <button label="瞬間傳é€" name="teleport_btn" tool_tip="瞬間傳é€åˆ°æ‰€é¸æ“‡çš„å€åŸŸ"/> + <button label="瞬間傳é€" name="teleport_btn" tool_tip="瞬間傳é€åˆ°æ‰€é¸çš„å€åŸŸ"/> </layout_panel> <layout_panel name="chat_btn_lp"> <button label="地圖" name="map_btn" tool_tip="åœ¨ä¸–ç•Œåœ°åœ–ä¸Šé¡¯ç¤ºç›¸å°æ‡‰çš„å€åŸŸ"/> @@ -24,7 +24,7 @@ <menu_button name="overflow_btn" tool_tip="顯示é¡å¤–é¸é …"/> </layout_panel> </layout_stack> - <layout_stack name="bottom_bar_ls3"> + <layout_stack name="bottom_bar_profile_ls"> <layout_panel name="profile_btn_lp"> <button label="檔案" name="profile_btn" tool_tip="顯示地點檔案"/> </layout_panel> diff --git a/indra/newview/skins/default/xui/zh/floater_postcard.xml b/indra/newview/skins/default/xui/zh/panel_postcard_message.xml index 6f6b75f468..563c4fca3c 100644 --- a/indra/newview/skins/default/xui/zh/floater_postcard.xml +++ b/indra/newview/skins/default/xui/zh/panel_postcard_message.xml @@ -1,33 +1,21 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="EMAIL SNAPSHOT"> - <floater.string name="default_subject"> - Postcard from [SECOND_LIFE]. - </floater.string> - <floater.string name="default_message"> - Check this out! - </floater.string> - <floater.string name="upload_message"> - 傳é€ä¸... - </floater.string> +<panel name="panel_postcard_message"> <text name="to_label"> - 收件人電å郵件地å€ï¼š - </text> - <text name="from_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"/> -</floater> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_postcard_settings.xml b/indra/newview/skins/default/xui/zh/panel_postcard_settings.xml new file mode 100644 index 0000000000..900ab3a54e --- /dev/null +++ b/indra/newview/skins/default/xui/zh/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/zh/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml index c5dce10d63..3a7d79e04b 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml @@ -3,6 +3,19 @@ <panel.string name="aspect_ratio_text"> [NUM]:[DEN] </panel.string> + <text name="Cache:"> + å¿«å–: + </text> + <spinner label="å¿«å–å¤§å° (64 - 9984MB)" name="cachesizespinner"/> + <text name="text_box5"> + MB + </text> + <button label="清除快å–" label_selected="清除快å–" name="clear_cache"/> + <text name="Cache location"> + å¿«å–ä½ç½®ï¼š + </text> + <button label="ç€è¦½" label_selected="ç€è¦½" name="set_cache"/> + <button label="é è¨ä½ç½®" label_selected="é è¨ä½ç½®" name="default_cache_location"/> <text name="UI Size:"> 使用者界é¢å°ºå¯¸ï¼š </text> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml b/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml index 738c77fd08..cf2f81d313 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml @@ -27,31 +27,9 @@ </text> <check_box label="群組èŠå¤©" name="EnableGroupChatPopups" tool_tip="當群組èŠå¤©è¨Šæ¯æŠµé”時查看çªé¡¯å¼è¦–窗"/> <check_box label="IM èŠå¤©" name="EnableIMChatPopups" tool_tip="ç•¶å³æ™‚è¨Šæ¯æŠµé”æ™‚查看çªé¡¯å¼è¦–窗"/> - <spinner label="Nearby chat toasts life time:" name="nearby_toasts_lifetime"/> - <spinner label="Nearby chat toasts fading time:" 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 (Danish)" name="Danish"/> - <combo_box.item label="Deutsch (German)" name="German"/> - <combo_box.item label="Español (Spanish)" name="Spanish"/> - <combo_box.item label="Français (French)" name="French"/> - <combo_box.item label="Italiano (Italian)" name="Italian"/> - <combo_box.item label="Magyar (Hungarian)" name="Hungarian"/> - <combo_box.item label="Nederlands (Dutch)" name="Dutch"/> - <combo_box.item label="Polski (Polish)" name="Polish"/> - <combo_box.item label="Português (Portuguese)" name="Portugese"/> - <combo_box.item label="РуÑÑкий (Russian)" name="Russian"/> - <combo_box.item label="Türkçe (Turkish)" name="Turkish"/> - <combo_box.item label="УкраїнÑька (Ukrainian)" name="Ukrainian"/> - <combo_box.item label="䏿–‡ (æ£é«”) (Chinese)" name="Chinese"/> - <combo_box.item label="日本語 (Japanese)" name="Japanese"/> - <combo_box.item label="한êµì–´ (Korean)" name="Korean"/> - </combo_box> + <spinner label="附近èŠå¤©å…§å®¹æç¤ºæ¡†åœé§æ™‚間:" name="nearby_toasts_lifetime"/> + <spinner label="附近èŠå¤©å…§å®¹æç¤ºæ¡†æ¶ˆé€€æ™‚間:" name="nearby_toasts_fadingtime"/> + <button label="ç¿»è¯â€¦" name="ok_btn"/> + <button label="自動å–代…" name="autoreplace_showgui"/> + <button label="æ‹¼å—æª¢æŸ¥â€¦" name="spellcheck_showgui"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml b/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml index 8d92eadd20..6af4bb8970 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml @@ -3,12 +3,12 @@ <text name="effects_color_textbox"> æˆ‘çš„æ•ˆæžœï¼ˆé¸æ“‡æŒ‡æ¨™ï¼‰ï¼š </text> - <color_swatch name="effect_color_swatch" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/> + <color_swatch name="effect_color_swatch" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/> <text name="font_colors"> èŠå¤©å—åž‹é¡è‰²ï¼š </text> <text name="text_box1"> - 自己 + 我自己 </text> <text name="text_box2"> 其他人 @@ -22,11 +22,14 @@ <text name="text_box5"> 錯誤 </text> + <text name="text_box10"> + 直接 + </text> <text name="text_box7"> - æ“æœ‰è€… + 所有人 </text> <text name="text_box9"> - URLs + URL </text> <text name="bubble_chat"> å稱標籤背景色(亦會影響èŠå¤©æ³¡æ³¡ï¼‰ï¼š diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_general.xml b/indra/newview/skins/default/xui/zh/panel_preferences_general.xml index 6827fab6e6..7e67a0d02d 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_general.xml @@ -1,19 +1,22 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="一般" name="general_panel"> +<panel label="基本è¨å®š" name="general_panel"> <text name="language_textbox"> 語言: </text> <combo_box name="language_combobox"> <combo_box.item label="系統é è¨" name="System Default Language"/> - <combo_box.item label="English (英語)" name="English"/> - <combo_box.item label="Dansk (丹麥語) - Beta" name="Danish"/> - <combo_box.item label="Deutsch (德語) - Beta" name="Deutsch(German)"/> - <combo_box.item label="Español (西ç牙語) - Beta" name="Spanish"/> - <combo_box.item label="Français (法語) - Beta" name="French"/> - <combo_box.item label="Italiano (義大利語) - Beta" name="Italian"/> - <combo_box.item label="Polski (波è˜èªžï¼‰ - Beta" name="Polish"/> - <combo_box.item label="Português (葡è„牙語) - Beta" name="Portugese"/> - <combo_box.item label="日本語 (日語) - Beta" name="(Japanese)"/> + <combo_box.item label="英語" name="English"/> + <combo_box.item label="Dansk(丹麥語)- 試用版" name="Danish"/> + <combo_box.item label="Deutsch(德語)- 試用版" name="Deutsch(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="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="(Japanese)"/> + <combo_box.item label="æ£é«”䏿–‡ - 測試版" name="Traditional Chinese"/> </combo_box> <text name="language_textbox2"> ï¼ˆé ˆé‡æ–°å•Ÿå‹•) @@ -38,15 +41,15 @@ å稱標籤: </text> <radio_group name="Name_Tag_Preference"> - <radio_item label="Off" name="radio" value="0"/> - <radio_item label="On" name="radio2" value="1"/> + <radio_item label="關閉" name="radio" value="0"/> + <radio_item label="啟動" name="radio2" value="1"/> <radio_item label="ç°¡çŸé¡¯ç¤º" name="radio3" value="2"/> </radio_group> <check_box label="我的åå—" name="show_my_name_checkbox1"/> <check_box label="使用者å稱" name="show_slids" tool_tip="顯示使用者åç¨±ï¼Œå°±åƒ bobsmith123 這類的"/> - <check_box label="群組é 銜" name="show_all_title_checkbox1" tool_tip="顯示群組é éŠœï¼Œåƒæ˜¯ Officer 或æˆå“¡"/> + <check_box label="群組é 銜" name="show_all_title_checkbox1" tool_tip="顯示群組é 銜,如è·å“¡æˆ–æˆå“¡"/> <check_box label="高亮標示朋å‹" name="show_friends" tool_tip="é«˜äº®é¡¯ç¤ºä½ æœ‹å‹çš„å稱標籤"/> - <check_box label="察看顯示å稱" name="display_names_check" tool_tip="Check to use display names in chat, IM, name tags, etc."/> + <check_box label="察看顯示å稱" name="display_names_check" tool_tip="若勾é¸ï¼Œå°‡åœ¨èŠå¤©ã€IM å’Œå稱標籤ç‰è™•使用顯示å稱。"/> <text name="inworld_typing_rg_label"> æŒ‰ä¸‹å—æ¯éµï¼š </text> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml index 874fb6b218..3948a48992 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="圖形" name="Display panel"> +<panel label="顯åƒ" name="Display panel"> <text name="QualitySpeed"> å“質與速度: </text> @@ -27,8 +27,20 @@ </text> <check_box initial_value="true" label="æ¸…æ¾ˆé€æ˜Žçš„æ°´" name="TransparentWater"/> <check_box initial_value="true" label="å‡¹å‡¸æ˜ å°„èˆ‡å…‰æ¾¤æ•ˆæžœ" name="BumpShiny"/> + <check_box initial_value="true" label="本地光線" name="LocalLights"/> <check_box initial_value="true" label="基本著色" name="BasicShaders" tool_tip="關閉æ¤ä¸€é¸é …å¯èƒ½é¿å…部分顯示å¡é©…å‹•ç¨‹å¼ææ¯€ç•¶æ©Ÿ"/> <check_box initial_value="true" label="大氣著色" name="WindLightUseAtmosShaders"/> + <check_box initial_value="true" label="光線和陰影" name="UseLightShaders"/> + <check_box initial_value="true" label="環境光é®è”½" name="UseSSAO"/> + <check_box initial_value="true" label="景深" name="UseDoF"/> + <text name="shadows_label"> + 陰影: + </text> + <combo_box name="ShadowDetail"> + <combo_box.item label="ç„¡" name="0"/> + <combo_box.item label="æ—¥ / 月" name="1"/> + <combo_box.item label="æ—¥ / 月 + 投影物" name="2"/> + </combo_box> <text name="reflection_label"> æ°´æ–‡å射: </text> @@ -45,11 +57,11 @@ </text> <slider label="æç¹ªè·é›¢ï¼š" name="DrawDistance"/> <text name="DrawDistanceMeterText2"> - m + 公尺 </text> <slider label="æœ€å¤§ç²’åæ•ˆæžœæ•¸é‡ï¼š" name="MaxParticleCount"/> - <slider label="Max. # of non-impostor avatars:" name="MaxNumberAvatarDrawn"/> - <slider label="後製å“質:" name="RenderPostProcess"/> + <slider label="éžå‡å†’化身上é™ï¼š" name="MaxNumberAvatarDrawn"/> + <slider label="後處ç†å“質:" name="RenderPostProcess"/> <text name="MeshDetailText"> ç¶²é¢ç´°ç¯€ï¼š </text> @@ -81,10 +93,10 @@ 低 </text> <text name="AvatarRenderingText"> - Avatar Rendering: + 化身呈åƒï¼š </text> - <check_box initial_value="true" label="Avatar impostors" name="AvatarImpostors"/> - <check_box initial_value="true" label="Hardware skinning" name="AvatarVertexProgram"/> + <check_box initial_value="true" label="化身å‡å†’者" name="AvatarImpostors"/> + <check_box initial_value="true" label="硬體æ›è†š" name="AvatarVertexProgram"/> <check_box initial_value="true" label="化身衣æœ" name="AvatarCloth"/> <text name="TerrainDetailText"> 地形細節: diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_move.xml b/indra/newview/skins/default/xui/zh/panel_preferences_move.xml index ce176b1e3c..3a27477885 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_move.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_move.xml @@ -7,18 +7,33 @@ </text> <check_box label="å»ºé€ / 編輯" name="edit_camera_movement" tool_tip="ä½¿ç”¨é€²å…¥æˆ–é›¢é–‹ç·¨è¼¯æ¨¡å¼æ™‚自動調整æ”影機ä½ç½®åŠŸèƒ½"/> <check_box label="編輯外觀" name="appearance_camera_movement" tool_tip="ä½¿ç”¨ç·¨è¼¯æ¨¡å¼æ™‚自動調整æ”影機ä½ç½®åŠŸèƒ½"/> - <check_box initial_value="true" label="å´é‚Šæ¬„" name="appearance_sidebar_positioning" tool_tip="使用開啟å´é‚Šæ¬„時自動調整æ”影機ä½ç½®åŠŸèƒ½"/> + <text name="keyboard_lbl"> + éµç›¤ï¼š + </text> + <check_box label="總是使用方å‘éµç§»å‹•" name="arrow_keys_move_avatar_check"/> + <check_box label="連點按ä½å¾Œè·‘æ¥" name="tap_tap_hold_to_run"/> + <text name="mouse_lbl"> + æ»‘é¼ ï¼š + </text> <check_box label="將我顯示於第一人稱視角ä¸" name="first_person_avatar_visible"/> <text name=" Mouse Sensitivity"> ç¬¬ä¸€äººç¨±è¦–è§’æ»‘é¼ æ•æ„Ÿåº¦ï¼š </text> <check_box label="å轉" name="invert_mouse"/> - <check_box label="總是使用方å‘éµç§»å‹•" name="arrow_keys_move_avatar_check"/> - <check_box label="連點按ä½å¾Œè·‘æ¥" name="tap_tap_hold_to_run"/> - <check_box label="雙擊以:" name="double_click_chkbox"/> - <radio_group name="double_click_action"> - <radio_item label="瞬間傳é€" name="radio_teleport"/> - <radio_item label="自動導航駕駛" name="radio_autopilot"/> - </radio_group> + <text name="single_click_action_lbl"> + 在土地上點按一下: + </text> + <combo_box name="single_click_action_combo"> + <combo_box.item label="無動作" name="0"/> + <combo_box.item label="移動至點按的地點" name="1"/> + </combo_box> + <text name="double_click_action_lbl"> + 在土地上點按兩下: + </text> + <combo_box name="double_click_action_combo"> + <combo_box.item label="無動作" name="0"/> + <combo_box.item label="移動至點按的地點" name="1"/> + <combo_box.item label="瞬間傳é€è‡³é»žæŒ‰çš„地點" name="2"/> + </combo_box> <button label="å…¶ä»–è¨å‚™" name="joystick_setup_button"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml b/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml index efefb92df6..a607a7c33b 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml @@ -11,34 +11,17 @@ </text> <check_box label="è‡ªè¨‚åŸ " name="connection_port_enabled"/> <spinner label="åŸ è™Ÿï¼š" name="connection_port"/> - <text name="cache_size_label_l"> - å¿«å–尺寸 - </text> - <text name="text_box5"> - MB - </text> - <text name="Cache location"> - å¿«å–ä½ç½®ï¼š - </text> - <button label="ç€è¦½" label_selected="ç€è¦½" name="set_cache"/> - <button label="" label_selected="é‡è¨" name="reset_cache"/> <text name="Web:"> ç¶²é : </text> <radio_group name="use_external_browser"> - <radio_item label="使用我的網é ç€è¦½å™¨ï¼ˆä¾‹å¦‚ IE, Firefox, Safari)" name="external" tool_tip="Use the default system web browser for help, web links, etc. Not recommended if running full screen." value="1"/> - <radio_item label="使用內建網é ç€è¦½å™¨" name="internal" tool_tip="Use the built-in web browser for help, web links, etc. This browser opens as a new window inside [APP_NAME]." value=""/> + <radio_item label="使用我的網é ç€è¦½å™¨ï¼ˆä¾‹å¦‚ IE, Firefox, Safari)" name="external" tool_tip="使用系統é è¨çš„ç€è¦½å™¨ç€è¦½å¹«åŠ©ï¼Œé–‹å•Ÿç¶²é 。全螢幕模å¼ä¸‹ä¸å»ºè°é€™éº¼åšã€‚" value="1"/> + <radio_item label="使用內建網é ç€è¦½å™¨" name="internal" tool_tip="使用內建的ç€è¦½å™¨ç€è¦½å¹«åŠ©ï¼Œé–‹å•Ÿç¶²é 。該ç€è¦½å™¨å°‡é€éŽ [APP_NAME] 開啟新視窗。" value=""/> </radio_group> <check_box initial_value="true" label="啟用外掛" name="browser_plugins_enabled"/> <check_box initial_value="true" label="æŽ¥å— cookies" name="cookies_enabled"/> <check_box initial_value="true" label="啟用 Javascript" name="browser_javascript_enabled"/> <check_box initial_value="false" label="啟用媒體ç€è¦½çš„çªé¡¯å¼è¦–窗" name="media_popup_enabled"/> - <check_box initial_value="false" label="啟用網é 代ç†ä¼ºæœå™¨" name="web_proxy_enabled"/> - <text name="Proxy location"> - 代ç†ä¼ºæœå™¨ä½ç½®ï¼š - </text> - <line_editor name="web_proxy_editor" tool_tip="The name or IP address of the proxy you would like to use"/> - <spinner label="åŸ è™Ÿï¼š" name="web_proxy_port"/> <text name="Software updates:"> 軟體更新: </text> @@ -46,4 +29,8 @@ <combo_box.item label="自動安è£" name="Install_automatically"/> <combo_box.item label="手動下載åŠå®‰è£" name="Install_manual"/> </combo_box> + <text name="Proxy Settings:"> + 代ç†ä¼ºæœå™¨è¨å®šï¼š + </text> + <button label="調整代ç†ä¼ºæœå™¨è¨å®š" label_selected="ç€è¦½" name="set_proxy"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml b/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml index 3280b9357b..e57f08fd74 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="è²éŸ³" name="Preference Media panel"> <panel.string name="middle_mouse"> - Middle Mouse + æ»‘é¼ ä¸éµ </panel.string> <slider label="主音é‡" name="System Volume"/> <check_box initial_value="true" name="mute_when_minimized"/> @@ -18,7 +18,8 @@ <slider label="語音èŠå¤©" name="Voice Volume"/> <check_box label="已啟用" name="enable_voice_check"/> <check_box label="å…è¨±åª’é«”è‡ªå‹•æ’æ”¾" name="media_auto_play_btn" tool_tip="è‹¥ä½ æƒ³è¦ï¼Œå¯ä»¥å‹¾é¸é€™å€‹å…è¨±åª’é«”è‡ªå‹•æ’æ”¾" value="true"/> - <check_box label="æ’æ”¾é™„åŠ åˆ°å…¶ä»–åŒ–èº«èº«ä¸Šçš„åª’é«”" name="media_show_on_others_btn" tool_tip="Uncheck this to hide media attached to other avatars nearby" value="true"/> + <check_box label="æ’æ”¾é™„åŠ åˆ°å…¶ä»–åŒ–èº«èº«ä¸Šçš„åª’é«”" name="media_show_on_others_btn" tool_tip="若未勾é¸ï¼Œå°‡éš±è—附著於附近其他化身身上的媒體" value="true"/> + <check_box label="æ’æ”¾ä¾†è‡ªå§¿å‹¢çš„è²éŸ³" name="gesture_audio_play_btn" tool_tip="勾é¸å³å¯è½åˆ°ä¾†è‡ªå§¿å‹¢çš„è²éŸ³" value="true"/> <text name="voice_chat_settings"> 語音èŠå¤©è¨å®š </text> @@ -30,33 +31,10 @@ <radio_item label="化身ä½ç½®" name="1"/> </radio_group> <check_box label="èªªè©±æ™‚åŒæ¥ç§»å‹•化身嘴唇" name="enable_lip_sync"/> - <check_box label="Toggle speak on/off when I press:" name="push_to_talk_toggle_check" tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down."/> - <line_editor label="Push-to-Speak trigger" name="modifier_combo"/> + <check_box label="切æ›èªªè©± / éœéŸ³ï¼Œç•¶æˆ‘按下:" name="push_to_talk_toggle_check" tool_tip="åœ¨åˆ‡æ›æ¨¡å¼ä¸‹ï¼ŒæŒ‰ä¸‹å†æ”¾é–‹å•Ÿå‹•éµä¸€æ¬¡ï¼Œå³å¯æ‰“開或關閉麥克風。 ä¸åœ¨åˆ‡æ›ç‹€æ…‹æ™‚ï¼Œéº¥å…‹é¢¨åªæœ‰åœ¨å•Ÿå‹•éµè¢«æŒ‰ä¸‹æ™‚æ‰æœƒæ”¾é€ä½ çš„è²éŸ³ã€‚"/> + <line_editor label="「按下後說話ã€å•Ÿå‹•éµ" name="modifier_combo"/> <button label="è¨å®šæŒ‰éµ" name="set_voice_hotkey_button"/> <button name="set_voice_middlemouse_button" tool_tip="é‡è¨æ»‘é¼ ä¸éµæŒ‰éˆ•"/> <button label="輸入 / 輸出è¨å‚™" name="device_settings_btn"/> - <panel label="è¨å‚™è¨å®š" name="device_settings_panel"> - <panel.string name="default_text"> - é è¨ - </panel.string> - <panel.string name="default system device"> - é è¨ç³»çµ±è¨å‚™ - </panel.string> - <panel.string name="no device"> - ç„¡è¨å‚™ - </panel.string> - <text name="Input"> - 輸入 - </text> - <text name="My volume label"> - 我的音é‡ï¼š - </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Change the volume using this slider"/> - <text name="wait_text"> - è«‹ç¨å€™ - </text> - <text name="Output"> - 輸出 - </text> - </panel> + <panel label="è¨å‚™è¨å®š" name="device_settings_panel"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml index df1a1b73a1..09043311da 100644 --- a/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml @@ -26,15 +26,15 @@ </string> <layout_stack name="progress_indicator_area"> <layout_panel name="media_progress_indicator"> - <progress_bar name="media_progress_bar" tool_tip="Media is Loading"/> + <progress_bar name="media_progress_bar" tool_tip="媒體載入ä¸"/> </layout_panel> </layout_stack> <layout_stack name="media_controls"> <layout_panel name="back"> - <button name="back_btn" tool_tip="Navigate back"/> + <button name="back_btn" tool_tip="å‘後導覽"/> </layout_panel> <layout_panel name="fwd"> - <button name="fwd_btn" tool_tip="Navigate forward"/> + <button name="fwd_btn" tool_tip="å‘å‰å°Žè¦½"/> </layout_panel> <layout_panel name="home"> <button name="home_btn" tool_tip="首é "/> @@ -61,31 +61,31 @@ <icon name="media_whitelist_flag" tool_tip="白å單已啟用"/> </layout_panel> <layout_panel> - <icon name="media_secure_lock_flag" tool_tip="Secured Browsing"/> + <icon name="media_secure_lock_flag" tool_tip="åŠ å¯†çš„ç€è¦½"/> </layout_panel> </layout_stack> </layout_panel> <layout_panel name="media_play_position"> - <slider_bar initial_value="0.5" name="media_play_slider" tool_tip="Movie play progress"/> + <slider_bar initial_value="0.5" name="media_play_slider" tool_tip="å½±ç‰‡æ’æ”¾é€²åº¦"/> </layout_panel> <layout_panel name="skip_back"> - <button name="skip_back_btn" tool_tip="Step back"/> + <button name="skip_back_btn" tool_tip="倒轉"/> </layout_panel> <layout_panel name="skip_forward"> - <button name="skip_forward_btn" tool_tip="Step forward"/> + <button name="skip_forward_btn" tool_tip="快轉"/> </layout_panel> <layout_panel name="media_volume"> - <button name="media_mute_button" tool_tip="Mute This Media"/> - <slider name="volume_slider" tool_tip="Media Volume"/> + <button name="media_mute_button" tool_tip="把這個媒體消音"/> + <slider name="volume_slider" tool_tip="媒體音é‡"/> </layout_panel> <layout_panel name="zoom_frame"> - <button name="zoom_frame_btn" tool_tip="Zoom into media"/> + <button name="zoom_frame_btn" tool_tip="以媒體為ä¸å¿ƒæ”¾å¤§"/> </layout_panel> <layout_panel name="close"> - <button name="close_btn" tool_tip="Zoom Back"/> + <button name="close_btn" tool_tip="縮å°"/> </layout_panel> <layout_panel name="new_window"> - <button name="new_window_btn" tool_tip="Open URL in browser"/> + <button name="new_window_btn" tool_tip="用ç€è¦½å™¨é–‹å•Ÿ URL"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_profile.xml b/indra/newview/skins/default/xui/zh/panel_profile.xml deleted file mode 100644 index 502449ac3a..0000000000 --- a/indra/newview/skins/default/xui/zh/panel_profile.xml +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="檔案" name="panel_profile"> - <string name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string name="payment_update_link_url"> - http://www.secondlife.com/account/billing.php?lang=en - </string> - <string name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=en - </string> - <string name="my_account_link_url" value="http://secondlife.com/account"/> - <string name="no_partner_text" value="ç„¡"/> - <string name="no_group_text" value="ç„¡"/> - <string name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string name="name_text_args"> - [NAME] - </string> - <string name="display_name_text_args"> - [DISPLAY_NAME] - </string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <scroll_container name="profile_scroll"> - <panel name="profile_scroll_panel"> - <panel name="second_life_image_panel"> - <text name="title_sl_descr_text" value="[SECOND_LIFE]:"/> - </panel> - <panel name="first_life_image_panel"> - <text name="title_rw_descr_text" value="真實世界:"/> - </panel> - <text name="title_member_text" value="æˆç‚ºå±…民自:"/> - <text name="title_acc_status_text" value="帳戶狀態:"/> - <text name="title_partner_text" value="é…å¶ï¼š"/> - <panel name="partner_data_panel"> - <text initial_value="(檢索ä¸ï¼‰" name="partner_text"/> - </panel> - <text name="title_groups_text" value="群組:"/> - </panel> - </scroll_container> - </layout_panel> - </layout_stack> - <layout_stack name="layout_verb_buttons"> - <layout_panel name="profile_buttons_panel"> - <layout_stack name="bottom_bar_ls"> - <layout_panel name="add_friend_btn_lp"> - <button label="åŠ ç‚ºæœ‹å‹" name="add_friend" tool_tip="發出交å‹é‚€è«‹çµ¦é€™å±…æ°‘"/> - </layout_panel> - <layout_panel name="im_btn_lp"> - <button label="IM" name="im" tool_tip="é–‹å•Ÿå³æ™‚è¨Šæ¯æœƒè©±"/> - </layout_panel> - <layout_panel name="call_btn_lp"> - <button label="通話" name="call" tool_tip="與這ä½å±…民通話"/> - </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="瞬間傳é€" name="teleport" tool_tip="發給瞬間傳é€è«‹æ±‚"/> - </layout_panel> - <layout_panel name="overflow_btn_lp"> - <menu_button label="â–¼" name="overflow_btn" tool_tip="支付金錢,或分享收ç´å€çµ¦å±…æ°‘"/> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_profile_view.xml b/indra/newview/skins/default/xui/zh/panel_profile_view.xml deleted file mode 100644 index 2684287692..0000000000 --- a/indra/newview/skins/default/xui/zh/panel_profile_view.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_target_profile"> - <string name="status_online"> - 上線 - </string> - <string name="status_offline"> - 離線 - </string> - <text name="display_name_label" value="顯示å稱:"/> - <text name="solo_username_label" value="使用者å稱:"/> - <text name="status" value="上線"/> - <text name="user_name_small" value="Jack oh look at me this is a super duper long name"/> - <button name="copy_to_clipboard" tool_tip="覆製到剪貼簿"/> - <text name="user_label" value="使用者å稱:"/> - <tab_container name="tabs"> - <panel label="檔案" name="panel_profile"/> - <panel label="ç²¾é¸åœ°é»ž" name="panel_picks"/> - <panel label="NOTES & PRIVACY" name="panel_notes"/> - </tab_container> -</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_covenant.xml b/indra/newview/skins/default/xui/zh/panel_region_covenant.xml index ad94c4c7e9..d5dd337795 100644 --- a/indra/newview/skins/default/xui/zh/panel_region_covenant.xml +++ b/indra/newview/skins/default/xui/zh/panel_region_covenant.xml @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="契約" name="Covenant"> <panel.string name="can_resell"> - Purchased land in this region may be resold. + 購買這地å€çš„土地å…許轉售。 </panel.string> <panel.string name="can_not_resell"> - Purchased land in this region may not be resold. + 購買這地å€çš„土地ä¸å…許轉售。 </panel.string> <panel.string name="can_change"> - Purchased land in this region may be joined or subdivided. + 購買這地å€çš„土地å…許進行åˆä½µæˆ–分割。 </panel.string> <panel.string name="can_not_change"> - Purchased land in this region may not be joined or subdivided. + 購買這地å€çš„土地ä¸å…許進行åˆä½µæˆ–分割。 </panel.string> <text name="estate_section_lbl"> é ˜åœ° @@ -19,10 +19,10 @@ å稱: </text> <text name="estate_name_text"> - mainland + 大陸 </text> <text name="estate_owner_lbl"> - æ“æœ‰è€…: + 所有人: </text> <text name="estate_owner_text"> (無) @@ -31,17 +31,17 @@ 契約: </text> <text name="covenant_timestamp_text"> - Last Modified Wed Dec 31 16:00:00 1969 + 上次修改於 Wed Dec 31 16:00:00 1969 </text> <text_editor name="covenant_editor"> - There is no Covenant provided for this Estate. + æ¤é ˜åœ°æ²’æœ‰ä»»ä½•å¥‘ç´„è¦æ±‚。 </text_editor> <button label="é‡è¨" name="reset_covenant"/> <text name="covenant_help_text"> - Changes to the covenant will show on all parcels in the estate. + å¥‘ç´„ä¿®è¨‚å…§å®¹å°‡é¡¯ç¤ºæ–¼é ˜åœ°è£¡æ‰€æœ‰åœ°æ®µã€‚ </text> <text name="covenant_instructions"> - Drag and drop a notecard to change the Covenant for this estate. + 拖曳並置放一張記事å¡ï¼Œå³å¯ä¿®è¨‚é ˜åœ°å¥‘ç´„ã€‚ </text> <text name="region_section_lbl"> åœ°å€ @@ -56,7 +56,7 @@ 類型: </text> <text name="region_landtype_text"> - Mainland / Homestead + 大陸 / 家園 </text> <text name="region_maturity_lbl"> 分級: diff --git a/indra/newview/skins/default/xui/zh/panel_region_debug.xml b/indra/newview/skins/default/xui/zh/panel_region_debug.xml index ed5e6e9d2c..e5d5e6eaf7 100644 --- a/indra/newview/skins/default/xui/zh/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/zh/panel_region_debug.xml @@ -7,7 +7,7 @@ 未知 </text> <check_box label="關閉腳本" name="disable_scripts_check" tool_tip="關閉這個地å€ç¾åœ¨çš„全部腳本"/> - <check_box label="關閉碰撞" name="disable_collisions_check" tool_tip="關閉這個地å€ç¾åœ¨çš„éžåŒ–身碰撞"/> + <check_box label="ç¦æ¢ç¢°æ’ž" name="disable_collisions_check" tool_tip="關閉這個地å€ç¾åœ¨çš„éžåŒ–身碰撞"/> <check_box label="關閉物ç†" name="disable_physics_check" tool_tip="關閉這個地å€ç¾åœ¨çš„全部物ç†"/> <button label="套用" name="apply_btn"/> <text name="objret_text_lbl"> @@ -28,7 +28,7 @@ <check_box label="æ–¼é€™å€‹é ˜åœ°å…§çš„æ¯ä¸€å€‹åœ°å€" name="return_estate_wide" tool_tip="é€€å›žé€™å€‹é ˜åœ°å…§å…¨éƒ¨åœ°å€ä¸æ¨™è¨˜ç‚ºä»–的物件"/> <button label="退回" name="return_btn"/> <button label="å–得最常碰撞的物件..." name="top_colliders_btn" tool_tip="æ¢åˆ—出目å‰é‹ä½œä¸æœ€å¸¸ç¢°æ’žçš„物件清單"/> - <button label="å–得最耗能腳本..." name="top_scripts_btn" tool_tip="æ¢åˆ—出目å‰é‹ä½œä¸æœ€è€—能的腳本清單"/> + <button label="å–得最耗能腳本..." name="top_scripts_btn" tool_tip="æ¢åˆ—���目å‰é‹ä½œä¸æœ€è€—能的腳本清單"/> <button label="地å€é‡æ–°å•Ÿå‹•" name="restart_btn" tool_tip="給予兩分é˜å€’æ•¸è¨ˆæ™‚ä¸¦é‡æ–°å•Ÿå‹•"/> - <button label="å»¶é²é‡æ–°å•Ÿå‹•" name="cancel_restart_btn" tool_tip="å»¶é²åœ°å€é‡æ–°å•Ÿå‹•䏀尿™‚"/> + <button label="å–æ¶ˆé‡æ–°å•Ÿå‹•" name="cancel_restart_btn" tool_tip="å–æ¶ˆåœ°å€é‡æ–°å•Ÿå‹•"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_environment.xml b/indra/newview/skins/default/xui/zh/panel_region_environment.xml new file mode 100644 index 0000000000..8f466af39e --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_region_environment.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="環境" name="panel_env_info"> + <text name="water_settings_title"> + 鏿“‡ä½ å¸Œæœ›åˆ°ä½ åœ°å€çš„訪客所能看到的水和天空 / 日循環è¨å®šã€‚ 詳情 + </text> + <radio_group name="region_settings_radio_group"> + <radio_item label="使用第二人生é è¨å€¼" name="use_sl_default_settings"/> + <radio_item label="使用以下è¨å®š" name="use_my_settings"/> + </radio_group> + <panel name="user_environment_settings"> + <text name="water_settings_title"> + æ°´çš„è¨å®š + </text> + <combo_box name="water_settings_preset_combo"> + <combo_box.item label="-鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/> + </combo_box> + <text name="sky_dayc_settings_title"> + 天空 / 日循環 + </text> + <radio_group name="sky_dayc_settings_radio_group"> + <radio_item label="固定天空" name="my_sky_settings"/> + <radio_item label="日循環" name="my_dayc_settings"/> + </radio_group> + <combo_box name="sky_settings_preset_combo"> + <combo_box.item label="-鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/> + </combo_box> + <combo_box name="dayc_settings_preset_combo"> + <combo_box.item label="-鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/> + </combo_box> + </panel> + <button label="套用" name="apply_btn"/> + <button label="å–æ¶ˆ" name="cancel_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_estate.xml b/indra/newview/skins/default/xui/zh/panel_region_estate.xml index efa3be2f51..f3c1c85379 100644 --- a/indra/newview/skins/default/xui/zh/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/zh/panel_region_estate.xml @@ -10,20 +10,20 @@ (未知) </text> <text name="owner_text"> - é ˜åœ°æ“æœ‰è€…: + é ˜åœ°æ‰€æœ‰äººï¼š </text> <text name="estate_owner"> (未知) </text> - <check_box label="Use Global Time" name="use_global_time_check"/> + <check_box label="使用全域時間" name="use_global_time_check"/> <check_box label="固定太陽" name="fixed_sun_check"/> - <slider label="Phase" name="sun_hour_slider"/> + <slider label="相ä½" name="sun_hour_slider"/> <check_box label="å…許公開出入" name="externally_visible_check"/> <text name="Only Allow"> - Restrict Access to accounts verified by: + 僅å…許符åˆä»¥ä¸‹æ¢ä»¶çš„居民進入: </text> - <check_box label="Payment Information on File" name="limit_payment" tool_tip="Ban unidentified Residents"/> - <check_box label="年齡驗è‰" name="limit_age_verified" tool_tip="Ban Residents who have not verified their age. See the [SUPPORT_SITE] for more information."/> + <check_box label="已經é 留付款資料" name="limit_payment" tool_tip="å±…æ°‘å¿…é ˆæä¾›ä»˜æ¬¾è³‡æ–™æ‰èƒ½é€²å…¥é€™é ˜åœ°ã€‚ åƒé–± [SUPPORT_SITE] ç²å–進一æ¥è³‡è¨Šã€‚"/> + <check_box label="已年滿 18 æ²" name="limit_age_verified" tool_tip="å±…æ°‘å¿…é ˆå¹´æ»¿ 18 æ²æ‰èƒ½é€²å…¥é€™é ˜åœ°ã€‚ åƒé–± [SUPPORT_SITE] ç²å–進一æ¥è³‡è¨Šã€‚"/> <check_box label="å…許語音èŠå¤©" name="voice_chat_check"/> <check_box label="å…許直接瞬間傳é€" name="allow_direct_teleport"/> <button label="套用" name="apply_btn"/> diff --git a/indra/newview/skins/default/xui/zh/panel_region_general.xml b/indra/newview/skins/default/xui/zh/panel_region_general.xml index a441b8898d..f6b2c46354 100644 --- a/indra/newview/skins/default/xui/zh/panel_region_general.xml +++ b/indra/newview/skins/default/xui/zh/panel_region_general.xml @@ -18,16 +18,17 @@ <text name="region_type"> 未知 </text> - <check_box label="阻æ¢è®Šå½¢" name="block_terraform_check"/> + <check_box label="阻æ¢åœŸåœ°è®Šå½¢" name="block_terraform_check"/> <check_box label="阻æ¢é£›è¡Œ" name="block_fly_check"/> <check_box label="å…許傷害" name="allow_damage_check"/> <check_box label="é™åˆ¶æŽ¨æ’ž" name="restrict_pushobject"/> <check_box label="å…許土地轉售" name="allow_land_resell_check"/> <check_box label="å…許土地 åˆä½µ/分割" name="allow_parcel_changes_check"/> <check_box label="阻擋土地顯示於æœå°‹ä¸" name="block_parcel_search_check" tool_tip="讓其他人å¯ä»¥åœ¨æœå°‹çµæžœä¸çœ‹åˆ°é€™å€‹åœ°å€èˆ‡å…¶ä¸çš„地段"/> + <check_box label="å…許網é¢ç‰©ä»¶" name="mesh_rez_enabled_check" tool_tip="å…許大家在æ¤åœ°å€ç”¢ç”Ÿç¶²é¢ç‰©ä»¶"/> <spinner label="人數上é™" name="agent_limit_spin"/> - <spinner label="Object Bonus" name="object_bonus_spin"/> - <text label="Maturity" name="access_text"> + <spinner label="物件紅利" name="object_bonus_spin"/> + <text label="分級" name="access_text"> 分級: </text> <icons_combo_box label="é©åº¦æˆäºº" name="access_combo"> @@ -36,8 +37,8 @@ <icons_combo_box.item label="一般普級" name="PG" value="13"/> </icons_combo_box> <button label="套用" name="apply_btn"/> - <button label="強制瞬間傳é€ä¸€å€‹å±…民回家..." name="kick_btn"/> - <button label="å¼·åˆ¶çž¬é–“å‚³é€æ‰€æœ‰å±…民回家..." name="kick_all_btn"/> - <button label="é€å‡ºè¨Šæ¯åˆ°åœ°å€..." name="im_btn"/> + <button label="瞬間傳é€ä¸€ä½å±…民回家..." name="kick_btn"/> + <button label="çž¬é–“å‚³é€æ‰€æœ‰å±…民回家..." name="kick_all_btn"/> + <button label="å‘地å€ç™¼å‡ºè¨Šæ¯..." name="im_btn"/> <button label="管ç†çž¬é–“傳é€ä¸å¿ƒ..." name="manage_telehub_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml index 7cae8fe8cf..85e759e445 100644 --- a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml @@ -9,11 +9,52 @@ <spinner label="水文高度" name="water_height_spin"/> <spinner label="地形æå‡é™åˆ¶" name="terrain_raise_spin"/> <spinner label="地形é™ä½Žé™åˆ¶" name="terrain_lower_spin"/> - <check_box label="ä½¿ç”¨é ˜åœ°çš„å¤ªé™½è¨å®š" name="use_estate_sun_check"/> - <check_box label="固定太陽" name="fixed_sun_check"/> - <slider label="Phase" name="sun_hour_slider"/> + <text name="detail_texture_text"> + 地形æè³ªï¼ˆé ˆ 512x512,24 ä½å…ƒ .tga æª”æ ¼å¼ï¼‰ + </text> + <text name="height_text_lbl"> + 1(低) + </text> + <text name="height_text_lbl2"> + 2 + </text> + <text name="height_text_lbl3"> + 3 + </text> + <text name="height_text_lbl4"> + 4(高) + </text> + <text name="height_text_lbl5"> + æè³ªæµ·æ‹”ç¯„åœ + </text> + <text name="height_text_lbl10"> + 這些值代表以上æè³ªçš„æ··åˆç¯„åœã€‚ + </text> + <text name="height_text_lbl11"> + 以公尺為單ä½ï¼Œä½Žå€¼æ˜¯æè³ª #1 的最大高度,高值是æè³ª #4 的最å°é«˜åº¦ã€‚ + </text> + <text name="height_text_lbl6"> + 西北 + </text> + <text name="height_text_lbl7"> + æ±åŒ— + </text> + <spinner label="低" name="height_start_spin_1"/> + <spinner label="低" name="height_start_spin_3"/> + <spinner label="高" name="height_range_spin_1"/> + <spinner label="高" name="height_range_spin_3"/> + <text name="height_text_lbl8"> + è¥¿å— + </text> + <text name="height_text_lbl9"> + æ±å— + </text> + <spinner label="低" name="height_start_spin_0"/> + <spinner label="低" name="height_start_spin_2"/> + <spinner label="高" name="height_range_spin_0"/> + <spinner label="高" name="height_range_spin_2"/> + <button label="下載 RAW 地形..." name="download_raw_btn" tool_tip="åªå…è¨±é ˜åœ°æ‰€æœ‰äººè€Œéžç®¡ç†è€…進行æ“作"/> + <button label="上傳 RAW 地形檔..." name="upload_raw_btn" tool_tip="åªå…è¨±é ˜åœ°æ‰€æœ‰äººè€Œéžç®¡ç†è€…進行æ“作"/> + <button label="確定地形" name="bake_terrain_btn" tool_tip="將目å‰åœ°å½¢è¨ç‚ºã€Œå‡é«˜ / é™ä½Žã€æ¥µé™çš„ä¸å¿ƒå€¼"/> <button label="套用" name="apply_btn"/> - <button label="下載 RAW 地形..." name="download_raw_btn" tool_tip="åªå…è¨±é ˜åœ°æ“æœ‰è€…而éžç®¡ç†è€…進行æ“作"/> - <button label="上傳 RAW 地形檔..." name="upload_raw_btn" tool_tip="åªå…è¨±é ˜åœ°æ“æœ‰è€…而éžç®¡ç†è€…進行æ“作"/> - <button label="Bake Terrain" name="bake_terrain_btn" tool_tip="Set current terrain as mid-point for raise/lower limits"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_texture.xml b/indra/newview/skins/default/xui/zh/panel_region_texture.xml deleted file mode 100644 index 7b6152121f..0000000000 --- a/indra/newview/skins/default/xui/zh/panel_region_texture.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="åœ°é¢æè³ª" name="Textures"> - <text name="region_text_lbl"> - 地å€ï¼š - </text> - <text name="region_text"> - 未知 - </text> - <text name="detail_texture_text"> - 地形æè³ªï¼ˆé ˆ 512x512,24 ä½å…ƒ .tga æª”æ ¼å¼ï¼‰ - </text> - <text name="height_text_lbl"> - 1 (Low) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (High) - </text> - <text name="height_text_lbl5"> - Texture Elevation Ranges - </text> - <text name="height_text_lbl6"> - Northwest - </text> - <text name="height_text_lbl7"> - Northeast - </text> - <spinner label="Low" name="height_start_spin_1"/> - <spinner label="Low" name="height_start_spin_3"/> - <spinner label="High" name="height_range_spin_1"/> - <spinner label="High" name="height_range_spin_3"/> - <text name="height_text_lbl8"> - Southwest - </text> - <text name="height_text_lbl9"> - Southeast - </text> - <spinner label="Low" name="height_start_spin_0"/> - <spinner label="Low" name="height_start_spin_2"/> - <spinner label="High" name="height_range_spin_0"/> - <spinner label="High" name="height_range_spin_2"/> - <text name="height_text_lbl10"> - These values represent the blend range for the textures above. - </text> - <text name="height_text_lbl11"> - Measured in meters, the LOW value is the MAXIMUM height of Texture #1, and the HIGH value is the MINIMUM height of Texture #4. - </text> - <button label="套用" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_script_ed.xml b/indra/newview/skins/default/xui/zh/panel_script_ed.xml index cc2b0fc673..29e9a35869 100644 --- a/indra/newview/skins/default/xui/zh/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/zh/panel_script_ed.xml @@ -4,7 +4,7 @@ 載入ä¸... </panel.string> <panel.string name="can_not_view"> - ä½ ä¸èƒ½å¯Ÿçœ‹æˆ–編輯æ¤è…³æœ¬ï¼Œè‡ªå¾žå®ƒè¢«è¨å®šç‚º "no copy" å¾Œã€‚ä½ éœ€è¦å®Œæ•´æ¬Šé™åŽ»å¯Ÿçœ‹æˆ–ç·¨è¼¯æœ‰åŒ…å«è…³æœ¬åœ¨å…§çš„物件。 + ä½ ç„¡æ³•å¯Ÿçœ‹æˆ–ç·¨è¼¯é€™è…³æœ¬ï¼Œå®ƒè¢«è¨ç‚ºã€Œç¦æ¢è¤‡è£½ã€ã€‚ ä½ éœ€è¦å®Œæ•´æ¬Šé™åŽ»å¯Ÿçœ‹æˆ–ç·¨è¼¯ç‰©ä»¶å…§çš„è…³æœ¬ã€‚ </panel.string> <panel.string name="public_objects_can_not_run"> 公開物件ä¸èƒ½åŸ·è¡Œè…³æœ¬ @@ -22,12 +22,14 @@ <menu label="檔案" name="File"> <menu_item_call label="儲å˜" name="Save"/> <menu_item_call label="還原全部變更" name="Revert All Changes"/> + <menu_item_call label="從檔案載入…" name="LoadFromFile"/> + <menu_item_call label="å˜å…¥æª”案…" name="SaveToFile"/> </menu> <menu label="編輯" name="Edit"> <menu_item_call label="復原" name="Undo"/> <menu_item_call label="é‡åš" name="Redo"/> <menu_item_call label="剪下" name="Cut"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="æšåº¨" name="Copy"/> <menu_item_call label="貼上" name="Paste"/> <menu_item_call label="å…¨é¸" name="Select All"/> <menu_item_call label="å–æ¶ˆé¸æ“‡" name="Deselect"/> diff --git a/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml index 32cc2f9a5d..eb32d39f78 100644 --- a/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml +++ b/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="我的化身" name="script_limits_my_avatar_panel"> <text name="script_memory"> - Avatar Script Usage + åŒ–èº«è…³æœ¬ä½¿ç”¨é‡ </text> <text name="loading_text"> 載入ä¸... </text> <scroll_list name="scripts_list"> <scroll_list.columns label="尺寸(kb)" name="size"/> - <scroll_list.columns label="URLs" name="urls"/> + <scroll_list.columns label="URL" name="urls"/> <scroll_list.columns label="物件å稱" name="name"/> <scroll_list.columns label="ä½ç½®" name="location"/> </scroll_list> - <button label="Refresh List" name="refresh_list_btn"/> + <button label="刷新清單" name="refresh_list_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml index 950abbfb4c..40a2dd6926 100644 --- a/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml +++ b/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml @@ -8,13 +8,13 @@ </text> <scroll_list name="scripts_list"> <scroll_list.columns label="尺寸(kb)" name="size"/> - <scroll_list.columns label="URLs" name="urls"/> + <scroll_list.columns label="URL" name="urls"/> <scroll_list.columns label="物件å稱" name="name"/> - <scroll_list.columns label="ç‰©ä»¶æ“æœ‰è€…" name="owner"/> + <scroll_list.columns label="物件所有人" name="owner"/> <scroll_list.columns label="地段" name="parcel"/> <scroll_list.columns label="ä½ç½®" name="location"/> </scroll_list> - <button label="Refresh List" name="refresh_list_btn"/> - <button label="Highlight" name="highlight_btn"/> + <button label="刷新清單" name="refresh_list_btn"/> + <button label="高亮顯示" name="highlight_btn"/> <button label="退回" name="return_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_script_question_toast.xml b/indra/newview/skins/default/xui/zh/panel_script_question_toast.xml new file mode 100644 index 0000000000..a2d0237da0 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_script_question_toast.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel label="script_question_panel" name="panel_script_question_toast"> + <panel label="buttons_panel" name="buttons_panel"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_side_tray.xml b/indra/newview/skins/default/xui/zh/panel_side_tray.xml deleted file mode 100644 index e5c7deb7d6..0000000000 --- a/indra/newview/skins/default/xui/zh/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="å´é‚Šæ¬„切æ›ã€‚" name="sidebar_openclose" tab_title="å´é‚Šæ¬„切æ›"/> - <sidetray_tab description="首é 。" name="sidebar_home" tab_title="首é "> - <panel label="首é " name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="ç·¨è¼¯ä½ çš„å…¬é–‹æª”æ¡ˆåŠç²¾é¸åœ°é»žã€‚" name="sidebar_me" tab_title="我的檔案"> - <panel_container name="panel_container"> - <panel label="自己" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Find your friends, contacts and people nearby." name="sidebar_people" tab_title="人群"> - <panel_container name="panel_container"> - <panel label="群組檔案" name="panel_group_info_sidetray"/> - <panel label="Blocked Residents & Objects" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Find places to go and places you've visited before." label="地點" name="sidebar_places" tab_title="地點"> - <panel label="地點" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="ç€è¦½ä½ 的收ç´å€ã€‚" name="sidebar_inventory" tab_title="我的收ç´å€"> - <panel label="編輯收ç´å€" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="è®Šæ›´ä½ çš„å¤–è§€èˆ‡ç›®å‰æ¨£è²Œã€‚" name="sidebar_appearance" tab_title="我的外觀"> - <panel label="編輯外觀" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml new file mode 100644 index 0000000000..20fb9b494a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/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/zh/panel_snapshot_local.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_local.xml new file mode 100644 index 0000000000..a929c9a3fb --- /dev/null +++ b/indra/newview/skins/default/xui/zh/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/zh/panel_snapshot_options.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml new file mode 100644 index 0000000000..82c2b10d8d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/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/zh/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_postcard.xml new file mode 100644 index 0000000000..853a856104 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/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/zh/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_profile.xml new file mode 100644 index 0000000000..6f64a4e83c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/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/zh/panel_sound_devices.xml b/indra/newview/skins/default/xui/zh/panel_sound_devices.xml new file mode 100644 index 0000000000..fa4e24a605 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_sound_devices.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel label="è¨å‚™è¨å®š" name="device_settings_panel"> + <panel.string name="default_text"> + é è¨ + </panel.string> + <string name="name_no_device"> + ç„¡è¨å‚™ + </string> + <string name="name_default_system_device"> + é è¨ç³»çµ±è¨å‚™ + </string> + <text name="Input"> + 輸入 + </text> + <text name="Output"> + 輸出 + </text> + <text name="My volume label"> + 我的音é‡ï¼š + </text> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="ç”¨é€™æŽ§åˆ¶æ¢æ”¹è®ŠéŸ³é‡"/> + <text name="wait_text"> + è«‹ç¨å€™ + </text> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml index 1dd3acef5d..4586d4eca1 100644 --- a/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml +++ b/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <!-- Width and height of this panel should be synchronized with "panel_modes" in the floater_moveview.xml--> <panel name="panel_stand_stop_flying"> - <button label="站立" name="stand_btn" tool_tip="點擊æ¤è™•起立。"/> + <button label="站立" name="stand_btn" tool_tip="點按æ¤è™•起立。"/> <button label="åœæ¢é£›è¡Œ" name="stop_fly_btn" tool_tip="åœæ¢é£›è¡Œ"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_status_bar.xml b/indra/newview/skins/default/xui/zh/panel_status_bar.xml index 808e14f3c3..b4cdff9d6b 100644 --- a/indra/newview/skins/default/xui/zh/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/zh/panel_status_bar.xml @@ -16,12 +16,13 @@ L$ [AMT] </panel.string> <panel name="balance_bg"> - <text name="balance" tool_tip="é»žæ“Šä»¥é‡æ–°æ›´æ–°ä½ çš„ L$ 帳戶餘é¡" value="L$20"/> - <button label="購買 L$" name="buyL" tool_tip="點擊以購買更多 L$"/> + <text name="balance" tool_tip="é»žæŒ‰ä»¥é‡æ–°æ›´æ–°ä½ çš„ L$ 帳戶餘é¡" value="L$20"/> + <button label="購買 L$" name="buyL" tool_tip="點按以購買更多 L$"/> + <button label="購物" name="goShop" tool_tip="打開第二人生購物市集"/> </panel> <text name="TimeText" tool_tip="ç›®å‰æ™‚å€ï¼ˆå¤ªå¹³æ´‹ï¼‰"> 24:00 AM PST </text> - <button name="media_toggle_btn" tool_tip="é–‹å§‹ / åœæ¢å…¨éƒ¨åª’體(音樂ã€å½±ç‰‡ã€ç¶²é )"/> + <button name="media_toggle_btn" tool_tip="é–‹å§‹/åœæ¢å…¨éƒ¨åª’體(音樂ã€å½±ç‰‡ã€ç¶²é )"/> <button name="volume_btn" tool_tip="å…¨åŸŸéŸ³é‡æŽ§åˆ¶"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_teleport_history.xml b/indra/newview/skins/default/xui/zh/panel_teleport_history.xml index a2a63db000..44d545a86d 100644 --- a/indra/newview/skins/default/xui/zh/panel_teleport_history.xml +++ b/indra/newview/skins/default/xui/zh/panel_teleport_history.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Teleport History"> <accordion name="history_accordion"> - <no_matched_tabs_text name="no_matched_teleports_msg" value="沒有發ç¾ä½ è¦æ‰¾çš„嗎?試試 [secondlife:///app/search/places/[SEARCH_TERM] æœå°‹]。"/> - <no_visible_tabs_text name="no_teleports_msg" value="瞬間傳é€ç´€éŒ„是空白的。試試 [secondlife:///app/search/places/ Search]。"/> + <no_matched_tabs_text name="no_matched_teleports_msg" value="找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試 [secondlife:///app/search/places/[SEARCH_TERM] æœå°‹]。"/> + <no_visible_tabs_text name="no_teleports_msg" value="çž¬é–“å‚³é€æ·å²è¨˜éŒ„ç›®å‰ç©ºç™½ã€‚ 請試試[secondlife:///app/search/places/ æœå°‹]。"/> <accordion_tab name="today" title="今天"/> <accordion_tab name="yesterday" title="昨天"/> <accordion_tab name="2_days_ago" title="å‰å¤©"/> diff --git a/indra/newview/skins/default/xui/zh/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/zh/panel_volume_pulldown.xml new file mode 100644 index 0000000000..70ec028176 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater"> + <slider label="主控音é‡" name="System Volume"/> + <slider label="按éµéŸ³" name="UI Volume"/> + <slider label="環境" name="Wind Volume"/> + <slider label="è²éŸ³" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="啟用姿勢è²éŸ³"/> + <slider label="音樂" name="Music Volume"/> + <check_box name="enable_music" tool_tip="啟用串æµéŸ³æ¨‚"/> + <slider label="媒體" name="Media Volume"/> + <check_box name="enable_media" tool_tip="啟用串æµåª’é«”"/> + <slider label="語音" name="Voice Volume"/> + <check_box name="enable_voice_check" tool_tip="啟用語音èŠå¤©"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_world_map.xml b/indra/newview/skins/default/xui/zh/panel_world_map.xml index b5aa659bf0..84018768a1 100644 --- a/indra/newview/skins/default/xui/zh/panel_world_map.xml +++ b/indra/newview/skins/default/xui/zh/panel_world_map.xml @@ -7,57 +7,57 @@ 無效的ä½ç½® </panel.string> <panel.string name="world_map_north"> - N + 北 </panel.string> <panel.string name="world_map_east"> E </panel.string> <panel.string name="world_map_west"> - W + 西 </panel.string> <panel.string name="world_map_south"> - S + å— </panel.string> <panel.string name="world_map_southeast"> - SE + æ±å— </panel.string> <panel.string name="world_map_northeast"> - NE + æ±åŒ— </panel.string> <panel.string name="world_map_southwest"> - SW + è¥¿å— </panel.string> <panel.string name="world_map_northwest"> - NW + 西北 </panel.string> <panel.string name="world_map_person"> - 1 person + 1 人 </panel.string> <panel.string name="world_map_people"> - [NUMBER] people + [NUMBER] 人 </panel.string> - <text label="N" name="floater_map_north"> - N + <text label="北" name="floater_map_north"> + 北 </text> <text label="E" name="floater_map_east"> E </text> - <text label="W" name="floater_map_west"> - W + <text label="西" name="floater_map_west"> + 西 </text> - <text label="S" name="floater_map_south"> - S + <text label="å—" name="floater_map_south"> + å— </text> - <text label="SE" name="floater_map_southeast"> - SE + <text label="æ±å—" name="floater_map_southeast"> + æ±å— </text> - <text label="NE" name="floater_map_northeast"> - NE + <text label="æ±åŒ—" name="floater_map_northeast"> + æ±åŒ— </text> - <text label="SW" name="floater_map_southwest"> - SW + <text label="西å—" name="floater_map_southwest"> + è¥¿å— </text> - <text label="NW" name="floater_map_northwest"> - NW + <text label="西北" name="floater_map_northwest"> + 西北 </text> </panel> diff --git a/indra/newview/skins/default/xui/zh/role_actions.xml b/indra/newview/skins/default/xui/zh/role_actions.xml index 32bf0d22d8..767bcecde7 100644 --- a/indra/newview/skins/default/xui/zh/role_actions.xml +++ b/indra/newview/skins/default/xui/zh/role_actions.xml @@ -1,73 +1,73 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <role_actions> - <action_set description="These Abilities include powers to add and remove group Members, and allow new Members to join without an invitation." name="Membership"> - <action description="é‚€è«‹ä»–äººåŠ å…¥é€™å€‹ç¾¤çµ„" longdescription="é‚€è«‹ä»–äººåŠ å…¥é€™å€‹ç¾¤çµ„ï¼Œè«‹æŒ‰ä¸‹æ–¼è§’è‰²å€æ®µä¸çš„æˆå“¡é 籤ä¸çš„ '邀請' 按鈕。" name="member invite" value="1"/> - <action description="將會員由這個群組ä¸è¸¢å‡º" longdescription="Eject Members from this Group using the 'Eject' button in the Roles section > Members tab. An Owner can eject anyone except another Owner. If you're not an Owner, a Member can be ejected from a group if, and only if, they're only in the Everyone Role, and NO other Roles. To remove Members from Roles, you need to have the 'Remove Members from Roles' Ability." name="member eject" value="2"/> - <action description="Toggle 'Open Enrollment' and change 'Enrollment fee'" longdescription="Toggle 'Open Enrollment' to let new Members join without an invitation, and change the 'Enrollment fee' in the General section." name="member options" value="3"/> + <action_set description="這些能力包括新增或移除群組æˆå“¡å’Œå…許新æˆå“¡ä¸å—é‚€å³å¯åŠ å…¥ç¾¤çµ„çš„ç‰æ¬ŠåŠ›ã€‚" name="Membership"> + <action description="é‚€è«‹ä»–äººåŠ å…¥é€™å€‹ç¾¤çµ„" longdescription="æ¬²é‚€è«‹ä»–äººåŠ å…¥é€™å€‹ç¾¤çµ„ï¼Œè«‹æŒ‰ä¸‹è§’è‰²æ¬„ä¸‹çš„æˆå“¡é 籤ä¸çš„ã€Œé‚€è«‹ã€æŒ‰éˆ•。" name="member invite" value="1"/> + <action description="將會員由這個群組ä¸è¸¢å‡º" longdescription="欲將æˆå“¡å¾žç¾¤çµ„踢出,請按下角色欄下的æˆå“¡é 籤ä¸çš„ã€Œè¸¢å‡ºã€æŒ‰éˆ•。 所有人å¯è¸¢å‡ºä»»ä½•ä¸å…·æ‰€æœ‰äººè§’色的人。 å¦‚æžœä½ ä¸æ˜¯æ‰€æœ‰äººï¼Œä¸€ä½æˆå“¡åªåœ¨ä»–僅屬於「任何人ã€è§’色且沒有其他角色的情æ³ä¸‹è¢«è¸¢å‡ºç¾¤çµ„。 欲å¸é™¤æˆå“¡çš„è§’è‰²ï¼Œä½ å¿…é ˆæœ‰ã€Œå¸é™¤æˆå“¡è§’色ã€çš„能力。" name="member eject" value="2"/> + <action description="切æ›ã€Œå…è²»è‡ªç”±åŠ å…¥ã€è¨å®šï¼Œæ›´æ”¹ã€ŒåŠ å…¥è²»ã€ã€‚" longdescription="切æ›ã€Œå…è²»è‡ªç”±åŠ å…¥ã€è¨å®šï¼Œè®“æˆå“¡ä¸å—邀也å¯åŠ å…¥ï¼Œä¸¦åœ¨åŸºæœ¬è¨å®šæ¬„æ›´æ”¹ã€ŒåŠ å…¥è²»ã€ã€‚" name="member options" value="3"/> </action_set> - <action_set description="These Abilities include powers to add, remove, and change group Roles, add and remove Members in Roles, and assign Abilities to Roles." name="Roles"> - <action description="創立一個新角色" longdescription="å‰µç«‹ä¸€å€‹æ–°è§’è‰²æ–¼è§’è‰²å€æ®µ > 角色é 籤。" name="role create" value="4"/> - <action description="刪除角色" longdescription="Delete Roles in the Roles section > Roles tab." name="role delete" value="5"/> - <action description="Change Role names, titles, descriptions, and whether Role members are publicly revealed" longdescription="Change Role names, titles, descriptions, and whether Role members are publicly revealed. This is done at the bottom of the the Roles section > Roles tab after selecting a Role." name="role properties" value="6"/> - <action description="Assign Members to Assigner's Roles" longdescription="Assign Members to Roles in the list of Assigned Roles (Roles section > Members tab). A Member with this Ability can only add Members to a Role that the assigner is already in." name="role assign member limited" value="7"/> - <action description="Assign Members to Any Role" longdescription="Assign Members to Any Role in the list of Assigned Roles (Roles section > Members tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability." name="role assign member" value="8"/> - <action description="由角色ä¸ç§»é™¤æˆå“¡" longdescription="Remove Members from Roles in the list of Assigned Roles (Roles section > Members tab). Owners can't be removed." name="role remove member" value="9"/> - <action description="Assign and Remove Abilities in Roles" longdescription="Assign and Remove Abilities for each Role in the list of Allowed Abilities (Roles section > Roles tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--all Abilities, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability." name="role change actions" value="10"/> + <action_set description="這些能力包括新增ã€ç§»é™¤ã€æ›´æ”¹ç¾¤çµ„角色,新增或移除æˆå“¡çš„角色,和為角色è¨å®šèƒ½åŠ›ç‰æ¬ŠåŠ›ã€‚" name="Roles"> + <action description="創立一個新角色" longdescription="到角色欄的角色é 籤,å¯ä»¥å»ºç«‹æ–°è§’色。" name="role create" value="4"/> + <action description="刪除角色" longdescription="到角色欄的角色é 籤,å¯ä»¥åˆªé™¤è§’色。" name="role delete" value="5"/> + <action description="變更角色å稱ã€é éŠœã€æè¿°ï¼Œè¨å®šè§’色的æˆå“¡å單是å¦å…¬é–‹" longdescription="變更角色å稱ã€é éŠœã€æè¿°ï¼Œè¨å®šè§’色的æˆå“¡å單是å¦å…¬é–‹ã€‚ é¸å–一個角色後,å¯åˆ°è§’色欄底下的角色é 籤完æˆé€™å‹•作。" name="role properties" value="6"/> + <action description="賦予æˆå“¡ã€ŒæŒ‡æ´¾è€…ã€è§’色" longdescription="從已知的指派角色ä¸é¸æ“‡è‹¥å¹²ï¼Œè³¦äºˆçµ¦æˆå“¡ï¼ˆè§’色欄 > æˆå“¡é 籤)。 有這能力的æˆå“¡ï¼Œåªèƒ½æŠŠä»–è‡ªå·±å·²èº«è² çš„è§’è‰²è³¦äºˆçµ¦åˆ¥çš„æˆå“¡ã€‚" name="role assign member limited" value="7"/> + <action description="賦予æˆå“¡ã€Œä»»ä½•人ã€è§’色" longdescription="從已知的指派角色ä¸ï¼Œè³¦äºˆçµ¦æˆå“¡ã€Œä»»ä½•人ã€è§’色(角色欄 > æˆå“¡é 籤)。 *è¦å‘Š* ä»»ä½•èº«è² å…·é€™èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡ï¼Œéƒ½å¯ä»¥æŠŠæŸäº›è§’è‰²è³¦äºˆè‡ªå·±æˆ–ä»»ä½•ä¸æ˜¯æ‰€æœ‰äººçš„æˆå“¡ï¼Œå› æ¤ä½¿è‡ªå·±æˆ–別人得到比ç¾åœ¨æ›´å¤šçš„æ¬ŠåŠ›ï¼Œæœ€çµ‚å¯èƒ½æ“有近似「所有人ã€çš„æ¬ŠåŠ›ã€‚ è³¦äºˆé€™é …èƒ½åŠ›ä¹‹å‰ï¼Œæ•¬è«‹æ…Žé‡è€ƒæ…®ã€‚" name="role assign member" value="8"/> + <action description="由角色ä¸ç§»é™¤æˆå“¡" longdescription="從已知的指派角色ä¸é¸æ“‡ï¼Œå°‡æˆå“¡å¸é™¤è©²è§’色(角色欄 > æˆå“¡é 籤)。 所有人角色ä¸å¾—被å¸é™¤ã€‚" name="role remove member" value="9"/> + <action description="è¨å®šæˆ–å¸é™¤è§’色能力" longdescription="從å…許的能力清單ä¸é¸æ“‡ï¼Œç‚ºæ¯ä¸€è§’色è¨å®šæˆ–å¸é™¤è©²èƒ½åŠ›ï¼ˆè§’è‰²æ¬„ > 角色é 籤)。 *è¦å‘Š* ä»»ä½•èº«è² å…·æœ‰é€™èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡ï¼Œéƒ½å¯ä»¥å°‡æ‰€æœ‰èƒ½åŠ›è³¦äºˆè‡ªå·±å’Œä»»ä½•å…¶ä»–ä¸æ˜¯æ‰€æœ‰äººçš„äººï¼Œå› æ¤è®“自己或他人æå‡ç‚ºè¿‘ä¼¼ã€Œæ‰€æœ‰äººã€æ¬ŠåŠ›çš„å±¤ç´šã€‚ è³¦äºˆé€™é …èƒ½åŠ›ä¹‹å‰ï¼Œæ•¬è«‹æ…Žé‡è€ƒæ…®ã€‚" name="role change actions" value="10"/> </action_set> - <action_set description="These Abilities include powers to modify this group's identity, such as changing public visibility, charter, and insignia." name="Group Identity"> - <action description="Change Charter, Insignia, and 'Show in search'" longdescription="Change Charter, Insignia, and 'Show in search'. This is done in the General section." name="group change identity" value="11"/> + <action_set description="這些能力包括有權修改群組身份,例如更改公開程度ã€è¦ç« å’Œå¾½ç« ã€‚" name="Group Identity"> + <action description="更改è¦ç« ã€å¾½ç« ,è¨å®šæ˜¯å¦ã€Œé¡¯ç¤ºæ–¼æœå°‹çµæžœã€ã€‚" longdescription="更改è¦ç« ã€å¾½ç« ,è¨å®šæ˜¯å¦ã€Œé¡¯ç¤ºæ–¼æœå°‹çµæžœã€ã€‚ 這å¯åœ¨ã€ŒåŸºæœ¬è³‡æ–™ã€æ¬„è¨å®šã€‚" name="group change identity" value="11"/> </action_set> - <action_set description="These Abilities include powers to deed, modify, and sell land in this group's land holdings. To get to the About Land window, right-click the ground and select 'About Land', or click the 'i' icon in the Navigation Bar." name="Parcel Management"> - <action description="讓渡土地或購買土地給群組" longdescription="Deed land and buy land for group. This is done in About Land > General tab." name="land deed" value="12"/> - <action description="Abandon land to Governor Linden" longdescription="Abandon land to Governor Linden. *WARNING* Any Member in a Role with this Ability can abandon group-owned land in About Land > General tab, reverting it to Linden ownership without a sale! Be sure you know what you're doing before assigning this Ability." name="land release" value="13"/> - <action description="Set land for sale info" longdescription="Set land for sale info. *WARNING* Any Member in a Role with this Ability can sell group-owned land in About Land > General tab as they wish! Be sure you know what you're doing before assigning this Ability." name="land set sale info" value="14"/> - <action description="Subdivide and join parcels" longdescription="Subdivide and join parcels. This is done by right-clicking the ground, 'Edit Terrain', and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click 'Subdivide'. To join, select two or more contiguous parcels and click 'Join'." name="land divide join" value="15"/> + <action_set description="這些能力包括有權讓渡ã€ä¿®æ”¹æˆ–å‡ºå”®æœ¬ç¾¤çµ„æ“æœ‰çš„土地。 欲å‰å¾€ã€ŒåœŸåœ°è³‡æ–™ã€è¦–窗,請在地é¢ä»»ä¸€è™•點按å³éµï¼Œé¸æ“‡ã€ŒåœŸåœ°è³‡æ–™ã€ï¼Œæˆ–點按導覽列的「iã€åœ–示。" name="Parcel Management"> + <action description="讓渡土地或購買土地給群組" longdescription="讓渡土地或為群組購地。 這å¯åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€> 基本é 籤完æˆã€‚" name="land deed" value="12"/> + <action description="放棄土地,將所有權轉給 Governor Linden(林登總長)" longdescription="放棄土地,將所有權轉給 Governor Linden(林登總長)。 *è¦å‘Š* ä»»ä½•èº«è² å…·æœ‰é€™èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡ï¼Œéƒ½å¯ä»¥åˆ°ã€ŒåœŸåœ°è³‡æ–™ã€> 基本é 籤放棄任何群組所有的土地,ä¸ç¶“出售就將所有權轉給 Lindenï¼ è³¦äºˆé€™é …èƒ½åŠ›ä¹‹å‰ï¼Œæ•¬è«‹æ…Žé‡è€ƒæ…®ã€‚" name="land release" value="13"/> + <action description="è¨å®šå¾…售土地資訊" longdescription="è¨å®šå¾…售土地資訊。 *è¦å‘Š* ä»»ä½•èº«è² å…·æœ‰é€™èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡ï¼Œéƒ½å¯ä»¥åˆ°ã€ŒåœŸåœ°è³‡æ–™ã€> 基本é 籤任æ„å‡ºå”®ç¾¤çµ„æ‰€æœ‰çš„åœŸåœ°ï¼ è³¦äºˆé€™é …èƒ½åŠ›ä¹‹å‰ï¼Œæ•¬è«‹æ…Žé‡è€ƒæ…®ã€‚" name="land set sale info" value="14"/> + <action description="分割或åˆä½µåœ°æ®µ" longdescription="分割或åˆä½µåœ°æ®µã€‚ 欲進行æ¤å‹•作,請在地é¢ä»»ä¸€è™•點按å³éµï¼Œé¸æ“‡ã€Œç·¨è¼¯åœ°å½¢ã€ï¼Œä¸¦åœ¨åœŸåœ°ä¸Šæ‹–æ›³æ»‘é¼ é¸å–一個範åœã€‚ è¦é€²è¡Œåˆ†å‰²ï¼Œåšå¥½é¸æ“‡å¾Œé»žæŒ‰ã€Œåˆ†å‰²ã€ã€‚ è¦åˆä½µï¼Œé¸å–至少兩塊相鄰地段,å†é»žé¸ã€Œåˆä½µã€ã€‚" name="land divide join" value="15"/> </action_set> - <action_set description="These Abilities include powers to change the parcel name and publish settings, Find directory visibility, and landing point & TP routing options." name="Parcel Identity"> - <action description="Toggle 'Show Place in Search' and set category" longdescription="Toggle 'Show Place in Search' and setting a parcel's category in About Land > Options tab." name="land find places" value="17"/> - <action description="Change parcel name, description, and 'Show Place in Search' settings" longdescription="Change parcel name, description, and 'Show Place in Search' settings. This is done in About Land > Options tab." name="land change identity" value="18"/> - <action description="Set landing point and set teleport routing" longdescription="On a group-owned parcel, Members in a Role with this Ability can set a landing point to specify where incoming teleports arrive, and also set teleport routing for further control. This is done in About Land > Options tab." name="land set landing point" value="19"/> + <action_set description="é€™äº›èƒ½åŠ›åŒ…æ‹¬å¯æ›´æ”¹åœ°æ®µå稱和發佈è¨å®šã€è¨å®šæ˜¯å¦å…¬é–‹åˆ°æœå°‹çµæžœã€è¨å®šç™»é™¸åœ°é»žå’Œçž¬é–“傳é€ç¹žè·¯é¸é …。" name="Parcel Identity"> + <action description="切æ›ã€Œå°‡åœ°é»žé¡¯ç¤ºåœ¨æœå°‹çµæžœã€è¨å®šï¼Œä¸¦é¸å®šé¡žåˆ¥" longdescription="切æ›ã€Œå°‡åœ°é»žé¡¯ç¤ºåœ¨æœå°‹çµæžœã€è¨å®šï¼Œä¸¦åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€> é¸é …é 籤è¨å®šåœ°æ®µé¡žåˆ¥ã€‚" name="land find places" value="17"/> + <action description="更改地段åç¨±ã€æè¿°ï¼Œå’Œã€Œå°‡åœ°é»žé¡¯ç¤ºåœ¨æœå°‹çµæžœã€è¨å®šã€‚" longdescription="更改地段åç¨±ã€æè¿°ï¼Œå’Œã€Œå°‡åœ°é»žé¡¯ç¤ºåœ¨æœå°‹çµæžœã€è¨å®šã€‚ 這å¯åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€> é¸é …é 籤完æˆã€‚" name="land change identity" value="18"/> + <action description="è¨å®šç™»é™¸åœ°é»žå’Œçž¬é–“傳é€ç¹žè·¯è¨å®šã€‚" longdescription="åœ¨ç¾¤çµ„æ‰€æœ‰çš„åœ°æ®µä¸Šï¼Œèº«è² å…·æ¤èƒ½åŠ›çš„æˆå“¡ï¼Œå¯ä»¥è¨å®šäººå€‘瞬間傳é€é€²ä¾†æ™‚的登陸地點,和瞬間傳é€çš„繞路é¸é …。 這å¯åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€> é¸é …é 籤完æˆã€‚" name="land set landing point" value="19"/> </action_set> - <action_set description="These Abilities include powers which affect parcel options, such as 'Create Objects', 'Edit Terrain', and music & media settings." name="Parcel Settings"> - <action description="Change music & media settings" longdescription="Change streaming music and movie settings in About Land > Media tab." name="land change media" value="20"/> - <action description="Toggle 'Edit Terrain'" longdescription="Toggle 'Edit Terrain'. *WARNING* About Land > Options tab > Edit Terrain allows anyone to terraform your land's shape, and place and move Linden plants. Be sure you know what you're doing before assigning this Ability. Editing terrain is toggled in About Land > Options tab." name="land edit" value="21"/> - <action description="Toggle various About Land > Options settings" longdescription="Toggle 'Safe (no damage)', 'Fly', and allow other Residents to: 'Edit Terrain', 'Build', 'Create Landmarks', and 'Run Scripts' on group-owned land in About Land > Options tab." name="land options" value="22"/> + <action_set description="這些能力包括有權更改地段é¸é …,例如「新建物件ã€ã€ã€Œç·¨è¼¯åœ°å½¢ã€ï¼Œå’ŒéŸ³æ¨‚ã€åª’é«”è¨å®šç‰ã€‚" name="Parcel Settings"> + <action description="更改音樂和媒體è¨å®š" longdescription="在「土地資料ã€> 媒體é 籤更改串æµéŸ³æ¨‚和影片è¨å®šã€‚" name="land change media" value="20"/> + <action description="切æ›ã€Œç·¨è¼¯åœ°å½¢ã€è¨å®š" longdescription="切æ›ã€Œç·¨è¼¯åœ°å½¢ã€è¨å®šã€‚ *è¦å‘Š* 「土地資料ã€> 「é¸é …ã€é 籤 >「編輯地形ã€å¯å…è¨±ä»»ä½•äººè®Šæ›´ä½ çš„åœŸåœ°å½¢ç‹€ï¼Œæ”¾ç½®æˆ–ç§»å‹• Linden æ¤ç‰©ã€‚ è³¦äºˆé€™é …èƒ½åŠ›ä¹‹å‰ï¼Œæ•¬è«‹æ…Žé‡è€ƒæ…®ã€‚ 編輯地形å¯åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€> é¸é …é 籤åšåˆ‡æ›ã€‚" name="land edit" value="21"/> + <action description="切æ›å„é …ã€ŒåœŸåœ°è³‡æ–™ã€> é¸é …è¨å®š" longdescription="在「土地資料ã€> é¸é …é 籤切æ›ã€Œå®‰å…¨ï¼ˆç„¡å‚·å®³ï¼‰ã€è¨å®šï¼Œä¸¦å…許其他居民在群組所有土地上「編輯地形ã€ã€ã€Œå»ºè£½ã€ã€ã€Œå»ºç«‹åœ°æ¨™ã€ã€ã€ŒåŸ·è¡Œè…³æœ¬ã€ã€‚" name="land options" value="22"/> </action_set> - <action_set description="These Abilities include powers which allow Members to bypass restrictions on group-owned parcels." name="Parcel Powers"> - <action description="Always allow 'Edit Terrain'" longdescription="Members in a Role with this Ability can edit terrain on a group-owned parcel, even if it's turned off in About Land > Options tab." name="land allow edit land" value="23"/> - <action description="Always allow 'Fly'" longdescription="Members in a Role with this Ability can fly on a group-owned parcel, even if it's turned off in About Land > Options tab." name="land allow fly" value="24"/> - <action description="Always allow 'Create Objects'" longdescription="Members in a Role with this Ability can create objects on a group-owned parcel, even if it's turned off in About Land > Options tab." name="land allow create" value="25"/> - <action description="總是å…許 'å‰µé€ åœ°æ¨™'" longdescription="Members in a Role with this Ability can landmark a group-owned parcel, even if it's turned off in About Land > Options tab." name="land allow landmark" value="26"/> - <action description="Allow 'Set Home to Here' on group land" longdescription="Members in a Role with this Ability can use World menu > Landmarks > Set Home to Here on a parcel deeded to this group." name="land allow set home" value="28"/> - <action description="Allow 'Event Hosting' on group land" longdescription="Members in a Role with this Ability can select group owned parcels as venus when hosting an event." name="land allow host event" value="41"/> + <action_set description="這些能力包括å¯å…許æˆå“¡åœ¨ç¾¤çµ„所有地段上è¦é¿é™åˆ¶ã€‚" name="Parcel Powers"> + <action description="固定å…許「編輯地形ã€" longdescription="èº«è² å…·æ¤èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡å¯ä»¥åœ¨ç¾¤çµ„所有地段上編輯地形,無論這功能在「土地資料ã€> é¸é …é 籤裡是å¦è¢«ç¦æ¢ã€‚" name="land allow edit land" value="23"/> + <action description="固定å…許「飛行ã€" longdescription="èº«è² å…·æ¤èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡å¯ä»¥åœ¨ç¾¤çµ„所有地段上飛行,無論這能力是å¦åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€> é¸é …é ç±¤è£¡è¢«ç¦æ¢ã€‚" name="land allow fly" value="24"/> + <action description="固定å…許「新建物件ã€" longdescription="èº«è² å…·æ¤èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡å¯ä»¥åœ¨ç¾¤çµ„所有地段上新建物件,無論這能力是å¦åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€> é¸é …é ç±¤è£¡è¢«ç¦æ¢ã€‚" name="land allow create" value="25"/> + <action description="總是å…許「新建地標ã€" longdescription="èº«è² å…·æ¤èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡å¯ä»¥å°‡ç¾¤çµ„所有的地段è¨ç‚ºåœ°æ¨™ï¼Œç„¡è«–這能力是å¦åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€> é¸é …é ç±¤è£¡è¢«ç¦æ¢ã€‚" name="land allow landmark" value="26"/> + <action description="å…許在群組所有土地上「將這裡è¨ç‚ºæˆ‘的家ã€" longdescription="èº«è² å…·æ¤èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡ï¼Œå¯ä»¥åœ¨è®“渡給這群組的地段上使用「世界ã€é¸å–® > 地標 > 「將這裡è¨ç‚ºæˆ‘的家ã€ã€‚" name="land allow set home" value="28"/> + <action description="å…許在群組所有土地上「開辦活動ã€" longdescription="èº«è² å…·é€™èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡ï¼Œå¯ä»¥é¸æ“‡ç¾¤çµ„æ‰€æœ‰çš„åœ°æ®µä½œç‚ºé–‹è¾¦æ´»å‹•çš„å ´åœ°ã€‚" name="land allow host event" value="41"/> </action_set> - <action_set description="These Abilities include powers to allow or restrict access to group-owned parcels, including freezing and ejecting Residents." name="Parcel Access"> - <action description="Manage parcel Access lists" longdescription="Manage parcel Access lists in About Land > Access tab." name="land manage allowed" value="29"/> - <action description="Manage parcel Ban lists" longdescription="Manage parcel Ban lists in About Land > Access tab." name="land manage banned" value="30"/> - <action description="Change parcel 'Sell passes to' settings" longdescription="Change parcel 'Sell passes to' settings in About Land > Access tab." name="land manage passes" value="31"/> - <action description="將地段內的居民踢出åŠå‡çµ" longdescription="Members in a Role with this Ability can handle an unwelcome Resident on a group-owned parcel by right-clicking them, then selecting 'Eject' or 'Freeze'." name="land admin" value="32"/> + <action_set description="這些能力包括å¯å…許或é™åˆ¶äººå€‘出入群組所有的地段,包括把居民å‡çµæˆ–踢出。" name="Parcel Access"> + <action description="管ç†åœ°æ®µå‡ºå…¥è¨±å¯åå–®" longdescription="在「土地資料ã€> 出入許å¯é 籤管ç†åœ°æ®µçš„出入許å¯å單。" name="land manage allowed" value="29"/> + <action description="管ç†åœ°æ®µç¦å…¥åå–®" longdescription="在「土地資料ã€> 出入許å¯é 籤管ç†åœ°æ®µçš„ç¦å…¥å單。" name="land manage banned" value="30"/> + <action description="變更地段的「通行è‰å‡ºå”®å°è±¡ã€è¨å®š" longdescription="在「土地資料ã€> 出入許å¯é 籤變更地段的「通行è‰å‡ºå”®å°è±¡ã€è¨å®šã€‚" name="land manage passes" value="31"/> + <action description="將地段內的居民踢出åŠå‡çµ" longdescription="èº«è² å…·æ¤èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡ï¼Œå¯ä»¥åœ¨ç¾¤çµ„所有地段上處置ä¸å—æ¡è¿Žçš„居民,按å³éµåŠ ä»¥ã€Œè¸¢å‡ºã€æˆ–「å‡çµã€ã€‚" name="land admin" value="32"/> </action_set> - <action_set description="These Abilities include powers to allow members to return objects and place and move Linden plants. This is useful for Members to clean up litter and do landscaping, but it should also be used with care, because there's no undo for returning objects." name="Parcel Content"> - <action description="Return objects owned by group" longdescription="Return objects on group-owned parcels that are owned by the group in About Land > Objects tab." name="land return group owned" value="48"/> - <action description="Return objects set to group" longdescription="Return objects on group-owned parcels that are set to the group in About Land > Objects tab." name="land return group set" value="33"/> - <action description="退回éžç¾¤çµ„物件" longdescription="Return objects on group-owned parcels that are non-group in About Land > Objects tab." name="land return non group" value="34"/> - <action description="Landscaping using Linden plants" longdescription="Landscaping ability to place and move Linden trees, plants, and grasses. These items can be found in your inventory's Library > Objects folder, or they can be created via the Build menu." name="land gardening" value="35"/> + <action_set description="這些能力包括有權å…許æˆå“¡é€è¿”物件,或放置或移動 Linden æ¤ç‰©ã€‚ 這能力的用處是讓æˆå“¡æ¸…ç†ä¸€ä¸‹åœŸåœ°ï¼Œåšä¸€åšæ™¯è§€ä½ˆç½®ï¼Œä½†å¿…é ˆå°å¿ƒä½¿ç”¨ï¼Œå› 為物件一旦被é€è¿”後å³ç„¡æ³•復原。" name="Parcel Content"> + <action description="é€è¿”群組所有的物件" longdescription="在「土地資料ã€> 物件é 籤é€è¿”使–¼ç¾¤çµ„æ‰€æ“æœ‰åœ°æ®µä¸Šçš„ç¾¤çµ„æ‰€æ“æœ‰ç‰©ä»¶ã€‚" name="land return group owned" value="48"/> + <action description="é€è¿”è¨çµ¦ç¾¤çµ„的物件" longdescription="在「土地資料ã€> 物件é 籤é€è¿”使–¼ç¾¤çµ„æ‰€æ“æœ‰åœ°æ®µçš„è¨çµ¦ç¾¤çµ„的物件。" name="land return group set" value="33"/> + <action description="退回éžç¾¤çµ„物件" longdescription="在「土地資料ã€> 物件é 籤é€è¿”使–¼ç¾¤çµ„æ‰€æ“æœ‰åœ°æ®µçš„éžç¾¤çµ„物件。" name="land return non group" value="34"/> + <action description="用 Linden æ¤ç‰©ä½ˆç½®æ™¯è§€ã€‚" longdescription="å…許放置或移動 Linden 樹種ã€è‰åœ°å’Œå…¶ä»–æ¤ç‰©çš„æ™¯è§€ä½ˆç½®èƒ½åŠ›ã€‚ é€™äº›ç‰©é …åœ¨ä½ æ”¶ç´å€çš„資æºåº« > ç‰©ä»¶è³‡æ–™å¤¾å¯æ‰¾åˆ°ï¼Œä½ 也å¯ä»¥é€éŽã€Œå»ºè£½ã€é¸å–®åŠ ä»¥æ–°å»ºã€‚" name="land gardening" value="35"/> </action_set> - <action_set description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Build Tools > General tab. Right-click an object and Edit to see its settings." name="Object Management"> - <action description="讓渡物件給群組" longdescription="Deed objects to group in the Build Tools > General tab." name="object deed" value="36"/> - <action description="Manipulate (move, copy, modify) group-owned objects" longdescription="Manipulate (move, copy, modify) group-owned objects in the Build Tools > General tab." name="object manipulate" value="38"/> - <action description="Set group-owned objects for sale" longdescription="Set group-owned objects for sale in the Build Tools > General tab." name="object set sale" value="39"/> + <action_set description="這些能力包括有權讓渡ã€ä¿®æ”¹æˆ–å‡ºå”®æœ¬ç¾¤çµ„æ“æœ‰çš„物件。 這些變更å¯åœ¨ã€Œå»ºè£½å·¥å…·ã€> 基本é 籤完æˆã€‚ å°ä¸€å€‹ç‰©ä»¶é»žæŒ‰å³éµï¼Œé¸æ“‡ã€Œç·¨è¼¯ã€å³å¯å¯Ÿçœ‹å…¶è¨å®šã€‚" name="Object Management"> + <action description="讓渡物件給群組" longdescription="在「建製工具ã€> 基本é 籤將物件讓渡給群組。" name="object deed" value="36"/> + <action description="æ“縱(移動ã€è¤‡è£½ã€ä¿®æ”¹ï¼‰ç¾¤çµ„æ‰€æ“æœ‰ç‰©ä»¶" longdescription="在「建製工具ã€> 基本é 籤æ“縱(移動ã€è¤‡è£½ã€ä¿®æ”¹ï¼‰ç¾¤çµ„æ‰€æ“æœ‰ç‰©ä»¶ã€‚" name="object manipulate" value="38"/> + <action description="è¨å®šå‡ºå”®ç¾¤çµ„æ‰€æ“æœ‰ç‰©ä»¶" longdescription="在「建製工具ã€> 基本é 籤è¨å®šå‡ºå”®ç¾¤çµ„æ‰€æ“æœ‰ç‰©ä»¶ã€‚" name="object set sale" value="39"/> </action_set> - <action_set description="These Abilities include powers which require Members to pay group liabilities and receive group dividends, and restrict access to group account history." name="Accounting"> - <action description="Pay group liabilities and receive group dividends" longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees." name="accounting accountable" value="40"/> + <action_set description="é€™äº›èƒ½åŠ›åŒ…æ‹¬æœ‰æ¬Šè¦æ±‚æˆå“¡æ”¯ä»˜ç¾¤çµ„é–‹éŠ·ã€æ”¶å–群組利æ¯ï¼Œé™åˆ¶ç¾¤çµ„帳號æ·å²é–‹æ”¾å°è±¡ã€‚" name="Accounting"> + <action description="支付群組開銷,收å–群組利æ¯" longdescription="èº«è² å…·é€™èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡ï¼Œå°‡è‡ªå‹•支付群組開銷並收å–群組利æ¯ã€‚ 這表示他們將ç²å–ç¾¤çµ„æ‰€æ“æœ‰åœŸåœ°å‡ºå”®å¾Œçš„éƒ¨åˆ†æ”¶å…¥ï¼Œæ¯æ—¥çµç®—ï¼ŒåŒæ™‚並分攤地段刊登費ç‰é–‹éŠ·ã€‚" name="accounting accountable" value="40"/> </action_set> - <action_set description="These Abilities include powers to allow Members to send, receive, and view group Notices." name="Notices"> - <action description="é€å‡ºé€šçŸ¥" longdescription="Members in a Role with this Ability can send Notices via the Group > Notices section." name="notices send" value="42"/> - <action description="接收通知與察看éŽåŽ»é€šçŸ¥" longdescription="Members in a Role with this Ability can receive Notices and view past Notices in Group > Notices section." name="notices receive" value="43"/> + <action_set description="這些能力包括å¯å…許æˆå“¡ç™¼é€ã€æŽ¥æ”¶ä¸¦å¯Ÿçœ‹ç¾¤çµ„通知。" name="Notices"> + <action description="é€å‡ºé€šçŸ¥" longdescription="èº«è² å…·é€™èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡ï¼Œå¯ä»¥åˆ°ã€Œç¾¤çµ„ã€> 通知欄發é€é€šçŸ¥ã€‚" name="notices send" value="42"/> + <action description="接收通知與察看éŽåŽ»é€šçŸ¥" longdescription="èº«è² å…·é€™èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡ï¼Œå¯ä»¥åˆ°ã€Œç¾¤çµ„ã€> 通知欄接收通知並察看éŽåŽ»çš„é€šçŸ¥ã€‚" name="notices receive" value="43"/> </action_set> - <action_set description="These Abilities include powers to allow or restrict access to group chat sessions and group voice chat." name="Chat"> - <action description="åŠ å…¥ç¾¤çµ„èŠå¤©" longdescription="Members in a Role with this Ability can join group chat sessions, for text and voice." name="join group chat" value="16"/> - <action description="åŠ å…¥ç¾¤çµ„èªžéŸ³èŠå¤©" longdescription="Members in a Role with this Ability can join group voice chat sessions. NOTE: The Join Group Chat ability is required to access the voice chat session." name="join voice chat" value="27"/> - <action description="é©åº¦æˆäººå…§å®¹çš„群組èŠå¤©" longdescription="Members in a Role with this Ability can control access and participation in group voice and text chat sessions." name="moderate group chat" value="37"/> + <action_set description="這些能力包括å¯å…許或é™åˆ¶äººå€‘åŠ å…¥ç¾¤çµ„èŠå¤©æœƒè©±å’Œç¾¤çµ„語音èŠå¤©ã€‚" name="Chat"> + <action description="åŠ å…¥ç¾¤çµ„èŠå¤©" longdescription="èº«è² å…·é€™èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡ï¼Œå¯ä»¥åŠ å…¥ç¾¤çµ„çš„æ–‡å—æˆ–語音èŠå¤©æœƒè©±ã€‚" name="join group chat" value="16"/> + <action description="åŠ å…¥ç¾¤çµ„èªžéŸ³èŠå¤©" longdescription="èº«è² å…·é€™èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡ï¼Œå¯ä»¥åŠ å…¥ç¾¤çµ„çš„èªžéŸ³èŠå¤©æœƒè©±ã€‚ 注æ„ï¼šæ¬²åŠ å…¥èªžéŸ³èŠå¤©æœƒè©±ï¼Œéœ€æœ‰ã€ŒåŠ å…¥ç¾¤çµ„èŠå¤©ã€èƒ½åŠ›ã€‚" name="join voice chat" value="27"/> + <action description="é©åº¦æˆäººå…§å®¹çš„群組èŠå¤©" longdescription="èº«è² å…·é€™èƒ½åŠ›çš„è§’è‰²çš„æˆå“¡ï¼Œå¯ä»¥æŽ§åˆ¶èª°å¯åŠ å…¥ç¾¤çµ„èªžéŸ³å’Œæ–‡å—èŠå¤©æœƒè©±ã€‚" name="moderate group chat" value="37"/> </action_set> </role_actions> diff --git a/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml b/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml index 7d8a502594..83a9bdf6a5 100644 --- a/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml @@ -11,7 +11,7 @@ (狀態) </text> <text name="currentlook_name"> - MyOutfit With a really Long Name like MOOSE + å稱很長ã€å¾ˆé•·ã€å¾ˆé•·ã€å¾ˆé•·ã€å¾ˆé•·çš„ MyOutfit </text> <button label="" name="edit_outfit_btn" tool_tip="ç·¨è¼¯é€™è£æ‰®"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml b/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml index 7abe95a402..c8aae15011 100644 --- a/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml @@ -1,16 +1,37 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="事物" name="objects panel"> <panel label="" name="sidepanel__inventory_panel"> + <layout_stack name="inventory_layout_stack"> + <layout_panel name="inbox_layout_panel"> + <panel label="" name="marketplace_inbox"> + <string name="InboxLabelWithArg"> + æ”¶åˆ°çš„ç‰©é … ([NUM]) + </string> + <string name="InboxLabelNoArg"> + æ”¶åˆ°çš„ç‰©é … + </string> + <button label="æ”¶åˆ°çš„ç‰©é …" name="inbox_btn"/> + <text name="inbox_fresh_new_count"> + [NUM] é …æ–°çš„ + </text> + <panel name="inbox_inventory_placeholder_panel" tool_tip="å°‡ç‰©é …æ‹–æ›³ç½®æ”¾åˆ°æ”¶ç´å€ï¼Œå³å¯é–‹å§‹ä½¿ç”¨"> + <text name="inbox_inventory_placeholder"> + å¾žç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚é›†è³¼å¾—ç‰©é …å°‡é€åˆ°é€™è£¡ã€‚ + </text> + </panel> + </panel> + </layout_panel> + </layout_stack> <panel name="button_panel"> <layout_stack name="button_panel_ls"> <layout_panel name="info_btn_lp"> <button label="檔案" name="info_btn" tool_tip="顯示物件檔案"/> </layout_panel> <layout_panel name="share_btn_lp"> - <button label="分享" name="share_btn" tool_tip="Share an inventory item"/> + <button label="分享" name="share_btn" tool_tip="分享一個收ç´å€ç‰©å“"/> </layout_panel> <layout_panel name="shop_btn_lp"> - <button label="Shop" name="shop_btn" tool_tip="Open Marketplace webpage"/> + <button label="購物" name="shop_btn" tool_tip="開啟 Marketplace 購物市集網é "/> <button label="穿上" name="wear_btn" tool_tip="ç©¿ä¸Šæ‰€é¸æ“‡çš„è£æ‰®"/> <button label="æ’æ”¾" name="play_btn"/> <button label="瞬間傳é€" name="teleport_btn" tool_tip="瞬間傳é€åˆ°æ‰€é¸çš„å€åŸŸ"/> diff --git a/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml b/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml index adc815fb4b..1b093e0ecd 100644 --- a/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (未知) </panel.string> + <panel.string name="unknown_multiple"> + (未知 / å¤šé …ï¼‰ + </panel.string> <panel.string name="public"> (公開) </panel.string> @@ -10,7 +13,7 @@ ä½ å¯ä»¥ï¼š </panel.string> <panel.string name="owner_can"> - æ“æœ‰è€…å¯ä»¥ï¼š + 所有人å¯ä»¥ï¼š </panel.string> <panel.string name="acquiredDate"> [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] @@ -19,7 +22,7 @@ (收ç´å€ï¼‰ </panel.string> <panel.string name="origin_inworld"> - (Inworld) + (在虛擬世界) </panel.string> <text name="title" value="ç‰©å“æª”案"/> <text name="origin" value="(收ç´å€ï¼‰"/> @@ -35,7 +38,7 @@ å‰µé€ è€…ï¼š </text> <text name="LabelOwnerTitle"> - æ“æœ‰è€…: + 所有人: </text> <text name="LabelAcquiredTitle"> å–得於: @@ -45,26 +48,26 @@ ä½ å¯ä»¥ï¼š </text> <check_box label="修改" name="CheckOwnerModify"/> - <check_box label="覆製" name="CheckOwnerCopy"/> + <check_box label="æšåº¨" name="CheckOwnerCopy"/> <check_box label="轉移" name="CheckOwnerTransfer"/> <text name="AnyoneLabel"> 任何人: </text> - <check_box label="覆製" name="CheckEveryoneCopy"/> + <check_box label="æšåº¨" name="CheckEveryoneCopy"/> <text name="GroupLabel"> 群組: </text> - <check_box label="分享" name="CheckShareWithGroup" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."/> + <check_box label="分享" name="CheckShareWithGroup" tool_tip="å…許æ¤ç¾¤çµ„所有æˆå“¡å…±äº«ä½ 修改æ¤ç‰©ä»¶çš„æ¬Šé™ã€‚ ä½ å¿…é ˆè®“æ¸¡æ‰èƒ½å•Ÿå‹•角色é™åˆ¶ã€‚"/> <text name="NextOwnerLabel"> - ä¸‹ä¸€å€‹æ“æœ‰è€…: + 下一個所有人: </text> <check_box label="修改" name="CheckNextOwnerModify"/> - <check_box label="覆製" name="CheckNextOwnerCopy"/> - <check_box label="轉移" name="CheckNextOwnerTransfer" tool_tip="Next owner can give away or resell this object"/> + <check_box label="æšåº¨" name="CheckNextOwnerCopy"/> + <check_box label="轉移" name="CheckNextOwnerTransfer" tool_tip="下一個所有人å¯è´ˆé€æˆ–轉售這個物件"/> </panel> <check_box label="出售" name="CheckPurchase"/> <combo_box name="combobox sale copy"> - <combo_box.item label="副本" name="Copy"/> + <combo_box.item label="æšåº¨" name="Copy"/> <combo_box.item label="原件" name="Original"/> </combo_box> <spinner label="åƒ¹æ ¼ï¼š L$" name="Edit Cost"/> diff --git a/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml b/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml index 3d46e52726..982dde4010 100644 --- a/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml @@ -7,28 +7,34 @@ 讓渡 </panel.string> <panel.string name="text modify info 1"> - ä½ å¯ä»¥ä¿®æ”¹é€™å€‹ç‰©ä»¶ + ä½ èƒ½ä¿®æ”¹é€™å€‹ç‰©ä»¶ </panel.string> <panel.string name="text modify info 2"> - ä½ å¯ä»¥ä¿®æ”¹é€™äº›ç‰©ä»¶ + ä½ èƒ½ä¿®æ”¹é€™äº›ç‰©ä»¶ </panel.string> <panel.string name="text modify info 3"> - ä½ ä¸å¯ä»¥ä¿®æ”¹é€™å€‹ç‰©ä»¶ + ä½ ä¸èƒ½ä¿®æ”¹é€™å€‹ç‰©ä»¶ </panel.string> <panel.string name="text modify info 4"> - ä½ ä¸å¯ä»¥ä¿®æ”¹é€™äº›ç‰©ä»¶ + ä½ ä¸èƒ½ä¿®æ”¹é€™äº›ç‰©ä»¶ + </panel.string> + <panel.string name="text modify info 5"> + 無法跨地å€ä¿®æ”¹é€™å€‹ç‰©ä»¶ + </panel.string> + <panel.string name="text modify info 6"> + 無法跨地å€ä¿®æ”¹é€™äº›ç‰©ä»¶ </panel.string> <panel.string name="text modify warning"> - 這個物件有è¯çµåˆ°å…¶ä»–部分 + é€™å€‹ç‰©ä»¶å«æœ‰è¯çµçš„部分 </panel.string> <panel.string name="Cost Default"> åƒ¹æ ¼ï¼š L$ </panel.string> <panel.string name="Cost Total"> - 總價: L$ + 總價:L$ </panel.string> <panel.string name="Cost Per Unit"> - 單價: L$ + 單價:L$ </panel.string> <panel.string name="Cost Mixed"> æ··åˆåƒ¹æ ¼ @@ -37,7 +43,7 @@ æ··åˆéŠ·å”® </panel.string> <text name="title" value="物件檔案"/> - <text name="where" value="(Inworld)"/> + <text name="where" value="(在虛擬世界)"/> <panel label="" name="properties_panel"> <text name="Name:"> å稱: @@ -49,23 +55,23 @@ å‰µé€ è€…ï¼š </text> <text name="Owner:"> - æ“æœ‰è€…: + 所有人: </text> <text name="Group_label"> 群組: </text> - <button name="button set group" tool_tip="鏿“‡ä¸€å€‹ç¾¤çµ„以分享這個物件的權é™"/> + <button name="button set group" tool_tip="鏿“‡ä¸€å€‹ç¾¤çµ„以分享這物件的權é™"/> <name_box initial_value="載入ä¸..." name="Group Name Proxy"/> - <button label="讓渡" label_selected="讓渡" name="button deed" tool_tip="Deeding gives this item away with next owner permissions. Group shared objects can be deeded by a group officer."/> + <button label="讓渡" label_selected="讓渡" name="button deed" tool_tip="ã€Œè®“æ¸¡ã€æœƒæŠŠé€™ç‰©ä»¶è´ˆé€å‡ºåŽ»ä¸¦è³¦äºˆã€Œä¸‹ä¸€å€‹æ‰€æœ‰äººã€æ¬Šé™ã€‚ 群組所分享的物件å¯ç”±ç¾¤çµ„è·å“¡åŠ ä»¥è®“æ¸¡ã€‚"/> <text name="label click action"> - 點擊以: + 點按以: </text> <combo_box name="clickaction"> <combo_box.item label="觸碰(é è¨ï¼‰" name="Touch/grab(default)"/> <combo_box.item label="å在物件上" name="Sitonobject"/> <combo_box.item label="購買物件" name="Buyobject"/> <combo_box.item label="支付物件" name="Payobject"/> - <combo_box.item label="開啟" name="Open"/> + <combo_box.item label="打開" name="Open"/> </combo_box> <panel name="perms_inv"> <text name="perm_modify"> @@ -74,27 +80,30 @@ <text name="Anyone can:"> 任何人: </text> - <check_box label="覆製" name="checkbox allow everyone copy"/> + <check_box label="æšåº¨" name="checkbox allow everyone copy"/> <check_box label="移動" name="checkbox allow everyone move"/> <text name="GroupLabel"> 群組: </text> - <check_box label="分享" name="checkbox share with group" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."/> + <check_box label="分享" name="checkbox share with group" tool_tip="å…許æ¤ç¾¤çµ„所有æˆå“¡å…±äº«ä½ 修改æ¤ç‰©ä»¶çš„æ¬Šé™ã€‚ ä½ å¿…é ˆè®“æ¸¡æ‰èƒ½å•Ÿå‹•角色é™åˆ¶ã€‚"/> <text name="NextOwnerLabel"> - ä¸‹ä¸€å€‹æ“æœ‰è€…: + 下一個所有人: </text> <check_box label="修改" name="checkbox next owner can modify"/> - <check_box label="覆製" name="checkbox next owner can copy"/> - <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="ä¸‹ä¸€å€‹æ“æœ‰è€…å¯ä»¥é€å‡ºæˆ–轉售這個物件"/> + <check_box label="æšåº¨" name="checkbox next owner can copy"/> + <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="下一個所有人å¯è´ˆé€æˆ–轉售這個物件"/> </panel> <check_box label="出售" name="checkbox for sale"/> <combo_box name="sale type"> - <combo_box.item label="副本" name="Copy"/> + <combo_box.item label="æšåº¨" name="Copy"/> <combo_box.item label="內容" name="Contents"/> <combo_box.item label="原件" name="Original"/> </combo_box> <spinner label="åƒ¹æ ¼ï¼š L$" name="Edit Cost"/> <check_box label="顯示在æœå°‹ä¸" name="search_check" tool_tip="讓其他人å¯ä»¥åœ¨æœå°‹çµæžœä¸å¯Ÿçœ‹åˆ°æ¤ç‰©ä»¶"/> + <text name="pathfinding_attributes_label"> + 尋徑屬性: + </text> <text name="B:"> B: </text> @@ -115,7 +124,7 @@ </text> </panel> <panel name="button_panel"> - <button label="開啟" name="open_btn"/> + <button label="打開" name="open_btn"/> <button label="支付" name="pay_btn"/> <button label="購買" name="buy_btn"/> <button label="細節" name="details_btn"/> diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml index 6dbe44d32e..7e17ed6864 100644 --- a/indra/newview/skins/default/xui/zh/strings.xml +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -29,11 +29,14 @@ å¿«å–æ¸…除ä¸... </string> <string name="StartupInitializingTextureCache"> - æè³ªå¿«å–åˆå§‹åŒ–ä¸... + æ£åœ¨åˆå§‹åŒ–æè³ªå¿«å–... </string> <string name="StartupInitializingVFS"> VFS åˆå§‹åŒ–ä¸... </string> + <string name="StartupRequireDriverUpdate"> + 顯åƒåˆå§‹åŒ–失敗。 è«‹æ›´æ–°ä½ çš„é¡¯åƒå¡é©…動程å¼ï¼ + </string> <string name="ProgressRestoring"> 回å˜ä¸... </string> @@ -44,7 +47,7 @@ 全亮(舊版) </string> <string name="LoginInProgress"> - 登入ä¸ã€‚[APP_NAME] å¯èƒ½å‡ºç¾å‡çµç‹€æ…‹ã€‚è«‹è€å¿ƒç¨ç‰ã€‚ + 登入ä¸ã€‚[APP_NAME] å¯èƒ½çœ‹ä¼¼å‡çµï¼Œè«‹è€å¿ƒç¨ç‰ã€‚ è«‹ç¨å€™ã€‚ </string> <string name="LoginInProgressNoFrozen"> 登入ä¸... @@ -56,7 +59,7 @@ 進行帳戶ç¶è·... </string> <string name="LoginAttempt"> - å…ˆå‰ä¼åœ–嘗試登入失敗。ç¾ç™»å…¥ä¸ï¼Œå˜—試 [NUMBER] + å‰ä¸€æ¬¡ç™»å…¥å¤±æ•—。 登入ä¸ï¼Œç¬¬ [NUMBER] 次嘗試 </string> <string name="LoginPrecaching"> 世界載入ä¸... @@ -74,10 +77,10 @@ é©—è‰å¿«å–檔案(約需 60-90 ç§’å·¦å³ï¼‰... </string> <string name="LoginProcessingResponse"> - 回應處ç†ä¸... + æ£åœ¨è™•ç†å›žæ‡‰... </string> <string name="LoginInitializingWorld"> - 世界åˆå§‹åŒ–ä¸... + æ£åœ¨åˆå§‹åŒ–虛擬世界… </string> <string name="LoginDecodingImages"> 圖åƒè§£ç¢¼ä¸... @@ -91,6 +94,12 @@ <string name="LoginQuicktimeOK"> QuickTime å·²æˆåŠŸåˆå§‹åŒ–。 </string> + <string name="LoginRequestSeedCapGrant"> + è©¢å•地å€è² è·åŠ›â€¦ + </string> + <string name="LoginRetrySeedCapGrant"> + è©¢å•地å€è² è·åŠ›ï¼Œç¬¬ [NUMBER] 次嘗試… + </string> <string name="LoginWaitingForRegionHandshake"> 地å€äº¤æ¡ç‰å¾…ä¸... </string> @@ -101,25 +110,25 @@ æœè£ä¸‹è¼‰ä¸... </string> <string name="InvalidCertificate"> - 伺æœå™¨å›žå‚³ä¸€å€‹ç„¡æ•ˆæžœæå£žçš„æ†‘è‰ã€‚è«‹é€£ç¹«ç¶²æ ¼ç®¡ç†è€…。 + 伺æœå™¨å›žå‚³ä¸€å€‹ç„¡æ•ˆæˆ–æå£žçš„æ†‘è‰ã€‚ è«‹è¯çµ¡ç¶²æ ¼ç®¡ç†å“¡ã€‚ </string> <string name="CertInvalidHostname"> - An invalid hostname was used to access the server, please check your SLURL or Grid hostname. + 用了無效的主機å來è¯çµ¡ä¼ºæœå™¨ï¼Œè«‹æª¢æŸ¥ä½ çš„ SLURL æˆ–ç¶²æ ¼ä¸»æ©Ÿå。 </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. + 伺æœå™¨å‚³å›žçš„æ†‘è‰ç„¡æ³•用於 SSL。 è«‹è¯çµ¡ç¶²æ ¼ç®¡ç†å“¡ã€‚ </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"> 登入失敗。 @@ -128,10 +137,138 @@ çµæŸé€€å‡º </string> <string name="create_account_url"> - http://join.secondlife.com/ + http://join.secondlife.com/?sourceid=[sourceid] + </string> + <string name="LoginFailedViewerNotPermitted"> + ä½ ç›®å‰æ‰€ç”¨çš„ Viewer 已經無法å†é€²å…¥ç¬¬äºŒäººç”Ÿã€‚ 請到這個é é¢ä¸‹è¼‰æœ€æ–° Viewer: +http://secondlife.com/download + +欲知詳情,請åƒé–±ä¸‹é¢çš„常見å•題集: +http://secondlife.com/viewer-access-faq + </string> + <string name="LoginIntermediateOptionalUpdateAvailable"> + 有å¯ä»¥é¸æ“‡æ€§å®‰è£çš„æ›´æ–°ç‰ˆï¼š[VERSION] + </string> + <string name="LoginFailedRequiredUpdate"> + ä½ å¿…é ˆæ›´æ–°ç‚ºé€™å€‹ç‰ˆæœ¬ï¼š[VERSION] + </string> + <string name="LoginFailedAlreadyLoggedIn"> + æ¤ç”¨æˆ¶å·²ç¶“登入。 + </string> + <string name="LoginFailedAuthenticationFailed"> + 抱æ‰ï¼ æˆ‘å€‘ç„¡æ³•è®“ä½ ç™»å…¥ã€‚ +è«‹æª¢æŸ¥ç¢ºå®šä½ è¼¸å…¥äº†æ£ç¢ºçš„ + * 使用者å稱(例:bobsmith123 或 steller.sunshine) + * 密碼 +並請確定éµç›¤æ²’有鎖定大寫éµã€‚ + </string> + <string name="LoginFailedPasswordChanged"> + ç‚ºäº†å®‰å…¨èµ·è¦‹ï¼Œå·²ç¶“è®Šæ›´ä½ çš„å¯†ç¢¼ã€‚ +è«‹åˆ°ä½æ–¼ http://secondlife.com/password 的帳號é é¢ +回ç”安全驗è‰å•題後,é‡è¨å¯†ç¢¼ã€‚ +å¦‚æœ‰é€ æˆä¸ä¾¿è«‹å¤šåŒ…涵。 + </string> + <string name="LoginFailedPasswordReset"> + æˆ‘å€‘ç³»çµ±æœ‰æ‰€è®Šæ›´ï¼Œä½ å¿…é ˆé‡è¨å¯†ç¢¼ã€‚ +è«‹åˆ°ä½æ–¼ http://secondlife.com/password 的帳號é é¢ +回ç”安全驗è‰å•題後,é‡è¨å¯†ç¢¼ã€‚ +å¦‚æœ‰é€ æˆä¸ä¾¿è«‹å¤šåŒ…涵。 + </string> + <string name="LoginFailedEmployeesOnly"> + ç¬¬äºŒäººç”Ÿç›®å‰æš«æ™‚關閉進行ç¶è·ã€‚ +ç›®å‰åƒ…å…許林登員工登入。 +請到 www.secondlife.com/status 察看最新公告。 + </string> + <string name="LoginFailedPremiumOnly"> + ç¬¬äºŒäººç”Ÿæ¤æ™‚暫時é™åˆ¶ç™»å…¥ï¼Œä»¥ç¢ºä¿ä¸å½±éŸ¿æ•ˆèƒ½ï¼Œè®“ç›®å‰è™›æ“¬ä¸–ç•Œè£¡çš„ç”¨æˆ¶äº«å—æœ€ä½³çš„體驗。 + +å…è²»å¸³æˆ¶çš„ç”¨æˆ¶æ¤æ™‚æš«æ™‚ç„¡æ³•é€²å…¥ç¬¬äºŒäººç”Ÿï¼Œå› ç‚ºæˆ‘å€‘å¿…é ˆå„ªå…ˆå®¹ç´ä»˜è²»ç”¨æˆ¶ã€‚ + </string> + <string name="LoginFailedComputerProhibited"> + 無法從這部電腦進入第二人生。 +å¦‚ä½ èªç‚ºé€™æ˜¯æˆ‘們弄錯,請è¯çµ¡ support@secondlife.com。 + </string> + <string name="LoginFailedAcountSuspended"> + ä½ çš„å¸³è™Ÿè¦ç‰åˆ° [TIME] (太平洋時間)æ‰å¯ä½¿ç”¨ã€‚ + </string> + <string name="LoginFailedAccountDisabled"> + æ¤æ™‚無法完æˆä½ 的請求。 +請到 http://secondlife.com/support è¯çµ¡æ”¯æ´äººå“¡ç²å¾—幫助。 +å¦‚æžœä½ ç„¡æ³•è®Šæ›´å¯†ç¢¼ï¼Œè«‹è‡´é›» (866) 476-9763 (美國)。 + </string> + <string name="LoginFailedTransformError"> + 登入時的資料ä¸ä¸€è‡´ã€‚ +è«‹è¯çµ¡ support@secondlife.com。 + </string> + <string name="LoginFailedAccountMaintenance"> + ä½ çš„å¸³è™Ÿç›®å‰æ£åœ¨é€²è¡Œå°è¦æ¨¡çš„ç¶è·ã€‚ +ä½ çš„å¸³è™Ÿè¦ç‰åˆ° [TIME] (太平洋時間)æ‰å¯ä½¿ç”¨ã€‚ +å¦‚ä½ èªç‚ºé€™æ˜¯æˆ‘們弄錯,請è¯çµ¡ support@secondlife.com。 + </string> + <string name="LoginFailedPendingLogoutFault"> + 模擬器回應:登出請求出錯。 + </string> + <string name="LoginFailedPendingLogout"> + 系統æ£åœ¨è™•ç†ä½ 的登出。 +ä½ çš„å¸³è™Ÿè¦ç‰åˆ° [TIME] (太平洋時間)æ‰å¯ä½¿ç”¨ã€‚ + </string> + <string name="LoginFailedUnableToCreateSession"> + 無法建立有效的時域。 + </string> + <string name="LoginFailedUnableToConnectToSimulator"> + 無法連接到模擬器。 + </string> + <string name="LoginFailedRestrictedHours"> + ä½ çš„å¸³è™Ÿåƒ…èƒ½åœ¨ [START] 到 [END] (太平洋時間)時段進入第二人生。 +è«‹è€å¿ƒç‰åˆ°è©²æ™‚段å†å›žä¾†ã€‚ +å¦‚ä½ èªç‚ºé€™æ˜¯æˆ‘們弄錯,請è¯çµ¡ support@secondlife.com。 + </string> + <string name="LoginFailedIncorrectParameters"> + éŒ¯èª¤çš„åƒæ•¸ã€‚ +å¦‚ä½ èªç‚ºé€™æ˜¯æˆ‘們弄錯,請è¯çµ¡ support@secondlife.com。 + </string> + <string name="LoginFailedFirstNameNotAlphanumeric"> + å…¨å的第一個å—(first name)é ˆç‚ºè‹±æ–‡å—æ¯æˆ–數å—。 +å¦‚ä½ èªç‚ºé€™æ˜¯æˆ‘們弄錯,請è¯çµ¡ support@secondlife.com。 + </string> + <string name="LoginFailedLastNameNotAlphanumeric"> + å…¨å的第二個å—(last name)é ˆç‚ºè‹±æ–‡å—æ¯æˆ–數å—。 +å¦‚ä½ èªç‚ºé€™æ˜¯æˆ‘們弄錯,請è¯çµ¡ support@secondlife.com。 + </string> + <string name="LogoutFailedRegionGoingOffline"> + 地å€å³å°‡é›¢ç·šã€‚ +è«‹ç¨å¾…一分é˜å†è©¦ã€‚ + </string> + <string name="LogoutFailedAgentNotInRegion"> + 用戶ä¸åœ¨åœ°å€è£¡ã€‚ +è«‹ç¨å¾…一分é˜å†è©¦ã€‚ + </string> + <string name="LogoutFailedPendingLogin"> + åœ°å€æ£åœ¨ç™»å…¥å¦ä¸€å€‹æ™‚域。 +è«‹ç¨å¾…一分é˜å†è©¦ã€‚ + </string> + <string name="LogoutFailedLoggingOut"> + åœ°å€æ£åœ¨ç™»å…¥ä¸Šä¸€å€‹æ™‚域。 +è«‹ç¨å¾…一分é˜å†è©¦ã€‚ + </string> + <string name="LogoutFailedStillLoggingOut"> + åœ°å€æ£åœ¨ç™»å‡ºä¸Šä¸€å€‹æ™‚域。 +è«‹ç¨å¾…一分é˜å†è©¦ã€‚ + </string> + <string name="LogoutSucceeded"> + 地å€å‰›å‰›ç™»å‡ºä¸Šä¸€å€‹æ™‚域。 +è«‹ç¨å¾…一分é˜å†è©¦ã€‚ + </string> + <string name="LogoutFailedLogoutBegun"> + 地å€å·²ç¶“開始登出程åºã€‚ +è«‹ç¨å¾…一分é˜å†è©¦ã€‚ + </string> + <string name="LoginFailedLoggingOutSession"> + ç³»çµ±å·²ç¶“é–‹å§‹ç™»å‡ºä½ çš„ä¸Šä¸€å€‹æ™‚åŸŸã€‚ +è«‹ç¨å¾…一分é˜å†è©¦ã€‚ </string> <string name="AgentLostConnection"> - 這個地å€å¯èƒ½éé‡å•é¡Œï¼Œè«‹æª¢æŸ¥ä½ çš„ç¶²è·¯é€£ç·šã€‚ + 本å€åŸŸå¯èƒ½æ£ç™¼ç”Ÿå•題。 è«‹æª¢æŸ¥ä½ çš„ç¶²éš›ç¶²è·¯é€£ç·šæ˜¯å¦æ£å¸¸ã€‚ </string> <string name="SavingSettings"> ä½ çš„è¨å®šå„²å˜ä¸... @@ -158,7 +295,7 @@ (無å稱) </string> <string name="TooltipOwner"> - æ“æœ‰è€…: + 所有人: </string> <string name="TooltipPublic"> 公開 @@ -196,60 +333,90 @@ <string name="TooltipMustSingleDrop"> åªæœ‰ä¸€å€‹ç‰©å“å¯ä»¥è¢«æ‹–曳到æ¤è™• </string> - <string name="TooltipPrice" value="L$[AMOUNT]:"/> + <string name="TooltipPrice" value="L$[AMOUNT]:"/> + <string name="TooltipOutboxDragToWorld"> + å•†å®¶ç™¼ä»¶åŒ£å…§çš„ç‰©é …ç„¡æ³•ç”¢ç”Ÿåˆ°è™›æ“¬ä¸–ç•Œ + </string> + <string name="TooltipOutboxNoTransfer"> + 至少一個物件無法出售或轉移。 + </string> + <string name="TooltipOutboxNotInInventory"> + ä½ çš„å•†å®¶ç™¼ä»¶åŒ£åªèƒ½æŽ¥å—直接來自收ç´å€çš„ç‰©é …ã€‚ + </string> + <string name="TooltipOutboxWorn"> + ä½ ç©¿è‘—ä¸çš„ç‰©é …ç„¡æ³•æ”¾å…¥å•†å®¶ç™¼ä»¶åŒ£ã€‚ + </string> + <string name="TooltipOutboxCallingCard"> + å片ä¸å¾—放入商家發件匣 + </string> + <string name="TooltipOutboxFolderLevels"> + å·¢ç‹€è³‡æ–™å¤¾æ·±åº¦è¶…éŽ 3 + </string> + <string name="TooltipOutboxTooManyFolders"> + é ‚å±¤è³‡æ–™å¤¾çš„åè³‡æ–™å¤¾æ•¸ç›®è¶…éŽ 20 + </string> + <string name="TooltipOutboxTooManyObjects"> + é ‚å±¤è³‡æ–™å¤¾ç‰©é …æ•¸ç›®è¶…éŽ 200 + </string> + <string name="TooltipDragOntoOwnChild"> + 資料夾ä¸å¾—移到其å資料夾底下 + </string> + <string name="TooltipDragOntoSelf"> + 資料夾移動的目標ä¸å¾—為它本身 + </string> <string name="TooltipHttpUrl"> - 點擊以察看這個網é + 點按以察看這個網é </string> <string name="TooltipSLURL"> - 點擊以察看這個ä½ç½®è³‡è¨Š + 點按以察看這個ä½ç½®è³‡è¨Š </string> <string name="TooltipAgentUrl"> - 點擊以察看這個居民檔案 + 點按以察看這個居民檔案 </string> <string name="TooltipAgentInspect"> çžè§£æ›´å¤šæœ‰é—œé€™å€‹å±…æ°‘ </string> <string name="TooltipAgentMute"> - 點擊以å°éޖ這ä½å±…æ°‘ + 點按以å°éޖ這ä½å±…æ°‘ </string> <string name="TooltipAgentUnmute"> - 點擊以解除å°éޖ這ä½å±…æ°‘ + 點按以解除å°éޖ這ä½å±…æ°‘ </string> <string name="TooltipAgentIM"> - 點擊開始 IM 這ä½å±…æ°‘ + 點按開始 IM 這ä½å±…æ°‘ </string> <string name="TooltipAgentPay"> - 點擊以支付這ä½å±…æ°‘ + 點按以支付這ä½å±…æ°‘ </string> <string name="TooltipAgentOfferTeleport"> - 點擊以é€å‡ºçž¬é–“傳é€é‚€è«‹çµ¦é€™ä½å±…æ°‘ + 點按以é€å‡ºçž¬é–“傳é€é‚€è«‹çµ¦é€™ä½å±…æ°‘ </string> <string name="TooltipAgentRequestFriend"> - 點擊以é€å‡ºäº¤å‹é‚€è«‹çµ¦é€™ä½å±…æ°‘ + 點按以é€å‡ºäº¤å‹é‚€è«‹çµ¦é€™ä½å±…æ°‘ </string> <string name="TooltipGroupUrl"> - 點擊以察看這個群組的æè¿° + 點按以察看這個群組的æè¿° </string> <string name="TooltipEventUrl"> - 點擊以察看這個活動的æè¿° + 點按以察看這個活動的æè¿° </string> <string name="TooltipClassifiedUrl"> - Click to view this classified + 點按察看這個個人廣告 </string> <string name="TooltipParcelUrl"> - 點擊以察看這個地段的æè¿° + 點按以察看這個地段的æè¿° </string> <string name="TooltipTeleportUrl"> - 點擊以傳é€åˆ°é€™å€‹ä½ç½® + 點按以傳é€åˆ°é€™å€‹ä½ç½® </string> <string name="TooltipObjectIMUrl"> - 點擊以察看這個物件的æè¿° + 點按以察看這個物件的æè¿° </string> <string name="TooltipMapUrl"> - 點擊以察看æ¤è™•在地圖上的ä½ç½® + 點按以察看æ¤è™•在地圖上的ä½ç½® </string> <string name="TooltipSLAPP"> - 點擊以執行 secondlife:// 指令 + 點按以執行 secondlife:// 指令 </string> <string name="CurrentURL" value="ç›®å‰ç¶²å€ï¼š[CurrentURL]"/> <string name="SLurlLabelTeleport"> @@ -304,7 +471,7 @@ æœå°‹ä¸... </string> <string name="NoneFound"> - 未發ç¾ã€‚ + æŸ¥ç„¡çµæžœã€‚ </string> <string name="RetrievingData"> 檢索... @@ -328,7 +495,7 @@ (無) </string> <string name="AvalineCaller"> - Avaline Caller [ORDER] + Avaline 通話者 [ORDER] </string> <string name="AssetErrorNone"> 無錯誤 @@ -355,10 +522,10 @@ 檔案傳輸逾時 </string> <string name="AssetErrorCircuitGone"> - Circuit gone + 失去線路 </string> <string name="AssetErrorPriceMismatch"> - Viewer and server do not agree on price + Viewer 和伺æœå™¨ç„¡æ³•åŒæ„åƒ¹æ ¼ </string> <string name="AssetErrorUnknownStatus"> 未知狀態 @@ -391,13 +558,13 @@ 資料夾 </string> <string name="root"> - root + æ ¹ç›®éŒ„ </string> <string name="lsl2 script"> - LSL2 script + LSL2 腳本 </string> <string name="lsl bytecode"> - LSL bytecode + LSL ä½å…ƒçµ„碼 </string> <string name="tga texture"> tga æè³ª @@ -409,7 +576,7 @@ å¿«ç…§ </string> <string name="lost and found"> - Lost and Found + å¤±ç‰©æ‹›é ˜ </string> <string name="targa image"> targa åœ–åƒ @@ -438,6 +605,9 @@ <string name="symbolic folder link"> 資料夾è¯çµ </string> + <string name="mesh"> + ç¶²é¢ + </string> <string name="AvatarEditingAppearance"> (外觀編輯ä¸ï¼‰ </string> @@ -457,88 +627,88 @@ 生氣 </string> <string name="anim_away"> - Away + 離開 </string> <string name="anim_backflip"> - Backflip + 後空翻 </string> <string name="anim_express_laugh"> - Belly Laugh + æ§è…¹å¤§ç¬‘ </string> <string name="anim_express_toothsmile"> - BigSmile + 大微笑 </string> <string name="anim_blowkiss"> - Blow Kiss + é£›å» </string> <string name="anim_express_bored"> ç„¡èŠ </string> <string name="anim_bow"> - Bow + 彎腰點é </string> <string name="anim_clap"> æ‹æ‰‹ </string> <string name="anim_courtbow"> - Court Bow + å®®å»·éž èº¬ </string> <string name="anim_express_cry"> 哿³£ </string> <string name="anim_dance1"> - Dance 1 + 跳舞1 </string> <string name="anim_dance2"> - Dance 2 + 跳舞2 </string> <string name="anim_dance3"> - Dance 3 + 跳舞3 </string> <string name="anim_dance4"> - Dance 4 + 跳舞4 </string> <string name="anim_dance5"> - Dance 5 + 跳舞5 </string> <string name="anim_dance6"> - Dance 6 + 跳舞6 </string> <string name="anim_dance7"> - Dance 7 + 跳舞7 </string> <string name="anim_dance8"> - Dance 8 + 跳舞8 </string> <string name="anim_express_disdain"> - Disdain + 鄙視 </string> <string name="anim_drink"> - Drink + å–ä¸€å£ </string> <string name="anim_express_embarrased"> - Embarrassed + å°·å°¬ </string> <string name="anim_angry_fingerwag"> - Finger Wag + æ®å‹•食指 </string> <string name="anim_fist_pump"> - Fist Pump + é«˜èˆ‰å³æ‹³ </string> <string name="anim_yoga_float"> - Floating Yoga + 漂浮瑜伽 </string> <string name="anim_express_frown"> - Frown + 皺眉 </string> <string name="anim_impatient"> - Impatient + ä¸è€ç…© </string> <string name="anim_jumpforjoy"> - Jump For Joy + é›€èº </string> <string name="anim_kissmybutt"> - Kiss My Butt + 親我å±è‚¡ï¼ </string> <string name="anim_express_kiss"> è¦ªå» @@ -547,55 +717,55 @@ 笑 </string> <string name="anim_musclebeach"> - Muscle Beach + ç§€å¥ç¾Žè‚Œè‚‰ </string> <string name="anim_no_unhappy"> ä¸ï¼ˆä¸å¿«æ¨‚) </string> <string name="anim_no_head"> - ä¸ + å¦ </string> <string name="anim_nyanya"> Nya-nya-nya </string> <string name="anim_punch_onetwo"> - One-Two Punch + 連續左å³å‡ºæ‹³ </string> <string name="anim_express_open_mouth"> - Open Mouth + å¼µå£ </string> <string name="anim_peace"> - Peace + 和平手勢 </string> <string name="anim_point_you"> - Point at Other + 指著別人 </string> <string name="anim_point_me"> - Point at Self + 指著自己 </string> <string name="anim_punch_l"> - Punch Left + 左出拳 </string> <string name="anim_punch_r"> - Punch Right + å³å‡ºæ‹³ </string> <string name="anim_rps_countdown"> - RPS count + 剪刀石é 布é 備動作 </string> <string name="anim_rps_paper"> - RPS paper + 剪刀石é 布:布 </string> <string name="anim_rps_rock"> - RPS rock + 剪刀石é 布:石é </string> <string name="anim_rps_scissors"> - RPS scissors + 剪刀石é 布:剪刀 </string> <string name="anim_express_repulsed"> - Repulsed + ä½œå™ </string> <string name="anim_kick_roundhouse_r"> - Roundhouse Kick + 旋踢 </string> <string name="anim_express_sad"> 傷心 @@ -604,37 +774,37 @@ 敬禮 </string> <string name="anim_shout"> - Shout + å¶å–Š </string> <string name="anim_express_shrug"> - Shrug + è³è³è‚© </string> <string name="anim_express_smile"> 微笑 </string> <string name="anim_smoke_idle"> - Smoke Idle + æ‚ é–’æŠ½è¸ </string> <string name="anim_smoke_inhale"> - Smoke Inhale + å¸ä¸€å£è¸ </string> <string name="anim_smoke_throw_down"> - Smoke Throw Down + 甩è¸è’‚ </string> <string name="anim_express_surprise"> 驚喜 </string> <string name="anim_sword_strike_r"> - Sword Strike + åŠæ“Š </string> <string name="anim_angry_tantrum"> - Tantrum + 鬧脾氣 </string> <string name="anim_express_tongue_out"> - TongueOut + å舌é </string> <string name="anim_hello"> - Wave + æ®æ‰‹ </string> <string name="anim_whisper"> 耳語 @@ -657,6 +827,9 @@ <string name="anim_yes_head"> 是 </string> + <string name="multiple_textures"> + 多個 + </string> <string name="texture_loading"> 載入ä¸... </string> @@ -664,19 +837,19 @@ 離線 </string> <string name="worldmap_item_tooltip_format"> - [AREA] m² L$[PRICE] + [AREA] 平方公尺 L$[PRICE] </string> <string name="worldmap_results_none_found"> - 沒有發ç¾ã€‚ + æŸ¥ç„¡çµæžœã€‚ </string> <string name="Ok"> 確定 </string> <string name="Premature end of file"> - Premature end of file + æª”æ¡ˆç•°å¸¸ä¸æ¢ </string> <string name="ST_NO_JOINT"> - Can't find ROOT or JOINT. + 找ä¸åˆ° ROOT 或旋軸。 </string> <string name="whisper"> 低語: @@ -700,34 +873,37 @@ ç¾åœ¨ä½ 將釿–°è¯æŽ¥åˆ°é™„近的語音èŠå¤© </string> <string name="ScriptQuestionCautionChatGranted"> - '[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS]. + 物件「[OBJECTNAME]'ã€ï¼ˆæ‰€æœ‰äººã€Œ[OWNERNAME]ã€ï¼Œä½æ–¼ã€Œ[REGIONNAME]ã€ï¼Œæ–¹ä½ã€Œ[REGIONPOS]ã€ï¼‰å·²ç²å¾—下列權é™ï¼š[PERMISSIONS]。 </string> <string name="ScriptQuestionCautionChatDenied"> - '[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS]. + 物件「[OBJECTNAME]'ã€ï¼ˆæ‰€æœ‰äººã€Œ[OWNERNAME]ã€ï¼Œä½æ–¼ã€Œ[REGIONNAME]ã€ï¼Œæ–¹ä½ã€Œ[REGIONPOS]ã€ï¼‰å·²è¢«æ’¤é™¤ä¸‹åˆ—權é™ï¼š[PERMISSIONS]。 + </string> + <string name="AdditionalPermissionsRequestHeader"> + ä½ å¦‚æžœæ‰“é–‹å¸³æˆ¶æ¬Šé™ï¼Œä¹Ÿå°‡ä¸€ä½µå…許該物件: </string> <string name="ScriptTakeMoney"> ç”±ä½ èº«ä¸Šæ‹¿èµ°æž—ç™»å¹£ï¼ˆL$) </string> <string name="ActOnControlInputs"> - Act on your control inputs + æŒ‰ä½ çš„æŽ§åˆ¶è¼¸å…¥è¡Œå‹• </string> <string name="RemapControlInputs"> - Remap your control inputs + 釿–°è¦åŠƒä½ çš„æŽ§åˆ¶è¼¸å…¥ </string> <string name="AnimateYourAvatar"> - Animate your avatar + 使化身動起來 </string> <string name="AttachToYourAvatar"> - Attach to your avatar + é™„åŠ åˆ°åŒ–èº« </string> <string name="ReleaseOwnership"> - Release ownership and become public + 釋出所有權,開放給所有人 </string> <string name="LinkAndDelink"> - Link and delink from other objects + 連çµå…¶ä»–ç‰©ä»¶æˆ–åŽ»é™¤é€£çµ </string> <string name="AddAndRemoveJoints"> - Add and remove joints with other objects + 和其他物件建立或移除旋軸 </string> <string name="ChangePermissions"> è®Šæ›´å®ƒçš„æ¬Šé™ @@ -738,6 +914,9 @@ <string name="ControlYourCamera"> æŽ§åˆ¶ä½ çš„æ”影機 </string> + <string name="TeleportYourAgent"> + 瞬間傳é€ä½ 本人 + </string> <string name="NotConnected"> æœªè¯æŽ¥ </string> @@ -799,7 +978,7 @@ AVI è¦–é »æª”æ¡ˆ </string> <string name="xaf_animation_file"> - XAF Anim File + XAF 動畫檔案 </string> <string name="xml_file"> XML 檔案 @@ -816,6 +995,12 @@ <string name="choose_the_directory"> 鏿“‡ç›®éŒ„ </string> + <string name="script_files"> + 腳本 + </string> + <string name="dictionary_files"> + å—å…¸ + </string> <string name="AvatarSetNotAway"> éžé›¢é–‹ </string> @@ -991,19 +1176,19 @@ é€å‡ºç”± </string> <string name="GroupNotifyAttached"> - Attached: + 附件: </string> <string name="GroupNotifyViewPastNotices"> - View past notices or opt-out of receiving these messages here. + åœ¨é€™è£¡å¯Ÿçœ‹èˆŠé€šçŸ¥æˆ–é¸æ“‡ä¸æŽ¥æ”¶è¨Šæ¯ã€‚ </string> <string name="GroupNotifyOpenAttachment"> - Open Attachment + 開啟附件 </string> <string name="GroupNotifySaveAttachment"> - Save Attachment + 儲å˜é™„ä»¶ </string> <string name="TeleportOffer"> - Teleport offering + 發出「瞬間傳é€ã€é‚€è«‹ </string> <string name="StartUpNotifications"> ç•¶ä½ é›¢é–‹æ™‚æœ‰æ–°çš„é€šçŸ¥é€é”。 @@ -1042,16 +1227,75 @@ 按下 ESC éµå›žå¾©åˆ°ä¸–界的視角 </string> <string name="InventoryNoMatchingItems"> - 沒有發ç¾ä½ æƒ³è¦æ‰¾çš„嗎?試試 [secondlife:///app/search/all/[SEARCH_TERM] æœå°‹]。 + 找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試 [secondlife:///app/search/places/ æœå°‹]。 </string> <string name="PlacesNoMatchingItems"> - 沒有發ç¾ä½ æƒ³è¦æ‰¾çš„嗎?試試 [secondlife:///app/search/places/[SEARCH_TERM] æœå°‹]。 + 找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試 [secondlife:///app/search/places/[SEARCH_TERM] æœå°‹]。 </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"> + ä½ å¾žç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚é›†è³¼è²·çš„ç‰©å“將出ç¾åœ¨é€™è£¡ã€‚ ä½ å¯ä»¥æŠŠå®ƒå€‘æ‹–æ›³åˆ°ä½ çš„æ”¶ç´å€ï¼Œé–‹å§‹ä½¿ç”¨ã€‚ + </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"> + 任何人都å¯åœ¨ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集出售物å“。 + </string> + <string name="InventoryOutboxNotMerchantTooltip"/> + <string name="InventoryOutboxNotMerchant"> + å¦‚æžœä½ æƒ³æˆç‚ºå•†å®¶ï¼Œä½ 需è¦åœ¨ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集[[MARKETPLACE_CREATE_STORE_URL]é–‹è¨ä¸€é–“商店]。 + </string> + <string name="InventoryOutboxNoItemsTitle"> + ä½ çš„ç™¼ä»¶åŒ£ç›®å‰æ˜¯ç©ºçš„。 + </string> + <string name="InventoryOutboxNoItemsTooltip"/> + <string name="InventoryOutboxNoItems"> + 將資料夾拖曳到這個å€åŸŸï¼Œå†é»žæŒ‰ã€Œé€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集ã€ï¼Œå³å¯åœ¨[[MARKETPLACE_DASHBOARD_URL]第二人生購物市集]登列出售。 + </string> + <string name="Marketplace Error None"> + 零錯誤 + </string> + <string name="Marketplace Error Not Merchant"> + ç™¼ç”ŸéŒ¯èª¤ï¼šå°‡ç‰©é …é€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集之å‰ï¼Œä½ å¿…é ˆå–得商家的身份(å…費)。 + </string> + <string name="Marketplace Error Empty Folder"> + 錯誤:æ¤è³‡æ–™å¤¾æ²’有內容。 + </string> + <string name="Marketplace Error Unassociated Products"> + 錯誤:æ¤ç‰©é …ä¸Šå‚³å¤±æ•—ï¼Œå› ç‚ºä½ çš„å•†å®¶å¸³æˆ¶æœ‰å¤ªå¤šå’Œç”¢å“ç„¡é—œè¯çš„ç‰©é …ã€‚ è¦è§£æ±ºé€™å€‹å•é¡Œï¼Œè«‹ç™»å…¥ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚é›†ç¶²ç«™ï¼Œæ¸›ä½Žä½ çš„ç„¡é—œè¯ç‰©é …數目。 + </string> + <string name="Marketplace Error Object Limit"> + 錯誤:æ¤ç‰©é …包å«å¤ªå¤šç‰©ä»¶ã€‚ è¦è§£æ±ºé€™éŒ¯èª¤ï¼Œè«‹å°‡ç‰©ä»¶è£ç®±ï¼Œä½¿ç¸½ç‰©ä»¶æ•¸ç›®ä¸è¶…éŽ 200。 + </string> + <string name="Marketplace Error Folder Depth"> + 錯誤:æ¤ç‰©é …嫿œ‰å¤ªå¤šå±¤çš„巢狀資料夾。 è«‹åŠ ä»¥é‡æ–°æ•´ç†ï¼Œè‡³å¤šå…許 3 層的巢狀資料夾。 + </string> + <string name="Marketplace Error Unsellable Item"> + 錯誤:æ¤ç‰©é …無法在第二人生購物市集出售。 + </string> + <string name="Marketplace Error Internal Import"> + éŒ¯èª¤ï¼šé€™å€‹ç‰©é …æœ‰å•題。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚ + </string> + <string name="Open landmarks"> + 開啟地標 </string> <string name="no_transfer" value="ï¼ˆç¦æ¢è½‰è®“)"/> <string name="no_modify" value="ï¼ˆç¦æ¢ä¿®æ”¹ï¼‰"/> @@ -1066,7 +1310,7 @@ 無內容 </string> <string name="WornOnAttachmentPoint" value="(已穿 [ATTACHMENT_POINT])"/> - <string name="ActiveGesture" value="[GESLABEL] (active)"/> + <string name="ActiveGesture" value="[GESLABEL](使用ä¸ï¼‰"/> <string name="PermYes"> 是 </string> @@ -1078,30 +1322,27 @@ <string name="Wait" value="--- ç‰å¾…:"/> <string name="AnimFlagStop" value="åœæ¢å‹•作:"/> <string name="AnimFlagStart" value="開始動作:"/> - <string name="Wave" value="Wave"/> + <string name="Wave" value="æ®æ‰‹"/> <string name="GestureActionNone" value="ç„¡"/> - <string name="HelloAvatar" value="Hello, avatar!"/> + <string name="HelloAvatar" value="ä½ å¥½ï¼ŒåŒ–èº«ï¼"/> <string name="ViewAllGestures" value="察看全部 >>"/> <string name="GetMoreGestures" value="å–得更多 >>"/> - <string name="Animations" value="動作,"/> - <string name="Calling Cards" value="å片,"/> - <string name="Clothing" value="æœè£,"/> - <string name="Gestures" value="å§¿å‹¢,"/> - <string name="Landmarks" value="地標,"/> - <string name="Notecards" value="記事å¡,"/> - <string name="Objects" value="物件,"/> - <string name="Scripts" value="腳本,"/> - <string name="Sounds" value="è²éŸ³,"/> - <string name="Textures" value="æè³ª,"/> - <string name="Snapshots" value="å¿«ç…§,"/> - <string name="No Filters" value="No"/> + <string name="Animations" value="動作,"/> + <string name="Calling Cards" value="å片,"/> + <string name="Clothing" value="æœè£ï¼Œ"/> + <string name="Gestures" value="姿勢,"/> + <string name="Landmarks" value="地標,"/> + <string name="Notecards" value="記事å¡ï¼Œ"/> + <string name="Objects" value="物件,"/> + <string name="Scripts" value="腳本,"/> + <string name="Sounds" value="è²éŸ³ï¼Œ"/> + <string name="Textures" value="æè³ªï¼Œ"/> + <string name="Snapshots" value="快照,"/> + <string name="No Filters" value="å¦"/> <string name="Since Logoff" value="- 自上次登出"/> <string name="InvFolder My Inventory"> 我的收ç´å€ </string> - <string name="InvFolder My Favorites"> - 我的最愛 - </string> <string name="InvFolder Library"> 資æºåº« </string> @@ -1136,7 +1377,7 @@ æ”¶ç´å€ </string> <string name="InvFolder Uncompressed Images"> - Uncompressed Images + æœªå£“ç¸®åœ–åƒ </string> <string name="InvFolder Body Parts"> èº«é«”éƒ¨ä½ @@ -1148,10 +1389,10 @@ 相簿 </string> <string name="InvFolder Lost And Found"> - Lost And Found + å¤±ç‰©æ‹›é ˜ </string> <string name="InvFolder Uncompressed Sounds"> - 無壓縮è²éŸ³ + 未壓縮è²éŸ³ </string> <string name="InvFolder Animations"> 動作 @@ -1165,6 +1406,12 @@ <string name="InvFolder favorite"> 我的最愛 </string> + <string name="InvFolder Favorites"> + 我的最愛 + </string> + <string name="InvFolder favorites"> + 我的最愛 + </string> <string name="InvFolder Current Outfit"> ç›®å‰è£æ‰® </string> @@ -1177,17 +1424,32 @@ <string name="InvFolder Accessories"> é…ä»¶ </string> + <string name="InvFolder Meshes"> + ç¶²é¢ + </string> + <string name="InvFolder Received Items"> + æ”¶åˆ°çš„ç‰©é … + </string> + <string name="InvFolder Merchant Outbox"> + 商家發件匣 + </string> <string name="InvFolder Friends"> æœ‹å‹ </string> <string name="InvFolder All"> 全部 </string> + <string name="no_attachments"> + 未穿著任何附件 + </string> + <string name="Attachments remain"> + 附件(尚å¯å®¹ç´ [COUNT] 件) + </string> <string name="Buy"> 購買 </string> <string name="BuyforL$"> - Buy for L$ + 出價購買:L$ </string> <string name="Stone"> 石é @@ -1211,13 +1473,13 @@ æ©¡è† </string> <string name="Light"> - Light + å…‰æº </string> <string name="KBShift"> - Shift + Shift éµ </string> <string name="KBCtrl"> - Ctrl + Ctrl éµ </string> <string name="Chest"> 胸部 @@ -1250,7 +1512,7 @@ 骨盆 </string> <string name="Mouth"> - 嘴 + 嘴巴 </string> <string name="Chin"> 下巴 @@ -1309,23 +1571,29 @@ <string name="Right Pec"> å³èƒ¸è‚Œ </string> + <string name="Neck"> + é ¸éƒ¨ + </string> + <string name="Avatar Center"> + 化身ä¸å¿ƒ + </string> <string name="Invalid Attachment"> - ç„¡æ•ˆçš„é™„ä»¶è¯æŽ¥é»ž + 無效的附接點 </string> <string name="YearsMonthsOld"> - [AGEYEARS] [AGEMONTHS] old + 年齡:[AGEYEARS] å¹´ [AGEMONTHS] 月 </string> <string name="YearsOld"> - [AGEYEARS] old + 年齡:[AGEYEARS] å¹´ </string> <string name="MonthsOld"> - [AGEMONTHS] old + [AGEMONTHS] 月 </string> <string name="WeeksOld"> - [AGEWEEKS] old + [AGEWEEKS] 週 </string> <string name="DaysOld"> - [AGEDAYS] old + [AGEDAYS] 天 </string> <string name="TodayOld"> ä»Šæ—¥å‰›åŠ å…¥ @@ -1367,40 +1635,40 @@ [COUNT] 天 </string> <string name="GroupMembersA"> - [COUNT] æˆå“¡ + [COUNT] 使ˆå“¡ </string> <string name="GroupMembersB"> - [COUNT] æˆå“¡ + [COUNT] 使ˆå“¡ </string> <string name="GroupMembersC"> - [COUNT] æˆå“¡ + [COUNT] 使ˆå“¡ </string> <string name="AcctTypeResident"> å±…æ°‘ </string> <string name="AcctTypeTrial"> - Trial + 試用 </string> <string name="AcctTypeCharterMember"> - Charter Member + è€ç‰Œ Charter æˆå“¡ </string> <string name="AcctTypeEmployee"> 林登實驗室員工 </string> <string name="PaymentInfoUsed"> - Payment Info Used + 使用的付款資料 </string> <string name="PaymentInfoOnFile"> - Payment Info On File + é 留付款資料 </string> <string name="NoPaymentInfoOnFile"> - No Payment Info On File + 未é 留付款資料 </string> <string name="AgeVerified"> - å·²å¹´é½¡é©—è‰ + 通éŽå¹´é½¡é©—è‰ </string> <string name="NotAgeVerified"> - æœªå¹´é½¡é©—è‰ + 未通éŽå¹´é½¡é©—è‰ </string> <string name="Center 2"> ä¸å¤® 2 @@ -1427,22 +1695,22 @@ å³ä¸‹ </string> <string name="CompileQueueDownloadedCompiling"> - 已下載,ç¾åœ¨é€²è¡Œç·¨è¯ä¸ + 已下載,æ£åœ¨ç·¨è¯ä¸ </string> <string name="CompileQueueScriptNotFound"> 伺æœå™¨ä¸Šæœªç™¼ç¾è…³æœ¬ã€‚ </string> <string name="CompileQueueProblemDownloading"> - å•é¡Œä¸‹è¼‰ä¸ + 下載時出å•題 </string> <string name="CompileQueueInsufficientPermDownload"> - Insufficient permissions to download a script. + 下載腳本的權é™ä¸è¶³ã€‚ </string> <string name="CompileQueueInsufficientPermFor"> - Insufficient permissions for + 權é™ä¸è¶³ï¼š </string> <string name="CompileQueueUnknownFailure"> - Unknown failure to download + ä¸‹è¼‰å¤±æ•—ï¼ŒåŽŸå› ä¸æ˜Ž </string> <string name="CompileQueueTitle"> 釿–°ç·¨è¯é€²åº¦ @@ -1457,19 +1725,19 @@ é‡è¨ </string> <string name="RunQueueTitle"> - è¨å®šåŸ·è¡Œä¸ç¨‹åº + è¨å®šã€ŒåŸ·è¡Œä¸ã€é€²åº¦ </string> <string name="RunQueueStart"> - è¨ç‚ºåŸ·è¡Œä¸ + è¨ç‚ºã€ŒåŸ·è¡Œä¸ã€ </string> <string name="NotRunQueueTitle"> - è¨å®šéžåŸ·è¡Œä¸ç¨‹åº + è¨å®šã€ŒéžåŸ·è¡Œä¸ã€é€²åº¦ </string> <string name="NotRunQueueStart"> - è¨ç‚ºéžåŸ·è¡Œä¸ + è¨ç‚ºã€ŒéžåŸ·è¡Œä¸ã€ </string> <string name="CompileSuccessful"> - ç·¨è¯æˆåŠŸ!! + ç·¨è¯æˆåŠŸï¼ </string> <string name="CompileSuccessfulSaving"> ç·¨è¯æˆåŠŸï¼Œå„²å˜ä¸... @@ -1490,36 +1758,42 @@ <string name="Unknown"> (未知) </string> - <string name="SummaryForTheWeek" value="Summary for this week, beginning on"/> + <string name="SummaryForTheWeek" value="本週摘è¦ï¼Œèµ·å§‹æ—¥ï¼š"/> <string name="NextStipendDay" value="下一個發薪日為"/> - <string name="GroupIndividualShare" value="Group Individual Share"/> + <string name="GroupPlanningDate"> + [mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc] + </string> + <string name="GroupIndividualShare" value="群組 個人份é¡"/> <string name="GroupColumn" value="群組"/> <string name="Balance"> - Balance + é¤˜é¡ </string> <string name="Credits"> - Credits + 貸記 </string> <string name="Debits"> - Debits + 借記 </string> <string name="Total"> - Total + ç¸½é¡ </string> <string name="NoGroupDataFound"> - ç„¡ç¾¤çµ„è³‡æ–™ç™¼ç¾ + 查無群組資料 </string> <string name="IMParentEstate"> - parent estate + æ¯é ˜åœ° </string> <string name="IMMainland"> - mainland + 大陸 </string> <string name="IMTeen"> - teen + é’å°‘å¹´ + </string> + <string name="Anyone"> + 任何人 </string> <string name="RegionInfoError"> - error + 錯誤 </string> <string name="RegionInfoAllEstatesOwnedBy"> [OWNER] æ‰€æ“æœ‰çš„çš„å…¨éƒ¨é ˜åœ° @@ -1528,13 +1802,13 @@ ä½ æ‰€æ“æœ‰çš„å…¨éƒ¨é ˜åœ° </string> <string name="RegionInfoAllEstatesYouManage"> - all estates that you manage for [OWNER] + ä½ ç‚º [OWNER] 管ç†çš„å…¨éƒ¨é ˜åœ° </string> <string name="RegionInfoAllowedResidents"> - Allowed Residents: ([ALLOWEDAGENTS], max [MAXACCESS]) + å…許居民:([ALLOWEDAGENTS],最多 [MAXACCESS]) </string> <string name="RegionInfoAllowedGroups"> - å…許的群群組:([ALLOWEDGROUPS],最大 [MAXACCESS]) + å…許的群組:([ALLOWEDGROUPS],最多 [MAXACCESS]) </string> <string name="ScriptLimitsParcelScriptMemory"> 地段腳本記憶體 @@ -1549,28 +1823,28 @@ 記憶體用é‡ï¼š[COUNT] kb </string> <string name="ScriptLimitsParcelScriptURLs"> - 地段腳本 URLs + 地段腳本的 URL </string> <string name="ScriptLimitsURLsUsed"> - URLs used: [COUNT] out of [MAX]; [AVAILABLE] available + URL 使用狀æ³ï¼šæœ€å¤šå¯ç”¨ [MAX],已用 [COUNT],剩餘 [AVAILABLE] </string> <string name="ScriptLimitsURLsUsedSimple"> - URLs used: [COUNT] + 已用 URL:[COUNT] </string> <string name="ScriptLimitsRequestError"> - Error requesting information + 調資料時出錯 </string> <string name="ScriptLimitsRequestNoParcelSelected"> - ç„¡åœ°æ®µè¢«é¸æ“‡ + æœªé¸æ“‡åœ°æ®µ </string> <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"> å在 @@ -1666,34 +1940,34 @@ 左胸肌 </string> <string name="ATTACH_HUD_CENTER_2"> - HUD Center 2 + æ“¡é 顯示ä¸å¤® 2 </string> <string name="ATTACH_HUD_TOP_RIGHT"> - HUD Top Right + æ“¡é 顯示å³ä¸Š </string> <string name="ATTACH_HUD_TOP_CENTER"> - HUD Top Center + æ“¡é 顯示ä¸å¤®ä¸Šæ–¹ </string> <string name="ATTACH_HUD_TOP_LEFT"> - HUD Top Left + æ“¡é 顯示左上 </string> <string name="ATTACH_HUD_CENTER_1"> - HUD Center 1 + æ“¡é 顯示ä¸å¤® 1 </string> <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> <string name="CursorPos"> - Line [LINE], Column [COLUMN] + 橫行 [LINE],縱列 [COLUMN] </string> <string name="PanelDirCountFound"> - [COUNT] found + 找到 [COUNT] </string> <string name="PanelDirTimeStr"> [hour12,datetime,slt]:[min,datetime,slt] [ampm,datetime,slt] @@ -1702,16 +1976,16 @@ [mthnum,datetime,slt]/[day,datetime,slt] </string> <string name="PanelContentsTooltip"> - 物件的內容 + 物件內容 </string> <string name="PanelContentsNewScript"> 新腳本 </string> <string name="BusyModeResponseDefault"> - ä½ å‚³é€è¨Šæ¯çš„å±…æ°‘ç›®å‰è™•於忙碌模å¼ä¸ï¼Œé€™æ„å‘³è‘—ä»–è¦æ±‚ä¸è¢«æ‰“æ“¾ã€‚ä½ æ‰€å‚³çš„è¨Šæ¯ä»å°‡æœƒç•™å˜ä¸¦é¡¯ç¤ºæ–¼ IM 颿¿ä¸Šä¾›ä»–ç¨å¾Œæ™‚查閱。 + ä½ å‚³è¨ŠéŽåŽ»çš„å±…æ°‘ç›®å‰è™•於忙碌狀態,這æ„å‘³è‘—ä»–è¦æ±‚ä¸è¢«æ‰“擾。 ä½ çš„è¨Šæ¯ä»å°‡ç•™å˜ä¸¦é¡¯ç¤ºæ–¼å°æ–¹çš„ IM 颿¿ä¸Šä¾›ç¨å¾ŒæŸ¥é–±ã€‚ </string> <string name="MuteByName"> - (由å稱) + (按å稱) </string> <string name="MuteAgent"> (居民) @@ -1726,12 +2000,12 @@ (外部) </string> <string name="RegionNoCovenant"> - æ¤é ˜åœ°æœªæä¾›ä»»ä½•å¥‘ç´„è¦æ±‚。 + æ¤é ˜åœ°æ²’æœ‰ä»»ä½•å¥‘ç´„è¦æ±‚。 </string> <string name="RegionNoCovenantOtherOwner"> - There is no Covenant provided for this Estate. The land on this estate is being sold by the Estate owner, not Linden Lab. Please contact the Estate Owner for sales details. + æ¤é ˜åœ°æ²’æœ‰ä»»ä½•å¥‘ç´„è¦æ±‚。 æœ¬é ˜åœ°åœŸåœ°çš„å‡ºå”®äººæ˜¯é ˜åœ°æ‰€æœ‰äººï¼Œä¸æ˜¯æž—登實驗室。 è«‹è¯çµ¡é ˜åœ°æ‰€æœ‰äººç²çŸ¥å”®åœ°è©³æƒ…。 </string> - <string name="covenant_last_modified" value="最後修改於:"/> + <string name="covenant_last_modified" value="最後修改時間:"/> <string name="none_text" value="(無)"/> <string name="never_text" value="(絕ä¸ï¼‰"/> <string name="GroupOwned"> @@ -1740,14 +2014,20 @@ <string name="Public"> 公開 </string> + <string name="LocalSettings"> + 本地è¨å®š + </string> + <string name="RegionSettings"> + 地å€è¨å®š + </string> <string name="ClassifiedClicksTxt"> - Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile + 點按:[TELEPORT] 瞬間傳é€ï¼Œ[MAP] 地圖,[PROFILE] 檔案 </string> <string name="ClassifiedUpdateAfterPublish"> - (將於發布後自動更新) + (將於發布後更新) </string> <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"> 使用者無精é¸åœ°é»žæˆ–個人廣告 @@ -1762,86 +2042,89 @@ 屬性 </string> <string name="InvOfferAnObjectNamed"> - An object named + 一個物件,å為 </string> <string name="InvOfferOwnedByGroup"> - ç¾¤çµ„æ‰€æ“æœ‰ + 屬於群組 </string> <string name="InvOfferOwnedByUnknownGroup"> - ç”±ä¸€å€‹æœªçŸ¥çš„ç¾¤çµ„æ‰€æ“æœ‰ + 屬於一個未知群組 </string> <string name="InvOfferOwnedBy"> - owned by + 所有人: </string> <string name="InvOfferOwnedByUnknownUser"> - owned by an unknown user + å±¬æ–¼æŸæœªçŸ¥ä½¿ç”¨è€… </string> <string name="InvOfferGaveYou"> - gave you + çµ¦äºˆä½ </string> <string name="InvOfferDecline"> - You decline [DESC] from <nolink>[NAME]</nolink>. + ä½ æ‹’çµ•äº†ä¾†è‡ª <nolink>[NAME]</nolink> çš„ [DESC]。 </string> <string name="GroupMoneyTotal"> - Total + ç¸½é¡ </string> <string name="GroupMoneyBought"> - bought + 買了 </string> <string name="GroupMoneyPaidYou"> - paid you + æ”¯ä»˜çµ¦ä½ </string> <string name="GroupMoneyPaidInto"> - paid into + 支付給 </string> <string name="GroupMoneyBoughtPassTo"> - bought pass to + 買了通行權: </string> <string name="GroupMoneyPaidFeeForEvent"> - paid fee for event + 付了費用åƒåŠ æ´»å‹• </string> <string name="GroupMoneyPaidPrizeForEvent"> - paid prize for event + 付了賞金åƒåŠ æ´»å‹• </string> <string name="GroupMoneyBalance"> - Balance + é¤˜é¡ </string> <string name="GroupMoneyCredits"> - Credits + 貸記 </string> <string name="GroupMoneyDebits"> - Debits + 借記 + </string> + <string name="GroupMoneyDate"> + [weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc] </string> <string name="ViewerObjectContents"> - Contents + 內容 </string> <string name="AcquiredItems"> - Acquired Items + å–å¾—ç‰©å“ </string> <string name="Cancel"> å–æ¶ˆ </string> <string name="UploadingCosts"> - 花費 L$ [AMOUNT] 上傳 [NAME] + 上傳 [NAME] 費用 L$ [AMOUNT] </string> <string name="BuyingCosts"> - 花費 L$ [AMOUNT] 購買這個 + è³¼è²·é€™å€‹éœ€è¦ L$ [AMOUNT] </string> <string name="UnknownFileExtension"> 未知的副檔å .%s -é æœŸç‚º .wav, .tga, .bmp, .jpg, .jpeg, or .bvh 類型 +應該是 .wavã€.tgaã€.bmpã€.jpgã€.jpeg 或 .bvh </string> <string name="MuteObject2"> - Block + å°éŽ– </string> <string name="MuteAvatar"> - Block + å°éŽ– </string> <string name="UnmuteObject"> - Unblock + 解除å°éŽ– </string> <string name="UnmuteAvatar"> - Unblock + 解除å°éŽ– </string> <string name="AddLandmarkNavBarMenu"> æ·»åŠ åˆ°æˆ‘çš„åœ°æ¨™... @@ -1877,25 +2160,25 @@ æŽ¥æ”¶ä¸ </string> <string name="AM"> - AM + ä¸Šåˆ </string> <string name="PM"> - PM + ä¸‹åˆ </string> <string name="PST"> - PST + 太平洋時間 </string> <string name="PDT"> - PDT + 太平洋日光節約時間 </string> <string name="Direction_Forward"> å‘å‰ </string> <string name="Direction_Left"> - å‘å·¦ + å·¦ç§»éµ </string> <string name="Direction_Right"> - å‘å³ + å³ç§»éµ </string> <string name="Direction_Back"> å‘後 @@ -1913,46 +2196,46 @@ æ± </string> <string name="Direction_Up"> - å‘上 + ä¸Šç§»éµ </string> <string name="Direction_Down"> - å‘下 + ä¸‹ç§»éµ </string> <string name="Any Category"> 任何類別 </string> <string name="Shopping"> - 採購 + 購物 </string> <string name="Land Rental"> - Land Rental + 土地租賃 </string> <string name="Property Rental"> - Property Rental + 房產租賃 </string> <string name="Special Attraction"> - Special Attraction + 熱門地點 </string> <string name="New Products"> - New Products + æ–°ç”¢å“ </string> <string name="Employment"> - Employment + 徵人 </string> <string name="Wanted"> - Wanted + 徵求 </string> <string name="Service"> - Service + æœå‹™ </string> <string name="Personal"> - Personal + äº¤å‹ </string> <string name="None"> ç„¡ </string> <string name="Linden Location"> - Linden Location + æž—ç™»ä½ç½® </string> <string name="Adult"> 完全æˆäºº @@ -1973,25 +2256,25 @@ èšæœƒæ‰€ </string> <string name="Newcomer Friendly"> - 新手å‹å–„ + æ¡è¿Žæ–°æ‰‹å…‰è‡¨ </string> <string name="Parks&Nature"> - 公園與自然 + 公園與自然景觀 </string> <string name="Residential"> ä½å®… </string> <string name="Stage"> - Stage + 舞臺 </string> <string name="Other"> - Other + å…¶ä»– </string> <string name="Rental"> - Rental + 出租 </string> <string name="Any"> - Any + 任何 </string> <string name="You"> ä½ @@ -2027,7 +2310,7 @@ 多媒體 </string> <string name="Play Media"> - æ’æ”¾ï¼æš«åœ 媒體 + æ’æ”¾/æš«åœåª’é«” </string> <string name="MBCmdLineError"> è§£æžå‘½ä»¤åˆ—時發ç¾éŒ¯èª¤ã€‚ @@ -2038,1510 +2321,1510 @@ [APP_NAME] 命令列用法: </string> <string name="MBUnableToAccessFile"> - [APP_NAME] 無法å˜å–它所需è¦çš„æª”案。 + [APP_NAME] 無法å˜å–它所需的檔案。 -This can be because you somehow have multiple copies running, or your system incorrectly thinks a file is open. -If this message persists, restart your computer and try again. -If it continues to persist, you may need to completely uninstall [APP_NAME] and reinstall it. +ä½ å¯èƒ½æœ‰å¤šé‡å¯¦ä¾‹åŸ·è¡Œä¸ï¼Œæˆ–ä½ çš„ç³»çµ±èª¤ä»¥ç‚ºæŸæª”案已經開啟。 +å¦‚æžœé€™å€‹è¨Šæ¯æŒçºŒå‡ºç¾ï¼Œè«‹é‡æ–°å•Ÿå‹•ä½ çš„é›»è…¦ã€‚ +如果å•題ä»ç„¶å˜åœ¨ï¼Œä½ å¯èƒ½éœ€è¦å¾¹åº•å¸é™¤ [APP_NAME] å†é‡æ–°å®‰è£ã€‚ </string> <string name="MBFatalError"> 致命錯誤 </string> <string name="MBRequiresAltiVec"> - [APP_NAME] requires a processor with AltiVec (G4 or later). + [APP_NAME] éœ€è¦æœ‰ AltiVec(G4 或更新版)的處ç†å™¨ã€‚ </string> <string name="MBAlreadyRunning"> [APP_NAME] 已經在執行ä¸ã€‚ -è«‹æª¢æŸ¥ä½ çš„å·¥ä½œåˆ—è£¡æ˜¯å¦æœ‰å…¶ä»–最å°åŒ–的相åŒç¨‹å¼ã€‚ +è«‹æª¢æŸ¥ä½ çš„å·¥ä½œåˆ—è£¡æ˜¯å¦å·²æœ‰æœ€å°åŒ–的相åŒç¨‹å¼ã€‚ å¦‚æžœé€™å€‹è¨Šæ¯æŒçºŒå‡ºç¾ï¼Œè«‹é‡æ–°å•Ÿå‹•ä½ çš„é›»è…¦ã€‚ </string> <string name="MBFrozenCrashed"> - [APP_NAME] appears to have frozen or crashed on the previous run. -Would you like to send a crash report? + [APP_NAME] 上次執行時好åƒå‡ºç¾å‡çµæˆ–當掉。 +ä½ æ˜¯å¦æƒ³è¦å ±å‘Šç•¶æ©Ÿäº‹ä¾‹ï¼Ÿ </string> <string name="MBAlert"> 通知 </string> <string name="MBNoDirectX"> - [APP_NAME] is unable to detect DirectX 9.0b or greater. -[APP_NAME] uses DirectX to detect hardware and/or outdated drivers that can cause stability problems, poor performance and crashes. While you can run [APP_NAME] without it, we highly recommend running with DirectX 9.0b. + [APP_NAME] 嵿¸¬ä¸åˆ° DirectX 9.0b 或更新版。 +[APP_NAME] 使用 DirectX 來嵿¸¬å¯èƒ½å°Žè‡´ä¸ç©©å®šã€åŸ·è¡Œæ•ˆèƒ½ä¸ä½³æˆ–當機發生的硬體或è€èˆŠé©…動器。 ä½ å¯ä»¥é¸æ“‡ä¸ç”¨ DirectX 9.0b 來執行 [APP_NAME]ï¼Œä½†æˆ‘å€‘å¤§åŠ›æŽ¨è–¦ä½ ä½¿ç”¨ã€‚ -Do you wish to continue? +ä½ ç¢ºå®šè¦ç¹¼çºŒå—Žï¼Ÿ </string> <string name="MBWarning"> è¦å‘Š </string> <string name="MBNoAutoUpdate"> - Automatic updating is not yet implemented for Linux. -Please download the latest version from www.secondlife.com. + 尚無試用於 Linux 的自動更新功能。 +請到 www.secondlife.com 下載最新版本。 </string> <string name="MBRegClassFailed"> - RegisterClass failed + RegisterClass 失敗 </string> <string name="MBError"> 錯誤 </string> <string name="MBFullScreenErr"> - 無法執行全螢幕於 [WIDTH] x [HEIGHT]. -執行於視窗ä¸ã€‚ + [WIDTH] x [HEIGHT] è§£æžåº¦ä¸‹ç„¡æ³•執行全螢幕。 +在視窗ä¸åŸ·è¡Œã€‚ </string> <string name="MBDestroyWinFailed"> - Shutdown Error while destroying window (DestroyWindow() failed) + 消滅視窗時發生強行關閉錯誤(DestroyWindow()失敗) </string> <string name="MBShutdownErr"> - Shutdown Error + 強行關閉出錯 </string> <string name="MBDevContextErr"> - Can't make GL device context + 無法建立 GL è£ç½®ç’°å¢ƒ </string> <string name="MBPixelFmtErr"> - Can't find suitable pixel format + 找ä¸åˆ°é©åˆçš„åƒç´ æ ¼å¼ </string> <string name="MBPixelFmtDescErr"> - Can't get pixel format description + 無法å–å¾—åƒç´ æ ¼å¼æè¿° </string> <string name="MBTrueColorWindow"> - [APP_NAME] requires True Color (32-bit) to run. -Please go to your computer's display settings and set the color mode to 32-bit. + [APP_NAME] 需è¦å…¨å½©ï¼ˆ32ä½å…ƒï¼‰æ‰èƒ½åŸ·è¡Œã€‚ +請到電腦的顯示è¨å®šï¼Œå°‡è‰²å½©æ¨¡å¼è¨ç‚º 32 ä½å…ƒã€‚ </string> <string name="MBAlpha"> - [APP_NAME] is unable to run because it can't get an 8 bit alpha channel. Usually this is due to video card driver issues. -Please make sure you have the latest video card drivers installed. -Also be sure your monitor is set to True Color (32-bit) in Control Panels > Display > Settings. -If you continue to receive this message, contact the [SUPPORT_SITE]. + [APP_NAME] 無法執行,無法å–å¾— 8 ä½å…ƒ alpha é »é“。 é€™é€šå¸¸æ˜¯å› ç‚ºé¡¯ç¤ºå¡é©…動程å¼å‡ºå•題。 +è«‹ç¢ºå®šä½ å®‰è£äº†æœ€æ–°çš„顯示å¡é©…動程å¼ã€‚ +è«‹åˆ°æŽ§åˆ¶å° > 顯示 > è¨å®šè™•將螢幕è¨ç‚ºå…¨å½©ï¼ˆ32 ä½å…ƒï¼‰ã€‚ +å¦‚æžœä½ ç¹¼çºŒçœ‹åˆ°æ¤è¨Šæ¯ï¼Œè«‹è¯çµ¡ [SUPPORT_SITE]。 </string> <string name="MBPixelFmtSetErr"> 無法è¨å®šåƒç´ æ ¼å¼ </string> <string name="MBGLContextErr"> - Can't create GL rendering context + 無法建立 GL 呈åƒç’°å¢ƒ </string> <string name="MBGLContextActErr"> - Can't activate GL rendering context + 無法啟動 GL 呈åƒç’°å¢ƒ </string> <string name="MBVideoDrvErr"> - [APP_NAME] is unable to run because your video card drivers did not install properly, are out of date, or are for unsupported hardware. Please make sure you have the latest video card drivers and even if you do have the latest, try reinstalling them. + [APP_NAME] 無法執行,這å¯èƒ½å› ç‚ºä½ çš„é¡¯ç¤ºå¡é©…動程å¼å®‰è£ä¸ç•¶ã€ç‰ˆæœ¬éŽèˆŠï¼Œæˆ–è€…ä½ çš„ç¡¬é«”ä¸å—支æ´ã€‚ è«‹ç¢ºå®šä½ å®‰è£äº†æœ€æ–°çš„顯示å¡é©…動程å¼ã€‚如果已è£äº†æœ€æ–°é©…動程å¼ï¼Œè«‹å†é‡æ–°å®‰è£ã€‚ -If you continue to receive this message, contact the [SUPPORT_SITE]. +å¦‚æžœä½ ç¹¼çºŒçœ‹åˆ°æ¤è¨Šæ¯ï¼Œè«‹è¯çµ¡ [SUPPORT_SITE]。 </string> <string name="5 O'Clock Shadow"> - 5 O'Clock Shadow + 下åˆäº”é»žçš„æ–°é¬æ¸£ </string> <string name="All White"> 全白 </string> <string name="Anime Eyes"> - Anime Eyes + æ—¥å¼å‹•漫眼 </string> <string name="Arced"> - Arced + 彎拱的 </string> <string name="Arm Length"> - Arm Length + 臂長 </string> <string name="Attached"> - Attached + 貼附的 </string> <string name="Attached Earlobes"> - Attached Earlobes + 附著耳垂 </string> <string name="Back Fringe"> - Back Fringe + å¾Œç€æµ· </string> <string name="Baggy"> - Baggy + 袋型的 </string> <string name="Bangs"> - Bangs + ç€æµ· </string> <string name="Beady Eyes"> - Beady Eyes + ç 圓銳光眼 </string> <string name="Belly Size"> - Belly Size + è…¹éƒ¨å¤§å° </string> <string name="Big"> - Big + 大 </string> <string name="Big Butt"> - Big Butt + 大臀部 </string> <string name="Big Hair Back"> - Big Hair: Back + 大型é é«®ï¼šå¾Œé¢ </string> <string name="Big Hair Front"> - Big Hair: Front + 大型é 髮:å‰é¢ </string> <string name="Big Hair Top"> - Big Hair: Top + 大型é é«®ï¼šé ‚éƒ¨ </string> <string name="Big Head"> - Big Head + 大é </string> <string name="Big Pectorals"> - Big Pectorals + 大胸肌 </string> <string name="Big Spikes"> - Big Spikes + 大尖直髮 </string> <string name="Black"> - Black + 黑色 </string> <string name="Blonde"> - Blonde + 金色 </string> <string name="Blonde Hair"> - Blonde Hair + 金髮 </string> <string name="Blush"> - Blush + 腮紅 </string> <string name="Blush Color"> - Blush Color + 淺粉色 </string> <string name="Blush Opacity"> - Blush Opacity + 腮紅ä¸é€æ˜Žåº¦ï¼š </string> <string name="Body Definition"> - Body Definition + 身體çµå¯¦åº¦ </string> <string name="Body Fat"> - Body Fat + 體脂肪 </string> <string name="Body Freckles"> - Body Freckles + 身體雀斑 </string> <string name="Body Thick"> - Body Thick + 寬厚體型 </string> <string name="Body Thickness"> - Body Thickness + 體型厚度 </string> <string name="Body Thin"> - Body Thin + 窄瘦體型 </string> <string name="Bow Legged"> - Bow Legged + 弓形腿 </string> <string name="Breast Buoyancy"> - Breast Buoyancy + 乳房彈性 </string> <string name="Breast Cleavage"> - Breast Cleavage + ä¹³æºæ·±æ·º </string> <string name="Breast Size"> - Breast Size + 乳房尺寸 </string> <string name="Bridge Width"> - Bridge Width + å…©çœ¼é–“è· </string> <string name="Broad"> - Broad + 寬 </string> <string name="Brow Size"> - Brow Size + çœ‰æ¯›å¤§å° </string> <string name="Bug Eyes"> - Bug Eyes + çªçœ¼ </string> <string name="Bugged Eyes"> - Bugged Eyes + çªçœ¼ </string> <string name="Bulbous"> - Bulbous + çƒç‹€ </string> <string name="Bulbous Nose"> - Bulbous Nose + çƒç‹€é¼» </string> <string name="Breast Physics Mass"> - Breast Mass + ä¹³æˆ¿è³ªé‡ </string> <string name="Breast Physics Smoothing"> - Breast Smoothing + 乳房增圓滑 </string> <string name="Breast Physics Gravity"> - Breast Gravity + 乳房é‡åŠ›ç‰¹æ€§ </string> <string name="Breast Physics Drag"> - Breast Drag + 乳房阻力 </string> <string name="Breast Physics InOut Max Effect"> - Max Effect + 最大效果 </string> <string name="Breast Physics InOut Spring"> - Spring + 彈跳 </string> <string name="Breast Physics InOut Gain"> - Gain + 增益 </string> <string name="Breast Physics InOut Damping"> - Damping + 阻尼 </string> <string name="Breast Physics UpDown Max Effect"> - Max Effect + 最大效果 </string> <string name="Breast Physics UpDown Spring"> - Spring + 彈跳 </string> <string name="Breast Physics UpDown Gain"> - Gain + 增益 </string> <string name="Breast Physics UpDown Damping"> - Damping + 阻尼 </string> <string name="Breast Physics LeftRight Max Effect"> - Max Effect + 最大效果 </string> <string name="Breast Physics LeftRight Spring"> - Spring + 彈跳 </string> <string name="Breast Physics LeftRight Gain"> - Gain + 增益 </string> <string name="Breast Physics LeftRight Damping"> - Damping + 阻尼 </string> <string name="Belly Physics Mass"> - Belly Mass + è…¹éƒ¨è³ªé‡ </string> <string name="Belly Physics Smoothing"> - Belly Smoothing + 腹部增圓滑 </string> <string name="Belly Physics Gravity"> - Belly Gravity + 腹部é‡åŠ›ç‰¹æ€§ </string> <string name="Belly Physics Drag"> - Belly Drag + 腹部阻力 </string> <string name="Belly Physics UpDown Max Effect"> - Max Effect + 最大效果 </string> <string name="Belly Physics UpDown Spring"> - Spring + 彈跳 </string> <string name="Belly Physics UpDown Gain"> - Gain + 增益 </string> <string name="Belly Physics UpDown Damping"> - Damping + 阻尼 </string> <string name="Butt Physics Mass"> - Butt Mass + è‡€éƒ¨è³ªé‡ </string> <string name="Butt Physics Smoothing"> - Butt Smoothing + 臀部增圓滑 </string> <string name="Butt Physics Gravity"> - Butt Gravity + 臀部é‡åŠ›ç‰¹æ€§ </string> <string name="Butt Physics Drag"> - Butt Drag + 臀部阻力 </string> <string name="Butt Physics UpDown Max Effect"> - Max Effect + 最大效果 </string> <string name="Butt Physics UpDown Spring"> - Spring + 彈跳 </string> <string name="Butt Physics UpDown Gain"> - Gain + 增益 </string> <string name="Butt Physics UpDown Damping"> - Damping + 阻尼 </string> <string name="Butt Physics LeftRight Max Effect"> - Max Effect + 最大效果 </string> <string name="Butt Physics LeftRight Spring"> - Spring + 彈跳 </string> <string name="Butt Physics LeftRight Gain"> - Gain + 增益 </string> <string name="Butt Physics LeftRight Damping"> - Damping + 阻尼 </string> <string name="Bushy Eyebrows"> - Bushy Eyebrows + 濃眉 </string> <string name="Bushy Hair"> - Bushy Hair + 濃密é é«® </string> <string name="Butt Size"> - Butt Size + è‡€éƒ¨å¤§å° </string> <string name="Butt Gravity"> - Butt Gravity + 臀部é‡åŠ›ç‰¹æ€§ </string> <string name="bustle skirt"> - Bustle Skirt + å´çšºéŽè†é•·è£™ </string> <string name="no bustle"> - No Bustle + ç„¡å´çšº </string> <string name="more bustle"> - More Bustle + å¢žåŠ å´çšº </string> <string name="Chaplin"> Chaplin </string> <string name="Cheek Bones"> - Cheek Bones + 顴骨 </string> <string name="Chest Size"> - Chest Size + èƒ¸éƒ¨å¤§å° </string> <string name="Chin Angle"> 下巴角度 </string> <string name="Chin Cleft"> - Chin Cleft + 下巴裂度 </string> <string name="Chin Curtains"> - Chin Curtains + çµ¡è…®é¬ </string> <string name="Chin Depth"> - Chin Depth + 下巴深度 </string> <string name="Chin Heavy"> - Chin Heavy + ä¸‹å·´åŽšé‡ </string> <string name="Chin In"> - Chin In + 下巴後縮 </string> <string name="Chin Out"> - Chin Out + 下巴çªå‡º </string> <string name="Chin-Neck"> - Chin-Neck + 下巴-é ¸éƒ¨ </string> <string name="Clear"> 清除 </string> <string name="Cleft"> - Cleft + 分裂 </string> <string name="Close Set Eyes"> - Close Set Eyes + 雙眼é è¿‘ </string> <string name="Closed"> - Closed + é–‰åˆ </string> <string name="Closed Back"> - Closed Back + å¾Œé–‰åˆ </string> <string name="Closed Front"> - Closed Front + å‰é–‰åˆ </string> <string name="Closed Left"> - Closed Left + å·¦é–‰åˆ </string> <string name="Closed Right"> - Closed Right + å³é–‰åˆ </string> <string name="Coin Purse"> - Coin Purse + å°éŒ¢åŒ… </string> <string name="Collar Back"> - Collar Back + 後 Collar </string> <string name="Collar Front"> - Collar Front + å‰ Collar </string> <string name="Corner Down"> - Corner Down + è§’è½æœä¸‹ </string> <string name="Corner Up"> - Corner Up + è§’è½æœä¸Š </string> <string name="Creased"> - Creased + 皺褶 </string> <string name="Crooked Nose"> - Crooked Nose + 彎曲鼻 </string> <string name="Cuff Flare"> - Cuff Flare + 袖å£è£é£¾ </string> <string name="Dark"> - Dark + 深暗 </string> <string name="Dark Green"> - Dark Green + æ·±ç¶ </string> <string name="Darker"> - Darker + 更深暗 </string> <string name="Deep"> - Deep + æ·± </string> <string name="Default Heels"> - Default Heels + é è¨é«˜è·Ÿéž‹ </string> <string name="Dense"> - Dense + ç¨ å¯† </string> <string name="Double Chin"> - Double Chin + 雙下巴 </string> <string name="Downturned"> - Downturned + 嘴角下垂 </string> <string name="Duffle Bag"> - Duffle Bag + 旅行袋 </string> <string name="Ear Angle"> - Ear Angle + 耳朵角度 </string> <string name="Ear Size"> - Ear Size + è€³æœµå¤§å° </string> <string name="Ear Tips"> - Ear Tips + 耳端 </string> <string name="Egg Head"> - Egg Head + 蛋形é </string> <string name="Eye Bags"> - Eye Bags + 眼袋 </string> <string name="Eye Color"> - Eye Color + 眼ç›é¡è‰² </string> <string name="Eye Depth"> - Eye Depth + çœ¼ç›æ·±åº¦ </string> <string name="Eye Lightness"> - Eye Lightness + 眼ç›äº®åº¦ </string> <string name="Eye Opening"> - Eye Opening + 眼ç›åž‚ç›´å¤§å° </string> <string name="Eye Pop"> - Eye Pop + çœ¼ç› Pop </string> <string name="Eye Size"> - Eye Size + 眼ç›å¤§å° </string> <string name="Eye Spacing"> - Eye Spacing + é›™çœ¼é–“è· </string> <string name="Eyebrow Arc"> - Eyebrow Arc + 眉毛弧度 </string> <string name="Eyebrow Density"> - Eyebrow Density + 眉毛密度 </string> <string name="Eyebrow Height"> - Eyebrow Height + 眉毛高度 </string> <string name="Eyebrow Points"> - Eyebrow Points + 眉毛點 </string> <string name="Eyebrow Size"> - Eyebrow Size + 眉毛尺寸 </string> <string name="Eyelash Length"> - Eyelash Length + ç«æ¯›é•·åº¦ </string> <string name="Eyeliner"> - Eyeliner + çœ¼ç·šç† </string> <string name="Eyeliner Color"> - Eyeliner Color + 眼影ç†é¡è‰² </string> <string name="Eyes Bugged"> - Eyes Bugged + çªçœ¼ </string> <string name="Face Shear"> - Face Shear + 臉部åç§» </string> <string name="Facial Definition"> - Facial Definition + 臉部çµå¯¦åº¦ </string> <string name="Far Set Eyes"> - Far Set Eyes + 雙眼è·é›¢é </string> <string name="Fat Lips"> - Fat Lips + 厚脣 </string> <string name="Female"> - Female + 女性 </string> <string name="Fingerless"> - Fingerless + 無手指 </string> <string name="Fingers"> - Fingers + 手指 </string> <string name="Flared Cuffs"> - Flared Cuffs + 帶è£é£¾è¢–å£ </string> <string name="Flat"> - Flat + å¹³ </string> <string name="Flat Butt"> - Flat Butt + 臀部æ‰å¹³ </string> <string name="Flat Head"> - Flat Head + é 部æ‰å¹³ </string> <string name="Flat Toe"> - Flat Toe + 腳趾æ‰å¹³ </string> <string name="Foot Size"> - Foot Size + è…³éƒ¨å¤§å° </string> <string name="Forehead Angle"> - Forehead Angle + å‰é¡è§’度 </string> <string name="Forehead Heavy"> - Forehead Heavy + å‰é¡å¯¬åŽš </string> <string name="Freckles"> - Freckles + 雀斑 </string> <string name="Front Fringe"> - Front Fringe + å‰ç€æµ· </string> <string name="Full Back"> - Full Back + 後部飽滿 </string> <string name="Full Eyeliner"> - Full Eyeliner + 厚é‡çœ¼ç·š </string> <string name="Full Front"> - Full Front + å‰é¢é£½æ»¿ </string> <string name="Full Hair Sides"> - Full Hair Sides + å´é«®é£½æ»¿ </string> <string name="Full Sides"> - Full Sides + å…©å´é£½æ»¿ </string> <string name="Glossy"> - Glossy + 光亮 </string> <string name="Glove Fingers"> - Glove Fingers + 手套手指 </string> <string name="Glove Length"> - Glove Length + 手套長度 </string> <string name="Hair"> é é«® </string> <string name="Hair Back"> - Hair: Back + é é«®ï¼šå¾Œé¢ </string> <string name="Hair Front"> - Hair: Front + é 髮:å‰é¢ </string> <string name="Hair Sides"> - Hair: Sides + é 髮:å´é¢ </string> <string name="Hair Sweep"> - Hair Sweep + é 髮垂擺 </string> <string name="Hair Thickess"> - Hair Thickness + é 髮厚度 </string> <string name="Hair Thickness"> - Hair Thickness + é 髮厚度 </string> <string name="Hair Tilt"> - Hair Tilt + é 髮傾度 </string> <string name="Hair Tilted Left"> - Hair Tilted Left + é 髮傾左 </string> <string name="Hair Tilted Right"> - Hair Tilted Right + é é«®å‚¾å³ </string> <string name="Hair Volume"> - Hair: Volume + é é«®ï¼šé«®é‡ </string> <string name="Hand Size"> - Hand Size + æ‰‹éƒ¨å¤§å° </string> <string name="Handlebars"> - Handlebars + 把手 </string> <string name="Head Length"> - Head Length + é 部長度 </string> <string name="Head Shape"> - Head Shape + é åž‹ </string> <string name="Head Size"> - Head Size + é éƒ¨å¤§å° </string> <string name="Head Stretch"> - Head Stretch + é 部延展度 </string> <string name="Heel Height"> - Heel Height + 腳踵高度 </string> <string name="Heel Shape"> - Heel Shape + 腳踵形狀 </string> <string name="Height"> - Height + 高度 </string> <string name="High"> - High + 高 </string> <string name="High Heels"> - High Heels + 高跟鞋 </string> <string name="High Jaw"> - High Jaw + 高顎 </string> <string name="High Platforms"> - High Platforms + 高平臺 </string> <string name="High and Tight"> - High and Tight + 高而緊緻 </string> <string name="Higher"> - Higher + 更高 </string> <string name="Hip Length"> - Hip Length + è…°é•· </string> <string name="Hip Width"> - Hip Width + 腰寬 </string> <string name="In"> - In + å‘å…§ </string> <string name="In Shdw Color"> - Inner Shadow Color + å…§é™°å½±é¡è‰² </string> <string name="In Shdw Opacity"> - Inner Shadow Opacity + å…§é™°å½±ä¸é€æ˜Žåº¦ </string> <string name="Inner Eye Corner"> - Inner Eye Corner + 眼內角 </string> <string name="Inner Eye Shadow"> - Inner Eye Shadow + 內眼陰影 </string> <string name="Inner Shadow"> - Inner Shadow + å…§é™°å½± </string> <string name="Jacket Length"> - Jacket Length + 外套長度 </string> <string name="Jacket Wrinkles"> - Jacket Wrinkles + 外套皺褶 </string> <string name="Jaw Angle"> - Jaw Angle + 顎角度 </string> <string name="Jaw Jut"> - Jaw Jut + 顎çªå‡º </string> <string name="Jaw Shape"> - Jaw Shape + 顎形 </string> <string name="Join"> - Join + åŠ å…¥ </string> <string name="Jowls"> - Jowls + ä¸‹é œ </string> <string name="Knee Angle"> - Knee Angle + è†éƒ¨è§’度 </string> <string name="Knock Kneed"> - Knock Kneed + å…«å—è…¿ </string> <string name="Large"> - Large + 大 </string> <string name="Large Hands"> - Large Hands + 大手掌 </string> <string name="Left Part"> - Left Part + 左邊分 </string> <string name="Leg Length"> - Leg Length + è…¿é•· </string> <string name="Leg Muscles"> - Leg Muscles + 腿肌肉 </string> <string name="Less"> - Less + æ›´å°‘ </string> <string name="Less Body Fat"> - Less Body Fat + 體脂肪較少 </string> <string name="Less Curtains"> - Less Curtains + 絡腮é¬è¼ƒçŸ </string> <string name="Less Freckles"> - Less Freckles + 雀斑較少 </string> <string name="Less Full"> - Less Full + 較ä¸é£½æ»¿ </string> <string name="Less Gravity"> - Less Gravity + 較少é‡åŠ› </string> <string name="Less Love"> - Less Love + 少一點愛 </string> <string name="Less Muscles"> - Less Muscles + 少一點肌肉 </string> <string name="Less Muscular"> - Less Muscular + 少一點肌壯感 </string> <string name="Less Rosy"> - Less Rosy + 少一點紅潤 </string> <string name="Less Round"> - Less Round + 少一點圓度 </string> <string name="Less Saddle"> - Less Saddle + è…¿é æ”一點 </string> <string name="Less Square"> - Less Square + 少一點方形 </string> <string name="Less Volume"> - Less Volume + å°‘ä¸€é»žé‡ </string> <string name="Less soul"> - Less soul + 少一點éˆé‚ </string> <string name="Lighter"> - Lighter + 亮一點 </string> <string name="Lip Cleft"> - Lip Cleft + 脣裂度 </string> <string name="Lip Cleft Depth"> - Lip Cleft Depth + 脣裂深度 </string> <string name="Lip Fullness"> - Lip Fullness + è„£è±åº¦ </string> <string name="Lip Pinkness"> - Lip Pinkness + 脣色粉紅度 </string> <string name="Lip Ratio"> - Lip Ratio + 脣比率 </string> <string name="Lip Thickness"> - Lip Thickness + 脣厚度 </string> <string name="Lip Width"> - Lip Width + 脣寬度 </string> <string name="Lipgloss"> - Lipgloss + 脣蜜 </string> <string name="Lipstick"> - Lipstick + è„£è† </string> <string name="Lipstick Color"> - Lipstick Color + è„£è†é¡è‰² </string> <string name="Long"> - Long + é•· </string> <string name="Long Head"> - Long Head + 長臉 </string> <string name="Long Hips"> - Long Hips + 高腰 </string> <string name="Long Legs"> - Long Legs + é•·è…¿ </string> <string name="Long Neck"> - Long Neck + é•·é ¸ </string> <string name="Long Pigtails"> - Long Pigtails + é•·è¾®å </string> <string name="Long Ponytail"> - Long Ponytail + 長馬尾辮 </string> <string name="Long Torso"> - Long Torso + 長軀幹 </string> <string name="Long arms"> - Long arms + 長臂 </string> <string name="Loose Pants"> - Loose Pants + 寬鬆褲å </string> <string name="Loose Shirt"> - Loose Shirt + 寬鬆襯衫 </string> <string name="Loose Sleeves"> - Loose Sleeves + 寬鬆袖å </string> <string name="Love Handles"> - Love Handles + 腰間贅肉 </string> <string name="Low"> - Low + 低 </string> <string name="Low Heels"> - Low Heels + 低跟鞋 </string> <string name="Low Jaw"> - Low Jaw + 低顎 </string> <string name="Low Platforms"> - Low Platforms + 低平臺 </string> <string name="Low and Loose"> - Low and Loose + 低而寬鬆 </string> <string name="Lower"> - Lower + é™ä½Ž </string> <string name="Lower Bridge"> - Lower Bridge + 鼻樑低一點 </string> <string name="Lower Cheeks"> - Lower Cheeks + é›™é °ä½Žä¸€é»ž </string> <string name="Male"> 男性 </string> <string name="Middle Part"> - Middle Part + ä¸é–“邊分 </string> <string name="More"> 更多 </string> <string name="More Blush"> - More Blush + å¢žåŠ è…®ç´… </string> <string name="More Body Fat"> - More Body Fat + å¢žåŠ é«”è„‚è‚ª </string> <string name="More Curtains"> - More Curtains + å¢žåŠ çµ¡è…®é¬ </string> <string name="More Eyeshadow"> - More Eyeshadow + å¢žåŠ çœ¼å½± </string> <string name="More Freckles"> - More Freckles + å¢žåŠ é›€æ–‘ </string> <string name="More Full"> - More Full + 更飽滿 </string> <string name="More Gravity"> - More Gravity + å¢žåŠ é‡åŠ› </string> <string name="More Lipstick"> - More Lipstick + å¤šä¸€é»žè„£è† </string> <string name="More Love"> - More Love + 多一點愛 </string> <string name="More Lower Lip"> - More Lower Lip + ä¸‹è„£æ›´è±æ»¿ </string> <string name="More Muscles"> - More Muscles + 多一點肌肉 </string> <string name="More Muscular"> - More Muscular + å¢žåŠ è‚Œå£¯æ„Ÿ </string> <string name="More Rosy"> - More Rosy + æ›´åŠ ç´…æ½¤ </string> <string name="More Round"> - More Round + å¢žåŠ åœ“åº¦ </string> <string name="More Saddle"> - More Saddle + è…¿æ›´åŠ å¼µé–‹ </string> <string name="More Sloped"> - More Sloped + æ›´åŠ å‚¾æ–œ </string> <string name="More Square"> - More Square + å¢žåŠ æ–¹å½¢ </string> <string name="More Upper Lip"> - More Upper Lip + ä¸Šè„£æ›´è±æ»¿ </string> <string name="More Vertical"> - More Vertical + æ›´åŠ åž‚ç›´ </string> <string name="More Volume"> - More Volume + å¤šä¸€é»žé‡ </string> <string name="More soul"> - More soul + 多一點éˆé‚ </string> <string name="Moustache"> - Moustache + é«é¬ </string> <string name="Mouth Corner"> - Mouth Corner + 嘴角 </string> <string name="Mouth Position"> - Mouth Position + 嘴巴ä½ç½® </string> <string name="Mowhawk"> - Mowhawk + 莫éœå…‹é«®åž‹ </string> <string name="Muscular"> - Muscular + è‚Œè‚‰ç™¼é” </string> <string name="Mutton Chops"> - Mutton Chops + 羊排å¼çµ¡è…®é¬ </string> <string name="Nail Polish"> - Nail Polish + 指甲油 </string> <string name="Nail Polish Color"> - Nail Polish Color + 指甲油é¡è‰² </string> <string name="Narrow"> - Narrow + 窄 </string> <string name="Narrow Back"> - Narrow Back + 後窄 </string> <string name="Narrow Front"> - Narrow Front + å‰çª„ </string> <string name="Narrow Lips"> - Narrow Lips + 窄脣 </string> <string name="Natural"> - Natural + 自然 </string> <string name="Neck Length"> - Neck Length + é ¸é•· </string> <string name="Neck Thickness"> - Neck Thickness + é ¸éƒ¨åŽšåº¦ </string> <string name="No Blush"> - No Blush + 無腮紅 </string> <string name="No Eyeliner"> - No Eyeliner + 無眼線 </string> <string name="No Eyeshadow"> - No Eyeshadow + 無眼影 </string> <string name="No Lipgloss"> - No Lipgloss + 無脣蜜 </string> <string name="No Lipstick"> - No Lipstick + ç„¡è„£è† </string> <string name="No Part"> - No Part + 無邊分 </string> <string name="No Polish"> - No Polish + 無指甲油 </string> <string name="No Red"> - No Red + 去紅色 </string> <string name="No Spikes"> - No Spikes + ç„¡å°–ç›´å½¢ </string> <string name="No White"> - No White + 去白色 </string> <string name="No Wrinkles"> - No Wrinkles + 無皺紋 </string> <string name="Normal Lower"> - Normal Lower + æ£å¸¸ä¸‹åŠ </string> <string name="Normal Upper"> - Normal Upper + æ£å¸¸ä¸ŠåŠ </string> <string name="Nose Left"> - Nose Left + 左鼻 </string> <string name="Nose Right"> - Nose Right + å³é¼» </string> <string name="Nose Size"> - Nose Size + é¼»éƒ¨å¤§å° </string> <string name="Nose Thickness"> - Nose Thickness + é¼»å厚度 </string> <string name="Nose Tip Angle"> - Nose Tip Angle + 鼻尖角度 </string> <string name="Nose Tip Shape"> - Nose Tip Shape + 鼻尖形狀 </string> <string name="Nose Width"> - Nose Width + 鼻寬 </string> <string name="Nostril Division"> - Nostril Division + é¼»å”分開度 </string> <string name="Nostril Width"> - Nostril Width + é¼»å”寬 </string> <string name="Opaque"> - Opaque + ä¸é€æ˜Ž </string> <string name="Open"> - Open + 打開 </string> <string name="Open Back"> - Open Back + 後開 </string> <string name="Open Front"> - Open Front + å‰é–‹ </string> <string name="Open Left"> - Open Left + 左開 </string> <string name="Open Right"> - Open Right + å³é–‹ </string> <string name="Orange"> - Orange + 橘色 </string> <string name="Out"> - Out + 外 </string> <string name="Out Shdw Color"> - Outer Shadow Color + 外陰影é¡è‰² </string> <string name="Out Shdw Opacity"> - Outer Shadow Opacity + 外陰影ä¸é€æ˜Žåº¦ </string> <string name="Outer Eye Corner"> - Outer Eye Corner + 眼外角 </string> <string name="Outer Eye Shadow"> - Outer Eye Shadow + 外眼陰影 </string> <string name="Outer Shadow"> - Outer Shadow + 外陰影 </string> <string name="Overbite"> - Overbite + 齙牙 </string> <string name="Package"> - Package + é…套 </string> <string name="Painted Nails"> - Painted Nails + 美甲 </string> <string name="Pale"> - Pale + 蒼白 </string> <string name="Pants Crotch"> - Pants Crotch + è¤²è¥ </string> <string name="Pants Fit"> - Pants Fit + 褲ååˆèº«åº¦ </string> <string name="Pants Length"> - Pants Length + 褲長 </string> <string name="Pants Waist"> - Pants Waist + 褲腰 </string> <string name="Pants Wrinkles"> - Pants Wrinkles + 褲å皺褶 </string> <string name="Part"> - Part + 邊分 </string> <string name="Part Bangs"> - Part Bangs + é‚Šåˆ†ç€æµ· </string> <string name="Pectorals"> - Pectorals + 胸肌 </string> <string name="Pigment"> - Pigment + è‰²ç´ </string> <string name="Pigtails"> - Pigtails + è¾®å </string> <string name="Pink"> - Pink + 粉紅 </string> <string name="Pinker"> - Pinker + å¢žåŠ ç²‰ç´… </string> <string name="Platform Height"> - Platform Height + 平臺高度 </string> <string name="Platform Width"> - Platform Width + 平臺寬度 </string> <string name="Pointy"> - Pointy + å°–ç‹€ </string> <string name="Pointy Heels"> - Pointy Heels + 尖狀高跟鞋 </string> <string name="Ponytail"> - Ponytail + 馬尾辮 </string> <string name="Poofy Skirt"> - Poofy Skirt + 蓬蓬裙 </string> <string name="Pop Left Eye"> - Pop Left Eye + 左眼 Pop </string> <string name="Pop Right Eye"> - Pop Right Eye + å³çœ¼ Pop </string> <string name="Puffy"> - Puffy + 眼腫 </string> <string name="Puffy Eyelids"> - Puffy Eyelids + 眼瞼腫 </string> <string name="Rainbow Color"> - Rainbow Color + 虹彩 </string> <string name="Red Hair"> - Red Hair + ç´…é«® </string> <string name="Regular"> - Regular + 一般 </string> <string name="Right Part"> - Right Part + å³é‚Šåˆ† </string> <string name="Rosy Complexion"> - Rosy Complexion + 臉色紅潤 </string> <string name="Round"> - Round + 圓 </string> <string name="Ruddiness"> - Ruddiness + 紅潤度 </string> <string name="Ruddy"> - Ruddy + 紅潤 </string> <string name="Rumpled Hair"> - Rumpled Hair + 亂髮 </string> <string name="Saddle Bags"> - Saddle Bags + 馬éžåž‹å·¥å…·è¢‹ </string> <string name="Scrawny Leg"> - Scrawny Leg + 削瘦的腿 </string> <string name="Separate"> - Separate + 分開 </string> <string name="Shallow"> - Shallow + æ·º </string> <string name="Shear Back"> - Shear Back + 後åç§» </string> <string name="Shear Face"> - Shear Face + 臉部åç§» </string> <string name="Shear Front"> - Shear Front + å‰åç§» </string> <string name="Shear Left Up"> - Shear Left Up + 左上åç§» </string> <string name="Shear Right Up"> - Shear Right Up + å³ä¸Šåç§» </string> <string name="Sheared Back"> - Sheared Back + 後åç§» </string> <string name="Sheared Front"> - Sheared Front + å‰åç§» </string> <string name="Shift Left"> - Shift Left + 左移 </string> <string name="Shift Mouth"> - Shift Mouth + 嘴部åç§» </string> <string name="Shift Right"> - Shift Right + å³ç§» </string> <string name="Shirt Bottom"> - Shirt Bottom + 襯衫底 </string> <string name="Shirt Fit"> - Shirt Fit + 襯衫åˆèº«åº¦ </string> <string name="Shirt Wrinkles"> - Shirt Wrinkles + 襯衫皺褶 </string> <string name="Shoe Height"> - Shoe Height + 鞋高 </string> <string name="Short"> - Short + çŸ </string> <string name="Short Arms"> - Short Arms + çŸè‡‚ </string> <string name="Short Legs"> - Short Legs + çŸè…¿ </string> <string name="Short Neck"> - Short Neck + çŸé ¸ </string> <string name="Short Pigtails"> - Short Pigtails + çŸè¾®å </string> <string name="Short Ponytail"> - Short Ponytail + çŸé¦¬å°¾è¾® </string> <string name="Short Sideburns"> - Short Sideburns + çŸé¬¢é¬š </string> <string name="Short Torso"> - Short Torso + çŸè»€å¹¹ </string> <string name="Short hips"> - Short hips + çŸè…° </string> <string name="Shoulders"> - Shoulders + 肩膀 </string> <string name="Side Fringe"> - Side Fringe + å´ç€æµ· </string> <string name="Sideburns"> - Sideburns + 鬢鬚 </string> <string name="Sides Hair"> - Sides Hair + å´é¢é é«® </string> <string name="Sides Hair Down"> - Sides Hair Down + å´é¢é 髮下部 </string> <string name="Sides Hair Up"> - Sides Hair Up + å´é¢é 髮上部 </string> <string name="Skinny Neck"> - Skinny Neck + å‰Šç˜¦é ¸éƒ¨ </string> <string name="Skirt Fit"> - Skirt Fit + 裙ååˆèº«åº¦ </string> <string name="Skirt Length"> - Skirt Length + 裙長 </string> <string name="Slanted Forehead"> - Slanted Forehead + æ–œå‰é¡ </string> <string name="Sleeve Length"> - Sleeve Length + 袖長 </string> <string name="Sleeve Looseness"> - Sleeve Looseness + 袖å寬鬆度 </string> <string name="Slit Back"> - Slit: Back + 後分 </string> <string name="Slit Front"> - Slit: Front + å‰åˆ† </string> <string name="Slit Left"> - Slit: Left + 左分 </string> <string name="Slit Right"> - Slit: Right + å³åˆ† </string> <string name="Small"> - Small + å° </string> <string name="Small Hands"> - Small Hands + å°æ‰‹ </string> <string name="Small Head"> - Small Head + å°é </string> <string name="Smooth"> - Smooth + 平滑 </string> <string name="Smooth Hair"> - Smooth Hair + 平滑é é«® </string> <string name="Socks Length"> - Socks Length + 襪長 </string> <string name="Soulpatch"> - Soulpatch + è„£ä¸‹æ’®é¬ </string> <string name="Sparse"> - Sparse + ç¨€ç– </string> <string name="Spiked Hair"> - Spiked Hair + å°–ç›´é é«® </string> <string name="Square"> - Square + 方形 </string> <string name="Square Toe"> - Square Toe + å¹³é éž‹ </string> <string name="Squash Head"> - Squash Head + 長瓜形臉 </string> <string name="Stretch Head"> - Stretch Head + 延展é 部 </string> <string name="Sunken"> - Sunken + 深陷 </string> <string name="Sunken Chest"> - Sunken Chest + 胸部內陷 </string> <string name="Sunken Eyes"> - Sunken Eyes + çœ¼ç›æ·±é™· </string> <string name="Sweep Back"> - Sweep Back + 後垂擺 </string> <string name="Sweep Forward"> - Sweep Forward + å‰åž‚擺 </string> <string name="Tall"> - Tall + 高 </string> <string name="Taper Back"> - Taper Back + 後漸細 </string> <string name="Taper Front"> - Taper Front + 剿¼¸ç´° </string> <string name="Thick Heels"> - Thick Heels + 粗腳跟 </string> <string name="Thick Neck"> - Thick Neck + ç²—é ¸ </string> <string name="Thick Toe"> - Thick Toe + 粗腳趾 </string> <string name="Thin"> - Thin + 瘦 </string> <string name="Thin Eyebrows"> - Thin Eyebrows + 細眉 </string> <string name="Thin Lips"> - Thin Lips + ç´°è„£ </string> <string name="Thin Nose"> - Thin Nose + ç´°é¼» </string> <string name="Tight Chin"> - Tight Chin + 緊緻下巴 </string> <string name="Tight Cuffs"> - Tight Cuffs + ç·Šç·»è¢–å£ </string> <string name="Tight Pants"> - Tight Pants + 緊緻褲å </string> <string name="Tight Shirt"> - Tight Shirt + 緊緻襯衫 </string> <string name="Tight Skirt"> - Tight Skirt + 緊緻裙å </string> <string name="Tight Sleeves"> - Tight Sleeves + 緊緻袖å </string> <string name="Toe Shape"> - Toe Shape + 腳趾形狀 </string> <string name="Toe Thickness"> - Toe Thickness + 腳趾粗細 </string> <string name="Torso Length"> - Torso Length + 軀幹長度 </string> <string name="Torso Muscles"> - Torso Muscles + 軀幹肌肉 </string> <string name="Torso Scrawny"> - Torso Scrawny + 軀幹削瘦 </string> <string name="Unattached"> - Unattached + 未附著 </string> <string name="Uncreased"> - Uncreased + 無皺痕 </string> <string name="Underbite"> - Underbite + 戽斗 </string> <string name="Unnatural"> - Unnatural + ä¸è‡ªç„¶ </string> <string name="Upper Bridge"> - Upper Bridge + ä¸Šé¼»æ¢ </string> <string name="Upper Cheeks"> - Upper Cheeks + ä¸Šè‡‰é ° </string> <string name="Upper Chin Cleft"> - Upper Chin Cleft + 上部顎裂 </string> <string name="Upper Eyelid Fold"> - Upper Eyelid Fold + 上眼瞼皺褶 </string> <string name="Upturned"> - Upturned + 嘴角上翹 </string> <string name="Very Red"> - Very Red + 大紅 </string> <string name="Waist Height"> - Waist Height + 腰高 </string> <string name="Well-Fed"> - Well-Fed + 飽食的 </string> <string name="White Hair"> - White Hair + 白髮 </string> <string name="Wide"> - Wide + 寬 </string> <string name="Wide Back"> - Wide Back + 後寬 </string> <string name="Wide Front"> - Wide Front + å‰å¯¬ </string> <string name="Wide Lips"> - Wide Lips + 寬脣 </string> <string name="Wild"> - Wild + 狂野 </string> <string name="Wrinkles"> - Wrinkles + 皺紋 </string> <string name="LocationCtrlAddLandmarkTooltip"> æ·»åŠ åˆ°æˆ‘çš„åœ°æ¨™ @@ -3585,6 +3868,15 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="LocationCtrlGeneralIconTooltip"> ä¸€èˆ¬æ™®ç´šåœ°å€ </string> + <string name="LocationCtrlSeeAVsTooltip"> + å¯çœ‹åˆ°æœ¬åœ°æ®µå¤–的化身,並與之交談 + </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + 地å€é‡æ–°ç”¢å‡ºä¹‹å‰ï¼Œå¯ç§»å‹•物件å¯èƒ½ç„¡æ³•æ£å¸¸é‹ä½œã€‚ + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + 這地å€ä¸¦æœªå•Ÿç”¨å‹•態尋徑。 + </string> <string name="UpdaterWindowTitle"> [APP_NAME] æ›´æ–° </string> @@ -3595,7 +3887,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. [APP_NAME] 安è£ä¸... </string> <string name="UpdaterUpdatingDescriptive"> - Your [APP_NAME] Viewer is being updated to the latest release. This may take some time, so please be patient. + ä½ çš„ [APP_NAME] Viewer æ£åœ¨æ›´æ–°ç‚ºæœ€æ–°ç™¼è¡Œç‰ˆã€‚ å¯èƒ½è¦ç‰ä¸€æœƒå…’,請è€å¿ƒç¨å€™ã€‚ </string> <string name="UpdaterProgressBarTextWithEllipses"> 更新下載ä¸... @@ -3607,7 +3899,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. å¤è¼‰æ›´æ–°å¤±æ•— </string> <string name="UpdaterFailUpdateDescriptive"> - An error occurred while updating [APP_NAME]. Please download the latest version from www.secondlife.com. + [APP_NAME] 更新時出錯。 請到 www.secondlife.com 下載最新版本。 </string> <string name="UpdaterFailInstallTitle"> å®‰è£æ›´æ–°å¤±æ•— @@ -3616,13 +3908,13 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 啟動ç€è¦½å™¨å¤±æ•— </string> <string name="ItemsComingInTooFastFrom"> - [APP_NAME]: Items coming in too fast from [FROM_NAME], automatic preview disabled for [TIME] seconds + [APP_NAME]:來自 [FROM_NAME] çš„é …ç›®é€Ÿåº¦éŽå¿«ï¼Œå› æ¤è‡ªå‹•é è¦½æš«åœ [TIME] ç§’ </string> <string name="ItemsComingInTooFast"> - [APP_NAME]: Items coming in too fast, automatic preview disabled for [TIME] seconds + [APP_NAME]ï¼šé€²ä¾†çš„é …ç›®é€Ÿåº¦éŽå¿«ï¼Œå› æ¤è‡ªå‹•é è¦½æš«åœ [TIME] ç§’ </string> <string name="IM_logging_string"> - -- Instant message logging enabled -- + -- å·²é–‹å•ŸåŠæ™‚訊æ¯è¨˜éŒ„ -- </string> <string name="IM_typing_start_string"> [NAME] æ£åœ¨è¼¸å…¥... @@ -3631,43 +3923,46 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. (未命å) </string> <string name="IM_moderated_chat_label"> - (Moderated: Voices off by default) + (有人主æŒï¼šé è¨é—œé–‰èªžéŸ³ï¼‰ </string> <string name="IM_unavailable_text_label"> - Text chat is not available for this call. + 這次通話無法使用文å—èŠå¤©ã€‚ </string> <string name="IM_muted_text_label"> - Your text chat has been disabled by a Group Moderator. + 群組主æŒäººå·²ç¦æ¢ä½ 進行文å—èŠå¤©ã€‚ </string> <string name="IM_default_text_label"> - 點擊æ¤è™•以傳é€å³æ™‚訊æ¯ã€‚ + 點按æ¤è™•以傳é€å³æ™‚訊æ¯ã€‚ </string> <string name="IM_to_label"> 至 </string> <string name="IM_moderator_label"> - (Moderator) + (主æŒäººï¼‰ </string> <string name="Saved_message"> - (Saved [LONG_TIMESTAMP]) + (於 [LONG_TIMESTAMP] 儲å˜ï¼‰ + </string> + <string name="IM_unblock_only_groups_friends"> + è¦å¯Ÿçœ‹é€™è¨Šæ¯ï¼Œä½ å¿…é ˆåˆ°ã€Œå好è¨å®š / éš±ç§ã€ï¼Œå–消勾é¸ã€Œåªæœ‰æˆ‘的朋å‹å’Œç¾¤çµ„å¯ä»¥ IM 或與我通話ã€ã€‚ </string> <string name="answered_call"> - Your call has been answered + ä½ çš„é€šè©±å·²ç¶“æŽ¥é€š </string> <string name="you_started_call"> - You started a voice call + ä½ ç™¼èµ·äº†èªžéŸ³é€šè©± </string> <string name="you_joined_call"> - You joined the voice call + ä½ ç™¼èµ·äº†èªžéŸ³é€šè©± </string> <string name="name_started_call"> - [NAME] started a voice call + [NAME] 發起了語音通話 </string> <string name="ringing-im"> åŠ å…¥èªžéŸ³é€šè©±... </string> <string name="connected-im"> - Connected, click Leave Call to hang up + å·²æŽ¥é€šï¼Œè¦æŽ›æ–·è«‹æŒ‰ã€Œé›¢é–‹é€šè©±ã€ </string> <string name="hang_up-im"> 離開語音通話 @@ -3676,40 +3971,40 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. è¯æŽ¥ä¸... </string> <string name="conference-title"> - Ad-hoc Conference + 臨時多方通話 </string> <string name="conference-title-incoming"> - Conference with [AGENT_NAME] + å’Œ [AGENT_NAME] 多方通話 </string> <string name="inventory_item_offered-im"> - Inventory item offered + æ”¶ç´å€ç‰©å“å·²ç™¼é€ </string> <string name="share_alert"> - Drag items from inventory here + 將收ç´å€ç‰©å“拖曳到這裡 </string> <string name="no_session_message"> (IM 會話ä¸å˜åœ¨ï¼‰ </string> <string name="only_user_message"> - You are the only user in this session. + é€™æ¬¡æœƒè©±åªæœ‰ä½ 一人。 </string> <string name="offline_message"> [NAME] 離線。 </string> <string name="invite_message"> - Click the [BUTTON NAME] button to accept/connect to this voice chat. + 點按 [BUTTON NAME] 按鈕接å—並連通到這個語音èŠå¤©ã€‚ </string> <string name="muted_message"> - You have blocked this Resident. Sending a message will automatically unblock them. + ä½ å·²ç¶“å°éޖ這ä½å±…民。 發é€è¨Šæ¯å°‡æœƒè‡ªå‹•解除å°éŽ–ã€‚ </string> <string name="generic"> - Error making request, please try again later. + é€å‡ºè«‹æ±‚時出錯,請ç¨å€™å†è©¦ã€‚ </string> <string name="generic_request_error"> - Error making request, please try again later. + é€å‡ºè«‹æ±‚時出錯,請ç¨å€™å†è©¦ã€‚ </string> <string name="insufficient_perms_error"> - You do not have sufficient permissions. + ä½ æ¬Šé™ä¸è¶³ã€‚ </string> <string name="session_does_not_exist_error"> æ¤æœƒè©±ä¸å†å˜åœ¨ @@ -3721,25 +4016,25 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. ä½ ä¸¦ä¸å…·æœ‰é€™å€‹èƒ½åŠ›ã€‚ </string> <string name="not_a_mod_error"> - You are not a session moderator. + ä½ ä¸å…·æœƒè©±ä¸»æŒäººèº«ä»½ã€‚ </string> <string name="muted"> - A group moderator disabled your text chat. + æŸç¾¤çµ„主æŒäººç¦æ¢äº†ä½ 的文å—èŠå¤©ã€‚ </string> <string name="muted_error"> - A group moderator disabled your text chat. + æŸç¾¤çµ„主æŒäººç¦æ¢äº†ä½ 的文å—èŠå¤©ã€‚ </string> <string name="add_session_event"> - Unable to add users to chat session with [RECIPIENT]. + ç„¡æ³•æ–°å¢žä½¿ç”¨è€…åŠ å…¥èˆ‡ [RECIPIENT] çš„èŠå¤©æœƒè©±ã€‚ </string> <string name="message"> - Unable to send your message to the chat session with [RECIPIENT]. + ä½ çš„è¨Šæ¯ç„¡æ³•傳é€çµ¦èˆ‡ [RECIPIENT] çš„èŠå¤©æœƒè©±ã€‚ </string> <string name="message_session_event"> - Unable to send your message to the chat session with [RECIPIENT]. + ä½ çš„è¨Šæ¯ç„¡æ³•傳é€çµ¦èˆ‡ [RECIPIENT] çš„èŠå¤©æœƒè©±ã€‚ </string> <string name="mute"> - Error while moderating. + ä¸»æŒæœŸé–“發生錯誤。 </string> <string name="removed"> ä½ å·²ç¶“ç”±ç¾¤çµ„ä¸è¢«ç§»é™¤ã€‚ @@ -3748,49 +4043,64 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. ä½ å·²ç¶“ç”±ç¾¤çµ„ä¸è¢«ç§»é™¤ã€‚ </string> <string name="close_on_no_ability"> - You no longer have the ability to be in the chat session. + ä½ å·²ç„¡æ³•é€²å…¥é€™å€‹èŠå¤©æœƒè©±ã€‚ </string> <string name="unread_chat_single"> - [SOURCES] has said something new + [SOURCES] åˆèªªäº†ä¸€äº›è©± </string> <string name="unread_chat_multiple"> - [SOURCES] have said something new + [SOURCES] åˆèªªäº†ä¸€äº›è©± </string> <string name="session_initialization_timed_out_error"> - The session initialization is timed out + 會話åˆå§‹åŒ–é€¾æ™‚ï¼Œç„¡æ³•å®Œæˆ + </string> + <string name="Home position set."> + 我的家ä½ç½®å·²å®šã€‚ </string> <string name="voice_morphing_url"> http://secondlife.com/landing/voicemorphing </string> <string name="paid_you_ldollars"> - [NAME] paid you L$[AMOUNT] [REASON]. + [NAME] æ”¯ä»˜ä½ L$[AMOUNT]([REASON])。 </string> <string name="paid_you_ldollars_no_reason"> - [NAME] paid you L$[AMOUNT]. + [NAME] æ”¯ä»˜ä½ L$[AMOUNT]。 </string> <string name="you_paid_ldollars"> - You paid [NAME] L$[AMOUNT] [REASON]. + ä½ æ”¯ä»˜ L$[AMOUNT] 給 [NAME]([REASON])。 </string> <string name="you_paid_ldollars_no_info"> - You paid L$[AMOUNT]. + ä½ æ”¯ä»˜äº† L$[AMOUNT]。 </string> <string name="you_paid_ldollars_no_reason"> - You paid [NAME] L$[AMOUNT]. + ä½ æ”¯ä»˜ L$[AMOUNT] 給 [NAME]。 </string> <string name="you_paid_ldollars_no_name"> - You paid L$[AMOUNT] [REASON]. + ä½ æ”¯ä»˜äº† L$[AMOUNT]([REASON])。 + </string> + <string name="you_paid_failure_ldollars"> + ä½ æ”¯ä»˜ L$[AMOUNT] 給 [NAME] 時出錯:[REASON]。 + </string> + <string name="you_paid_failure_ldollars_no_info"> + ä½ æ”¯ä»˜ L$[AMOUNT] 時出錯。 + </string> + <string name="you_paid_failure_ldollars_no_reason"> + ä½ æ”¯ä»˜ L$[AMOUNT] 給 [NAME] 時出錯。 + </string> + <string name="you_paid_failure_ldollars_no_name"> + ä½ æ”¯ä»˜ L$[AMOUNT] 時出錯:[REASON]。 </string> <string name="for item"> - for [ITEM] + 購買 [ITEM] </string> <string name="for a parcel of land"> - for a parcel of land + 購買一土地地段 </string> <string name="for a land access pass"> - for a land access pass + 購買土地出入通行權 </string> <string name="for deeding land"> - for deeding land + 讓渡土地 </string> <string name="to create a group"> ä»¥å‰µé€ ç¾¤çµ„ @@ -3802,39 +4112,39 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 以上傳 </string> <string name="to publish a classified ad"> - to publish a classified ad + 發布一則個人廣告 </string> <string name="giving"> - Giving L$ [AMOUNT] + æè´ˆ L$ [AMOUNT] </string> <string name="uploading_costs"> 上傳花費 L$ [AMOUNT] </string> <string name="this_costs"> - This costs L$ [AMOUNT] + 本次花費 L$ [AMOUNT] </string> <string name="buying_selected_land"> - Buying selected land for L$ [AMOUNT] + 花費 L$ [AMOUNT] 購買所é¸åœŸåœ° </string> <string name="this_object_costs"> - This object costs L$ [AMOUNT] + æœ¬ç‰©ä»¶åƒ¹æ ¼ L$ [AMOUNT] </string> <string name="group_role_everyone"> 任何人 </string> <string name="group_role_officers"> - Officers + è·å“¡ </string> <string name="group_role_owners"> - æ“æœ‰è€… + 所有人 </string> <string name="group_member_status_online"> 上線 </string> <string name="uploading_abuse_report"> 上傳ä¸... - -èˆ‰å ±æ¿«ç”¨ + +é•è¦èˆ‰å ± </string> <string name="New Shape"> 新體形 @@ -3861,7 +4171,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 新襪å </string> <string name="New Jacket"> - 新夾克 + 新外套 </string> <string name="New Gloves"> 新手套 @@ -3912,7 +4222,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 女性姿勢 </string> <string name="Other Gestures"> - å…¶ä»–å§¿å‹¢ + 其他���勢 </string> <string name="Speech Gestures"> 演說姿勢 @@ -3921,91 +4231,172 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 一般姿勢 </string> <string name="Male - Excuse me"> - Male - Excuse me + 男性 - Excuse me </string> <string name="Male - Get lost"> - Male - Get lost + Male - çµ¦æˆ‘æ»¾è›‹ï¼ </string> <string name="Male - Blow kiss"> - Male - Blow kiss + 男性 - é£›å» </string> <string name="Male - Boo"> - Male - Boo + 男性 - æˆ‘å™“ä½ </string> <string name="Male - Bored"> - Male - Bored + 男性 - ç„¡èŠç‹€ </string> <string name="Male - Hey"> - Male - Hey + 男性 - å˜¿ï¼ </string> <string name="Male - Laugh"> - Male - Laugh + 男性 - 笑 </string> <string name="Male - Repulsed"> - Male - Repulsed + 男性 - ä½œå™ </string> <string name="Male - Shrug"> - Male - Shrug + 男性 - è³è³è‚© </string> <string name="Male - Stick tougue out"> - Male - Stick tougue out + 男性 - å舌é </string> <string name="Male - Wow"> - Male - Wow + 男性 - 哇塞 </string> <string name="Female - Chuckle"> - Female - Chuckle + 女性 - 咯咯笑 </string> <string name="Female - Cry"> - Female - Cry + 女性 - å“ </string> <string name="Female - Embarrassed"> - Female - Embarrassed + 女性 - å°·å°¬ </string> <string name="Female - Excuse me"> - Female - Excuse me + 男性 - Excuse me </string> <string name="Female - Get lost"> - Female - Get lost + 女性 - çµ¦æˆ‘æ»¾è›‹ï¼ </string> <string name="Female - Blow kiss"> - Female - Blow kiss + 女性 - é£›å» </string> <string name="Female - Boo"> - Female - Boo + 女性 - æˆ‘å™“ä½ </string> <string name="Female - Bored"> - Female - Bored + 女性 - ç„¡èŠç‹€ </string> <string name="Female - Hey"> - Female - Hey + 女性 - å˜¿ï¼ </string> <string name="Female - Hey baby"> - Female - Hey baby + 女性 - å˜¿ï¼Œå¯¶è² </string> <string name="Female - Laugh"> - Female - Laugh + 女性 - 笑 </string> <string name="Female - Looking good"> - Female - Looking good + 女性 - 看我美ä¸ç¾Ž </string> <string name="Female - Over here"> - Female - Over here + 女性 - 我在這兒 </string> <string name="Female - Please"> - Female - Please + 女性 - è«‹ </string> <string name="Female - Repulsed"> - Female - Repulsed + 女性 - ä½œå™ </string> <string name="Female - Shrug"> - Female - Shrug + 女性 - è³è³è‚© </string> <string name="Female - Stick tougue out"> - Female - Stick tougue out + 女性 - å舌é </string> <string name="Female - Wow"> - Female - Wow + 女性 - 哇塞 + </string> + <string name="/bow"> + /彎腰點é + </string> + <string name="/clap"> + /æ‹æ‰‹ + </string> + <string name="/count"> + /計數 + </string> + <string name="/extinguish"> + /ç†„è¸ + </string> + <string name="/kmb"> + /çµ¦æˆ‘ä¸€å€‹å» + </string> + <string name="/muscle"> + /肌肉 + </string> + <string name="/no"> + /ä¸ + </string> + <string name="/no!"> + /ä¸ï¼ + </string> + <string name="/paper"> + /布 + </string> + <string name="/pointme"> + /指自己 + </string> + <string name="/pointyou"> + /指å‘ä½ + </string> + <string name="/rock"> + /石é + </string> + <string name="/scissor"> + /剪刀 + </string> + <string name="/smoke"> + /æŠ½è¸ + </string> + <string name="/stretch"> + /伸展 + </string> + <string name="/whistle"> + /å¹å£å“¨ + </string> + <string name="/yes"> + /是 + </string> + <string name="/yes!"> + /æ˜¯ï¼ + </string> + <string name="afk"> + 暫時離開 + </string> + <string name="dance1"> + 跳舞1 + </string> + <string name="dance2"> + 跳舞2 + </string> + <string name="dance3"> + 跳舞3 + </string> + <string name="dance4"> + 跳舞4 + </string> + <string name="dance5"> + 跳舞5 + </string> + <string name="dance6"> + 跳舞6 + </string> + <string name="dance7"> + 跳舞7 + </string> + <string name="dance8"> + 跳舞8 </string> <string name="AvatarBirthDateFormat"> [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] @@ -4018,34 +4409,34 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. </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. - If you continue to experience problems, please check your network and firewall setup. + 請察訪 status.secondlifegrid.net 看是å¦ç™¼ç”Ÿäº†å·²çŸ¥ç‹€æ³ã€‚ + å¦‚æžœæ–‡é«”ç¹¼çºŒç™¼ç”Ÿï¼Œè«‹æª¢æŸ¥ä½ çš„ç¶²è·¯å’Œé˜²ç«ç‰†è¨å®šã€‚ </string> <string name="dateTimeWeekdaysNames"> - Sunday:Monday:Tuesday:Wednesday:Thursday:Friday:Saturday + 星期日:星期一:星期二:星期三:星期四:星期五:æ˜ŸæœŸå… </string> <string name="dateTimeWeekdaysShortNames"> - Sun:Mon:Tue:Wed:Thu:Fri:Sat + 星期日:星期一:星期二:星期三:星期四:星期五:æ˜ŸæœŸå… </string> <string name="dateTimeMonthNames"> - January:February:March:April:May:June:July:August:September:October:November:December + 一月:二月:三月:四月:五月:å…æœˆ:七月:八月:乿œˆ:åæœˆ:å一月:å二月 </string> <string name="dateTimeMonthShortNames"> - Jan:Feb:Mar:Apr:May:Jun:Jul:Aug:Sep:Oct:Nov:Dec + 一月:二月:三月:四月:五月:å…æœˆ:七月:八月:乿œˆ:åæœˆ:å一月:å二月 </string> <string name="dateTimeDayFormat"> [MDAY] </string> <string name="dateTimeAM"> - AM + ä¸Šåˆ </string> <string name="dateTimePM"> - PM + ä¸‹åˆ </string> <string name="LocalEstimateUSD"> - US$ [AMOUNT] + $ [AMOUNT] 美元 </string> <string name="Membership"> æˆå“¡è³‡æ ¼ @@ -4054,25 +4445,25 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 角色 </string> <string name="Group Identity"> - Group Identity + 群組身份 </string> <string name="Parcel Management"> åœ°æ®µç®¡ç† </string> <string name="Parcel Identity"> - Parcel Identity + 地段å </string> <string name="Parcel Settings"> 地段è¨å®š </string> <string name="Parcel Powers"> - Parcel Powers + 地段權利 </string> <string name="Parcel Access"> - Parcel Access + 地段出入 </string> <string name="Parcel Content"> - Parcel Content + 地段內容 </string> <string name="Object Management"> ç‰©ä»¶ç®¡ç† @@ -4090,7 +4481,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 刪除所é¸å–的物å“? </string> <string name="DeleteItem"> - 刪除所é¸å–的物å“? + 刪除所é¸å–的物���? </string> <string name="EmptyOutfitText"> 沒有任何物å“åœ¨é€™å€‹è£æ‰®å…§ @@ -4099,72 +4490,78 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 鏿“‡ä¸€å€‹ç·¨è¼¯å™¨ä½¿ç”¨ ExternalEditor è¨å®šã€‚ </string> <string name="ExternalEditorNotFound"> - Cannot find the external editor you specified. -Try enclosing path to the editor with double quotes. -(e.g. "/path to my/editor" "%s") + 找ä¸åˆ°ä½ 指定的外部編輯器。 +請嘗試在編輯器路經å‰å¾ŒåŠ ä¸Šè‹±æ–‡é›™æ‹¬è™Ÿã€‚ +(例:"/path to my/editor" "%s") </string> <string name="ExternalEditorCommandParseError"> - Error parsing the external editor command. + è§£æžå¤–部編輯器指令時出錯。 </string> <string name="ExternalEditorFailedToRun"> 執行外部編輯器失敗。 </string> + <string name="TranslationFailed"> + 無法翻è¯ï¼š[REASON] + </string> + <string name="TranslationResponseParseError"> + 無法剖æžå¹³ç§»å›žæ‡‰ã€‚ + </string> <string name="Esc"> - Esc + Esc éµ </string> <string name="Space"> - Space + ç©ºé–“éµ </string> <string name="Enter"> - Enter + Enter éµ </string> <string name="Tab"> - Tab + Tab éµ </string> <string name="Ins"> - Ins + Ins éµ </string> <string name="Del"> - Del + Del éµ </string> <string name="Backsp"> - Backsp + Backspace éµ </string> <string name="Shift"> - Shift + Shift éµ </string> <string name="Ctrl"> - Ctrl + Ctrl éµ </string> <string name="Alt"> - Alt + Alt éµ </string> <string name="CapsLock"> - CapsLock + CapsLock éµ </string> <string name="Left"> - Left + å·¦ç§»éµ </string> <string name="Right"> - Right + å³ç§»éµ </string> <string name="Up"> - Up + ä¸Šç§»éµ </string> <string name="Down"> - Down + ä¸‹ç§»éµ </string> <string name="Home"> - Home + Home éµ </string> <string name="End"> - End + End éµ </string> <string name="PgUp"> - PgUp + PgUp éµ </string> <string name="PgDn"> - PgDn + PgDn éµ </string> <string name="F1"> F1 @@ -4203,16 +4600,16 @@ Try enclosing path to the editor with double quotes. F12 </string> <string name="Add"> - Add + æ·»åŠ </string> <string name="Subtract"> - Subtract + 減 </string> <string name="Multiply"> - Multiply + 乘 </string> <string name="Divide"> - Divide + 除 </string> <string name="PAD_DIVIDE"> PAD_DIVIDE @@ -4392,7 +4789,7 @@ Try enclosing path to the editor with double quotes. M </string> <string name="N"> - N + 北 </string> <string name="O"> O @@ -4407,7 +4804,7 @@ Try enclosing path to the editor with double quotes. R </string> <string name="S"> - S + å— </string> <string name="T"> T @@ -4419,7 +4816,7 @@ Try enclosing path to the editor with double quotes. V </string> <string name="W"> - W + 西 </string> <string name="X"> X @@ -4431,24 +4828,243 @@ Try enclosing path to the editor with double quotes. Z </string> <string name="BeaconParticle"> - Viewing particle beacons (blue) + æª¢è¦–ç²’åæ•ˆæžœçš„導引(è—色) </string> <string name="BeaconPhysical"> - Viewing physical object beacons (green) + æª¢è¦–å…·é«”ç‰©ä»¶çš„å°Žå¼•ï¼ˆç¶ è‰²ï¼‰ </string> <string name="BeaconScripted"> - Viewing scripted object beacons (red) + 檢視腳本物件的導引(紅色) </string> <string name="BeaconScriptedTouch"> - Viewing scripted object with touch function beacons (red) + 檢視帶有觸摸函å¼è…³æœ¬ç‰©ä»¶çš„導引(紅色) </string> <string name="BeaconSound"> - Viewing sound beacons (yellow) + 檢視è²éŸ³çš„導引(黃色) </string> <string name="BeaconMedia"> - Viewing media beacons (white) + 檢視媒體的導引(白色) </string> <string name="ParticleHiding"> - Hiding Particles + éš±è—ç²’åæ•ˆæžœ + </string> + <string name="Command_AboutLand_Label"> + 土地資料 + </string> + <string name="Command_Appearance_Label"> + 編輯外觀 + </string> + <string name="Command_Avatar_Label"> + 化身 + </string> + <string name="Command_Build_Label"> + å»ºé€ + </string> + <string name="Command_Chat_Label"> + èŠå¤© + </string> + <string name="Command_Compass_Label"> + 羅盤 + </string> + <string name="Command_Destinations_Label"> + 目的地 + </string> + <string name="Command_Gestures_Label"> + å§¿å‹¢ + </string> + <string name="Command_HowTo_Label"> + ç°¡æ˜“æ•™å¸ + </string> + <string name="Command_Inventory_Label"> + æ”¶ç´å€ + </string> + <string name="Command_Map_Label"> + 地圖 + </string> + <string name="Command_Marketplace_Label"> + 第二人生購物市集 + </string> + <string name="Command_MiniMap_Label"> + è¿·ä½ åœ°åœ– + </string> + <string name="Command_Move_Label"> + 行走 / è·‘æ¥ / 飛行 + </string> + <string name="Command_Outbox_Label"> + 商家發件匣 + </string> + <string name="Command_People_Label"> + 人群 + </string> + <string name="Command_Picks_Label"> + ç²¾é¸åœ°é»ž + </string> + <string name="Command_Places_Label"> + 地點 + </string> + <string name="Command_Preferences_Label"> + å好è¨å®š + </string> + <string name="Command_Profile_Label"> + 檔案 + </string> + <string name="Command_Search_Label"> + æœå°‹ + </string> + <string name="Command_Snapshot_Label"> + å¿«ç…§ + </string> + <string name="Command_Speak_Label"> + 說話 + </string> + <string name="Command_View_Label"> + æ”影機控制 + </string> + <string name="Command_Voice_Label"> + 語音è¨å®š + </string> + <string name="Command_AboutLand_Tooltip"> + æœ‰é—œä½ æ‰€è™•åœŸåœ°çš„è³‡è¨Š + </string> + <string name="Command_Appearance_Tooltip"> + 改變化身 + </string> + <string name="Command_Avatar_Tooltip"> + 鏿“‡ä¸€å€‹å®Œæ•´çš„化身 + </string> + <string name="Command_Build_Tooltip"> + 建製物件和é‡å¡‘地形 + </string> + <string name="Command_Chat_Tooltip"> + é€éŽæ–‡å—和附近人們èŠå¤© + </string> + <string name="Command_Compass_Tooltip"> + 指å—é‡ + </string> + <string name="Command_Destinations_Tooltip"> + ä½ å¯èƒ½æ„Ÿèˆˆè¶£çš„目的地 + </string> + <string name="Command_Gestures_Tooltip"> + ä½ åŒ–èº«å¯ç”¨çš„å§¿å‹¢ + </string> + <string name="Command_HowTo_Tooltip"> + 如何完æˆå¸¸ç”¨çš„動作 + </string> + <string name="Command_Inventory_Tooltip"> + å¯Ÿçœ‹ä¸¦ä½¿ç”¨ä½ æ“æœ‰çš„物件 + </string> + <string name="Command_Map_Tooltip"> + 世界地圖 + </string> + <string name="Command_Marketplace_Tooltip"> + å‰å¾€è³¼ç‰© + </string> + <string name="Command_MiniMap_Tooltip"> + 顯示附近的人 + </string> + <string name="Command_Move_Tooltip"> + 移動化身 + </string> + <string name="Command_Outbox_Tooltip"> + å°‡ç‰©é …è½‰ç§»åˆ°ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚é›†å¾…å”® + </string> + <string name="Command_People_Tooltip"> + 朋å‹ã€ç¾¤çµ„和附近的人 + </string> + <string name="Command_Picks_Tooltip"> + é¡¯ç¤ºåœ¨ä½ çš„å°æª”案ä¸çš„æœ€æ„›åœ°é»ž + </string> + <string name="Command_Places_Tooltip"> + ä½ å„²å˜çš„地點 + </string> + <string name="Command_Preferences_Tooltip"> + å好è¨å®š + </string> + <string name="Command_Profile_Tooltip"> + ç·¨è¼¯æˆ–å¯Ÿçœ‹ä½ çš„å°æª”案 + </string> + <string name="Command_Search_Tooltip"> + å°‹æ‰¾åœ°é»žã€æ´»å‹•ã€å…¶ä»–人 + </string> + <string name="Command_Snapshot_Tooltip"> + æ‹ä¸€å¼µç…§ç‰‡ + </string> + <string name="Command_Speak_Tooltip"> + 用麥克風和附近人們交談 + </string> + <string name="Command_View_Tooltip"> + 調整æ”影機角度 + </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%"> + ä¿ç•™% + </string> + <string name="Detail"> + 細節 + </string> + <string name="Better Detail"> + 更多細節 + </string> + <string name="Surface"> + è¡¨é¢ + </string> + <string name="Solid"> + 固體 + </string> + <string name="Wrap"> + Wrap + </string> + <string name="Preview"> + é 覽 + </string> + <string name="Normal"> + æ£å¸¸ + </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + ç„¡ + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + å½±éŸ¿å°Žèˆªç¶²é¢ + </string> + <string name="Pathfinding_Object_Attr_Character"> + 角色 + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + ï¼ˆå¤šé …ï¼‰ + </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> + <string name="TeleportMaturityExceeded"> + æ¤å±…æ°‘ä¸å¾—進入æ¤åœ°å€ã€‚ + </string> + <string name="UserDictionary"> + [User] </string> </strings> diff --git a/indra/newview/skins/default/xui/zh/teleport_strings.xml b/indra/newview/skins/default/xui/zh/teleport_strings.xml index bfdb107810..37080a8d0c 100644 --- a/indra/newview/skins/default/xui/zh/teleport_strings.xml +++ b/indra/newview/skins/default/xui/zh/teleport_strings.xml @@ -2,15 +2,15 @@ <teleport_messages> <message_set name="errors"> <message name="invalid_tport"> - Problem encountered processing your teleport request. You may need to log back in before you can teleport. + 處ç†ä½ 瞬間傳é€è¦æ±‚時發生å•題。 如果想è¦çž¬é–“傳é€ï¼Œä½ å¯èƒ½éœ€è¦é‡æ–°ç™»å…¥ã€‚ å¦‚æžœä½ æŒçºŒå¾—到æ¤è¨Šæ¯ï¼Œè«‹æŸ¥é–± [SUPPORT_SITE]。 </message> <message name="invalid_region_handoff"> - Problem encountered processing your region crossing. You may need to log back in before you can cross regions. + 處ç†ä½ 跨越地å€å‹•作時發生å•題。 如果想è¦è·¨è¶Šåœ°å€ï¼Œä½ å¯èƒ½éœ€è¦é‡æ–°ç™»å…¥ã€‚ å¦‚æžœä½ æŒçºŒå¾—到æ¤è¨Šæ¯ï¼Œè«‹æŸ¥é–± [SUPPORT_SITE]。 </message> <message name="blocked_tport"> - 抱æ‰ï¼Œç›®å‰çž¬é–“傳é€å·²è¢«é˜»æ“‹ã€‚è«‹ç¨å¾Œå†è©¦ã€‚ + 抱æ‰ï¼Œç›®å‰ç¦æ¢çž¬é–“傳é€ã€‚ è«‹ç¨å¾Œå†è©¦ã€‚ å¦‚æžœä½ ä»ç„¡æ³•進行瞬間傳é€ï¼Œè«‹ç™»å‡ºå¾Œé‡æ–°å…¥ä¾†è§£æ±ºæ¤ä¸€å•題。 </message> <message name="nolandmark_tport"> @@ -21,40 +21,43 @@ è«‹ç¨å¾Œå†è©¦ã€‚ </message> <message name="NoHelpIslandTP"> - 您ä¸èƒ½çž¬é—´è½¬ç§»å›žâ€œæ´åЩ岛â€ã€‚ -去“公共æ´åЩ岛â€é‡å¤æ‚¨çš„æ•™ç¨‹ã€‚ + ä½ ç„¡æ³•çž¬é–“å‚³é€å›žã€Œæ–°æ‰‹å°Žå¼•å³¶ã€ã€‚ +請到「大眾新手導引島ã€é‡æ–°åƒåŠ å°Žå¼•æ•™å¸ã€‚ </message> <message name="noaccess_tport"> 抱æ‰ï¼Œä½ 並沒有權é™é€²å…¥è¦çž¬é–“傳é€çš„目的地。 </message> <message name="missing_attach_tport"> - Your attachments have not arrived yet. Try waiting for a few more seconds or log out and back in again before attempting to teleport. + ä½ çš„é™„ä»¶å°šæœªæŠµé”。 è«‹ç¨å€™ä¸€æœƒå…’ï¼Œæˆ–è«‹ç™»å‡ºå¾Œé‡æ–°ç™»å…¥ï¼Œå†å˜—試瞬間傳é€ã€‚ </message> <message name="too_many_uploads_tport"> - The asset queue in this region is currently clogged so your teleport request will not be able to succeed in a timely manner. Please try again in a few minutes or go to a less busy area. + 該地å€çš„資產查詢目å‰å¤ªéŽæ“å¡žï¼Œå› æ¤ä½ 的瞬間傳é€å‹•作å¯èƒ½ç„¡æ³•峿™‚發生。 è«‹ç¨å€™å†è©¦ï¼Œæˆ–è«‹å‰å¾€è¼ƒä¸æ“塞的地å€ã€‚ </message> <message name="expired_tport"> - Sorry, but the system was unable to complete your teleport request in a timely fashion. Please try again in a few minutes. + 抱æ‰ï¼Œç³»çµ±ç„¡æ³•峿™‚完æˆç‚ºä½ 瞬間傳é€ã€‚ è«‹ç¨å¾…幾分é˜å†è©¦ã€‚ </message> <message name="expired_region_handoff"> - Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes. + 抱æ‰ï¼Œç³»çµ±ç„¡æ³•峿™‚è®“ä½ è·¨è¶Šåœ°å€ã€‚ è«‹ç¨å¾…幾分é˜å†è©¦ã€‚ </message> <message name="no_host"> - Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes. + 找ä¸åˆ°çž¬é–“傳é€çš„目的地。 目的地å¯èƒ½æš«æ™‚ä¸å¯ç”¨ï¼Œæˆ–å·²ä¸å˜åœ¨ã€‚ è«‹ç¨å¾…幾分é˜å†è©¦ã€‚ </message> <message name="no_inventory_host"> æ”¶ç´å€åŠŸèƒ½ç›®å‰ç„¡æ³•使用。 </message> + <message name="MustGetAgeRegion"> + ä½ å¿…é ˆå¹´æ»¿ 18 æ²æ‰å¯é€²å…¥é€™åœ°å€ã€‚ + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> - Sending to destination. + é€å¾€ç›®çš„地。 </message> <message name="redirecting"> 釿–°å°Žå‘至ä¸åŒä½ç½®ã€‚ </message> <message name="relaying"> - Relaying to destination. + 接繼é€å¾€ç›®çš„地。 </message> <message name="sending_home"> é€å‡ºå®¶ä½ç½®çš„è¦æ±‚。 @@ -80,5 +83,8 @@ <message name="requesting"> 瞬間傳é€è¦æ±‚ä¸... </message> + <message name="pending"> + ç‰å¾…瞬間傳é€â€¦ + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/paths.xml b/indra/newview/skins/paths.xml deleted file mode 100644 index e6d68488ea..0000000000 --- a/indra/newview/skins/paths.xml +++ /dev/null @@ -1,10 +0,0 @@ -<paths> - <directory> - <subdir>xui</subdir> - <subdir>en</subdir> - </directory> - <directory> - <subdir>xui</subdir> - <subdir>[LANGUAGE]</subdir> - </directory> -</paths>
\ No newline at end of file diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp index c970d79975..3ba25f3c10 100644 --- a/indra/newview/tests/llagentaccess_test.cpp +++ b/indra/newview/tests/llagentaccess_test.cpp @@ -84,19 +84,25 @@ namespace tut LLAgentAccess aa(cgr); cgr.setU32("PreferredMaturity", SIM_ACCESS_PG); +#ifndef HACKED_GODLIKE_VIEWER ensure("1 prefersPG", aa.prefersPG()); ensure("1 prefersMature", !aa.prefersMature()); ensure("1 prefersAdult", !aa.prefersAdult()); +#endif // HACKED_GODLIKE_VIEWER cgr.setU32("PreferredMaturity", SIM_ACCESS_MATURE); +#ifndef HACKED_GODLIKE_VIEWER ensure("2 prefersPG", !aa.prefersPG()); ensure("2 prefersMature", aa.prefersMature()); ensure("2 prefersAdult", !aa.prefersAdult()); +#endif // HACKED_GODLIKE_VIEWER cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT); +#ifndef HACKED_GODLIKE_VIEWER ensure("3 prefersPG", !aa.prefersPG()); ensure("3 prefersMature", aa.prefersMature()); ensure("3 prefersAdult", aa.prefersAdult()); +#endif // HACKED_GODLIKE_VIEWER } template<> template<> @@ -107,45 +113,43 @@ namespace tut LLAgentAccess aa(cgr); // make sure default is PG +#ifndef HACKED_GODLIKE_VIEWER ensure("1 isTeen", aa.isTeen()); ensure("1 isMature", !aa.isMature()); ensure("1 isAdult", !aa.isAdult()); +#endif // HACKED_GODLIKE_VIEWER - // this is kinda bad -- setting this forces maturity to MATURE but !teen != Mature anymore - aa.setTeen(false); - ensure("2 isTeen", !aa.isTeen()); - ensure("2 isMature", aa.isMature()); - ensure("2 isAdult", !aa.isAdult()); - - // have to flip it back and make sure it still works - aa.setTeen(true); - ensure("3 isTeen", aa.isTeen()); - ensure("3 isMature", !aa.isMature()); - ensure("3 isAdult", !aa.isAdult()); - // check the conversion routine +#ifndef HACKED_GODLIKE_VIEWER ensure_equals("1 conversion", SIM_ACCESS_PG, aa.convertTextToMaturity('P')); ensure_equals("2 conversion", SIM_ACCESS_MATURE, aa.convertTextToMaturity('M')); ensure_equals("3 conversion", SIM_ACCESS_ADULT, aa.convertTextToMaturity('A')); ensure_equals("4 conversion", SIM_ACCESS_MIN, aa.convertTextToMaturity('Q')); +#endif // HACKED_GODLIKE_VIEWER // now try the other method of setting it - PG aa.setMaturity('P'); - ensure("4 isTeen", aa.isTeen()); - ensure("4 isMature", !aa.isMature()); - ensure("4 isAdult", !aa.isAdult()); + ensure("2 isTeen", aa.isTeen()); +#ifndef HACKED_GODLIKE_VIEWER + ensure("2 isMature", !aa.isMature()); + ensure("2 isAdult", !aa.isAdult()); +#endif // HACKED_GODLIKE_VIEWER // Mature aa.setMaturity('M'); - ensure("5 isTeen", !aa.isTeen()); - ensure("5 isMature", aa.isMature()); - ensure("5 isAdult", !aa.isAdult()); +#ifndef HACKED_GODLIKE_VIEWER + ensure("3 isTeen", !aa.isTeen()); + ensure("3 isMature", aa.isMature()); + ensure("3 isAdult", !aa.isAdult()); +#endif // HACKED_GODLIKE_VIEWER // Adult aa.setMaturity('A'); - ensure("6 isTeen", !aa.isTeen()); - ensure("6 isMature", aa.isMature()); - ensure("6 isAdult", aa.isAdult()); +#ifndef HACKED_GODLIKE_VIEWER + ensure("4 isTeen", !aa.isTeen()); + ensure("4 isMature", aa.isMature()); + ensure("4 isAdult", aa.isAdult()); +#endif // HACKED_GODLIKE_VIEWER } @@ -156,21 +160,35 @@ namespace tut cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); LLAgentAccess aa(cgr); +#ifndef HACKED_GODLIKE_VIEWER ensure("starts normal", !aa.isGodlike()); +#endif // HACKED_GODLIKE_VIEWER aa.setGodLevel(GOD_NOT); +#ifndef HACKED_GODLIKE_VIEWER ensure("stays normal", !aa.isGodlike()); +#endif // HACKED_GODLIKE_VIEWER aa.setGodLevel(GOD_FULL); +#ifndef HACKED_GODLIKE_VIEWER ensure("sets full", aa.isGodlike()); +#endif // HACKED_GODLIKE_VIEWER aa.setGodLevel(GOD_NOT); +#ifndef HACKED_GODLIKE_VIEWER ensure("resets normal", !aa.isGodlike()); +#endif // HACKED_GODLIKE_VIEWER aa.setAdminOverride(true); +#ifndef HACKED_GODLIKE_VIEWER ensure("admin true", aa.getAdminOverride()); ensure("overrides 1", aa.isGodlike()); +#endif // HACKED_GODLIKE_VIEWER aa.setGodLevel(GOD_FULL); +#ifndef HACKED_GODLIKE_VIEWER ensure("overrides 2", aa.isGodlike()); +#endif // HACKED_GODLIKE_VIEWER aa.setAdminOverride(false); +#ifndef HACKED_GODLIKE_VIEWER ensure("admin false", !aa.getAdminOverride()); ensure("overrides 3", aa.isGodlike()); +#endif // HACKED_GODLIKE_VIEWER } template<> template<> @@ -180,55 +198,73 @@ namespace tut cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); LLAgentAccess aa(cgr); +#ifndef HACKED_GODLIKE_VIEWER ensure("1 pg to start", aa.wantsPGOnly()); ensure("2 pg to start", !aa.canAccessMature()); ensure("3 pg to start", !aa.canAccessAdult()); +#endif // HACKED_GODLIKE_VIEWER aa.setGodLevel(GOD_FULL); +#ifndef HACKED_GODLIKE_VIEWER ensure("1 full god", !aa.wantsPGOnly()); ensure("2 full god", aa.canAccessMature()); ensure("3 full god", aa.canAccessAdult()); +#endif // HACKED_GODLIKE_VIEWER aa.setGodLevel(GOD_NOT); aa.setAdminOverride(true); +#ifndef HACKED_GODLIKE_VIEWER ensure("1 admin mode", !aa.wantsPGOnly()); ensure("2 admin mode", aa.canAccessMature()); ensure("3 admin mode", aa.canAccessAdult()); +#endif // HACKED_GODLIKE_VIEWER aa.setAdminOverride(false); aa.setMaturity('M'); // preferred is still pg by default +#ifndef HACKED_GODLIKE_VIEWER ensure("1 mature pref pg", aa.wantsPGOnly()); ensure("2 mature pref pg", !aa.canAccessMature()); ensure("3 mature pref pg", !aa.canAccessAdult()); +#endif // HACKED_GODLIKE_VIEWER cgr.setU32("PreferredMaturity", SIM_ACCESS_MATURE); +#ifndef HACKED_GODLIKE_VIEWER ensure("1 mature", !aa.wantsPGOnly()); ensure("2 mature", aa.canAccessMature()); ensure("3 mature", !aa.canAccessAdult()); +#endif // HACKED_GODLIKE_VIEWER cgr.setU32("PreferredMaturity", SIM_ACCESS_PG); +#ifndef HACKED_GODLIKE_VIEWER ensure("1 mature pref pg", aa.wantsPGOnly()); ensure("2 mature pref pg", !aa.canAccessMature()); ensure("3 mature pref pg", !aa.canAccessAdult()); +#endif // HACKED_GODLIKE_VIEWER aa.setMaturity('A'); +#ifndef HACKED_GODLIKE_VIEWER ensure("1 adult pref pg", aa.wantsPGOnly()); ensure("2 adult pref pg", !aa.canAccessMature()); ensure("3 adult pref pg", !aa.canAccessAdult()); +#endif // HACKED_GODLIKE_VIEWER cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT); +#ifndef HACKED_GODLIKE_VIEWER ensure("1 adult", !aa.wantsPGOnly()); ensure("2 adult", aa.canAccessMature()); ensure("3 adult", aa.canAccessAdult()); +#endif // HACKED_GODLIKE_VIEWER // make sure that even if pref is high, if access is low we block access // this shouldn't occur in real life but we want to be safe cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT); aa.setMaturity('P'); +#ifndef HACKED_GODLIKE_VIEWER ensure("1 pref adult, actual pg", aa.wantsPGOnly()); ensure("2 pref adult, actual pg", !aa.canAccessMature()); ensure("3 pref adult, actual pg", !aa.canAccessAdult()); +#endif // HACKED_GODLIKE_VIEWER } @@ -239,24 +275,16 @@ namespace tut cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); LLAgentAccess aa(cgr); - ensure("1 transition starts false", !aa.isInTransition()); - aa.setTransition(); - ensure("2 transition now true", aa.isInTransition()); - } - - template<> template<> - void agentaccess_object_t::test<6>() - { - LLControlGroup cgr("test"); - cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); - LLAgentAccess aa(cgr); - cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT); aa.setMaturity('M'); +#ifndef HACKED_GODLIKE_VIEWER ensure("1 preferred maturity pegged to M when maturity is M", cgr.getU32("PreferredMaturity") == SIM_ACCESS_MATURE); +#endif // HACKED_GODLIKE_VIEWER aa.setMaturity('P'); +#ifndef HACKED_GODLIKE_VIEWER ensure("1 preferred maturity pegged to P when maturity is P", cgr.getU32("PreferredMaturity") == SIM_ACCESS_PG); +#endif // HACKED_GODLIKE_VIEWER } } diff --git a/indra/newview/tests/llcapabilitylistener_test.cpp b/indra/newview/tests/llcapabilitylistener_test.cpp index 2ad08dc1f3..e1cbd28f92 100644 --- a/indra/newview/tests/llcapabilitylistener_test.cpp +++ b/indra/newview/tests/llcapabilitylistener_test.cpp @@ -156,7 +156,7 @@ namespace tut regionPump.post(request); ensure("got response", netio.pump()); ensure("success response", success); - ensure_equals(result.asString(), "success"); + ensure_equals(result["reply"].asString(), "success"); body["status"] = 499; body["reason"] = "custom error message"; diff --git a/indra/newview/tests/lldir_stub.cpp b/indra/newview/tests/lldir_stub.cpp index 18cf4e7419..2bc6772d86 100644 --- a/indra/newview/tests/lldir_stub.cpp +++ b/indra/newview/tests/lldir_stub.cpp @@ -32,7 +32,7 @@ BOOL LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask void LLDir::setChatLogsDir(const std::string &path) {} void LLDir::setPerAccountChatLogsDir(const std::string &first, const std::string &last) {} void LLDir::setLindenUserDir(const std::string &first, const std::string &last) {} -void LLDir::setSkinFolder(const std::string &skin_folder) {} +void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language) {} bool LLDir::setCacheDir(const std::string &path) { return true; } void LLDir::dumpCurrentDirectories() {} @@ -48,7 +48,7 @@ public: /*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask) { return 42; } /*virtual*/ BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap) { fname = fname + "_NEXT"; return false; } /*virtual*/ void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) { fname = "RANDOM_FILE"; } - /*virtual*/ BOOL fileExists(const std::string &filename) const { return false; } + /*virtual*/ bool fileExists(const std::string &filename) const { return false; } }; LLDir_stub gDirUtil; diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 9e321db889..7705b4c567 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -60,6 +60,7 @@ static LLEventStream gTestPump("test_pump"); #include "../llslurl.h" #include "../llstartup.h" LLSLURL LLStartUp::sStartSLURL; +LLSLURL& LLStartUp::getStartSLURL() { return sStartSLURL; } #include "lllogin.h" @@ -114,8 +115,9 @@ LLGridManager::~LLGridManager() { } -void LLGridManager::addGrid(LLSD& grid_data) +bool LLGridManager::addGrid(LLSD& grid_data) { + return true; } LLGridManager::LLGridManager() : @@ -136,7 +138,7 @@ void LLGridManager::addSystemGrid(const std::string& label, const std::string& login_id) { } -std::map<std::string, std::string> LLGridManager::getKnownGrids(bool favorite_only) +std::map<std::string, std::string> LLGridManager::getKnownGrids() { std::map<std::string, std::string> result; return result; @@ -151,8 +153,6 @@ bool LLGridManager::isInProductionGrid() return false; } -void LLGridManager::saveFavorites() -{} std::string LLGridManager::getSLURLBase(const std::string& grid_name) { return "myslurl"; diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp index f96f79006a..09343ef227 100644 --- a/indra/newview/tests/llslurl_test.cpp +++ b/indra/newview/tests/llslurl_test.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llsecapi_test.cpp * @author Roxie * @date 2009-02-10 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2009&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$ */ @@ -31,8 +31,8 @@ #include "../llslurl.h" #include "../../llxml/llcontrol.h" #include "llsdserialize.h" -//---------------------------------------------------------------------------- -// Mock objects for the dependencies of the code we're testing +//---------------------------------------------------------------------------- +// Mock objects for the dependencies of the code we're testing LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) {} @@ -80,6 +80,39 @@ LLPointer<LLControlVariable> LLControlGroup::getControl(const std::string& name) } LLControlGroup gSavedSettings("test"); +const char *gSampleGridFile = + "<?xml version=\"1.0\"?>" + "<llsd>" + " <map>" + " <key>foo.bar.com</key>" + " <map>" + " <key>helper_uri</key><string>https://foobar/helpers/</string>" + " <key>label</key><string>Foobar Grid</string>" + " <key>login_page</key><string>foobar/loginpage</string>" + " <key>login_uri</key>" + " <array>" + " <string>foobar/loginuri</string>" + " </array>" + " <key>keyname</key><string>foo.bar.com</string>" + " <key>credential_type</key><string>agent</string>" + " <key>grid_login_id</key><string>FooBar</string>" + " </map>" + " <key>my.grid.com</key>" + " <map>" + " <key>helper_uri</key><string>https://mygrid/helpers/</string>" + " <key>label</key><string>My Grid</string>" + " <key>login_page</key><string>mygrid/loginpage</string>" + " <key>login_uri</key>" + " <array>" + " <string>mygrid/loginuri</string>" + " </array>" + " <key>keyname</key><string>my.grid.com</string>" + " <key>credential_type</key><string>agent</string>" + " <key>grid_login_id</key><string>MyGrid</string>" + " </map>" + " </map>" + "</llsd>" + ; // ------------------------------------------------------------------------------------------- // TUT @@ -90,171 +123,189 @@ namespace tut struct slurlTest { slurlTest() - { + { LLGridManager::getInstance()->initialize(std::string("")); } ~slurlTest() { } }; - + // Tut templating thingamagic: test group, object and test instance typedef test_group<slurlTest> slurlTestFactory; typedef slurlTestFactory::object slurlTestObject; tut::slurlTestFactory tut_test("LLSlurl"); - + // --------------------------------------------------------------------------------------- - // Test functions + // Test functions // --------------------------------------------------------------------------------------- // construction from slurl string template<> template<> void slurlTestObject::test<1>() { + llofstream gridfile("grid_test.xml"); + gridfile << gSampleGridFile; + gridfile.close(); + + LLGridManager::getInstance()->initialize("grid_test.xml"); + LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com"); - + LLSLURL slurl = LLSLURL(""); ensure_equals("null slurl", (int)slurl.getType(), LLSLURL::LAST_LOCATION); - + slurl = LLSLURL("http://slurl.com/secondlife/myregion"); ensure_equals("slurl.com slurl, region only - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals("slurl.com slurl, region only", slurl.getSLURLString(), + ensure_equals("slurl.com slurl, region only", slurl.getSLURLString(), "http://maps.secondlife.com/secondlife/myregion/128/128/0"); - + slurl = LLSLURL("http://maps.secondlife.com/secondlife/myregion/1/2/3"); ensure_equals("maps.secondlife.com slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals("maps.secondlife.com slurl, region + coords", slurl.getSLURLString(), + ensure_equals("maps.secondlife.com slurl, region + coords", slurl.getSLURLString(), "http://maps.secondlife.com/secondlife/myregion/1/2/3"); slurl = LLSLURL("secondlife://myregion"); ensure_equals("secondlife: slurl, region only - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals("secondlife: slurl, region only", slurl.getSLURLString(), + ensure_equals("secondlife: slurl, region only", slurl.getSLURLString(), "http://maps.secondlife.com/secondlife/myregion/128/128/0"); - + slurl = LLSLURL("secondlife://myregion/1/2/3"); ensure_equals("secondlife: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals("secondlife slurl, region + coords", slurl.getSLURLString(), + ensure_equals("secondlife slurl, region + coords", slurl.getSLURLString(), "http://maps.secondlife.com/secondlife/myregion/1/2/3"); - + slurl = LLSLURL("/myregion"); ensure_equals("/region slurl, region- type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals("/region slurl, region ", slurl.getSLURLString(), + ensure_equals("/region slurl, region ", slurl.getSLURLString(), "http://maps.secondlife.com/secondlife/myregion/128/128/0"); - + slurl = LLSLURL("/myregion/1/2/3"); ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals("/ slurl, region + coords", slurl.getSLURLString(), - "http://maps.secondlife.com/secondlife/myregion/1/2/3"); - + ensure_equals("/ slurl, region + coords", slurl.getSLURLString(), + "http://maps.secondlife.com/secondlife/myregion/1/2/3"); + slurl = LLSLURL("my region/1/2/3"); ensure_equals(" slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals(" slurl, region + coords", slurl.getSLURLString(), - "http://maps.secondlife.com/secondlife/my%20region/1/2/3"); - - LLGridManager::getInstance()->setGridChoice("my.grid.com"); + ensure_equals(" slurl, region + coords", slurl.getSLURLString(), + "http://maps.secondlife.com/secondlife/my%20region/1/2/3"); + + LLGridManager::getInstance()->setGridChoice("my.grid.com"); slurl = LLSLURL("https://my.grid.com/region/my%20region/1/2/3"); ensure_equals("grid slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals("grid slurl, region + coords", slurl.getSLURLString(), - "https://my.grid.com/region/my%20region/1/2/3"); - + ensure_equals("grid slurl, region + coords", slurl.getSLURLString(), + "https://my.grid.com/region/my%20region/1/2/3"); + slurl = LLSLURL("https://my.grid.com/region/my region"); ensure_equals("grid slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals("grid slurl, region + coords", slurl.getSLURLString(), + ensure_equals("grid slurl, region + coords", slurl.getSLURLString(), "https://my.grid.com/region/my%20region/128/128/0"); - - LLGridManager::getInstance()->setGridChoice("foo.bar.com"); + + LLGridManager::getInstance()->setGridChoice("foo.bar.com"); slurl = LLSLURL("/myregion/1/2/3"); ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals("/ slurl, region + coords", slurl.getSLURLString(), - "https://foo.bar.com/region/myregion/1/2/3"); - + ensure_equals("/ slurl, region + coords", slurl.getSLURLString(), + "https://foo.bar.com/region/myregion/1/2/3"); + slurl = LLSLURL("myregion/1/2/3"); ensure_equals(": slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals(" slurl, region + coords", slurl.getSLURLString(), - "https://foo.bar.com/region/myregion/1/2/3"); - + ensure_equals(" slurl, region + coords", slurl.getSLURLString(), + "https://foo.bar.com/region/myregion/1/2/3"); + slurl = LLSLURL(LLSLURL::SIM_LOCATION_HOME); ensure_equals("home", slurl.getType(), LLSLURL::HOME_LOCATION); slurl = LLSLURL(LLSLURL::SIM_LOCATION_LAST); ensure_equals("last", slurl.getType(), LLSLURL::LAST_LOCATION); - + slurl = LLSLURL("secondlife:///app/foo/bar?12345"); - ensure_equals("app", slurl.getType(), LLSLURL::APP); + ensure_equals("app", slurl.getType(), LLSLURL::APP); ensure_equals("appcmd", slurl.getAppCmd(), "foo"); ensure_equals("apppath", slurl.getAppPath().size(), 1); ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar"); ensure_equals("appquery", slurl.getAppQuery(), "12345"); - ensure_equals("grid1", "foo.bar.com", slurl.getGrid()); - + ensure_equals("grid1", slurl.getGrid(), "FooBar"); + slurl = LLSLURL("secondlife://Aditi/app/foo/bar?12345"); - ensure_equals("app", slurl.getType(), LLSLURL::APP); + ensure_equals("app", slurl.getType(), LLSLURL::APP); ensure_equals("appcmd", slurl.getAppCmd(), "foo"); ensure_equals("apppath", slurl.getAppPath().size(), 1); ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar"); ensure_equals("appquery", slurl.getAppQuery(), "12345"); - ensure_equals("grid2", "util.aditi.lindenlab.com", slurl.getGrid()); + ensure_equals("grid2", slurl.getGrid(), "Aditi"); - LLGridManager::getInstance()->setGridChoice("foo.bar.com"); + LLGridManager::getInstance()->setGridChoice("foo.bar.com"); slurl = LLSLURL("secondlife:///secondlife/myregion/1/2/3"); ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); ensure_equals("location", slurl.getType(), LLSLURL::LOCATION); ensure_equals("region" , "myregion", slurl.getRegion()); - ensure_equals("grid3", "util.agni.lindenlab.com", slurl.getGrid()); - + ensure_equals("grid3", slurl.getGrid(), "util.agni.lindenlab.com"); + slurl = LLSLURL("secondlife://Aditi/secondlife/myregion/1/2/3"); ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); ensure_equals("location", slurl.getType(), LLSLURL::LOCATION); ensure_equals("region" , "myregion", slurl.getRegion()); - ensure_equals("grid4", "util.aditi.lindenlab.com", slurl.getGrid()); - + ensure_equals("grid4", slurl.getGrid(), "Aditi" ); + LLGridManager::getInstance()->setGridChoice("my.grid.com"); slurl = LLSLURL("https://my.grid.com/app/foo/bar?12345"); - ensure_equals("app", slurl.getType(), LLSLURL::APP); + ensure_equals("app", slurl.getType(), LLSLURL::APP); ensure_equals("appcmd", slurl.getAppCmd(), "foo"); ensure_equals("apppath", slurl.getAppPath().size(), 1); ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar"); - ensure_equals("appquery", slurl.getAppQuery(), "12345"); - + ensure_equals("appquery", slurl.getAppQuery(), "12345"); + } - + // construction from grid/region/vector combos template<> template<> void slurlTestObject::test<2>() { - LLSLURL slurl = LLSLURL("mygrid.com", "my region"); + llofstream gridfile("grid_test.xml"); + gridfile << gSampleGridFile; + gridfile.close(); + + LLGridManager::getInstance()->initialize("grid_test.xml"); + + LLSLURL slurl = LLSLURL("my.grid.com", "my region"); ensure_equals("grid/region - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals("grid/region", slurl.getSLURLString(), - "https://mygrid.com/region/my%20region/128/128/0"); - - slurl = LLSLURL("mygrid.com", "my region", LLVector3(1,2,3)); + ensure_equals("grid/region", slurl.getSLURLString(), + "https://my.grid.com/region/my%20region/128/128/0"); + + slurl = LLSLURL("my.grid.com", "my region", LLVector3(1,2,3)); ensure_equals("grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals(" grid/region/vector", slurl.getSLURLString(), - "https://mygrid.com/region/my%20region/1/2/3"); + ensure_equals(" grid/region/vector", slurl.getSLURLString(), + "https://my.grid.com/region/my%20region/1/2/3"); - LLGridManager::getInstance()->setGridChoice("foo.bar.com.bar"); + LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com"); slurl = LLSLURL("my region", LLVector3(1,2,3)); - ensure_equals("grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals(" grid/region/vector", slurl.getSLURLString(), - "https://foo.bar.com.bar/region/my%20region/1/2/3"); - - LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com"); + ensure_equals("default grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals(" default grid/region/vector", slurl.getSLURLString(), + "http://maps.secondlife.com/secondlife/my%20region/1/2/3"); + + LLGridManager::getInstance()->setGridChoice("MyGrid"); slurl = LLSLURL("my region", LLVector3(1,2,3)); ensure_equals("default grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION); - ensure_equals(" default grid/region/vector", slurl.getSLURLString(), - "http://maps.secondlife.com/secondlife/my%20region/1/2/3"); - + ensure_equals(" default grid/region/vector", slurl.getSLURLString(), + "https://my.grid.com/region/my%20region/1/2/3"); + } // Accessors template<> template<> void slurlTestObject::test<3>() { - LLGridManager::getInstance()->setGridChoice("my.grid.com"); + llofstream gridfile("grid_test.xml"); + gridfile << gSampleGridFile; + gridfile.close(); + + LLGridManager::getInstance()->initialize("grid_test.xml"); + + LLGridManager::getInstance()->setGridChoice("my.grid.com"); LLSLURL slurl = LLSLURL("https://my.grid.com/region/my%20region/1/2/3"); ensure_equals("login string", slurl.getLoginString(), "uri:my region&1&2&3"); ensure_equals("location string", slurl.getLocationString(), "my region/1/2/3"); ensure_equals("grid", slurl.getGrid(), "my.grid.com"); ensure_equals("region", slurl.getRegion(), "my region"); ensure_equals("position", slurl.getPosition(), LLVector3(1, 2, 3)); - + } } diff --git a/indra/newview/tests/lltranslate_test.cpp b/indra/newview/tests/lltranslate_test.cpp index 10e37fae97..fd9527d631 100644 --- a/indra/newview/tests/lltranslate_test.cpp +++ b/indra/newview/tests/lltranslate_test.cpp @@ -299,11 +299,6 @@ LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLCo std::string LLControlGroup::getString(const std::string& name) { return "dummy"; } LLControlGroup::~LLControlGroup() {} -namespace boost { - void intrusive_ptr_add_ref(LLCurl::Responder*) {} - void intrusive_ptr_release(LLCurl::Responder*) {} -} - LLCurl::Responder::Responder() {} void LLCurl::Responder::completedHeader(U32, std::string const&, LLSD const&) {} void LLCurl::Responder::completedRaw(U32, const std::string&, const LLChannelDescriptors&, const LLIOPipe::buffer_ptr_t& buffer) {} @@ -314,7 +309,7 @@ void LLCurl::Responder::result(LLSD const&) {} LLCurl::Responder::~Responder() {} void LLHTTPClient::get(const std::string&, const LLSD&, ResponderPtr, const LLSD&, const F32) {} -void LLHTTPClient::get(const std::string&, boost::intrusive_ptr<LLCurl::Responder>, const LLSD&, const F32) {} +void LLHTTPClient::get(const std::string&, LLPointer<LLCurl::Responder>, const LLSD&, const F32) {} LLBufferStream::LLBufferStream(const LLChannelDescriptors& channels, LLBufferArray* buffer) : std::iostream(&mStreamBuf), mStreamBuf(channels, buffer) {} diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index 3faddc13c1..f8923b9868 100644 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -35,6 +35,31 @@ #include "lluuid.h" #include "llsdutil.h" #include "llregionhandle.h" +#include "../llvoavatar.h" + +void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts) +{ + counts.resize(3); + counts[0] = 0; + counts[1] = 0; + counts[2] = 1; +} + +// static +std::string LLVOAvatar::rezStatusToString(S32 rez_status) +{ + if (rez_status==0) return "cloud"; + if (rez_status==1) return "gray"; + if (rez_status==2) return "textured"; + return "unknown"; +} + +// static +LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name) +{ + static LLViewerStats::StatsAccumulator junk; + return junk; +} static const char * all_keys[] = { @@ -104,18 +129,25 @@ is_single_key_map(const LLSD & sd, const std::string & key) { return sd.isMap() && 1 == sd.size() && sd.has(key); } -#endif static bool is_double_key_map(const LLSD & sd, const std::string & key1, const std::string & key2) { return sd.isMap() && 2 == sd.size() && sd.has(key1) && sd.has(key2); } +#endif + +static bool +is_triple_key_map(const LLSD & sd, const std::string & key1, const std::string & key2, const std::string& key3) +{ + return sd.isMap() && 3 == sd.size() && sd.has(key1) && sd.has(key2) && sd.has(key3); +} + static bool is_no_stats_map(const LLSD & sd) { - return is_double_key_map(sd, "duration", "regions"); + return is_triple_key_map(sd, "duration", "regions", "avatar"); } static bool @@ -226,7 +258,7 @@ namespace tut // Once the region is set, we will get a response even with no data collection it->setRegion(region1_handle); sd_full = it->asLLSD(false); - ensure("Correct single-key LLSD map root", is_double_key_map(sd_full, "duration", "regions")); + ensure("Correct single-key LLSD map root", is_triple_key_map(sd_full, "duration", "regions", "avatar")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd_full["regions"], region1_handle)); LLSD sd = sd_full["regions"][0]; @@ -267,7 +299,7 @@ namespace tut it->setRegion(region1_handle); LLSD sd = it->asLLSD(false); - ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); + ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); sd = sd[0]; @@ -292,7 +324,7 @@ namespace tut LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); LLSD sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); + ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); sd = sd["regions"][0]; @@ -332,7 +364,7 @@ namespace tut LLSD sd = gViewerAssetStatsThread1->asLLSD(false); ensure("Other collector is empty", is_no_stats_map(sd)); sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); + ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); sd = sd["regions"][0]; @@ -382,7 +414,7 @@ namespace tut // std::cout << sd << std::endl; - ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions")); + ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle)); LLSD sd1 = get_region(sd, region1_handle); LLSD sd2 = get_region(sd, region2_handle); @@ -405,7 +437,7 @@ namespace tut // Reset leaves current region in place gViewerAssetStatsMain->reset(); sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); + ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle)); sd2 = sd["regions"][0]; @@ -454,7 +486,7 @@ namespace tut LLSD sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions")); + ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle)); LLSD sd1 = get_region(sd, region1_handle); LLSD sd2 = get_region(sd, region2_handle); @@ -477,7 +509,7 @@ namespace tut // Reset leaves current region in place gViewerAssetStatsMain->reset(); sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct single-key LLSD map root", is_double_key_map(sd, "duration", "regions")); + ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle)); sd2 = get_region(sd, region2_handle); ensure("Region2 is present in results", sd2.isMap()); @@ -523,7 +555,7 @@ namespace tut LLSD sd = gViewerAssetStatsThread1->asLLSD(false); ensure("Other collector is empty", is_no_stats_map(sd)); sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); + ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); sd = get_region(sd, region1_handle); ensure("Region1 is present in results", sd.isMap()); diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp index 3c89b64d52..a1e97ea17e 100644 --- a/indra/newview/tests/llviewernetwork_test.cpp +++ b/indra/newview/tests/llviewernetwork_test.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llviewernetwork_test.cpp * @author Roxie * @date 2009-03-9 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2009&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$ */ @@ -31,8 +31,8 @@ #include "../../llxml/llcontrol.h" #include "llfile.h" -//---------------------------------------------------------------------------- -// Mock objects for the dependencies of the code we're testing +//---------------------------------------------------------------------------- +// Mock objects for the dependencies of the code we're testing LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) {} @@ -81,26 +81,57 @@ LLPointer<LLControlVariable> LLControlGroup::getControl(const std::string& name) LLControlGroup gSavedSettings("test"); -const char *gSampleGridFile = "<llsd><map>" -"<key>grid1</key><map>" -" <key>favorite</key><integer>1</integer>" -" <key>helper_uri</key><string>https://helper1/helpers/</string>" -" <key>label</key><string>mylabel</string>" -" <key>login_page</key><string>loginpage</string>" -" <key>login_uri</key><array><string>myloginuri</string></array>" -" <key>name</key><string>grid1</string>" -" <key>visible</key><integer>1</integer>" -" <key>credential_type</key><string>agent</string>" -" <key>grid_login_id</key><string>MyGrid</string>" -"</map>" -"<key>util.agni.lindenlab.com</key><map>" -" <key>favorite</key><integer>1</integer>" -" <key>helper_uri</key><string>https://helper1/helpers/</string>" -" <key>label</key><string>mylabel</string>" -" <key>login_page</key><string>loginpage</string>" -" <key>login_uri</key><array><string>myloginuri</string></array>" -" <key>name</key><string>util.agni.lindenlab.com</string>" -"</map></map></llsd>"; +const char *gSampleGridFile = + "<?xml version=\"1.0\"?>" + "<llsd>" + " <map>" + " <key>altgrid.long.name</key>" + " <map>" + " <key>helper_uri</key><string>https://helper1/helpers/</string>" + " <key>label</key><string>Alternative Grid</string>" + " <key>login_page</key><string>altgrid/loginpage</string>" + " <key>login_uri</key>" + " <array>" + " <string>altgrid/myloginuri1</string>" + " <string>altgrid/myloginuri2</string>" + " </array>" + " <key>keyname</key><string>altgrid.long.name</string>" + " <key>credential_type</key><string>agent</string>" + " <key>grid_login_id</key><string>AltGrid</string>" + " </map>" + " <key>minimal.long.name</key>" + " <map>" + " <key>keyname</key><string>minimal.long.name</string>" + " </map>" + " <!-- Note that the values for agni and aditi below are deliberately" + " incorrect to test that they are not overwritten -->" + " <key>util.agni.lindenlab.com</key> <!-- conflict -->" + " <map>" + " <key>helper_uri</key><string>https://helper1/helpers/</string>" + " <key>grid_login_id</key><string>mylabel</string>" + " <key>label</key><string>mylabel</string>" + " <key>login_page</key><string>loginpage</string>" + " <key>login_uri</key>" + " <array>" + " <string>myloginuri</string>" + " </array>" + " <key>keyname</key><string>util.agni.lindenlab.com</string> <!-- conflict -->" + " </map>" + " <key>util.foobar.lindenlab.com</key>" + " <map>" + " <key>helper_uri</key><string>https://helper1/helpers/</string>" + " <key>grid_login_id</key><string>Aditi</string> <!-- conflict -->" + " <key>label</key><string>mylabel</string>" + " <key>login_page</key><string>loginpage</string>" + " <key>login_uri</key>" + " <array>" + " <string>myloginuri</string>" + " </array>" + " <key>keyname</key><string>util.foobar.lindenlab.com</string>" + " </map>" + " </map>" + "</llsd>" + ; // ------------------------------------------------------------------------------------------- // TUT // ------------------------------------------------------------------------------------------- @@ -116,63 +147,89 @@ namespace tut gCmdLineGridChoice.clear(); gCmdLineHelperURI.clear(); gLoginPage.clear(); - gCurrentGrid.clear(); + gCurrentGrid.clear(); } ~viewerNetworkTest() { LLFile::remove("grid_test.xml"); } }; - + // Tut templating thingamagic: test group, object and test instance typedef test_group<viewerNetworkTest> viewerNetworkTestFactory; typedef viewerNetworkTestFactory::object viewerNetworkTestObject; tut::viewerNetworkTestFactory tut_test("LLViewerNetwork"); - + // --------------------------------------------------------------------------------------- - // Test functions + // Test functions // --------------------------------------------------------------------------------------- // initialization without a grid file template<> template<> void viewerNetworkTestObject::test<1>() { - LLGridManager *manager = LLGridManager::getInstance(); // grid file doesn't exist manager->initialize("grid_test.xml"); // validate that some of the defaults are available. std::map<std::string, std::string> known_grids = manager->getKnownGrids(); - ensure_equals("Known grids is a string-string map of size 23", known_grids.size(), 23); - ensure_equals("Agni has the right name and label", - known_grids[std::string("util.agni.lindenlab.com")], std::string("Agni")); - ensure_equals("None exists", known_grids[""], "None"); - - LLSD grid; - LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com", grid); - ensure("Grid info for agni is a map", grid.isMap()); - ensure_equals("name is correct for agni", - grid[GRID_VALUE].asString(), std::string("util.agni.lindenlab.com")); - ensure_equals("label is correct for agni", - grid[GRID_LABEL_VALUE].asString(), std::string("Agni")); - ensure("Login URI is an array", - grid[GRID_LOGIN_URI_VALUE].isArray()); - ensure_equals("Agni login uri is correct", - grid[GRID_LOGIN_URI_VALUE][0].asString(), + ensure_equals("Known grids is a string-string map of size 2", known_grids.size(), 2); + ensure_equals("Agni has the right name and label", + known_grids[std::string("util.agni.lindenlab.com")], + std::string("Second Life Main Grid (Agni)")); + ensure_equals("Aditi has the right name and label", + known_grids[std::string("util.aditi.lindenlab.com")], + std::string("Second Life Beta Test Grid (Aditi)")); + ensure_equals("name for agni", + LLGridManager::getInstance()->getGrid("util.agni.lindenlab.com"), + std::string("util.agni.lindenlab.com")); + ensure_equals("id for agni", + std::string("Agni"), + LLGridManager::getInstance()->getGridId("util.agni.lindenlab.com")); + ensure_equals("label for agni", + LLGridManager::getInstance()->getGridLabel("util.agni.lindenlab.com"), + std::string("Second Life Main Grid (Agni)")); + + std::vector<std::string> login_uris; + LLGridManager::getInstance()->getLoginURIs(std::string("util.agni.lindenlab.com"), login_uris); + ensure_equals("Number of login uris for agni", 1, login_uris.size()); + ensure_equals("Agni login uri", + login_uris[0], std::string("https://login.agni.lindenlab.com/cgi-bin/login.cgi")); - ensure_equals("Agni helper uri is correct", - grid[GRID_HELPER_URI_VALUE].asString(), + ensure_equals("Agni helper uri", + LLGridManager::getInstance()->getHelperURI("util.agni.lindenlab.com"), std::string("https://secondlife.com/helpers/")); - ensure_equals("Agni login page is correct", - grid[GRID_LOGIN_PAGE_VALUE].asString(), + ensure_equals("Agni login page", + LLGridManager::getInstance()->getLoginPage("util.agni.lindenlab.com"), std::string("http://viewer-login.agni.lindenlab.com/")); - ensure("Agni is a favorite", - grid.has(GRID_IS_FAVORITE_VALUE)); - ensure("Agni is a system grid", - grid.has(GRID_IS_SYSTEM_GRID_VALUE)); - ensure("Grid file wasn't greated as it wasn't saved", - !LLFile::isfile("grid_test.xml")); + ensure("Agni is a system grid", + LLGridManager::getInstance()->isSystemGrid("util.agni.lindenlab.com")); + + ensure_equals("name for aditi", + LLGridManager::getInstance()->getGrid("util.aditi.lindenlab.com"), + std::string("util.aditi.lindenlab.com")); + ensure_equals("id for aditi", + LLGridManager::getInstance()->getGridId("util.aditi.lindenlab.com"), + std::string("Aditi")); + ensure_equals("label for aditi", + LLGridManager::getInstance()->getGridLabel("util.aditi.lindenlab.com"), + std::string("Second Life Beta Test Grid (Aditi)")); + + LLGridManager::getInstance()->getLoginURIs(std::string("util.aditi.lindenlab.com"), login_uris); + + ensure_equals("Number of login uris for aditi", 1, login_uris.size()); + ensure_equals("Aditi login uri", + login_uris[0], + std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi")); + ensure_equals("Aditi helper uri", + LLGridManager::getInstance()->getHelperURI("util.aditi.lindenlab.com"), + std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/")); + ensure_equals("Aditi login page", + LLGridManager::getInstance()->getLoginPage("util.aditi.lindenlab.com"), + std::string("http://viewer-login.agni.lindenlab.com/")); + ensure("Aditi is a system grid", + LLGridManager::getInstance()->isSystemGrid("util.aditi.lindenlab.com")); } - + // initialization with a grid file template<> template<> void viewerNetworkTestObject::test<2>() @@ -180,402 +237,172 @@ namespace tut llofstream gridfile("grid_test.xml"); gridfile << gSampleGridFile; gridfile.close(); - + LLGridManager::getInstance()->initialize("grid_test.xml"); std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure_equals("adding a grid via a grid file increases known grid size", - known_grids.size(), 24); - ensure_equals("Agni is still there after we've added a grid via a grid file", - known_grids["util.agni.lindenlab.com"], std::string("Agni")); - - - // assure Agni doesn't get overwritten - LLSD grid; - LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com", grid); + ensure_equals("adding a grid via a grid file increases known grid size",4, + known_grids.size()); - ensure_equals("Agni grid label was not modified by grid file", - grid[GRID_LABEL_VALUE].asString(), std::string("Agni")); - - ensure_equals("Agni name wasn't modified by grid file", - grid[GRID_VALUE].asString(), std::string("util.agni.lindenlab.com")); - ensure("Agni grid URI is still an array after grid file", - grid[GRID_LOGIN_URI_VALUE].isArray()); - ensure_equals("Agni login uri still the same after grid file", - grid[GRID_LOGIN_URI_VALUE][0].asString(), + // Verify that Agni and Aditi were not overwritten + ensure_equals("Agni has the right name and label", + known_grids[std::string("util.agni.lindenlab.com")], + std::string("Second Life Main Grid (Agni)")); + ensure_equals("Aditi has the right name and label", + known_grids[std::string("util.aditi.lindenlab.com")], + std::string("Second Life Beta Test Grid (Aditi)")); + ensure_equals("name for agni", + LLGridManager::getInstance()->getGrid("util.agni.lindenlab.com"), + std::string("util.agni.lindenlab.com")); + ensure_equals("id for agni", + LLGridManager::getInstance()->getGridId("util.agni.lindenlab.com"), + std::string("Agni")); + ensure_equals("label for agni", + LLGridManager::getInstance()->getGridLabel("util.agni.lindenlab.com"), + std::string("Second Life Main Grid (Agni)")); + std::vector<std::string> login_uris; + LLGridManager::getInstance()->getLoginURIs(std::string("util.agni.lindenlab.com"), login_uris); + ensure_equals("Number of login uris for agni", 1, login_uris.size()); + ensure_equals("Agni login uri", + login_uris[0], std::string("https://login.agni.lindenlab.com/cgi-bin/login.cgi")); - ensure_equals("Agni helper uri still the same after grid file", - grid[GRID_HELPER_URI_VALUE].asString(), + ensure_equals("Agni helper uri", + LLGridManager::getInstance()->getHelperURI("util.agni.lindenlab.com"), std::string("https://secondlife.com/helpers/")); - ensure_equals("Agni login page the same after grid file", - grid[GRID_LOGIN_PAGE_VALUE].asString(), + ensure_equals("Agni login page", + LLGridManager::getInstance()->getLoginPage("util.agni.lindenlab.com"), std::string("http://viewer-login.agni.lindenlab.com/")); - ensure("Agni still a favorite after grid file", - grid.has(GRID_IS_FAVORITE_VALUE)); - ensure("Agni system grid still set after grid file", - grid.has(GRID_IS_SYSTEM_GRID_VALUE)); - - ensure_equals("Grid file adds to name<->label map", - known_grids["grid1"], std::string("mylabel")); - LLGridManager::getInstance()->getGridInfo("grid1", grid); - ensure_equals("grid file grid name is set", - grid[GRID_VALUE].asString(), std::string("grid1")); - ensure_equals("grid file label is set", - grid[GRID_LABEL_VALUE].asString(), std::string("mylabel")); - ensure("grid file login uri is an array", - grid[GRID_LOGIN_URI_VALUE].isArray()); - ensure_equals("grid file login uri is set", - grid[GRID_LOGIN_URI_VALUE][0].asString(), - std::string("myloginuri")); - ensure_equals("grid file helper uri is set", - grid[GRID_HELPER_URI_VALUE].asString(), - std::string("https://helper1/helpers/")); - ensure_equals("grid file login page is set", - grid[GRID_LOGIN_PAGE_VALUE].asString(), - std::string("loginpage")); - ensure("grid file favorite is set", - grid.has(GRID_IS_FAVORITE_VALUE)); - ensure("grid file isn't a system grid", - !grid.has(GRID_IS_SYSTEM_GRID_VALUE)); - ensure("Grid file still exists after loading", - LLFile::isfile("grid_test.xml")); - } - - // Initialize via command line - - template<> template<> - void viewerNetworkTestObject::test<3>() - { - // USE --grid command line - // initialize with a known grid - LLSD grid; - gCmdLineGridChoice = "Aditi"; - LLGridManager::getInstance()->initialize("grid_test.xml"); - // with single login uri specified. - std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure_equals("Using a known grid via command line doesn't increase number of known grids", - known_grids.size(), 23); - ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("Aditi")); - // initialize with a known grid in lowercase - gCmdLineGridChoice = "agni"; - LLGridManager::getInstance()->initialize("grid_test.xml"); - ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("Agni")); - - // now try a command line with a custom grid identifier - gCmdLineGridChoice = "mycustomgridchoice"; - LLGridManager::getInstance()->initialize("grid_test.xml"); - known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure_equals("adding a command line grid with custom name increases known grid size", - known_grids.size(), 24); - ensure_equals("Custom Command line grid is added to the list of grids", - known_grids["mycustomgridchoice"], std::string("mycustomgridchoice")); - LLGridManager::getInstance()->getGridInfo("mycustomgridchoice", grid); - ensure_equals("Custom Command line grid name is set", - grid[GRID_VALUE].asString(), std::string("mycustomgridchoice")); - ensure_equals("Custom Command line grid label is set", - grid[GRID_LABEL_VALUE].asString(), std::string("mycustomgridchoice")); - ensure("Custom Command line grid login uri is an array", - grid[GRID_LOGIN_URI_VALUE].isArray()); - ensure_equals("Custom Command line grid login uri is set", - grid[GRID_LOGIN_URI_VALUE][0].asString(), - std::string("https://mycustomgridchoice/cgi-bin/login.cgi")); - ensure_equals("Custom Command line grid helper uri is set", - grid[GRID_HELPER_URI_VALUE].asString(), - std::string("https://mycustomgridchoice/helpers/")); - ensure_equals("Custom Command line grid login page is set", - grid[GRID_LOGIN_PAGE_VALUE].asString(), - std::string("http://mycustomgridchoice/app/login/")); - } - - // validate override of login uri with cmd line - template<> template<> - void viewerNetworkTestObject::test<4>() - { - // Override with loginuri - // override known grid - LLSD grid; - gCmdLineGridChoice = "Aditi"; - gCmdLineLoginURI = "https://my.login.uri/cgi-bin/login.cgi"; - LLGridManager::getInstance()->initialize("grid_test.xml"); - std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure_equals("Override known grid login uri: No grids are added", - known_grids.size(), 23); - LLGridManager::getInstance()->getGridInfo(grid); - ensure("Override known grid login uri: login uri is an array", - grid[GRID_LOGIN_URI_VALUE].isArray()); - ensure_equals("Override known grid login uri: Command line grid login uri is set", - grid[GRID_LOGIN_URI_VALUE][0].asString(), - std::string("https://my.login.uri/cgi-bin/login.cgi")); - ensure_equals("Override known grid login uri: helper uri is not changed", - grid[GRID_HELPER_URI_VALUE].asString(), - std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/")); - ensure_equals("Override known grid login uri: login page is not set", - grid[GRID_LOGIN_PAGE_VALUE].asString(), - std::string("http://viewer-login.agni.lindenlab.com/")); - - // Override with loginuri - // override custom grid - gCmdLineGridChoice = "mycustomgridchoice"; - gCmdLineLoginURI = "https://my.login.uri/cgi-bin/login.cgi"; - LLGridManager::getInstance()->initialize("grid_test.xml"); - known_grids = LLGridManager::getInstance()->getKnownGrids(); - LLGridManager::getInstance()->getGridInfo(grid); - ensure_equals("Override custom grid login uri: Grid is added", - known_grids.size(), 24); - ensure("Override custom grid login uri: login uri is an array", - grid[GRID_LOGIN_URI_VALUE].isArray()); - ensure_equals("Override custom grid login uri: login uri is set", - grid[GRID_LOGIN_URI_VALUE][0].asString(), - std::string("https://my.login.uri/cgi-bin/login.cgi")); - ensure_equals("Override custom grid login uri: Helper uri is not set", - grid[GRID_HELPER_URI_VALUE].asString(), - std::string("https://mycustomgridchoice/helpers/")); - ensure_equals("Override custom grid login uri: Login page is not set", - grid[GRID_LOGIN_PAGE_VALUE].asString(), - std::string("http://mycustomgridchoice/app/login/")); - } - - // validate override of helper uri with cmd line - template<> template<> - void viewerNetworkTestObject::test<5>() - { - // Override with helperuri - // override known grid - LLSD grid; - gCmdLineGridChoice = "Aditi"; - gCmdLineLoginURI = ""; - gCmdLineHelperURI = "https://my.helper.uri/mycustomhelpers"; - LLGridManager::getInstance()->initialize("grid_test.xml"); - std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure_equals("Override known grid helper uri: No grids are added", - known_grids.size(), 23); - LLGridManager::getInstance()->getGridInfo(grid); - ensure("Override known known helper uri: login uri is an array", - grid[GRID_LOGIN_URI_VALUE].isArray()); - ensure_equals("Override known grid helper uri: login uri is not changed", - grid[GRID_LOGIN_URI_VALUE][0].asString(), - std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi")); - ensure_equals("Override known grid helper uri: helper uri is changed", - grid[GRID_HELPER_URI_VALUE].asString(), - std::string("https://my.helper.uri/mycustomhelpers")); - ensure_equals("Override known grid helper uri: login page is not changed", - grid[GRID_LOGIN_PAGE_VALUE].asString(), - std::string("http://viewer-login.agni.lindenlab.com/")); - - // Override with helperuri - // override custom grid - gCmdLineGridChoice = "mycustomgridchoice"; - gCmdLineHelperURI = "https://my.helper.uri/mycustomhelpers"; - LLGridManager::getInstance()->initialize("grid_test.xml"); - known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure_equals("Override custom grid helper uri: grids is added", - known_grids.size(), 24); - LLGridManager::getInstance()->getGridInfo(grid); - ensure("Override custom helper uri: login uri is an array", - grid[GRID_LOGIN_URI_VALUE].isArray()); - ensure_equals("Override custom grid helper uri: login uri is not changed", - grid[GRID_LOGIN_URI_VALUE][0].asString(), - std::string("https://mycustomgridchoice/cgi-bin/login.cgi")); - ensure_equals("Override custom grid helper uri: helper uri is changed", - grid[GRID_HELPER_URI_VALUE].asString(), - std::string("https://my.helper.uri/mycustomhelpers")); - ensure_equals("Override custom grid helper uri: login page is not changed", - grid[GRID_LOGIN_PAGE_VALUE].asString(), - std::string("http://mycustomgridchoice/app/login/")); - } - - // validate overriding of login page via cmd line - template<> template<> - void viewerNetworkTestObject::test<6>() - { - // Override with login page - // override known grid - LLSD grid; - gCmdLineGridChoice = "Aditi"; - gCmdLineHelperURI = ""; - gLoginPage = "myloginpage"; - LLGridManager::getInstance()->initialize("grid_test.xml"); - std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure_equals("Override known grid login page: No grids are added", - known_grids.size(), 23); - LLGridManager::getInstance()->getGridInfo(grid); - ensure("Override known grid login page: Command line grid login uri is an array", - grid[GRID_LOGIN_URI_VALUE].isArray()); - ensure_equals("Override known grid login page: login uri is not changed", - grid[GRID_LOGIN_URI_VALUE][0].asString(), + ensure("Agni is a system grid", + LLGridManager::getInstance()->isSystemGrid("util.agni.lindenlab.com")); + + ensure_equals("name for aditi", + LLGridManager::getInstance()->getGrid("util.aditi.lindenlab.com"), + std::string("util.aditi.lindenlab.com")); + ensure_equals("id for aditi", + LLGridManager::getInstance()->getGridId("util.aditi.lindenlab.com"), + std::string("Aditi")); + ensure_equals("label for aditi", + LLGridManager::getInstance()->getGridLabel("util.aditi.lindenlab.com"), + std::string("Second Life Beta Test Grid (Aditi)")); + + LLGridManager::getInstance()->getLoginURIs(std::string("util.aditi.lindenlab.com"), login_uris); + ensure_equals("Number of login uris for aditi", 1, login_uris.size()); + ensure_equals("Aditi login uri", + login_uris[0], std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi")); - ensure_equals("Override known grid login page: helper uri is not changed", - grid[GRID_HELPER_URI_VALUE].asString(), + ensure_equals("Aditi helper uri", + LLGridManager::getInstance()->getHelperURI("util.aditi.lindenlab.com"), std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/")); - ensure_equals("Override known grid login page: login page is changed", - grid[GRID_LOGIN_PAGE_VALUE].asString(), - std::string("myloginpage")); - - // Override with login page - // override custom grid - gCmdLineGridChoice = "mycustomgridchoice"; - gLoginPage = "myloginpage"; - LLGridManager::getInstance()->initialize("grid_test.xml"); - known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure_equals("Override custom grid login page: grids are added", - known_grids.size(), 24); - LLGridManager::getInstance()->getGridInfo(grid); - ensure("Override custom grid login page: Command line grid login uri is an array", - grid[GRID_LOGIN_URI_VALUE].isArray()); - ensure_equals("Override custom grid login page: login uri is not changed", - grid[GRID_LOGIN_URI_VALUE][0].asString(), - std::string("https://mycustomgridchoice/cgi-bin/login.cgi")); - ensure_equals("Override custom grid login page: helper uri is not changed", - grid[GRID_HELPER_URI_VALUE].asString(), - std::string("https://mycustomgridchoice/helpers/")); - ensure_equals("Override custom grid login page: login page is changed", - grid[GRID_LOGIN_PAGE_VALUE].asString(), - std::string("myloginpage")); - + ensure_equals("Aditi login page", + LLGridManager::getInstance()->getLoginPage("util.aditi.lindenlab.com"), + std::string("http://viewer-login.agni.lindenlab.com/")); + ensure("Aditi is a system grid", + LLGridManager::getInstance()->isSystemGrid("util.aditi.lindenlab.com")); + + // Check the additional grid from the file + ensure_equals("alternative grid is in name<->label map", + known_grids["altgrid.long.name"], + std::string("Alternative Grid")); + ensure_equals("alternative grid name is set", + LLGridManager::getInstance()->getGrid("altgrid.long.name"), + std::string("altgrid.long.name")); + ensure_equals("alternative grid id", + LLGridManager::getInstance()->getGridId("altgrid.long.name"), + std::string("AltGrid")); + ensure_equals("alternative grid label", + LLGridManager::getInstance()->getGridLabel("altgrid.long.name"), + std::string("Alternative Grid")); + std::vector<std::string> alt_login_uris; + LLGridManager::getInstance()->getLoginURIs(std::string("altgrid.long.name"), alt_login_uris); + ensure_equals("Number of login uris for altgrid", 2, alt_login_uris.size()); + ensure_equals("alternative grid first login uri", + alt_login_uris[0], + std::string("altgrid/myloginuri1")); + ensure_equals("alternative grid second login uri", + alt_login_uris[1], + std::string("altgrid/myloginuri2")); + ensure_equals("alternative grid helper uri", + LLGridManager::getInstance()->getHelperURI("altgrid.long.name"), + std::string("https://helper1/helpers/")); + ensure_equals("alternative grid login page", + LLGridManager::getInstance()->getLoginPage("altgrid.long.name"), + std::string("altgrid/loginpage")); + ensure("alternative grid is NOT a system grid", + ! LLGridManager::getInstance()->isSystemGrid("altgrid.long.name")); + + ensure_equals("minimal grid is in name<->label map", + known_grids["minimal.long.name"], + std::string("minimal.long.name")); + ensure_equals("minimal grid name is set", + LLGridManager::getInstance()->getGrid("minimal.long.name"), + std::string("minimal.long.name")); + ensure_equals("minimal grid id", + LLGridManager::getInstance()->getGridId("minimal.long.name"), + std::string("minimal.long.name")); + ensure_equals("minimal grid label", + LLGridManager::getInstance()->getGridLabel("minimal.long.name"), + std::string("minimal.long.name")); + + LLGridManager::getInstance()->getLoginURIs(std::string("minimal.long.name"), alt_login_uris); + ensure_equals("Number of login uris for altgrid", 1, alt_login_uris.size()); + ensure_equals("minimal grid login uri", + alt_login_uris[0], + std::string("https://minimal.long.name/cgi-bin/login.cgi")); + ensure_equals("minimal grid helper uri", + LLGridManager::getInstance()->getHelperURI("minimal.long.name"), + std::string("https://minimal.long.name/helpers/")); + ensure_equals("minimal grid login page", + LLGridManager::getInstance()->getLoginPage("minimal.long.name"), + std::string("http://minimal.long.name/app/login/")); + } - + + // validate grid selection template<> template<> void viewerNetworkTestObject::test<7>() - { - LLSD loginURI = LLSD::emptyArray(); - LLSD grid = LLSD::emptyMap(); + { // adding a grid with simply a name will populate the values. - grid[GRID_VALUE] = "myaddedgrid"; + llofstream gridfile("grid_test.xml"); + gridfile << gSampleGridFile; + gridfile.close(); LLGridManager::getInstance()->initialize("grid_test.xml"); - LLGridManager::getInstance()->addGrid(grid); - LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com"); - ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("Agni")); - ensure_equals("getGrid", LLGridManager::getInstance()->getGrid(), + + LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com"); + ensure_equals("getGridLabel", + LLGridManager::getInstance()->getGridLabel(), + std::string("Second Life Main Grid (Agni)")); + ensure_equals("getGridId", + LLGridManager::getInstance()->getGridId(), + std::string("Agni")); + ensure_equals("getGrid", + LLGridManager::getInstance()->getGrid(), std::string("util.agni.lindenlab.com")); - ensure_equals("getHelperURI", LLGridManager::getInstance()->getHelperURI(), + ensure_equals("getHelperURI", + LLGridManager::getInstance()->getHelperURI(), std::string("https://secondlife.com/helpers/")); - ensure_equals("getLoginPage", LLGridManager::getInstance()->getLoginPage(), + ensure_equals("getLoginPage", + LLGridManager::getInstance()->getLoginPage(), std::string("http://viewer-login.agni.lindenlab.com/")); - ensure_equals("getLoginPage2", LLGridManager::getInstance()->getLoginPage("util.agni.lindenlab.com"), - std::string("http://viewer-login.agni.lindenlab.com/")); - ensure("Is Agni a production grid", LLGridManager::getInstance()->isInProductionGrid()); + ensure("Is Agni a production grid", LLGridManager::getInstance()->isInProductionGrid()); std::vector<std::string> uris; LLGridManager::getInstance()->getLoginURIs(uris); - ensure_equals("getLoginURIs size", uris.size(), 1); - ensure_equals("getLoginURIs", uris[0], + ensure_equals("getLoginURIs size", 1, uris.size()); + ensure_equals("getLoginURIs", + uris[0], std::string("https://login.agni.lindenlab.com/cgi-bin/login.cgi")); - LLGridManager::getInstance()->setGridChoice("myaddedgrid"); - ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("myaddedgrid")); - ensure("Is myaddedgrid a production grid", !LLGridManager::getInstance()->isInProductionGrid()); - - LLGridManager::getInstance()->setFavorite(); - LLGridManager::getInstance()->getGridInfo("myaddedgrid", grid); - ensure("setting favorite", grid.has(GRID_IS_FAVORITE_VALUE)); - } - - // name based grid population - template<> template<> - void viewerNetworkTestObject::test<8>() - { - LLGridManager::getInstance()->initialize("grid_test.xml"); - LLSD grid = LLSD::emptyMap(); - // adding a grid with simply a name will populate the values. - grid[GRID_VALUE] = "myaddedgrid"; - LLGridManager::getInstance()->addGrid(grid); - LLGridManager::getInstance()->getGridInfo("myaddedgrid", grid); - - ensure_equals("name based grid has name value", - grid[GRID_VALUE].asString(), - std::string("myaddedgrid")); - ensure_equals("name based grid has label value", - grid[GRID_LABEL_VALUE].asString(), - std::string("myaddedgrid")); - ensure_equals("name based grid has name value", - grid[GRID_HELPER_URI_VALUE].asString(), - std::string("https://myaddedgrid/helpers/")); - ensure_equals("name based grid has name value", - grid[GRID_LOGIN_PAGE_VALUE].asString(), - std::string("http://myaddedgrid/app/login/")); - ensure("name based grid has array loginuri", - grid[GRID_LOGIN_URI_VALUE].isArray()); - ensure_equals("name based grid has single login uri value", - grid[GRID_LOGIN_URI_VALUE].size(), 1); - ensure_equals("Name based grid login uri is correct", - grid[GRID_LOGIN_URI_VALUE][0].asString(), - std::string("https://myaddedgrid/cgi-bin/login.cgi")); - ensure("name based grid is not a favorite yet", - !grid.has(GRID_IS_FAVORITE_VALUE)); - ensure("name based grid does not have system setting", - !grid.has(GRID_IS_SYSTEM_GRID_VALUE)); - - llofstream gridfile("grid_test.xml"); - gridfile << gSampleGridFile; - gridfile.close(); - } - - // persistence of the grid list with an empty gridfile. - template<> template<> - void viewerNetworkTestObject::test<9>() - { - // try with initial grid list without a grid file, - // without setting the grid to a saveable favorite. - LLGridManager::getInstance()->initialize("grid_test.xml"); - LLSD grid = LLSD::emptyMap(); - grid[GRID_VALUE] = std::string("mynewgridname"); - LLGridManager::getInstance()->addGrid(grid); - LLGridManager::getInstance()->saveFavorites(); - ensure("Grid file exists after saving", - LLFile::isfile("grid_test.xml")); - LLGridManager::getInstance()->initialize("grid_test.xml"); - // should not be there - std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure("New grid wasn't added to persisted list without being marked a favorite", - known_grids.find(std::string("mynewgridname")) == known_grids.end()); - - // mark a grid a favorite to make sure it's persisted - LLGridManager::getInstance()->addGrid(grid); - LLGridManager::getInstance()->setGridChoice("mynewgridname"); - LLGridManager::getInstance()->setFavorite(); - LLGridManager::getInstance()->saveFavorites(); - ensure("Grid file exists after saving", - LLFile::isfile("grid_test.xml")); - LLGridManager::getInstance()->initialize("grid_test.xml"); - // should not be there - known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure("New grid wasn't added to persisted list after being marked a favorite", - known_grids.find(std::string("mynewgridname")) != - known_grids.end()); - } - - // persistence of the grid file with existing gridfile - template<> template<> - void viewerNetworkTestObject::test<10>() - { - - llofstream gridfile("grid_test.xml"); - gridfile << gSampleGridFile; - gridfile.close(); - - LLGridManager::getInstance()->initialize("grid_test.xml"); - LLSD grid = LLSD::emptyMap(); - grid[GRID_VALUE] = std::string("mynewgridname"); - LLGridManager::getInstance()->addGrid(grid); - LLGridManager::getInstance()->saveFavorites(); - // validate we didn't lose existing favorites - LLGridManager::getInstance()->initialize("grid_test.xml"); - std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure("New grid wasn't added to persisted list after being marked a favorite", - known_grids.find(std::string("grid1")) != - known_grids.end()); - - // add a grid - LLGridManager::getInstance()->addGrid(grid); - LLGridManager::getInstance()->setGridChoice("mynewgridname"); - LLGridManager::getInstance()->setFavorite(); - LLGridManager::getInstance()->saveFavorites(); - known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure("New grid wasn't added to persisted list after being marked a favorite", - known_grids.find(std::string("grid1")) != - known_grids.end()); - known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure("New grid wasn't added to persisted list after being marked a favorite", - known_grids.find(std::string("mynewgridname")) != - known_grids.end()); + + LLGridManager::getInstance()->setGridChoice("altgrid.long.name"); + ensure_equals("getGridLabel", + LLGridManager::getInstance()->getGridLabel(), + std::string("Alternative Grid")); + ensure_equals("getGridId", + LLGridManager::getInstance()->getGridId(), + std::string("AltGrid")); + ensure("alternative grid is not a system grid", + !LLGridManager::getInstance()->isSystemGrid()); + ensure("alternative grid is not a production grid", + !LLGridManager::getInstance()->isInProductionGrid()); } + } diff --git a/indra/newview/tests/llworldmipmap_test.cpp b/indra/newview/tests/llworldmipmap_test.cpp index 4c0959d1a9..e7ef017760 100644 --- a/indra/newview/tests/llworldmipmap_test.cpp +++ b/indra/newview/tests/llworldmipmap_test.cpp @@ -100,9 +100,9 @@ namespace tut { S32 level = mMap->scaleToLevel(0.0); ensure("scaleToLevel() test 1 failed", level == LLWorldMipmap::MAP_LEVELS); - level = mMap->scaleToLevel(LLWorldMipmap::MAP_TILE_SIZE); + level = mMap->scaleToLevel((F32)LLWorldMipmap::MAP_TILE_SIZE); ensure("scaleToLevel() test 2 failed", level == 1); - level = mMap->scaleToLevel(10 * LLWorldMipmap::MAP_TILE_SIZE); + level = mMap->scaleToLevel(10.f * LLWorldMipmap::MAP_TILE_SIZE); ensure("scaleToLevel() test 3 failed", level == 1); } // Test 2 : globalToMipmap() diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 0931c4ec9b..e7108141ee 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -28,6 +28,7 @@ $/LicenseInfo$ """ import sys import os.path +import errno import re import tarfile import time @@ -74,23 +75,30 @@ class ViewerManifest(LLManifest): # include the list of Lindens (if any) # see https://wiki.lindenlab.com/wiki/Generated_Linden_Credits linden_names_path = os.getenv("LINDEN_CREDITS") - if linden_names_path : + if not linden_names_path : + print "No 'LINDEN_CREDITS' specified in environment, using built-in list" + else: try: linden_file = open(linden_names_path,'r') + except IOError: + print "No Linden names found at '%s', using built-in list" % linden_names_path + else: # all names should be one line, but the join below also converts to a string linden_names = ', '.join(linden_file.readlines()) self.put_in_file(linden_names, "lindens.txt") linden_file.close() print "Linden names extracted from '%s'" % linden_names_path self.file_list.append([linden_names_path,self.dst_path_of("lindens.txt")]) - except IOError: - print "No Linden names found at '%s', using built-in list" % linden_names_path - pass - else : - print "No 'LINDEN_CREDITS' specified in environment, using built-in list" # ... and the entire windlight directory self.path("windlight") + + # ... and the included spell checking dictionaries + pkgdir = os.path.join(self.args['build'], os.pardir, 'packages') + if self.prefix(src=pkgdir,dst=""): + self.path("dictionaries") + self.end_prefix(pkgdir) + self.end_prefix("app_settings") if self.prefix(src="character"): @@ -107,7 +115,6 @@ class ViewerManifest(LLManifest): # skins if self.prefix(src="skins"): - self.path("paths.xml") # include the entire textures directory recursively if self.prefix(src="*/textures"): self.path("*/*.tga") @@ -125,11 +132,18 @@ class ViewerManifest(LLManifest): self.path("*/*.xml") # Local HTML files (e.g. loading screen) - if self.prefix(src="*/html"): + # The claim is that we never use local html files any + # longer. But rather than commenting out this block, let's + # rename every html subdirectory as html.old. That way, if + # we're wrong, a user actually does have the relevant + # files; s/he just needs to rename every html.old + # directory back to html to recover them. + if self.prefix(src="*/html", dst="*/html.old"): self.path("*.png") self.path("*/*/*.html") self.path("*/*/*.gif") self.end_prefix("*/html") + self.end_prefix("skins") # local_assets dir (for pre-cached textures) @@ -142,14 +156,9 @@ class ViewerManifest(LLManifest): self.path("gpu_table.txt") # The summary.json file gets left in the base checkout dir by - # build.sh. It's only created for a build.sh build, therefore we - # have to check whether it exists. :-P - summary_json = "summary.json" - summary_json_path = os.path.join(os.pardir, os.pardir, summary_json) - if os.path.exists(os.path.join(self.get_src_prefix(), summary_json_path)): - self.path(summary_json_path, summary_json) - else: - print "No %s" % os.path.join(self.get_src_prefix(), summary_json_path) + # build.sh. It's only created for a build.sh build. + if not self.path2basename(os.path.join(os.pardir, os.pardir), "summary.json"): + print "No summary.json file" def login_channel(self): """Channel reported for login and upgrade purposes ONLY; @@ -320,13 +329,13 @@ class WindowsManifest(ViewerManifest): self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe()) # Plugin host application - self.path(os.path.join(os.pardir, - 'llplugin', 'slplugin', self.args['configuration'], "slplugin.exe"), - "slplugin.exe") + self.path2basename(os.path.join(os.pardir, + 'llplugin', 'slplugin', self.args['configuration']), + "slplugin.exe") #self.disable_manifest_check() - self.path(src="../viewer_components/updater/scripts/windows/update_install.bat", dst="update_install.bat") + self.path2basename("../viewer_components/updater/scripts/windows", "update_install.bat") # Get shared libs from the shared libs staging directory if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']), dst=""): @@ -360,9 +369,7 @@ class WindowsManifest(ViewerManifest): # Get fmod dll, continue if missing - try: - self.path("fmod.dll") - except: + if not self.path("fmod.dll"): print "Skipping fmod.dll" # For textures @@ -393,6 +400,9 @@ class WindowsManifest(ViewerManifest): self.path("ssleay32.dll") self.path("libeay32.dll") + # Hunspell + self.path("libhunspell.dll") + # For google-perftools tcmalloc allocator. try: if self.args['configuration'].lower() == 'debug': @@ -527,6 +537,7 @@ class WindowsManifest(ViewerManifest): result += 'File ' + pkg_file + '\n' else: result += 'Delete ' + wpath(os.path.join('$INSTDIR', rel_file)) + '\n' + # at the end of a delete, just rmdir all the directories if not install: deleted_file_dirs = [os.path.dirname(pair[1].replace(self.get_dst_prefix()+os.path.sep,'')) for pair in self.file_list] @@ -659,6 +670,7 @@ class DarwinManifest(ViewerManifest): # copy additional libs in <bundle>/Contents/MacOS/ self.path("../packages/lib/release/libndofdev.dylib", dst="Resources/libndofdev.dylib") + self.path("../packages/lib/release/libhunspell-1.3.0.dylib", dst="Resources/libhunspell-1.3.0.dylib") self.path("../viewer_components/updater/scripts/darwin/update_install", "MacOS/update_install") @@ -699,85 +711,82 @@ class DarwinManifest(ViewerManifest): self.path("uk.lproj") self.path("zh-Hans.lproj") - libdir = "../packages/lib/release" - dylibs = {} + def path_optional(src, dst): + """ + For a number of our self.path() calls, not only do we want + to deal with the absence of src, we also want to remember + which were present. Return either an empty list (absent) + or a list containing dst (present). Concatenate these + return values to get a list of all libs that are present. + """ + if self.path(src, dst): + return [dst] + print "Skipping %s" % dst + return [] - # Need to get the llcommon dll from any of the build directories as well - lib = "llcommon" - libfile = "lib%s.dylib" % lib - try: - self.path(self.find_existing_file(os.path.join(os.pardir, - lib, - self.args['configuration'], - libfile), - os.path.join(libdir, libfile)), - dst=libfile) - except RuntimeError: - print "Skipping %s" % libfile - dylibs[lib] = False - else: - dylibs[lib] = True - - if dylibs["llcommon"]: - for libfile in ("libapr-1.0.dylib", - "libaprutil-1.0.dylib", - "libexpat.1.5.2.dylib", - "libexception_handler.dylib", - "libGLOD.dylib", - "libcollada14dom.dylib" - ): - self.path(os.path.join(libdir, libfile), libfile) - - # SLVoice and vivox lols - for libfile in ('libsndfile.dylib', 'libvivoxoal.dylib', 'libortp.dylib', \ - 'libvivoxsdk.dylib', 'libvivoxplatform.dylib', 'SLVoice') : - self.path(os.path.join(libdir, libfile), libfile) + libdir = "../packages/lib/release" + # dylibs is a list of all the .dylib files we expect to need + # in our bundled sub-apps. For each of these we'll create a + # symlink from sub-app/Contents/Resources to the real .dylib. + # Need to get the llcommon dll from any of the build directories as well. + libfile = "libllcommon.dylib" + dylibs = path_optional(self.find_existing_file(os.path.join(os.pardir, + "llcommon", + self.args['configuration'], + libfile), + os.path.join(libdir, libfile)), + dst=libfile) + + for libfile in ( + "libapr-1.0.dylib", + "libaprutil-1.0.dylib", + "libcollada14dom.dylib", + "libexpat.1.5.2.dylib", + "libexception_handler.dylib", + "libGLOD.dylib", + ): + dylibs += path_optional(os.path.join(libdir, libfile), libfile) + + # SLVoice and vivox lols, no symlinks needed + for libfile in ( + 'libortp.dylib', + 'libsndfile.dylib', + 'libvivoxoal.dylib', + 'libvivoxsdk.dylib', + 'libvivoxplatform.dylib', + 'SLVoice', + ): + self.path2basename(libdir, libfile) - try: - # FMOD for sound - self.path(self.args['configuration'] + "/libfmodwrapper.dylib", "libfmodwrapper.dylib") - except: - print "Skipping FMOD - not found" + # FMOD for sound + libfile = "libfmodwrapper.dylib" + path_optional(os.path.join(self.args['configuration'], libfile), libfile) # our apps - self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app") - self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app") - - # plugin launcher - self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin.app", "SLPlugin.app") - - # our apps dependencies on shared libs - if dylibs["llcommon"]: - mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources") - mac_updater_res_path = self.dst_path_of("mac-updater.app/Contents/Resources") - slplugin_res_path = self.dst_path_of("SLPlugin.app/Contents/Resources") - for libfile in ("libllcommon.dylib", - "libapr-1.0.dylib", - "libaprutil-1.0.dylib", - "libexpat.1.5.2.dylib", - "libexception_handler.dylib", - "libGLOD.dylib", - "libcollada14dom.dylib" - ): - target_lib = os.path.join('../../..', libfile) - self.run_command("ln -sf %(target)r %(link)r" % - {'target': target_lib, - 'link' : os.path.join(mac_crash_logger_res_path, libfile)} - ) - self.run_command("ln -sf %(target)r %(link)r" % - {'target': target_lib, - 'link' : os.path.join(mac_updater_res_path, libfile)} - ) - self.run_command("ln -sf %(target)r %(link)r" % - {'target': target_lib, - 'link' : os.path.join(slplugin_res_path, libfile)} - ) + for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"), + ("mac_updater", "mac-updater.app"), + # plugin launcher + (os.path.join("llplugin", "slplugin"), "SLPlugin.app"), + ): + self.path2basename(os.path.join(os.pardir, + app_bld_dir, self.args['configuration']), + app) + + # our apps dependencies on shared libs + # for each app, for each dylib we collected in dylibs, + # create a symlink to the real copy of the dylib. + resource_path = self.dst_path_of(os.path.join(app, "Contents", "Resources")) + for libfile in dylibs: + symlinkf(os.path.join(os.pardir, os.pardir, os.pardir, libfile), + os.path.join(resource_path, libfile)) # plugins if self.prefix(src="", dst="llplugin"): - self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib") - self.path("../media_plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib") - self.path("../packages/lib/release/libllqtwebkit.dylib", "libllqtwebkit.dylib") + self.path2basename("../media_plugins/quicktime/" + self.args['configuration'], + "media_plugin_quicktime.dylib") + self.path2basename("../media_plugins/webkit/" + self.args['configuration'], + "media_plugin_webkit.dylib") + self.path2basename("../packages/lib/release", "libllqtwebkit.dylib") self.end_prefix("llplugin") @@ -805,6 +814,30 @@ class DarwinManifest(ViewerManifest): self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script)) def package_finish(self): + # Sign the app if requested. + if 'signature' in self.args: + identity = self.args['signature'] + if identity == '': + identity = 'Developer ID Application' + + # Look for an environment variable set via build.sh when running in Team City. + try: + build_secrets_checkout = os.environ['build_secrets_checkout'] + except KeyError: + pass + else: + # variable found so use it to unlock keyvchain followed by codesign + home_path = os.environ['HOME'] + keychain_pwd_path = os.path.join(build_secrets_checkout,'code-signing-osx','password.txt') + keychain_pwd = open(keychain_pwd_path).read().rstrip() + + self.run_command('security unlock-keychain -p "%s" "%s/Library/Keychains/viewer.keychain"' % ( keychain_pwd, home_path ) ) + self.run_command('codesign --verbose --force --keychain "%(home_path)s/Library/Keychains/viewer.keychain" --sign %(identity)r %(bundle)r' % { + 'home_path' : home_path, + 'identity': identity, + 'bundle': self.get_dst_prefix() + }) + channel_standin = 'Second Life Viewer' # hah, our default channel is not usable on its own if not self.default_channel(): channel_standin = self.channel() @@ -920,20 +953,24 @@ class LinuxManifest(ViewerManifest): self.path("client-readme-voice.txt","README-linux-voice.txt") self.path("client-readme-joystick.txt","README-linux-joystick.txt") self.path("wrapper.sh","secondlife") - self.path("handle_secondlifeprotocol.sh", "etc/handle_secondlifeprotocol.sh") - self.path("register_secondlifeprotocol.sh", "etc/register_secondlifeprotocol.sh") - self.path("refresh_desktop_app_entry.sh", "etc/refresh_desktop_app_entry.sh") - self.path("launch_url.sh","etc/launch_url.sh") + if self.prefix(src="", dst="etc"): + self.path("handle_secondlifeprotocol.sh") + self.path("register_secondlifeprotocol.sh") + self.path("refresh_desktop_app_entry.sh") + self.path("launch_url.sh") + self.end_prefix("etc") self.path("install.sh") self.end_prefix("linux_tools") # Create an appropriate gridargs.dat for this package, denoting required grid. self.put_in_file(self.flags_list(), 'etc/gridargs.dat') - self.path("secondlife-bin","bin/do-not-directly-run-secondlife-bin") - self.path("../linux_crash_logger/linux-crash-logger","bin/linux-crash-logger.bin") - self.path("../linux_updater/linux-updater", "bin/linux-updater.bin") - self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin") + if self.prefix(src="", dst="bin"): + self.path("secondlife-bin","do-not-directly-run-secondlife-bin") + self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") + self.path2basename("../llplugin/slplugin", "SLPlugin") + self.path2basename("../viewer_components/updater/scripts/linux", "update_install") + self.end_prefix("bin") if self.prefix("res-sdl"): self.path("*") @@ -949,17 +986,13 @@ class LinuxManifest(ViewerManifest): self.end_prefix("res-sdl") self.end_prefix(icon_path) - self.path("../viewer_components/updater/scripts/linux/update_install", "bin/update_install") - # plugins if self.prefix(src="", dst="bin/llplugin"): - self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so") + self.path2basename("../media_plugins/webkit", "libmedia_plugin_webkit.so") self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so") self.end_prefix("bin/llplugin") - try: - self.path("../llcommon/libllcommon.so", "lib/libllcommon.so") - except: + if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"): print "Skipping llcommon.so (assuming llcommon was linked statically)" self.path("featuretable_linux.txt") @@ -983,9 +1016,7 @@ class LinuxManifest(ViewerManifest): else: installer_name += '_' + self.channel_oneword().upper() - if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): - print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build" - self.run_command("find %(d)r/bin %(d)r/lib -type f \\! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure + self.strip_binaries() # Fix access permissions self.run_command(""" @@ -1020,6 +1051,11 @@ class LinuxManifest(ViewerManifest): 'dst': self.get_dst_prefix(), 'inst': self.build_path_of(installer_name)}) + def strip_binaries(self): + if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): + print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build" + self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure + class Linux_i686Manifest(LinuxManifest): def construct(self): super(Linux_i686Manifest, self).construct() @@ -1027,39 +1063,64 @@ class Linux_i686Manifest(LinuxManifest): 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("libapr-1.so.0.4.5") self.path("libaprutil-1.so") self.path("libaprutil-1.so.0") - self.path("libaprutil-1.so.0.3.10") + self.path("libaprutil-1.so.0.4.1") + self.path("libboost_program_options-mt.so.*") + self.path("libboost_regex-mt.so.*") + self.path("libboost_thread-mt.so.*") + self.path("libboost_filesystem-mt.so.*") + self.path("libboost_signals-mt.so.*") + self.path("libboost_system-mt.so.*") self.path("libbreakpad_client.so.0.0.0") self.path("libbreakpad_client.so.0") 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("libdirectfb-1.4.so.5") + self.path("libfusion-1.4.so.5") + self.path("libdirect-1.4.so.5*") + self.path("libhunspell-1.3.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 + # KLUDGE: As of 2012-04-11, the 'fontconfig' package installs + # libfontconfig.so.1.4.4, along with symlinks libfontconfig.so.1 + # and libfontconfig.so. Before we added support for library-file + # wildcards, though, this self.path() call specifically named + # libfontconfig.so.1.4.4 WITHOUT also copying the symlinks. When I + # (nat) changed the call to self.path("libfontconfig.so.*"), we + # ended up with the libfontconfig.so.1 symlink in the target + # directory as well. But guess what! At least on Ubuntu 10.04, + # certain viewer fonts look terrible with libfontconfig.so.1 + # present in the target directory. Removing that symlink suffices + # to improve them. I suspect that means we actually do better when + # the viewer fails to find our packaged libfontconfig.so*, falling + # back on the system one instead -- but diagnosing and fixing that + # is a bit out of scope for the present project. Meanwhile, this + # particular wildcard specification gets us exactly what the + # previous call did, without having to explicitly state the + # version number. + self.path("libfontconfig.so.*.*") + try: + self.path("libtcmalloc.so*") #formerly called google perf tools + pass + except: + print "tcmalloc files not found, skipping" + pass + try: self.path("libfmod-3.75.so") pass @@ -1080,9 +1141,7 @@ class Linux_i686Manifest(LinuxManifest): self.path("libvivoxplatform.so") self.end_prefix("lib") - if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): - print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build" - self.run_command("find %(d)r/bin %(d)r/lib -type f \\! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure + self.strip_binaries() class Linux_x86_64Manifest(LinuxManifest): @@ -1094,5 +1153,25 @@ class Linux_x86_64Manifest(LinuxManifest): ################################################################ +def symlinkf(src, dst): + """ + Like ln -sf, but uses os.symlink() instead of running ln. + """ + try: + os.symlink(src, dst) + except OSError, err: + if err.errno != errno.EEXIST: + raise + # We could just blithely attempt to remove and recreate the target + # file, but that strategy doesn't work so well if we don't have + # permissions to remove it. Check to see if it's already the + # symlink we want, which is the usual reason for EEXIST. + if not (os.path.islink(dst) and os.readlink(dst) == src): + # Here either dst isn't a symlink or it's the wrong symlink. + # Remove and recreate. Caller will just have to deal with any + # exceptions at this stage. + os.remove(dst) + os.symlink(src, dst) + if __name__ == "__main__": main() |